[DTP-Worker] Sprint 4 · Générateur workflow vente ERPNext (lead → CONFOTUR)

Contrat pipeline commercial CRM natif (lead → visite → devis → réservation →
contrat → CONFOTUR) → fixtures Frappe/ERPNext v15 : Workflow (9 états / 11
transitions) + Workflow State + Workflow Action Master + MANIFEST.

Rôles gardant états/transitions résolus depuis rbac_50_roles.json (réutilisation,
zéro duplication · #6) : le contrat ne cite qu'un id de rôle, jamais un nom
Frappe en dur. CLI build/validate refuse d'écrire si l'un des 9 invariants de
graphe casse (monotonie doc_status, atteignabilité, séparation des pouvoirs sur
les étapes engageant de l'argent / clôturant).

25 tests (stdlib pur + oracle jsonschema) · job CI crm-workflow-vente-tests ajouté
au gate · 146 tests de régression verts au total. Application VPS (DocType porteur
OTO Dossier Vente + bench migrate) = agent ERPNext Backend, hors périmètre worker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Code DTP Worker
2026-07-30 05:36:27 +00:00
parent 915fc5194a
commit 34f202af40
17 changed files with 1797 additions and 1 deletions
@@ -0,0 +1,48 @@
{
"generated_from": "workflow_vente_spec.json",
"rbac_source": "rbac_50_roles.json",
"source_version": "1.0.0",
"workflow_name": "OTO Vente Pipeline",
"document_type": "OTO Dossier Vente",
"document_type_custom": true,
"counts": {
"states": 9,
"transitions": 11,
"workflow_state_masters": 9,
"workflow_action_masters": 9,
"terminal_states": 3
},
"custom_doctypes_a_confirmer": [
"OTO Dossier Vente"
],
"roles_rbac_utilises": [
{
"role_id": "direction-cco",
"erpnext_role_name": "OTO Direction Commerciale"
},
{
"role_id": "ventes-chef-equipe",
"erpnext_role_name": "OTO Ventes Chef Équipe"
},
{
"role_id": "ventes-confotur",
"erpnext_role_name": "OTO Ventes CONFOTUR"
},
{
"role_id": "ventes-conseiller",
"erpnext_role_name": "OTO Ventes Conseiller"
},
{
"role_id": "ventes-contrats",
"erpnext_role_name": "OTO Ventes Contrats"
},
{
"role_id": "ventes-directeur",
"erpnext_role_name": "OTO Ventes Directeur"
},
{
"role_id": "ventes-reservations",
"erpnext_role_name": "OTO Ventes Réservations"
}
]
}
@@ -0,0 +1,185 @@
[
{
"doctype": "Workflow",
"name": "OTO Vente Pipeline",
"workflow_name": "OTO Vente Pipeline",
"document_type": "OTO Dossier Vente",
"workflow_state_field": "workflow_state",
"is_active": 1,
"send_email_alert": 0,
"override_status": 0,
"states": [
{
"state": "Lead",
"doc_status": "0",
"allow_edit": "OTO Ventes Conseiller",
"update_field": "statut_pipeline",
"update_value": "lead",
"is_optional_state": 0,
"message": "Nouveau prospect qualifie a contacter."
},
{
"state": "Visite planifiée",
"doc_status": "0",
"allow_edit": "OTO Ventes Conseiller",
"update_field": "statut_pipeline",
"update_value": "visite",
"is_optional_state": 0,
"message": "Visite du site ou de l'unite temoin programmee."
},
{
"state": "Devis émis",
"doc_status": "0",
"allow_edit": "OTO Ventes Conseiller",
"update_field": "statut_pipeline",
"update_value": "devis",
"is_optional_state": 0,
"message": "Devis chiffre remis au prospect (attente decision)."
},
{
"state": "Réservation confirmée",
"doc_status": "1",
"allow_edit": "OTO Ventes Réservations",
"update_field": "statut_pipeline",
"update_value": "reservation",
"is_optional_state": 0,
"message": "Depot de reservation encaisse ; dossier verrouille (soumis)."
},
{
"state": "Contrat signé",
"doc_status": "1",
"allow_edit": "OTO Ventes Contrats",
"update_field": "statut_pipeline",
"update_value": "contrat",
"is_optional_state": 0,
"message": "Contrat de vente signe par les deux parties."
},
{
"state": "CONFOTUR déposé",
"doc_status": "1",
"allow_edit": "OTO Ventes CONFOTUR",
"update_field": "statut_pipeline",
"update_value": "confotur_depose",
"is_optional_state": 0,
"message": "Dossier d'incitation CONFOTUR depose aupres de l'autorite."
},
{
"state": "CONFOTUR approuvé",
"doc_status": "1",
"allow_edit": "OTO Ventes CONFOTUR",
"update_field": "statut_pipeline",
"update_value": "confotur_approuve",
"is_optional_state": 0,
"message": "Incitation CONFOTUR approuvee ; cycle de vente clos avec succes."
},
{
"state": "Abandonné",
"doc_status": "0",
"allow_edit": "OTO Ventes Chef Équipe",
"update_field": "statut_pipeline",
"update_value": "abandonne",
"is_optional_state": 0,
"message": "Piste abandonnee avant reservation (brouillon)."
},
{
"state": "Perdu",
"doc_status": "2",
"allow_edit": "OTO Ventes Directeur",
"update_field": "statut_pipeline",
"update_value": "perdu",
"is_optional_state": 0,
"message": "Affaire soumise resiliee/annulee (dossier annule)."
}
],
"transitions": [
{
"state": "CONFOTUR déposé",
"action": "Approuver CONFOTUR",
"next_state": "CONFOTUR approuvé",
"allowed": "OTO Ventes CONFOTUR",
"allow_self_approval": 0,
"condition": null
},
{
"state": "Contrat signé",
"action": "Déposer CONFOTUR",
"next_state": "CONFOTUR déposé",
"allowed": "OTO Ventes CONFOTUR",
"allow_self_approval": 1,
"condition": null
},
{
"state": "Contrat signé",
"action": "Résilier (perdu)",
"next_state": "Perdu",
"allowed": "OTO Direction Commerciale",
"allow_self_approval": 0,
"condition": null
},
{
"state": "Devis émis",
"action": "Abandonner",
"next_state": "Abandonné",
"allowed": "OTO Ventes Chef Équipe",
"allow_self_approval": 1,
"condition": null
},
{
"state": "Devis émis",
"action": "Confirmer réservation",
"next_state": "Réservation confirmée",
"allowed": "OTO Ventes Réservations",
"allow_self_approval": 0,
"condition": null
},
{
"state": "Lead",
"action": "Abandonner",
"next_state": "Abandonné",
"allowed": "OTO Ventes Conseiller",
"allow_self_approval": 1,
"condition": null
},
{
"state": "Lead",
"action": "Planifier visite",
"next_state": "Visite planifiée",
"allowed": "OTO Ventes Conseiller",
"allow_self_approval": 1,
"condition": null
},
{
"state": "Réservation confirmée",
"action": "Annuler (perdu)",
"next_state": "Perdu",
"allowed": "OTO Ventes Directeur",
"allow_self_approval": 0,
"condition": null
},
{
"state": "Réservation confirmée",
"action": "Signer contrat",
"next_state": "Contrat signé",
"allowed": "OTO Ventes Contrats",
"allow_self_approval": 0,
"condition": null
},
{
"state": "Visite planifiée",
"action": "Abandonner",
"next_state": "Abandonné",
"allowed": "OTO Ventes Conseiller",
"allow_self_approval": 1,
"condition": null
},
{
"state": "Visite planifiée",
"action": "Émettre devis",
"next_state": "Devis émis",
"allowed": "OTO Ventes Conseiller",
"allow_self_approval": 1,
"condition": null
}
]
}
]
@@ -0,0 +1,47 @@
[
{
"doctype": "Workflow Action Master",
"name": "Abandonner",
"workflow_action_name": "Abandonner"
},
{
"doctype": "Workflow Action Master",
"name": "Annuler (perdu)",
"workflow_action_name": "Annuler (perdu)"
},
{
"doctype": "Workflow Action Master",
"name": "Approuver CONFOTUR",
"workflow_action_name": "Approuver CONFOTUR"
},
{
"doctype": "Workflow Action Master",
"name": "Confirmer réservation",
"workflow_action_name": "Confirmer réservation"
},
{
"doctype": "Workflow Action Master",
"name": "Déposer CONFOTUR",
"workflow_action_name": "Déposer CONFOTUR"
},
{
"doctype": "Workflow Action Master",
"name": "Planifier visite",
"workflow_action_name": "Planifier visite"
},
{
"doctype": "Workflow Action Master",
"name": "Résilier (perdu)",
"workflow_action_name": "Résilier (perdu)"
},
{
"doctype": "Workflow Action Master",
"name": "Signer contrat",
"workflow_action_name": "Signer contrat"
},
{
"doctype": "Workflow Action Master",
"name": "Émettre devis",
"workflow_action_name": "Émettre devis"
}
]
@@ -0,0 +1,56 @@
[
{
"doctype": "Workflow State",
"name": "Abandonné",
"workflow_state_name": "Abandonné",
"style": "Danger"
},
{
"doctype": "Workflow State",
"name": "CONFOTUR approuvé",
"workflow_state_name": "CONFOTUR approuvé",
"style": "Success"
},
{
"doctype": "Workflow State",
"name": "CONFOTUR déposé",
"workflow_state_name": "CONFOTUR déposé",
"style": "Info"
},
{
"doctype": "Workflow State",
"name": "Contrat signé",
"workflow_state_name": "Contrat signé",
"style": "Success"
},
{
"doctype": "Workflow State",
"name": "Devis émis",
"workflow_state_name": "Devis émis",
"style": "Warning"
},
{
"doctype": "Workflow State",
"name": "Lead",
"workflow_state_name": "Lead",
"style": "Primary"
},
{
"doctype": "Workflow State",
"name": "Perdu",
"workflow_state_name": "Perdu",
"style": "Danger"
},
{
"doctype": "Workflow State",
"name": "Réservation confirmée",
"workflow_state_name": "Réservation confirmée",
"style": "Primary"
},
{
"doctype": "Workflow State",
"name": "Visite planifiée",
"workflow_state_name": "Visite planifiée",
"style": "Info"
}
]