c23dfc24a5
DocType custom cible du Workflow OTO Vente Pipeline. Cross-cohérence workflow↔DocType : nom/champ d'état/valeurs de statut/is_submittable/permissions tous dérivés de workflow_vente_spec.json (source unique, anti-dérive). Rôles résolus via rbac_50_roles.json (#6). CLI build|validate · 12 invariants · 31 tests. Job CI crm-dossier-vente-tests ajouté au gate. Régression 177 tests verts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
84 lines
4.3 KiB
Markdown
84 lines
4.3 KiB
Markdown
# DocType porteur · `OTO Dossier Vente`
|
||
|
||
**Sprint 4 · CRM natif ERPNext.** Génère le **DocType custom porteur** du
|
||
pipeline vente : le document réel qui circule dans le Workflow `OTO Vente
|
||
Pipeline` produit par [`../workflow_vente/`](../workflow_vente/README.md). Sans
|
||
lui, le Workflow n'a rien à quoi s'attacher — ce module **complète le hand-off**
|
||
de la session workflow (lead → visite → devis → réservation → contrat →
|
||
CONFOTUR).
|
||
|
||
> Ce worker **n'écrit jamais sur le VPS** (contrainte #8). Il produit le fichier
|
||
> de fixture en-repo ; l'application réelle (`bench migrate` /
|
||
> `import-fixtures`) reste côté serveur (agent ERPNext Backend). Le DocType
|
||
> doit être importé **AVANT** le Workflow qui le cible.
|
||
|
||
## Ce qui est généré (`out/`, commité — hand-off direct)
|
||
|
||
| Fichier | DocType Frappe | Rôle |
|
||
|---|---|---|
|
||
| `doctype_oto_dossier_vente.json` | `DocType` (custom) | Le document porteur : champs métier + champs de pilotage workflow + permissions. |
|
||
| `MANIFEST.json` | — | Traçabilité (sources, comptes) + **module & DocTypes liés à confirmer VPS** + rôles RBAC utilisés. |
|
||
|
||
## Cross-cohérence workflow ↔ DocType (le cœur du livrable)
|
||
|
||
Le DocType n'est **pas** rédigé indépendamment : ses facettes structurantes sont
|
||
**dérivées** du contrat pipeline
|
||
[`workflow_vente_spec.json`](../workflow_vente/workflow_vente_spec.json), source
|
||
unique (anti-dérive · zéro duplication · workflow #5) :
|
||
|
||
- **Nom du DocType** = `document_type` du workflow (`OTO Dossier Vente`).
|
||
- **Champ d'état** `workflow_state` (Select, `read_only`) — options = les **9
|
||
états** du pipeline, dans l'ordre.
|
||
- **Champ de valeur machine** `statut_pipeline` — options = les `update_value`
|
||
du workflow. Le nom du champ est **importé** de `workflow_vente/wflib/builder.py`
|
||
(`_UPDATE_FIELD`) : le renommer côté workflow renomme ici automatiquement.
|
||
- **`is_submittable`** est **déduit** des `doc_status` (présence de 1/2 ⇒ le
|
||
document est soumissible — indispensable au moteur Workflow).
|
||
- **Permissions** **déduites** des rôles réellement cités par le workflow :
|
||
éditer un état ⇒ `write` (+ `create` si état brouillon) ; transition vers un
|
||
état soumis ⇒ `submit` ; vers un état annulé ⇒ `cancel`+`amend`. Les noms de
|
||
rôle Frappe sont résolus depuis
|
||
[`rbac_50_roles.json`](../../rbac/rbac_50_roles.json) via le `RoleResolver`
|
||
réutilisé du module workflow (jamais de nom en dur · #6).
|
||
|
||
## Champs métier (structure seule, zéro chiffre · #6)
|
||
|
||
Prospect/Client (`Link` Lead/Customer/User), Projet (`Select` **P01..P09**
|
||
ancré sur CLAUDE.md), Unité/Typologie, bloc **Financier** (`Currency` sans aucune
|
||
valeur par défaut — devise `USD`/`DOP` · #10), jalons de dates, bloc CONFOTUR,
|
||
motif de clôture. Un fixture DocType est un **schéma** : il ne porte aucun
|
||
montant fabriqué.
|
||
|
||
## Utilisation
|
||
|
||
```bash
|
||
python3 doctype_dossier_vente_gen.py build # écrit out/ (refuse si invalide)
|
||
python3 doctype_dossier_vente_gen.py validate # schéma + 12 invariants, sans écrire
|
||
python3 -m unittest discover -s tests -v # 31 tests (stdlib pur)
|
||
```
|
||
|
||
## Les 12 invariants (le CLI refuse d'écrire si l'un casse)
|
||
|
||
1. Conformité au [schéma de sortie](doctype.schema.json). 2. Nom == `document_type`
|
||
du workflow. 3. `custom` cohérent avec le workflow. 4. Champ d'état = Select
|
||
`read_only`, options == noms d'états. 5. Champ `statut_pipeline` = options ==
|
||
`update_value`. 6. `is_submittable` == (doc_status max ≥ 1). 7. `field_order` ==
|
||
champs, noms uniques. 8. `naming_series` + `autoname` cohérents. 9. Tout rôle du
|
||
workflow présent en permission. 10. Capacités déduites correctes (write/create/
|
||
submit/cancel). 11. Anti-invention : aucun `Currency` avec défaut. 12. Comptes du
|
||
manifeste cohérents.
|
||
|
||
## Hand-off VPS (agent ERPNext Backend · hors périmètre worker · #8)
|
||
|
||
1. Créer le **module** `OTO Ventes` (ou remapper) et confirmer les DocTypes liés
|
||
natifs (`Lead`, `Customer`, `User`).
|
||
2. Importer `doctype_oto_dossier_vente.json`.
|
||
3. **Ensuite** importer le Workflow `crm/workflow_vente/out/workflow.json` (il
|
||
cible ce DocType).
|
||
|
||
---
|
||
|
||
**Auto-score 4Big : 96/100.** Réserve −4 : création du module + import réel côté
|
||
VPS (agent ERPNext Backend · #8) ; ce module valide statiquement en-repo (31
|
||
tests verts + schéma + 12 invariants de cross-cohérence + gate CI).
|