Files
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

106 lines
5.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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/`](../../crm/workflow_vente/README.md),
le DocType porteur [`../../crm/dossier_vente/`](../../crm/dossier_vente/README.md)
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`](../../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`](../../crm/workflow_vente/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`](../../rbac/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
```bash
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](ecf.schema.json). 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](fixtures/dossier_exemple.json) 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).