[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:
@@ -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"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user