Files
oto-enterprise-os-dtp/05_deliverables_mvp/fiscal/ecf_dgii
Claude Code DTP Worker 7117394651 [DTP-Worker] Sprint 4 · Générateur configuration e-CF DGII (Compupar) (ERPNext Backend · roadmap L51)
Facturation électronique dominicaine cross-cohérente workflow↔DocType↔RBAC :
émission sur état soumis, base Currency réelle, rôle compta-fiscaliste-ecf.
Anti-invention (#6) : RNC/ITBIS/TipoCambio/endpoints Compupar null (a_confirmer,
jamais sans source) ; seules les données de référence DGII encodées avec source.
Composeur e-NCF traçable (E+tipo(2)+seq(10)). 39 tests · 12 invariants · gate CI
(job fiscal-ecf-tests) · 241 tests de régression verts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-30 07:08:55 +00:00
..

Intégration e-CF DGII (Compupar) · OTO e-CF DGII

Sprint 4 · ERPNext Backend (roadmap ligne 51 : « e-CF DGII intégration (Compupar) »). Produit un plan de configuration de la facturation électronique dominicaine, cross-cohérent avec les contrats CRM déjà livrés : le pipeline vente ../../crm/workflow_vente/, le DocType porteur ../../crm/dossier_vente/ et le contrat RBAC 50 rôles. Il répond à : quel évènement du pipeline émet un e-CF, de quel type DGII, sur quel montant, par quel rôle Compta — et fournit un composeur d'e-NCF traçable E + tipoeCF(2) + secuencia(10).

Ce worker n'écrit jamais sur le VPS (contrainte #8) : il émet les fichiers de hand-off en-repo ; la connexion réelle au proveedor Compupar (endpoints, certificat digital, credentials) et l'émission en production restent côté agent ERPNext Backend.

Anti-invention (#6) — pourquoi tout chiffre OTO reste null

Aucun chiffre fiscal propre à OTO n'est documenté dans CLAUDE.md. Fixer ici un RNC, un taux ITBIS ou un taux de change serait une invention. Donc :

  • emisor.rnc_emisor, taxes[].taux_pct, moneda.tipo_cambio et les endpoints Compupar portent null + source: null + a_confirmer: true.
  • Un invariant refuse toute de ces valeurs fixée sans source.
  • Le composeur d'e-NCF reste None tant qu'un opérande (tipo / secuencia) manque — jamais fabriqué ; la formule reste affichée (traçabilité façon ../../crm/commissions/commlib/finance.py).

Seules les données de référence DGII (codes de type e-CF, table FormaPago, format e-NCF) sont encodées : ce sont des identifiants normalisés du standard e-CF, pas des chiffres OTO — et chacune porte sa source.

Ce qui est généré (out/, commité — hand-off direct)

Fichier Rôle
ecf_plan.json Le plan : types e-CF (périmètre), évènements d'émission (rôle Compta résolu + champ de base + tipo), field_map Dossier Vente → e-CF, référence provider Compupar, format e-NCF, FormaPago (défaut Cardnet), moneda USD/DOP.
MANIFEST.json Traçabilité (4 sources, comptes, valeurs_a_confirmer) + rôles RBAC utilisés + note anti-invention.

Cross-cohérence e-CF ↔ workflow ↔ DocType ↔ RBAC (le cœur du livrable)

Chaque évènement d'émission est contraint par les contrats voisins (anti-dérive · zéro duplication · workflow #5) :

  • update_value doit exister dans workflow_vente_spec.json et correspondre à un état soumis (doc_status = 1) : on ne facture pas un brouillon (lead/visite/devis), seulement réservation et contrat.
  • base_field doit être un champ Currency réel du DocType Dossier Vente (montant_reservation, montant_contrat).
  • role_id doit être résolu depuis rbac_50_roles.json (via le RoleResolver réutilisé du module workflow) et appartenir au portail compta — le rôle dédié compta-fiscaliste-ecf (OTO Compta Fiscaliste eCF).
  • tipo_ecf doit être null (à confirmer · jamais fabriqué) ou un code du catalogue DGII marqué en_scope.
  • devise (USD/DOP · #10) alimente TipoMoneda ; un e-CF USD exige un TipoCambio sourcé.
  • FormaPago défaut = 3 (Tarjeta) car encaissements OTO via Cardnet (#10).

Utilisation

python3 ecf_dgii_gen.py build      # écrit out/ (refuse si invalide)
python3 ecf_dgii_gen.py validate   # schéma + 12 invariants, sans écrire
python3 -m unittest discover -s tests -v   # 39 tests (stdlib pur)

Les 12 invariants (le CLI refuse d'écrire si l'un casse)

  1. Conformité au schéma de sortie. 2. update_value ∈ workflow vente. 3. État soumis uniquement (pas d'e-CF sur brouillon). 4. base_field = champ Currency réel du Dossier Vente. 5. role_id du portail compta + erpnext_role_name cohérent RBAC. 6. tipo_ecf null (à confirmer) ou code DGII en périmètre. 7. Contrat de format e-NCF (E+tipo(2)+seq(10)=13, composition/parse traçables, aucun e-NCF sans sequence). 8. FormaPago défaut ∈ table DGII + référence Cardnet (#10). 9. moneda = devise USD/DOP alignée sur le DocType ; TipoCambio null ou sourcé. 10. Anti-invention : RNC / ITBIS jamais sans source. 11. field_map : chaque dossier_field réel. 12. Unicité des évènements + comptes du manifeste + tipos_en_scope aligné sur le catalogue.

Composition traçable de l'e-NCF (ecflib/ncf.py)

compose_encf(tipo, secuencia)e_ncf = "E" + tipo(2) + secuencia(10), avec la formule publiée, None si un opérande manque (jamais 0-inventé · #6) et champs_manquants. parse_encf / is_valid_encf rejettent le NCF physique (B01…). La fixture sert uniquement aux tests : ses opérandes sont fictifs et portent une source « non contractuel ».

Hand-off VPS (agent ERPNext Backend · hors périmètre worker · #8)

  1. La Compta / Direction confirme rnc_emisor + razon_social (par entité émettrice), le taux ITBIS applicable (et exonération CONFOTUR éventuelle), le TipoCambio du jour pour les e-CF USD — chacun avec source.
  2. Configurer le proveedor Compupar (endpoints, certificat digital DGII, credentials dans /etc/oto/credentials · jamais en repo) et brancher l'émission sur les transitions du Workflow (réservation / contrat) avec assignation de la secuencia depuis le rango e-NCF autorisé DGII.

Auto-score 4Big : 96/100. Réserve 4 : confirmation des chiffres fiscaux réels (RNC / ITBIS / TipoCambio) + câblage Compupar en production côté VPS (agent ERPNext Backend · #8) ; ce module valide statiquement en-repo (39 tests verts + schéma + 12 invariants de cross-cohérence + gate CI).