@factpulse/sdk 2.0.11 → 2.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/SETUP_GITHUB_ACTIONS.md +70 -8
- package/.github/workflows/publish-npm.yml +5 -7
- package/.openapi-generator/FILES +58 -26
- package/CHANGELOG.md +3 -3
- package/README.md +165 -116
- package/api/afnorpdppaapi.ts +149 -0
- package/api/chorus-pro-api.ts +151 -181
- package/api/traitement-facture-api.ts +12 -12
- package/api/vrification-pdfxmlapi.ts +536 -0
- package/api.ts +1 -0
- package/dist/api/afnorpdppaapi.d.ts +65 -0
- package/dist/api/afnorpdppaapi.js +142 -1
- package/dist/api/afnorpdppadirectory-service-api.js +4 -1
- package/dist/api/afnorpdppaflow-service-api.js +4 -1
- package/dist/api/chorus-pro-api.d.ts +168 -103
- package/dist/api/chorus-pro-api.js +155 -160
- package/dist/api/sant-api.js +4 -1
- package/dist/api/traitement-facture-api.d.ts +12 -12
- package/dist/api/traitement-facture-api.js +16 -13
- package/dist/api/utilisateur-api.js +4 -1
- package/dist/api/vrification-pdfxmlapi.d.ts +237 -0
- package/dist/api/vrification-pdfxmlapi.js +514 -0
- package/dist/api.d.ts +1 -0
- package/dist/api.js +1 -0
- package/dist/base.js +4 -1
- package/dist/esm/api/afnorpdppaapi.d.ts +65 -0
- package/dist/esm/api/afnorpdppaapi.js +139 -1
- package/dist/esm/api/chorus-pro-api.d.ts +168 -103
- package/dist/esm/api/chorus-pro-api.js +151 -159
- package/dist/esm/api/traitement-facture-api.d.ts +12 -12
- package/dist/esm/api/traitement-facture-api.js +12 -12
- package/dist/esm/api/vrification-pdfxmlapi.d.ts +237 -0
- package/dist/esm/api/vrification-pdfxmlapi.js +504 -0
- package/dist/esm/api.d.ts +1 -0
- package/dist/esm/api.js +1 -0
- package/dist/esm/models/{utilisateur.d.ts → apierror.d.ts} +12 -15
- package/dist/esm/models/beneficiaire.d.ts +26 -0
- package/dist/esm/models/bounding-box-schema.d.ts +44 -0
- package/dist/esm/models/cadre-de-facturation.d.ts +3 -1
- package/dist/esm/models/champ-verifie-schema.d.ts +42 -0
- package/dist/esm/models/code-cadre-facturation.d.ts +3 -0
- package/dist/esm/models/code-cadre-facturation.js +3 -0
- package/dist/esm/models/destinataire.d.ts +1 -1
- package/dist/esm/models/dimension-page-schema.d.ts +24 -0
- package/dist/esm/models/{quota-info.d.ts → direction-flux.d.ts} +6 -8
- package/dist/esm/models/direction-flux.js +20 -0
- package/dist/esm/models/error-level.d.ts +16 -0
- package/dist/esm/models/error-level.js +17 -0
- package/dist/esm/models/{body-ajouter-fichier-api-v1-chorus-pro-transverses-ajouter-fichier-post.d.ts → error-source.d.ts} +11 -9
- package/dist/esm/models/error-source.js +23 -0
- package/dist/esm/models/facture-entrante.d.ts +68 -0
- package/dist/esm/models/facture-factur-x.d.ts +2 -0
- package/dist/esm/models/{body-rechercher-factures-destinataire-api-v1-chorus-pro-factures-rechercher-destinataire-post.d.ts → flux-resume.d.ts} +12 -8
- package/dist/esm/models/format-facture.d.ts +20 -0
- package/dist/esm/models/format-facture.js +21 -0
- package/dist/esm/models/fournisseur-entrant.d.ts +29 -0
- package/dist/esm/models/fournisseur.d.ts +1 -1
- package/dist/esm/models/index.d.ts +28 -13
- package/dist/esm/models/index.js +28 -13
- package/dist/esm/models/ligne-de-tva.d.ts +3 -1
- package/dist/esm/models/nature-operation.d.ts +31 -0
- package/dist/esm/models/nature-operation.js +32 -0
- package/dist/esm/models/note-obligatoire-schema.d.ts +34 -0
- package/dist/esm/models/note.d.ts +2 -2
- package/dist/esm/models/pdpcredentials.d.ts +33 -0
- package/dist/esm/models/profil-flux.d.ts +20 -0
- package/dist/esm/models/profil-flux.js +21 -0
- package/dist/esm/models/{body-completer-facture-api-v1-chorus-pro-factures-completer-post.d.ts → reponse-healthcheck-afnor.d.ts} +16 -8
- package/dist/esm/models/reponse-recherche-flux.d.ts +33 -0
- package/dist/esm/models/reponse-soumission-flux.d.ts +38 -0
- package/dist/esm/models/reponse-verification-succes.d.ts +56 -0
- package/dist/esm/models/reponse-verification-succes.js +14 -0
- package/dist/esm/models/requete-recherche-flux.d.ts +34 -0
- package/dist/esm/models/requete-recherche-flux.js +14 -0
- package/dist/esm/models/requete-soumission-flux.d.ts +31 -0
- package/dist/esm/models/requete-soumission-flux.js +14 -0
- package/dist/esm/models/statut-acquittement.d.ts +20 -0
- package/dist/esm/models/statut-acquittement.js +21 -0
- package/dist/esm/models/statut-champ-api.d.ts +22 -0
- package/dist/esm/models/statut-champ-api.js +23 -0
- package/dist/esm/models/syntaxe-flux.d.ts +22 -0
- package/dist/esm/models/syntaxe-flux.js +23 -0
- package/dist/esm/models/type-document.d.ts +37 -0
- package/dist/esm/models/type-document.js +38 -0
- package/dist/esm/models/type-facture.d.ts +65 -3
- package/dist/esm/models/type-facture.js +65 -3
- package/dist/esm/models/type-flux.d.ts +22 -0
- package/dist/esm/models/type-flux.js +23 -0
- package/dist/esm/models/validation-error-detail.d.ts +32 -0
- package/dist/esm/models/validation-error-detail.js +14 -0
- package/dist/esm/src/helpers/client.d.ts +265 -0
- package/dist/esm/src/helpers/client.js +817 -0
- package/dist/esm/src/helpers/exceptions.d.ts +23 -0
- package/dist/esm/src/helpers/exceptions.js +27 -0
- package/dist/esm/src/helpers/index.d.ts +3 -0
- package/dist/esm/src/helpers/index.js +6 -0
- package/dist/models/{utilisateur.d.ts → apierror.d.ts} +12 -15
- package/dist/models/beneficiaire.d.ts +26 -0
- package/dist/models/bounding-box-schema.d.ts +44 -0
- package/dist/models/cadre-de-facturation.d.ts +3 -1
- package/dist/models/champ-verifie-schema.d.ts +42 -0
- package/dist/models/code-cadre-facturation.d.ts +3 -0
- package/dist/models/code-cadre-facturation.js +3 -0
- package/dist/models/destinataire.d.ts +1 -1
- package/dist/models/dimension-page-schema.d.ts +24 -0
- package/dist/models/{quota-info.d.ts → direction-flux.d.ts} +6 -8
- package/dist/models/direction-flux.js +23 -0
- package/dist/models/error-level.d.ts +16 -0
- package/dist/models/error-level.js +20 -0
- package/dist/models/error-source.d.ts +22 -0
- package/dist/models/error-source.js +26 -0
- package/dist/models/facture-entrante.d.ts +68 -0
- package/dist/models/facture-factur-x.d.ts +2 -0
- package/dist/models/flux-resume.d.ts +24 -0
- package/dist/models/format-facture.d.ts +20 -0
- package/dist/models/format-facture.js +24 -0
- package/dist/models/fournisseur-entrant.d.ts +29 -0
- package/dist/models/fournisseur.d.ts +1 -1
- package/dist/models/index.d.ts +28 -13
- package/dist/models/index.js +28 -13
- package/dist/models/ligne-de-tva.d.ts +3 -1
- package/dist/models/nature-operation.d.ts +31 -0
- package/dist/models/nature-operation.js +35 -0
- package/dist/models/note-obligatoire-schema.d.ts +34 -0
- package/dist/models/note.d.ts +2 -2
- package/dist/models/pdpcredentials.d.ts +33 -0
- package/dist/models/profil-flux.d.ts +20 -0
- package/dist/models/profil-flux.js +24 -0
- package/dist/{esm/models/body-recycler-facture-api-v1-chorus-pro-factures-recycler-post.d.ts → models/reponse-healthcheck-afnor.d.ts} +16 -8
- package/dist/models/reponse-recherche-flux.d.ts +33 -0
- package/dist/models/reponse-soumission-flux.d.ts +38 -0
- package/dist/models/reponse-verification-succes.d.ts +56 -0
- package/dist/models/reponse-verification-succes.js +15 -0
- package/dist/models/requete-recherche-flux.d.ts +34 -0
- package/dist/models/requete-recherche-flux.js +15 -0
- package/dist/models/requete-soumission-flux.d.ts +31 -0
- package/dist/models/requete-soumission-flux.js +15 -0
- package/dist/models/statut-acquittement.d.ts +20 -0
- package/dist/models/statut-acquittement.js +24 -0
- package/dist/models/statut-champ-api.d.ts +22 -0
- package/dist/models/statut-champ-api.js +26 -0
- package/dist/models/syntaxe-flux.d.ts +22 -0
- package/dist/models/syntaxe-flux.js +26 -0
- package/dist/models/type-document.d.ts +37 -0
- package/dist/models/type-document.js +41 -0
- package/dist/models/type-facture.d.ts +65 -3
- package/dist/models/type-facture.js +65 -3
- package/dist/models/type-flux.d.ts +22 -0
- package/dist/models/type-flux.js +26 -0
- package/dist/models/validation-error-detail.d.ts +32 -0
- package/dist/models/validation-error-detail.js +15 -0
- package/dist/src/helpers/client.d.ts +265 -0
- package/dist/src/helpers/client.js +866 -0
- package/dist/src/helpers/exceptions.d.ts +23 -0
- package/dist/src/helpers/exceptions.js +35 -0
- package/dist/src/helpers/index.d.ts +3 -0
- package/dist/src/helpers/index.js +23 -0
- package/docs/AFNORPDPPAApi.md +108 -0
- package/docs/APIError.md +25 -0
- package/docs/Beneficiaire.md +31 -0
- package/docs/BoundingBoxSchema.md +33 -0
- package/docs/CadreDeFacturation.md +3 -1
- package/docs/ChampVerifieSchema.md +37 -0
- package/docs/ChorusProApi.md +54 -69
- package/docs/CodeCadreFacturation.md +1 -0
- package/docs/DimensionPageSchema.md +23 -0
- package/docs/DirectionFlux.md +11 -0
- package/docs/ErrorLevel.md +10 -0
- package/docs/ErrorSource.md +22 -0
- package/docs/FactureEntrante.md +57 -0
- package/docs/FactureFacturX.md +2 -0
- package/docs/FluxResume.md +35 -0
- package/docs/FormatFacture.md +13 -0
- package/docs/FournisseurEntrant.md +35 -0
- package/docs/LigneDeTVA.md +5 -1
- package/docs/NatureOperation.md +35 -0
- package/docs/Note.md +4 -4
- package/docs/NoteObligatoireSchema.md +33 -0
- package/docs/PDPCredentials.md +29 -0
- package/docs/ProfilFlux.md +13 -0
- package/docs/ReponseHealthcheckAFNOR.md +25 -0
- package/docs/ReponseRechercheFlux.md +27 -0
- package/docs/ReponseSoumissionFlux.md +33 -0
- package/docs/ReponseVerificationSucces.md +39 -0
- package/docs/RequeteRechercheFlux.md +37 -0
- package/docs/RequeteSoumissionFlux.md +31 -0
- package/docs/StatutAcquittement.md +13 -0
- package/docs/StatutChampAPI.md +17 -0
- package/docs/SyntaxeFlux.md +17 -0
- package/docs/TraitementFactureApi.md +3 -3
- package/docs/TypeDocument.md +17 -0
- package/docs/TypeFacture.md +31 -3
- package/docs/TypeFlux.md +17 -0
- package/docs/ValidationErrorDetail.md +29 -0
- package/docs/VrificationPDFXMLApi.md +335 -0
- package/models/{utilisateur.ts → apierror.ts} +12 -15
- package/models/beneficiaire.ts +34 -0
- package/models/bounding-box-schema.ts +50 -0
- package/models/cadre-de-facturation.ts +5 -1
- package/models/champ-verifie-schema.ts +54 -0
- package/models/code-cadre-facturation.ts +3 -0
- package/models/destinataire.ts +1 -1
- package/models/dimension-page-schema.ts +30 -0
- package/models/{quota-info.ts → direction-flux.ts} +10 -8
- package/models/error-level.ts +26 -0
- package/models/error-source.ts +32 -0
- package/models/facture-entrante.ts +82 -0
- package/models/facture-factur-x.ts +4 -0
- package/models/flux-resume.ts +30 -0
- package/models/format-facture.ts +30 -0
- package/models/fournisseur-entrant.ts +39 -0
- package/models/fournisseur.ts +1 -1
- package/models/index.ts +28 -13
- package/models/ligne-de-tva.ts +3 -1
- package/models/nature-operation.ts +41 -0
- package/models/{body-lister-services-structure-api-v1-chorus-pro-structures-id-structure-cpp-services-get.ts → note-obligatoire-schema.ts} +24 -5
- package/models/note.ts +2 -2
- package/models/pdpcredentials.ts +39 -0
- package/models/profil-flux.ts +30 -0
- package/models/reponse-healthcheck-afnor.ts +34 -0
- package/models/{body-ajouter-fichier-api-v1-chorus-pro-transverses-ajouter-fichier-post.ts → reponse-recherche-flux.ts} +21 -8
- package/models/{body-completer-facture-api-v1-chorus-pro-factures-completer-post.ts → reponse-soumission-flux.ts} +26 -10
- package/models/reponse-verification-succes.ts +68 -0
- package/models/requete-recherche-flux.ts +48 -0
- package/models/{body-rechercher-factures-destinataire-api-v1-chorus-pro-factures-rechercher-destinataire-post.ts → requete-soumission-flux.ts} +23 -6
- package/models/statut-acquittement.ts +30 -0
- package/models/statut-champ-api.ts +32 -0
- package/models/syntaxe-flux.ts +32 -0
- package/models/type-document.ts +47 -0
- package/models/type-facture.ts +65 -3
- package/models/type-flux.ts +32 -0
- package/models/validation-error-detail.ts +44 -0
- package/package.json +2 -2
- package/src/helpers/client.ts +882 -0
- package/src/helpers/exceptions.ts +32 -0
- package/src/helpers/index.ts +6 -0
- package/tsconfig.esm.json +1 -0
- package/tsconfig.json +1 -0
- package/dist/esm/models/body-lister-services-structure-api-v1-chorus-pro-structures-id-structure-cpp-services-get.d.ts +0 -17
- package/dist/esm/models/body-rechercher-factures-fournisseur-api-v1-chorus-pro-factures-rechercher-fournisseur-post.d.ts +0 -20
- package/dist/esm/models/body-telecharger-groupe-factures-api-v1-chorus-pro-factures-telecharger-groupe-post.d.ts +0 -20
- package/dist/esm/models/body-traiter-facture-recue-api-v1-chorus-pro-factures-traiter-facture-recue-post.d.ts +0 -20
- package/dist/esm/models/body-valideur-consulter-facture-api-v1-chorus-pro-factures-valideur-consulter-post.d.ts +0 -20
- package/dist/esm/models/body-valideur-rechercher-factures-api-v1-chorus-pro-factures-valideur-rechercher-post.d.ts +0 -20
- package/dist/esm/models/body-valideur-traiter-facture-api-v1-chorus-pro-factures-valideur-traiter-post.d.ts +0 -20
- package/dist/models/body-ajouter-fichier-api-v1-chorus-pro-transverses-ajouter-fichier-post.d.ts +0 -20
- package/dist/models/body-completer-facture-api-v1-chorus-pro-factures-completer-post.d.ts +0 -20
- package/dist/models/body-lister-services-structure-api-v1-chorus-pro-structures-id-structure-cpp-services-get.d.ts +0 -17
- package/dist/models/body-rechercher-factures-destinataire-api-v1-chorus-pro-factures-rechercher-destinataire-post.d.ts +0 -20
- package/dist/models/body-rechercher-factures-fournisseur-api-v1-chorus-pro-factures-rechercher-fournisseur-post.d.ts +0 -20
- package/dist/models/body-recycler-facture-api-v1-chorus-pro-factures-recycler-post.d.ts +0 -20
- package/dist/models/body-telecharger-groupe-factures-api-v1-chorus-pro-factures-telecharger-groupe-post.d.ts +0 -20
- package/dist/models/body-traiter-facture-recue-api-v1-chorus-pro-factures-traiter-facture-recue-post.d.ts +0 -20
- package/dist/models/body-valideur-consulter-facture-api-v1-chorus-pro-factures-valideur-consulter-post.d.ts +0 -20
- package/dist/models/body-valideur-rechercher-factures-api-v1-chorus-pro-factures-valideur-rechercher-post.d.ts +0 -20
- package/dist/models/body-valideur-traiter-facture-api-v1-chorus-pro-factures-valideur-traiter-post.d.ts +0 -20
- package/docs/BodyAjouterFichierApiV1ChorusProTransversesAjouterFichierPost.md +0 -24
- package/docs/BodyCompleterFactureApiV1ChorusProFacturesCompleterPost.md +0 -24
- package/docs/BodyListerServicesStructureApiV1ChorusProStructuresIdStructureCppServicesGet.md +0 -22
- package/docs/BodyRechercherFacturesDestinataireApiV1ChorusProFacturesRechercherDestinatairePost.md +0 -24
- package/docs/BodyRechercherFacturesFournisseurApiV1ChorusProFacturesRechercherFournisseurPost.md +0 -24
- package/docs/BodyRecyclerFactureApiV1ChorusProFacturesRecyclerPost.md +0 -24
- package/docs/BodyTelechargerGroupeFacturesApiV1ChorusProFacturesTelechargerGroupePost.md +0 -24
- package/docs/BodyTraiterFactureRecueApiV1ChorusProFacturesTraiterFactureRecuePost.md +0 -24
- package/docs/BodyValideurConsulterFactureApiV1ChorusProFacturesValideurConsulterPost.md +0 -24
- package/docs/BodyValideurRechercherFacturesApiV1ChorusProFacturesValideurRechercherPost.md +0 -24
- package/docs/BodyValideurTraiterFactureApiV1ChorusProFacturesValideurTraiterPost.md +0 -24
- package/docs/QuotaInfo.md +0 -29
- package/docs/Utilisateur.md +0 -43
- package/models/body-rechercher-factures-fournisseur-api-v1-chorus-pro-factures-rechercher-fournisseur-post.ts +0 -28
- package/models/body-recycler-facture-api-v1-chorus-pro-factures-recycler-post.ts +0 -28
- package/models/body-telecharger-groupe-factures-api-v1-chorus-pro-factures-telecharger-groupe-post.ts +0 -28
- package/models/body-traiter-facture-recue-api-v1-chorus-pro-factures-traiter-facture-recue-post.ts +0 -28
- package/models/body-valideur-consulter-facture-api-v1-chorus-pro-factures-valideur-consulter-post.ts +0 -28
- package/models/body-valideur-rechercher-factures-api-v1-chorus-pro-factures-valideur-rechercher-post.ts +0 -28
- package/models/body-valideur-traiter-facture-api-v1-chorus-pro-factures-valideur-traiter-post.ts +0 -28
- /package/dist/esm/models/{body-ajouter-fichier-api-v1-chorus-pro-transverses-ajouter-fichier-post.js → apierror.js} +0 -0
- /package/dist/esm/models/{body-completer-facture-api-v1-chorus-pro-factures-completer-post.js → beneficiaire.js} +0 -0
- /package/dist/esm/models/{body-lister-services-structure-api-v1-chorus-pro-structures-id-structure-cpp-services-get.js → bounding-box-schema.js} +0 -0
- /package/dist/esm/models/{body-rechercher-factures-destinataire-api-v1-chorus-pro-factures-rechercher-destinataire-post.js → champ-verifie-schema.js} +0 -0
- /package/dist/esm/models/{body-rechercher-factures-fournisseur-api-v1-chorus-pro-factures-rechercher-fournisseur-post.js → dimension-page-schema.js} +0 -0
- /package/dist/esm/models/{body-recycler-facture-api-v1-chorus-pro-factures-recycler-post.js → facture-entrante.js} +0 -0
- /package/dist/esm/models/{body-telecharger-groupe-factures-api-v1-chorus-pro-factures-telecharger-groupe-post.js → flux-resume.js} +0 -0
- /package/dist/esm/models/{body-traiter-facture-recue-api-v1-chorus-pro-factures-traiter-facture-recue-post.js → fournisseur-entrant.js} +0 -0
- /package/dist/esm/models/{body-valideur-consulter-facture-api-v1-chorus-pro-factures-valideur-consulter-post.js → note-obligatoire-schema.js} +0 -0
- /package/dist/esm/models/{body-valideur-rechercher-factures-api-v1-chorus-pro-factures-valideur-rechercher-post.js → pdpcredentials.js} +0 -0
- /package/dist/esm/models/{body-valideur-traiter-facture-api-v1-chorus-pro-factures-valideur-traiter-post.js → reponse-healthcheck-afnor.js} +0 -0
- /package/dist/esm/models/{quota-info.js → reponse-recherche-flux.js} +0 -0
- /package/dist/esm/models/{utilisateur.js → reponse-soumission-flux.js} +0 -0
- /package/dist/models/{body-ajouter-fichier-api-v1-chorus-pro-transverses-ajouter-fichier-post.js → apierror.js} +0 -0
- /package/dist/models/{body-completer-facture-api-v1-chorus-pro-factures-completer-post.js → beneficiaire.js} +0 -0
- /package/dist/models/{body-lister-services-structure-api-v1-chorus-pro-structures-id-structure-cpp-services-get.js → bounding-box-schema.js} +0 -0
- /package/dist/models/{body-rechercher-factures-destinataire-api-v1-chorus-pro-factures-rechercher-destinataire-post.js → champ-verifie-schema.js} +0 -0
- /package/dist/models/{body-rechercher-factures-fournisseur-api-v1-chorus-pro-factures-rechercher-fournisseur-post.js → dimension-page-schema.js} +0 -0
- /package/dist/models/{body-recycler-facture-api-v1-chorus-pro-factures-recycler-post.js → facture-entrante.js} +0 -0
- /package/dist/models/{body-telecharger-groupe-factures-api-v1-chorus-pro-factures-telecharger-groupe-post.js → flux-resume.js} +0 -0
- /package/dist/models/{body-traiter-facture-recue-api-v1-chorus-pro-factures-traiter-facture-recue-post.js → fournisseur-entrant.js} +0 -0
- /package/dist/models/{body-valideur-consulter-facture-api-v1-chorus-pro-factures-valideur-consulter-post.js → note-obligatoire-schema.js} +0 -0
- /package/dist/models/{body-valideur-rechercher-factures-api-v1-chorus-pro-factures-valideur-rechercher-post.js → pdpcredentials.js} +0 -0
- /package/dist/models/{body-valideur-traiter-facture-api-v1-chorus-pro-factures-valideur-traiter-post.js → reponse-healthcheck-afnor.js} +0 -0
- /package/dist/models/{quota-info.js → reponse-recherche-flux.js} +0 -0
- /package/dist/models/{utilisateur.js → reponse-soumission-flux.js} +0 -0
|
@@ -0,0 +1,866 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.FactPulseClient = void 0;
|
|
49
|
+
exports.montant = montant;
|
|
50
|
+
exports.montantTotal = montantTotal;
|
|
51
|
+
exports.ligneDePoste = ligneDePoste;
|
|
52
|
+
exports.ligneDeTva = ligneDeTva;
|
|
53
|
+
exports.adressePostale = adressePostale;
|
|
54
|
+
exports.adresseElectronique = adresseElectronique;
|
|
55
|
+
exports.fournisseur = fournisseur;
|
|
56
|
+
exports.destinataire = destinataire;
|
|
57
|
+
exports.beneficiaire = beneficiaire;
|
|
58
|
+
const axios_1 = __importDefault(require("axios"));
|
|
59
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
60
|
+
const fs = __importStar(require("fs"));
|
|
61
|
+
const path = __importStar(require("path"));
|
|
62
|
+
const exceptions_1 = require("./exceptions");
|
|
63
|
+
/** Convertit une valeur en string de montant pour l'API. */
|
|
64
|
+
function montant(value) {
|
|
65
|
+
if (value === null || value === undefined)
|
|
66
|
+
return '0.00';
|
|
67
|
+
if (typeof value === 'number')
|
|
68
|
+
return value.toFixed(2);
|
|
69
|
+
if (typeof value === 'string')
|
|
70
|
+
return value;
|
|
71
|
+
return '0.00';
|
|
72
|
+
}
|
|
73
|
+
/** Crée un objet MontantTotal simplifié. */
|
|
74
|
+
function montantTotal(ht, tva, ttc, aPayer, options) {
|
|
75
|
+
const result = {
|
|
76
|
+
montantHtTotal: montant(ht), montantTva: montant(tva),
|
|
77
|
+
montantTtcTotal: montant(ttc), montantAPayer: montant(aPayer),
|
|
78
|
+
};
|
|
79
|
+
if ((options === null || options === void 0 ? void 0 : options.remiseTtc) !== undefined)
|
|
80
|
+
result.montantRemiseGlobaleTtc = montant(options.remiseTtc);
|
|
81
|
+
if ((options === null || options === void 0 ? void 0 : options.motifRemise) !== undefined)
|
|
82
|
+
result.motifRemiseGlobaleTtc = options.motifRemise;
|
|
83
|
+
if ((options === null || options === void 0 ? void 0 : options.acompte) !== undefined)
|
|
84
|
+
result.acompte = montant(options.acompte);
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
/** Crée une ligne de poste (aligné sur LigneDePoste de models.py).
|
|
88
|
+
* Pour le taux TVA: soit tauxTva (code ex: "TVA20") soit tauxTvaManuel (valeur ex: 20.00) */
|
|
89
|
+
function ligneDePoste(numero, denomination, quantite, montantUnitaireHt, montantTotalLigneHt, options) {
|
|
90
|
+
var _a, _b, _c;
|
|
91
|
+
const result = {
|
|
92
|
+
numero, denomination, quantite: montant(quantite), montantUnitaireHt: montant(montantUnitaireHt),
|
|
93
|
+
montantTotalLigneHt: montant(montantTotalLigneHt),
|
|
94
|
+
categorieTva: (_a = options === null || options === void 0 ? void 0 : options.categorieTva) !== null && _a !== void 0 ? _a : 'S', unite: (_b = options === null || options === void 0 ? void 0 : options.unite) !== null && _b !== void 0 ? _b : 'FORFAIT',
|
|
95
|
+
};
|
|
96
|
+
// Soit tauxTva (code) soit tauxTvaManuel (valeur)
|
|
97
|
+
if (options === null || options === void 0 ? void 0 : options.tauxTva)
|
|
98
|
+
result.tauxTva = options.tauxTva;
|
|
99
|
+
else
|
|
100
|
+
result.tauxTvaManuel = montant((_c = options === null || options === void 0 ? void 0 : options.tauxTvaManuel) !== null && _c !== void 0 ? _c : '20.00');
|
|
101
|
+
if (options === null || options === void 0 ? void 0 : options.reference)
|
|
102
|
+
result.reference = options.reference;
|
|
103
|
+
if ((options === null || options === void 0 ? void 0 : options.montantRemiseHt) !== undefined)
|
|
104
|
+
result.montantRemiseHt = montant(options.montantRemiseHt);
|
|
105
|
+
if (options === null || options === void 0 ? void 0 : options.codeRaisonReduction)
|
|
106
|
+
result.codeRaisonReduction = options.codeRaisonReduction;
|
|
107
|
+
if (options === null || options === void 0 ? void 0 : options.raisonReduction)
|
|
108
|
+
result.raisonReduction = options.raisonReduction;
|
|
109
|
+
if (options === null || options === void 0 ? void 0 : options.dateDebutPeriode)
|
|
110
|
+
result.dateDebutPeriode = options.dateDebutPeriode;
|
|
111
|
+
if (options === null || options === void 0 ? void 0 : options.dateFinPeriode)
|
|
112
|
+
result.dateFinPeriode = options.dateFinPeriode;
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
/** Crée une ligne de TVA (aligné sur LigneDeTVA de models.py).
|
|
116
|
+
* Pour le taux: soit taux (code ex: "TVA20") soit tauxManuel (valeur ex: 20.00) */
|
|
117
|
+
function ligneDeTva(montantBaseHt, montantTva, options) {
|
|
118
|
+
var _a, _b;
|
|
119
|
+
const result = {
|
|
120
|
+
montantBaseHt: montant(montantBaseHt), montantTva: montant(montantTva), categorie: (_a = options === null || options === void 0 ? void 0 : options.categorie) !== null && _a !== void 0 ? _a : 'S',
|
|
121
|
+
};
|
|
122
|
+
// Soit taux (code) soit tauxManuel (valeur)
|
|
123
|
+
if (options === null || options === void 0 ? void 0 : options.taux)
|
|
124
|
+
result.taux = options.taux;
|
|
125
|
+
else
|
|
126
|
+
result.tauxManuel = montant((_b = options === null || options === void 0 ? void 0 : options.tauxManuel) !== null && _b !== void 0 ? _b : '20.00');
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
/** Crée une adresse postale pour l'API FactPulse. */
|
|
130
|
+
function adressePostale(ligne1, codePostal, ville, options) {
|
|
131
|
+
var _a;
|
|
132
|
+
const result = { ligneUn: ligne1, codePostal, nomVille: ville, paysCodeIso: (_a = options === null || options === void 0 ? void 0 : options.pays) !== null && _a !== void 0 ? _a : 'FR' };
|
|
133
|
+
if (options === null || options === void 0 ? void 0 : options.ligne2)
|
|
134
|
+
result.ligneDeux = options.ligne2;
|
|
135
|
+
if (options === null || options === void 0 ? void 0 : options.ligne3)
|
|
136
|
+
result.ligneTrois = options.ligne3;
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
/** Crée une adresse électronique pour l'API FactPulse. schemeId: "0009"=SIREN, "0225"=SIRET */
|
|
140
|
+
function adresseElectronique(identifiant, schemeId = '0009') {
|
|
141
|
+
return { identifiant, schemeId };
|
|
142
|
+
}
|
|
143
|
+
/** Calcule le numéro TVA intracommunautaire français depuis un SIREN. */
|
|
144
|
+
function calculerTvaIntra(siren) {
|
|
145
|
+
if (siren.length !== 9 || !/^\d+$/.test(siren))
|
|
146
|
+
return null;
|
|
147
|
+
const cle = (12 + 3 * (parseInt(siren, 10) % 97)) % 97;
|
|
148
|
+
return `FR${cle.toString().padStart(2, '0')}${siren}`;
|
|
149
|
+
}
|
|
150
|
+
/** Crée un fournisseur (émetteur) avec auto-calcul SIREN, TVA intracommunautaire et adresses. */
|
|
151
|
+
function fournisseur(nom, siret, adresseLigne1, codePostal, ville, options) {
|
|
152
|
+
var _a, _b, _c;
|
|
153
|
+
const opts = options !== null && options !== void 0 ? options : {};
|
|
154
|
+
const siren = (_a = opts.siren) !== null && _a !== void 0 ? _a : (siret.length === 14 ? siret.slice(0, 9) : undefined);
|
|
155
|
+
const numeroTvaIntra = (_b = opts.numeroTvaIntra) !== null && _b !== void 0 ? _b : (siren ? calculerTvaIntra(siren) : null);
|
|
156
|
+
const result = {
|
|
157
|
+
nom, idFournisseur: (_c = opts.idFournisseur) !== null && _c !== void 0 ? _c : 0, siret,
|
|
158
|
+
adresseElectronique: adresseElectronique(siret, '0225'),
|
|
159
|
+
adressePostale: adressePostale(adresseLigne1, codePostal, ville, { pays: opts.pays, ligne2: opts.adresseLigne2 }),
|
|
160
|
+
};
|
|
161
|
+
if (siren)
|
|
162
|
+
result.siren = siren;
|
|
163
|
+
if (numeroTvaIntra)
|
|
164
|
+
result.numeroTvaIntra = numeroTvaIntra;
|
|
165
|
+
if (opts.iban)
|
|
166
|
+
result.iban = opts.iban;
|
|
167
|
+
if (opts.codeService)
|
|
168
|
+
result.idServiceFournisseur = opts.codeService;
|
|
169
|
+
if (opts.codeCoordonnesBancaires)
|
|
170
|
+
result.codeCoordonnesBancairesFournisseur = opts.codeCoordonnesBancaires;
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
/** Crée un destinataire (client) avec auto-calcul SIREN et adresses. */
|
|
174
|
+
function destinataire(nom, siret, adresseLigne1, codePostal, ville, options) {
|
|
175
|
+
var _a;
|
|
176
|
+
const opts = options !== null && options !== void 0 ? options : {};
|
|
177
|
+
const siren = (_a = opts.siren) !== null && _a !== void 0 ? _a : (siret.length === 14 ? siret.slice(0, 9) : undefined);
|
|
178
|
+
const result = {
|
|
179
|
+
nom, siret,
|
|
180
|
+
adresseElectronique: adresseElectronique(siret, '0225'),
|
|
181
|
+
adressePostale: adressePostale(adresseLigne1, codePostal, ville, { pays: opts.pays, ligne2: opts.adresseLigne2 }),
|
|
182
|
+
};
|
|
183
|
+
if (siren)
|
|
184
|
+
result.siren = siren;
|
|
185
|
+
if (opts.codeServiceExecutant)
|
|
186
|
+
result.codeServiceExecutant = opts.codeServiceExecutant;
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Crée un bénéficiaire (factor) pour l'affacturage.
|
|
191
|
+
*
|
|
192
|
+
* Le bénéficiaire (BG-10 / PayeeTradeParty) est utilisé lorsque le paiement
|
|
193
|
+
* doit être effectué à un tiers différent du fournisseur, typiquement un
|
|
194
|
+
* factor (société d'affacturage).
|
|
195
|
+
*
|
|
196
|
+
* Pour les factures affacturées, il faut aussi:
|
|
197
|
+
* - Utiliser un type de document affacturé (393, 396, 501, 502, 472, 473)
|
|
198
|
+
* - Ajouter une note ACC avec la mention de subrogation
|
|
199
|
+
* - L'IBAN du bénéficiaire sera utilisé pour le paiement
|
|
200
|
+
*
|
|
201
|
+
* @param nom Raison sociale du factor (BT-59)
|
|
202
|
+
* @param options Options: siret (BT-60), siren (BT-61), iban, bic
|
|
203
|
+
* @returns Dict prêt à être utilisé dans une facture affacturée
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* const factor = beneficiaire('FACTOR SAS', {
|
|
207
|
+
* siret: '30000000700033',
|
|
208
|
+
* iban: 'FR76 3000 4000 0500 0012 3456 789',
|
|
209
|
+
* });
|
|
210
|
+
*/
|
|
211
|
+
function beneficiaire(nom, options) {
|
|
212
|
+
var _a;
|
|
213
|
+
const opts = options !== null && options !== void 0 ? options : {};
|
|
214
|
+
// Auto-calcul SIREN depuis SIRET
|
|
215
|
+
const siren = (_a = opts.siren) !== null && _a !== void 0 ? _a : (opts.siret && opts.siret.length === 14 ? opts.siret.slice(0, 9) : undefined);
|
|
216
|
+
const result = { nom };
|
|
217
|
+
if (opts.siret)
|
|
218
|
+
result.siret = opts.siret;
|
|
219
|
+
if (siren)
|
|
220
|
+
result.siren = siren;
|
|
221
|
+
if (opts.iban)
|
|
222
|
+
result.iban = opts.iban;
|
|
223
|
+
if (opts.bic)
|
|
224
|
+
result.bic = opts.bic;
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
// =============================================================================
|
|
228
|
+
// Client principal
|
|
229
|
+
// =============================================================================
|
|
230
|
+
const DEFAULT_API_URL = 'https://factpulse.fr';
|
|
231
|
+
const DEFAULT_POLLING_INTERVAL = 2000;
|
|
232
|
+
const DEFAULT_POLLING_TIMEOUT = 120000;
|
|
233
|
+
const DEFAULT_MAX_RETRIES = 1;
|
|
234
|
+
class FactPulseClient {
|
|
235
|
+
constructor(config) {
|
|
236
|
+
var _a;
|
|
237
|
+
this.accessToken = null;
|
|
238
|
+
this.refreshToken = null;
|
|
239
|
+
this.tokenExpiresAt = null;
|
|
240
|
+
this.config = {
|
|
241
|
+
email: config.email, password: config.password,
|
|
242
|
+
apiUrl: (config.apiUrl || DEFAULT_API_URL).replace(/\/$/, ''),
|
|
243
|
+
clientUid: config.clientUid || '',
|
|
244
|
+
chorusCredentials: config.chorusCredentials,
|
|
245
|
+
afnorCredentials: config.afnorCredentials,
|
|
246
|
+
pollingInterval: config.pollingInterval || DEFAULT_POLLING_INTERVAL,
|
|
247
|
+
pollingTimeout: config.pollingTimeout || DEFAULT_POLLING_TIMEOUT,
|
|
248
|
+
maxRetries: (_a = config.maxRetries) !== null && _a !== void 0 ? _a : DEFAULT_MAX_RETRIES,
|
|
249
|
+
};
|
|
250
|
+
this.chorusCredentials = config.chorusCredentials;
|
|
251
|
+
this.afnorCredentials = config.afnorCredentials;
|
|
252
|
+
this.httpClient = axios_1.default.create({ timeout: 30000, headers: { 'Content-Type': 'application/json' } });
|
|
253
|
+
}
|
|
254
|
+
getChorusCredentialsForApi() {
|
|
255
|
+
var _a;
|
|
256
|
+
if (!this.chorusCredentials)
|
|
257
|
+
return undefined;
|
|
258
|
+
return {
|
|
259
|
+
piste_client_id: this.chorusCredentials.pisteClientId,
|
|
260
|
+
piste_client_secret: this.chorusCredentials.pisteClientSecret,
|
|
261
|
+
chorus_pro_login: this.chorusCredentials.chorusProLogin,
|
|
262
|
+
chorus_pro_password: this.chorusCredentials.chorusProPassword,
|
|
263
|
+
sandbox: (_a = this.chorusCredentials.sandbox) !== null && _a !== void 0 ? _a : true,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
getAfnorCredentialsForApi() {
|
|
267
|
+
if (!this.afnorCredentials)
|
|
268
|
+
return undefined;
|
|
269
|
+
return {
|
|
270
|
+
client_id: this.afnorCredentials.clientId,
|
|
271
|
+
client_secret: this.afnorCredentials.clientSecret,
|
|
272
|
+
flow_service_url: this.afnorCredentials.flowServiceUrl,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
// Alias plus courts
|
|
276
|
+
getChorusProCredentials() { return this.getChorusCredentialsForApi(); }
|
|
277
|
+
getAfnorCredentials() { return this.getAfnorCredentialsForApi(); }
|
|
278
|
+
obtainToken() {
|
|
279
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
280
|
+
var _a, _b;
|
|
281
|
+
const payload = { username: this.config.email, password: this.config.password };
|
|
282
|
+
if (this.config.clientUid)
|
|
283
|
+
payload.client_uid = this.config.clientUid;
|
|
284
|
+
try {
|
|
285
|
+
const response = yield this.httpClient.post(`${this.config.apiUrl}/api/token/`, payload);
|
|
286
|
+
return response.data;
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
const axiosError = error;
|
|
290
|
+
throw new exceptions_1.FactPulseAuthError(`Impossible d'obtenir le token JWT: ${((_b = (_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.detail) || axiosError.message}`);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
ensureAuthenticated() {
|
|
295
|
+
return __awaiter(this, arguments, void 0, function* (forceRefresh = false) {
|
|
296
|
+
const now = Date.now();
|
|
297
|
+
if (forceRefresh || !this.accessToken || (this.tokenExpiresAt && now >= this.tokenExpiresAt)) {
|
|
298
|
+
const tokens = yield this.obtainToken();
|
|
299
|
+
this.accessToken = tokens.access;
|
|
300
|
+
this.refreshToken = tokens.refresh;
|
|
301
|
+
this.tokenExpiresAt = now + 28 * 60 * 1000;
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
resetAuth() { this.accessToken = this.refreshToken = null; this.tokenExpiresAt = null; }
|
|
306
|
+
pollTask(taskId, timeout, interval) {
|
|
307
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
308
|
+
var _a;
|
|
309
|
+
const timeoutMs = timeout !== null && timeout !== void 0 ? timeout : this.config.pollingTimeout;
|
|
310
|
+
const intervalMs = interval !== null && interval !== void 0 ? interval : this.config.pollingInterval;
|
|
311
|
+
const startTime = Date.now();
|
|
312
|
+
let currentInterval = intervalMs;
|
|
313
|
+
while (true) {
|
|
314
|
+
if (Date.now() - startTime > timeoutMs)
|
|
315
|
+
throw new exceptions_1.FactPulsePollingTimeout(taskId, timeoutMs);
|
|
316
|
+
yield this.ensureAuthenticated();
|
|
317
|
+
try {
|
|
318
|
+
const response = yield this.httpClient.get(`${this.config.apiUrl}/api/v1/traitement/taches/${taskId}/statut`, {
|
|
319
|
+
headers: { Authorization: `Bearer ${this.accessToken}` },
|
|
320
|
+
});
|
|
321
|
+
const { statut, resultat } = response.data;
|
|
322
|
+
if (statut === 'SUCCESS')
|
|
323
|
+
return resultat || {};
|
|
324
|
+
if (statut === 'FAILURE') {
|
|
325
|
+
// Format AFNOR: errorMessage, details
|
|
326
|
+
const result = resultat;
|
|
327
|
+
const errors = Array.isArray(result === null || result === void 0 ? void 0 : result.details) ? result.details.filter((e) => typeof e === 'object' && e !== null) : [];
|
|
328
|
+
throw new exceptions_1.FactPulseValidationError(`La tâche ${taskId} a échoué: ${(result === null || result === void 0 ? void 0 : result.errorMessage) || 'Erreur inconnue'}`, errors);
|
|
329
|
+
}
|
|
330
|
+
yield new Promise(resolve => setTimeout(resolve, currentInterval));
|
|
331
|
+
currentInterval = Math.min(currentInterval * 1.5, 10000);
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
if (error instanceof exceptions_1.FactPulseValidationError || error instanceof exceptions_1.FactPulsePollingTimeout)
|
|
335
|
+
throw error;
|
|
336
|
+
const axiosError = error;
|
|
337
|
+
if (((_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.status) === 401) {
|
|
338
|
+
this.resetAuth();
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
throw new exceptions_1.FactPulseValidationError(`Erreur API: ${axiosError.message}`);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
genererFacturx(factureData_1, pdfPath_1) {
|
|
347
|
+
return __awaiter(this, arguments, void 0, function* (factureData, pdfPath, profil = 'EN16931', formatSortie = 'pdf', sync = true, timeout) {
|
|
348
|
+
var _a, _b, _c, _d;
|
|
349
|
+
const jsonData = typeof factureData === 'string' ? factureData : JSON.stringify(factureData);
|
|
350
|
+
let taskId = null;
|
|
351
|
+
for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
|
|
352
|
+
yield this.ensureAuthenticated();
|
|
353
|
+
const form = new form_data_1.default();
|
|
354
|
+
form.append('donnees_facture', jsonData);
|
|
355
|
+
form.append('profil', profil);
|
|
356
|
+
form.append('format_sortie', formatSortie);
|
|
357
|
+
form.append('source_pdf', fs.createReadStream(pdfPath), { filename: path.basename(pdfPath), contentType: 'application/pdf' });
|
|
358
|
+
try {
|
|
359
|
+
const response = yield this.httpClient.post(`${this.config.apiUrl}/api/v1/traitement/generer-facture`, form, {
|
|
360
|
+
headers: Object.assign(Object.assign({}, form.getHeaders()), { Authorization: `Bearer ${this.accessToken}` }), timeout: 60000,
|
|
361
|
+
});
|
|
362
|
+
taskId = response.data.id_tache;
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
catch (error) {
|
|
366
|
+
const axiosError = error;
|
|
367
|
+
if (((_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.status) === 401 && attempt < this.config.maxRetries) {
|
|
368
|
+
this.resetAuth();
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
// Extraire les détails d'erreur du corps de la réponse
|
|
372
|
+
const responseData = (_b = axiosError.response) === null || _b === void 0 ? void 0 : _b.data;
|
|
373
|
+
let errorMsg = `Erreur API (${((_c = axiosError.response) === null || _c === void 0 ? void 0 : _c.status) || 'unknown'}): ${axiosError.message}`;
|
|
374
|
+
const errors = [];
|
|
375
|
+
if (responseData) {
|
|
376
|
+
// Format FastAPI/Pydantic: {"detail": [{"loc": [...], "msg": "...", "type": "..."}]}
|
|
377
|
+
if (Array.isArray(responseData.detail)) {
|
|
378
|
+
errorMsg = 'Erreur de validation';
|
|
379
|
+
for (const err of responseData.detail) {
|
|
380
|
+
if (typeof err === 'object' && err !== null) {
|
|
381
|
+
const loc = err.loc || [];
|
|
382
|
+
errors.push({
|
|
383
|
+
level: 'ERROR',
|
|
384
|
+
item: loc.map(String).join(' -> '),
|
|
385
|
+
reason: err.msg || String(err),
|
|
386
|
+
source: 'validation',
|
|
387
|
+
code: err.type,
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
else if (typeof responseData.detail === 'string') {
|
|
393
|
+
errorMsg = responseData.detail;
|
|
394
|
+
}
|
|
395
|
+
else if (responseData.errorMessage) {
|
|
396
|
+
errorMsg = responseData.errorMessage;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
console.error(`Erreur API ${(_d = axiosError.response) === null || _d === void 0 ? void 0 : _d.status}:`, responseData);
|
|
400
|
+
throw new exceptions_1.FactPulseValidationError(errorMsg, errors);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (!taskId)
|
|
404
|
+
throw new exceptions_1.FactPulseValidationError("Pas d'ID de tâche");
|
|
405
|
+
if (!sync)
|
|
406
|
+
return taskId;
|
|
407
|
+
const result = yield this.pollTask(taskId, timeout);
|
|
408
|
+
if (result.contenu_b64)
|
|
409
|
+
return Buffer.from(result.contenu_b64, 'base64');
|
|
410
|
+
throw new exceptions_1.FactPulseValidationError('Pas de contenu');
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
static formatMontant(m) {
|
|
414
|
+
if (m === null || m === undefined)
|
|
415
|
+
return '0.00';
|
|
416
|
+
if (typeof m === 'number')
|
|
417
|
+
return m.toFixed(2);
|
|
418
|
+
if (typeof m === 'string')
|
|
419
|
+
return m;
|
|
420
|
+
return '0.00';
|
|
421
|
+
}
|
|
422
|
+
// =========================================================================
|
|
423
|
+
// AFNOR - Authentication et helpers internes
|
|
424
|
+
// =========================================================================
|
|
425
|
+
/**
|
|
426
|
+
* Recupere les credentials AFNOR (mode stored ou zero-trust).
|
|
427
|
+
* Mode zero-trust: Retourne les afnorCredentials fournis au constructeur.
|
|
428
|
+
* Mode stored: Recupere les credentials via GET /api/v1/afnor/credentials.
|
|
429
|
+
*/
|
|
430
|
+
getAfnorCredentialsInternal() {
|
|
431
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
432
|
+
var _a, _b;
|
|
433
|
+
// Mode zero-trust : credentials fournis au constructeur
|
|
434
|
+
if (this.afnorCredentials) {
|
|
435
|
+
return this.afnorCredentials;
|
|
436
|
+
}
|
|
437
|
+
// Mode stored : recuperer les credentials via l'API
|
|
438
|
+
yield this.ensureAuthenticated();
|
|
439
|
+
try {
|
|
440
|
+
const response = yield this.httpClient.get(`${this.config.apiUrl}/api/v1/afnor/credentials`, {
|
|
441
|
+
headers: { Authorization: `Bearer ${this.accessToken}` },
|
|
442
|
+
});
|
|
443
|
+
const creds = response.data;
|
|
444
|
+
return {
|
|
445
|
+
flowServiceUrl: creds.flow_service_url,
|
|
446
|
+
tokenUrl: creds.token_url,
|
|
447
|
+
clientId: creds.client_id,
|
|
448
|
+
clientSecret: creds.client_secret,
|
|
449
|
+
directoryServiceUrl: creds.directory_service_url,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
catch (error) {
|
|
453
|
+
const axiosError = error;
|
|
454
|
+
if (((_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.status) === 400) {
|
|
455
|
+
const detail = (_b = axiosError.response.data) === null || _b === void 0 ? void 0 : _b.detail;
|
|
456
|
+
if (typeof detail === 'object' && (detail === null || detail === void 0 ? void 0 : detail.error) === 'NO_CLIENT_UID') {
|
|
457
|
+
throw new exceptions_1.FactPulseAuthError("Aucun client_uid dans le JWT. Pour utiliser les endpoints AFNOR, soit:\n" +
|
|
458
|
+
"1. Generez un token avec un client_uid (mode stored)\n" +
|
|
459
|
+
"2. Fournissez AFNORCredentials au constructeur du client (mode zero-trust)");
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
throw new exceptions_1.FactPulseAuthError(`Echec recuperation credentials AFNOR: ${axiosError.message}`);
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Obtient le token OAuth2 AFNOR et l'URL de la PDP.
|
|
468
|
+
* Cette methode:
|
|
469
|
+
* 1. Recupere les credentials AFNOR (mode stored ou zero-trust)
|
|
470
|
+
* 2. Fait l'OAuth AFNOR pour obtenir un token
|
|
471
|
+
* 3. Retourne le token et l'URL de la PDP
|
|
472
|
+
*/
|
|
473
|
+
getAfnorTokenAndUrl() {
|
|
474
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
475
|
+
// Etape 1: Obtenir les credentials AFNOR
|
|
476
|
+
const credentials = yield this.getAfnorCredentialsInternal();
|
|
477
|
+
// Etape 2: Faire l'OAuth AFNOR via le proxy FactPulse
|
|
478
|
+
const oauthData = new URLSearchParams({
|
|
479
|
+
grant_type: 'client_credentials',
|
|
480
|
+
client_id: credentials.clientId,
|
|
481
|
+
client_secret: credentials.clientSecret,
|
|
482
|
+
});
|
|
483
|
+
try {
|
|
484
|
+
const response = yield this.httpClient.post(`${this.config.apiUrl}/api/v1/afnor/oauth/token`, oauthData.toString(), {
|
|
485
|
+
headers: {
|
|
486
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
487
|
+
'X-PDP-Token-URL': credentials.tokenUrl,
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
const tokenData = response.data;
|
|
491
|
+
if (!tokenData.access_token) {
|
|
492
|
+
throw new exceptions_1.FactPulseAuthError('Reponse OAuth2 AFNOR invalide: access_token manquant');
|
|
493
|
+
}
|
|
494
|
+
return {
|
|
495
|
+
token: tokenData.access_token,
|
|
496
|
+
pdpBaseUrl: credentials.flowServiceUrl,
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
catch (error) {
|
|
500
|
+
const axiosError = error;
|
|
501
|
+
throw new exceptions_1.FactPulseAuthError(`Echec OAuth2 AFNOR: ${axiosError.message}`);
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Effectue une requete vers l'API AFNOR avec gestion d'auth et d'erreurs.
|
|
507
|
+
* IMPORTANT: Cette methode utilise le token OAuth AFNOR, PAS le JWT FactPulse!
|
|
508
|
+
*/
|
|
509
|
+
makeAfnorRequest(method, endpoint, options) {
|
|
510
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
511
|
+
var _a, _b, _c, _d;
|
|
512
|
+
// Obtenir le token AFNOR et l'URL de la PDP
|
|
513
|
+
const { token: afnorToken, pdpBaseUrl } = yield this.getAfnorTokenAndUrl();
|
|
514
|
+
const url = `${this.config.apiUrl}/api/v1/afnor${endpoint}`;
|
|
515
|
+
// TOUJOURS utiliser le token AFNOR + header X-PDP-Base-URL
|
|
516
|
+
const headers = {
|
|
517
|
+
'Authorization': `Bearer ${afnorToken}`,
|
|
518
|
+
'X-PDP-Base-URL': pdpBaseUrl,
|
|
519
|
+
};
|
|
520
|
+
try {
|
|
521
|
+
let response;
|
|
522
|
+
if (options === null || options === void 0 ? void 0 : options.files) {
|
|
523
|
+
response = yield this.httpClient.request({
|
|
524
|
+
method,
|
|
525
|
+
url,
|
|
526
|
+
data: options.files,
|
|
527
|
+
headers: Object.assign(Object.assign({}, options.files.getHeaders()), headers),
|
|
528
|
+
params: options === null || options === void 0 ? void 0 : options.params,
|
|
529
|
+
timeout: 60000,
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
response = yield this.httpClient.request({
|
|
534
|
+
method,
|
|
535
|
+
url,
|
|
536
|
+
data: options === null || options === void 0 ? void 0 : options.data,
|
|
537
|
+
headers: Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json' }),
|
|
538
|
+
params: options === null || options === void 0 ? void 0 : options.params,
|
|
539
|
+
timeout: 30000,
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
return response.data;
|
|
543
|
+
}
|
|
544
|
+
catch (error) {
|
|
545
|
+
const axiosError = error;
|
|
546
|
+
const errorMsg = ((_b = (_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.errorMessage) ||
|
|
547
|
+
((_d = (_c = axiosError.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.detail) ||
|
|
548
|
+
axiosError.message;
|
|
549
|
+
throw new exceptions_1.FactPulseValidationError(`Erreur AFNOR: ${errorMsg}`);
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
// ==================== AFNOR Directory ====================
|
|
554
|
+
rechercherSiretAfnor(siret) {
|
|
555
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
556
|
+
return this.makeAfnorRequest('GET', `/directory/siret/${siret}`);
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
rechercherSirenAfnor(siren) {
|
|
560
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
561
|
+
return this.makeAfnorRequest('GET', `/directory/siren/${siren}`);
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
listerCodesRoutageAfnor(siren) {
|
|
565
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
566
|
+
return this.makeAfnorRequest('GET', `/directory/siren/${siren}/routing-codes`);
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
// ==================== AFNOR Flow ====================
|
|
570
|
+
/**
|
|
571
|
+
* Soumet une facture a une PDP via l'API AFNOR.
|
|
572
|
+
* L'authentification utilise le token OAuth AFNOR (obtenu automatiquement),
|
|
573
|
+
* soit via les credentials stockes (mode stored), soit via les afnorCredentials
|
|
574
|
+
* fournis au constructeur (mode zero-trust).
|
|
575
|
+
*
|
|
576
|
+
* @param pdfBuffer Buffer du PDF Factur-X a soumettre
|
|
577
|
+
* @param flowName Nom du flux (ex: "Facture FAC-2025-001")
|
|
578
|
+
* @param options Options: trackingId, flowSyntax (CII/UBL), flowProfile
|
|
579
|
+
*/
|
|
580
|
+
soumettreFactureAfnor(pdfBuffer_1, flowName_1) {
|
|
581
|
+
return __awaiter(this, arguments, void 0, function* (pdfBuffer, flowName, options = {}) {
|
|
582
|
+
const { trackingId, flowSyntax = 'CII', flowProfile = 'EN16931' } = options;
|
|
583
|
+
// Calculer SHA-256
|
|
584
|
+
const crypto = require('crypto');
|
|
585
|
+
const sha256 = crypto.createHash('sha256').update(pdfBuffer).digest('hex');
|
|
586
|
+
// Preparer flowInfo
|
|
587
|
+
const flowInfo = { name: flowName, flowSyntax, flowProfile, sha256 };
|
|
588
|
+
if (trackingId)
|
|
589
|
+
flowInfo.trackingId = trackingId;
|
|
590
|
+
const form = new form_data_1.default();
|
|
591
|
+
form.append('file', pdfBuffer, { filename: 'facture.pdf', contentType: 'application/pdf' });
|
|
592
|
+
form.append('flowInfo', JSON.stringify(flowInfo), { contentType: 'application/json' });
|
|
593
|
+
return this.makeAfnorRequest('POST', '/flow/v1/flows', { files: form });
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
rechercherFluxAfnor() {
|
|
597
|
+
return __awaiter(this, arguments, void 0, function* (criteria = {}) {
|
|
598
|
+
var _a, _b;
|
|
599
|
+
const searchBody = {
|
|
600
|
+
offset: (_a = criteria.offset) !== null && _a !== void 0 ? _a : 0,
|
|
601
|
+
limit: (_b = criteria.limit) !== null && _b !== void 0 ? _b : 25,
|
|
602
|
+
where: {},
|
|
603
|
+
};
|
|
604
|
+
if (criteria.trackingId)
|
|
605
|
+
searchBody.where.trackingId = criteria.trackingId;
|
|
606
|
+
if (criteria.status)
|
|
607
|
+
searchBody.where.status = criteria.status;
|
|
608
|
+
return this.makeAfnorRequest('POST', '/flow/v1/flows/search', { data: searchBody });
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
telechargerFluxAfnor(flowId) {
|
|
612
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
613
|
+
// Pour le telechargement, on doit gerer le type de reponse differemment
|
|
614
|
+
const { token: afnorToken, pdpBaseUrl } = yield this.getAfnorTokenAndUrl();
|
|
615
|
+
const url = `${this.config.apiUrl}/api/v1/afnor/flow/v1/flows/${flowId}`;
|
|
616
|
+
const response = yield this.httpClient.get(url, {
|
|
617
|
+
headers: {
|
|
618
|
+
'Authorization': `Bearer ${afnorToken}`,
|
|
619
|
+
'X-PDP-Base-URL': pdpBaseUrl,
|
|
620
|
+
},
|
|
621
|
+
responseType: 'arraybuffer',
|
|
622
|
+
});
|
|
623
|
+
return Buffer.from(response.data);
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Récupère les métadonnées JSON d'un flux entrant (facture fournisseur).
|
|
628
|
+
* Télécharge un flux entrant depuis la PDP AFNOR et extrait les métadonnées
|
|
629
|
+
* de la facture vers un format JSON unifié. Supporte Factur-X, CII et UBL.
|
|
630
|
+
*
|
|
631
|
+
* Note: Cet endpoint utilise l'authentification JWT FactPulse (pas OAuth AFNOR).
|
|
632
|
+
* Le serveur FactPulse se charge d'appeler la PDP avec les credentials stockés.
|
|
633
|
+
*
|
|
634
|
+
* @param flowId Identifiant du flux (UUID)
|
|
635
|
+
* @param includeDocument Si true, inclut le document original encodé en base64
|
|
636
|
+
* @returns Métadonnées de la facture (fournisseur, montants, dates, etc.)
|
|
637
|
+
*
|
|
638
|
+
* @example
|
|
639
|
+
* const facture = await client.obtenirFactureEntranteAfnor("550e8400-...");
|
|
640
|
+
* console.log(`Fournisseur: ${facture.fournisseur.nom}`);
|
|
641
|
+
* console.log(`Montant TTC: ${facture.montant_ttc} ${facture.devise}`);
|
|
642
|
+
*/
|
|
643
|
+
obtenirFactureEntranteAfnor(flowId_1) {
|
|
644
|
+
return __awaiter(this, arguments, void 0, function* (flowId, includeDocument = false) {
|
|
645
|
+
var _a, _b;
|
|
646
|
+
yield this.ensureAuthenticated();
|
|
647
|
+
const url = `${this.config.apiUrl}/api/v1/afnor/flux-entrants/${flowId}`;
|
|
648
|
+
const params = {};
|
|
649
|
+
if (includeDocument) {
|
|
650
|
+
params.include_document = 'true';
|
|
651
|
+
}
|
|
652
|
+
try {
|
|
653
|
+
const response = yield this.httpClient.get(url, {
|
|
654
|
+
headers: { 'Authorization': `Bearer ${this.accessToken}` },
|
|
655
|
+
params: Object.keys(params).length > 0 ? params : undefined,
|
|
656
|
+
timeout: 60000,
|
|
657
|
+
});
|
|
658
|
+
return response.data;
|
|
659
|
+
}
|
|
660
|
+
catch (error) {
|
|
661
|
+
const axiosError = error;
|
|
662
|
+
throw new exceptions_1.FactPulseValidationError(`Erreur flux entrant: ${((_b = (_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.detail) || axiosError.message}`);
|
|
663
|
+
}
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
healthcheckAfnor() {
|
|
667
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
668
|
+
return this.makeAfnorRequest('GET', '/flow/v1/healthcheck');
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
// ==================== Chorus Pro ====================
|
|
672
|
+
rechercherStructureChorus(criteria) {
|
|
673
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
674
|
+
yield this.ensureAuthenticated();
|
|
675
|
+
const response = yield this.httpClient.post(`${this.config.apiUrl}/api/v1/chorus-pro/structures/rechercher`, criteria, {
|
|
676
|
+
headers: { Authorization: `Bearer ${this.accessToken}`, 'Content-Type': 'application/json' },
|
|
677
|
+
});
|
|
678
|
+
return response.data;
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
consulterStructureChorus(idStructureCpp) {
|
|
682
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
683
|
+
yield this.ensureAuthenticated();
|
|
684
|
+
const response = yield this.httpClient.post(`${this.config.apiUrl}/api/v1/chorus-pro/structures/consulter`, { id_structure_cpp: idStructureCpp }, {
|
|
685
|
+
headers: { Authorization: `Bearer ${this.accessToken}`, 'Content-Type': 'application/json' },
|
|
686
|
+
});
|
|
687
|
+
return response.data;
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Liste les services d'une structure Chorus Pro.
|
|
692
|
+
* @param idStructureCpp ID Chorus Pro de la structure
|
|
693
|
+
* @returns Objet avec listeServices, total, codeRetour, libelle
|
|
694
|
+
*/
|
|
695
|
+
listerServicesStructureChorus(idStructureCpp) {
|
|
696
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
697
|
+
yield this.ensureAuthenticated();
|
|
698
|
+
const response = yield this.httpClient.get(`${this.config.apiUrl}/api/v1/chorus-pro/structures/${idStructureCpp}/services`, {
|
|
699
|
+
headers: { Authorization: `Bearer ${this.accessToken}` },
|
|
700
|
+
});
|
|
701
|
+
return response.data;
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
obtenirIdChorusDepuisSiret(siret) {
|
|
705
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
706
|
+
const results = yield this.rechercherStructureChorus({ identifiant_structure: siret, type_identifiant: 'SIRET' });
|
|
707
|
+
if (results.length > 0 && results[0].id_structure_cpp)
|
|
708
|
+
return results[0].id_structure_cpp;
|
|
709
|
+
return null;
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
soumettreFactureChorus(factureData) {
|
|
713
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
714
|
+
yield this.ensureAuthenticated();
|
|
715
|
+
const response = yield this.httpClient.post(`${this.config.apiUrl}/api/v1/chorus/factures/soumettre`, factureData, {
|
|
716
|
+
headers: { Authorization: `Bearer ${this.accessToken}`, 'Content-Type': 'application/json' },
|
|
717
|
+
});
|
|
718
|
+
return response.data;
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
consulterFactureChorus(identifiantFactureCpp) {
|
|
722
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
723
|
+
yield this.ensureAuthenticated();
|
|
724
|
+
const response = yield this.httpClient.post(`${this.config.apiUrl}/api/v1/chorus/factures/consulter`, { identifiant_facture_cpp: identifiantFactureCpp }, {
|
|
725
|
+
headers: { Authorization: `Bearer ${this.accessToken}`, 'Content-Type': 'application/json' },
|
|
726
|
+
});
|
|
727
|
+
return response.data;
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
// ==================== Validation ====================
|
|
731
|
+
/**
|
|
732
|
+
* Valide un PDF Factur-X.
|
|
733
|
+
* @param pdfBuffer - Contenu du PDF en Buffer
|
|
734
|
+
* @param options - Options de validation
|
|
735
|
+
* @param options.profil - Profil Factur-X (MINIMUM, BASIC, EN16931, EXTENDED). Si non spécifié, auto-détecté.
|
|
736
|
+
* @param options.useVerapdf - Active la validation stricte PDF/A avec VeraPDF (défaut: false)
|
|
737
|
+
*/
|
|
738
|
+
validerPdfFacturx(pdfBuffer_1) {
|
|
739
|
+
return __awaiter(this, arguments, void 0, function* (pdfBuffer, options = {}) {
|
|
740
|
+
var _a;
|
|
741
|
+
yield this.ensureAuthenticated();
|
|
742
|
+
const form = new form_data_1.default();
|
|
743
|
+
form.append('fichier_pdf', pdfBuffer, { filename: 'facture.pdf', contentType: 'application/pdf' });
|
|
744
|
+
if (options.profil) {
|
|
745
|
+
form.append('profil', options.profil);
|
|
746
|
+
}
|
|
747
|
+
form.append('use_verapdf', String((_a = options.useVerapdf) !== null && _a !== void 0 ? _a : false));
|
|
748
|
+
const response = yield this.httpClient.post(`${this.config.apiUrl}/api/v1/traitement/valider-pdf-facturx`, form, {
|
|
749
|
+
headers: Object.assign(Object.assign({}, form.getHeaders()), { Authorization: `Bearer ${this.accessToken}` }),
|
|
750
|
+
});
|
|
751
|
+
return response.data;
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
validerXmlFacturx(xmlContent_1) {
|
|
755
|
+
return __awaiter(this, arguments, void 0, function* (xmlContent, profil = 'EN16931') {
|
|
756
|
+
yield this.ensureAuthenticated();
|
|
757
|
+
const form = new form_data_1.default();
|
|
758
|
+
form.append('fichier_xml', Buffer.from(xmlContent, 'utf-8'), { filename: 'facture.xml', contentType: 'application/xml' });
|
|
759
|
+
form.append('profil', profil);
|
|
760
|
+
const response = yield this.httpClient.post(`${this.config.apiUrl}/api/v1/traitement/valider-xml`, form, {
|
|
761
|
+
headers: Object.assign(Object.assign({}, form.getHeaders()), { Authorization: `Bearer ${this.accessToken}` }),
|
|
762
|
+
});
|
|
763
|
+
return response.data;
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
validerSignaturePdf(pdfBuffer) {
|
|
767
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
768
|
+
yield this.ensureAuthenticated();
|
|
769
|
+
const form = new form_data_1.default();
|
|
770
|
+
form.append('fichier_pdf', pdfBuffer, { filename: 'document.pdf', contentType: 'application/pdf' });
|
|
771
|
+
const response = yield this.httpClient.post(`${this.config.apiUrl}/api/v1/traitement/valider-signature-pdf`, form, {
|
|
772
|
+
headers: Object.assign(Object.assign({}, form.getHeaders()), { Authorization: `Bearer ${this.accessToken}` }),
|
|
773
|
+
});
|
|
774
|
+
return response.data;
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
// ==================== Signature ====================
|
|
778
|
+
/**
|
|
779
|
+
* Signe un PDF avec le certificat configuré côté serveur (via client_uid du JWT).
|
|
780
|
+
* Le certificat doit être préalablement configuré dans Django Admin.
|
|
781
|
+
*/
|
|
782
|
+
signerPdf(pdfBuffer_1) {
|
|
783
|
+
return __awaiter(this, arguments, void 0, function* (pdfBuffer, options = {}) {
|
|
784
|
+
yield this.ensureAuthenticated();
|
|
785
|
+
const form = new form_data_1.default();
|
|
786
|
+
form.append('fichier_pdf', pdfBuffer, { filename: 'document.pdf', contentType: 'application/pdf' });
|
|
787
|
+
if (options.raison)
|
|
788
|
+
form.append('raison', options.raison);
|
|
789
|
+
if (options.localisation)
|
|
790
|
+
form.append('localisation', options.localisation);
|
|
791
|
+
if (options.contact)
|
|
792
|
+
form.append('contact', options.contact);
|
|
793
|
+
if (options.usePadesLt !== undefined)
|
|
794
|
+
form.append('use_pades_lt', String(options.usePadesLt));
|
|
795
|
+
if (options.useTimestamp !== undefined)
|
|
796
|
+
form.append('use_timestamp', String(options.useTimestamp));
|
|
797
|
+
const response = yield this.httpClient.post(`${this.config.apiUrl}/api/v1/traitement/signer-pdf`, form, {
|
|
798
|
+
headers: Object.assign(Object.assign({}, form.getHeaders()), { Authorization: `Bearer ${this.accessToken}` }),
|
|
799
|
+
});
|
|
800
|
+
// L'API retourne du JSON avec pdf_signe_base64
|
|
801
|
+
const data = response.data;
|
|
802
|
+
if (data.pdf_signe_base64) {
|
|
803
|
+
return Buffer.from(data.pdf_signe_base64, 'base64');
|
|
804
|
+
}
|
|
805
|
+
throw new Error('Réponse de signature invalide');
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
/**
|
|
809
|
+
* Génère un certificat de test (NON PRODUCTION).
|
|
810
|
+
* Le certificat doit ensuite être configuré dans Django Admin.
|
|
811
|
+
*/
|
|
812
|
+
genererCertificatTest() {
|
|
813
|
+
return __awaiter(this, arguments, void 0, function* (options = {}) {
|
|
814
|
+
yield this.ensureAuthenticated();
|
|
815
|
+
const response = yield this.httpClient.post(`${this.config.apiUrl}/api/v1/traitement/generer-certificat-test`, {
|
|
816
|
+
cn: options.cn || 'Test Organisation',
|
|
817
|
+
organisation: options.organisation || 'Test Organisation',
|
|
818
|
+
email: options.email || 'test@example.com',
|
|
819
|
+
duree_jours: options.dureeJours || 365,
|
|
820
|
+
taille_cle: options.tailleClé || 2048,
|
|
821
|
+
}, {
|
|
822
|
+
headers: { Authorization: `Bearer ${this.accessToken}`, 'Content-Type': 'application/json' },
|
|
823
|
+
});
|
|
824
|
+
return response.data;
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
// ==================== Workflow complet ====================
|
|
828
|
+
/**
|
|
829
|
+
* Workflow complet : génération + validation + signature + soumission AFNOR.
|
|
830
|
+
* Note: La signature utilise le certificat configuré côté serveur (via client_uid du JWT).
|
|
831
|
+
* @param factureData Données de la facture
|
|
832
|
+
* @param pdfPath Chemin vers le PDF source
|
|
833
|
+
* @param options Options du workflow
|
|
834
|
+
* @returns Résultat avec pdfBuffer, validation, signature et afnor
|
|
835
|
+
*/
|
|
836
|
+
genererFacturxComplet(factureData_1, pdfPath_1) {
|
|
837
|
+
return __awaiter(this, arguments, void 0, function* (factureData, pdfPath, options = {}) {
|
|
838
|
+
const { profil = 'EN16931', valider = true, signer = false, soumettreAfnor = false, afnorFlowName, afnorTrackingId, timeout, } = options;
|
|
839
|
+
const result = { pdfBuffer: Buffer.alloc(0) };
|
|
840
|
+
// 1. Génération
|
|
841
|
+
const pdfBuffer = yield this.genererFacturx(factureData, pdfPath, profil, 'pdf', true, timeout);
|
|
842
|
+
result.pdfBuffer = pdfBuffer;
|
|
843
|
+
// 2. Validation
|
|
844
|
+
if (valider) {
|
|
845
|
+
const validation = yield this.validerPdfFacturx(pdfBuffer, { profil });
|
|
846
|
+
result.validation = validation;
|
|
847
|
+
}
|
|
848
|
+
// 3. Signature (utilise le certificat configuré côté serveur)
|
|
849
|
+
if (signer) {
|
|
850
|
+
const signedPdf = yield this.signerPdf(result.pdfBuffer);
|
|
851
|
+
result.pdfBuffer = signedPdf;
|
|
852
|
+
result.signature = { signe: true };
|
|
853
|
+
}
|
|
854
|
+
// 4. Soumission AFNOR
|
|
855
|
+
if (soumettreAfnor) {
|
|
856
|
+
const numeroFacture = (factureData.numeroFacture || factureData.numero_facture || 'FACTURE');
|
|
857
|
+
const flowName = afnorFlowName || `Facture ${numeroFacture}`;
|
|
858
|
+
const trackingId = afnorTrackingId || numeroFacture;
|
|
859
|
+
const afnorResult = yield this.soumettreFactureAfnor(result.pdfBuffer, flowName, { trackingId });
|
|
860
|
+
result.afnor = afnorResult;
|
|
861
|
+
}
|
|
862
|
+
return result;
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
exports.FactPulseClient = FactPulseClient;
|