""" Dispatch Settings — création du DocType Single dans ERPNext/Frappe ================================================================== Exécution (depuis le host) : docker cp frappe-setup/create_dispatch_settings.py frappe_docker-backend-1:/home/frappe/ docker exec frappe_docker-backend-1 bash -c \ "cd /home/frappe/frappe-bench && bench --site $(bench --site-list | head -1) execute /home/frappe/create_dispatch_settings.py" Ou directement dans la console bench : bench --site console >>> exec(open('/home/frappe/create_dispatch_settings.py').read()) """ import frappe FIELDS = [ # ── ERPNext / Frappe ───────────────────────────────────────────────────── {'fieldname': 'erp_section', 'fieldtype': 'Section Break', 'label': 'ERPNext / Frappe'}, {'fieldname': 'erp_url', 'fieldtype': 'Data', 'label': 'URL du serveur', 'description': 'Ex: http://localhost:8080 ou https://erp.monentreprise.com', 'default': 'http://localhost:8080'}, {'fieldname': 'erp_api_key', 'fieldtype': 'Data', 'label': 'API Key', 'description': 'Profil utilisateur ERPNext → API Access → API Key'}, {'fieldname': 'erp_api_secret', 'fieldtype': 'Password', 'label': 'API Secret'}, # ── Mapbox ─────────────────────────────────────────────────────────────── {'fieldname': 'mapbox_section', 'fieldtype': 'Section Break', 'label': 'Mapbox'}, {'fieldname': 'mapbox_token', 'fieldtype': 'Data', 'label': 'Token public (pk_)', 'description': 'Token public — visible dans le navigateur, limitez le scope dans le dashboard Mapbox', 'default': 'pk.eyJ1IjoidGFyZ29pbnRlcm5ldCIsImEiOiJjbW13Z3lwMXAwdGt1MnVvamsxNWkybzFkIn0.rdYB17XUdfn96czdnnJ6eg'}, # ── Twilio (SMS) ───────────────────────────────────────────────────────── {'fieldname': 'twilio_section', 'fieldtype': 'Section Break', 'label': 'Twilio — SMS'}, {'fieldname': 'twilio_account_sid', 'fieldtype': 'Data', 'label': 'Account SID', 'description': 'Commence par AC — console.twilio.com'}, {'fieldname': 'twilio_auth_token', 'fieldtype': 'Password', 'label': 'Auth Token'}, {'fieldname': 'twilio_from_number', 'fieldtype': 'Data', 'label': 'Numéro expéditeur', 'description': 'Format E.164 : +15141234567'}, # ── Stripe ─────────────────────────────────────────────────────────────── {'fieldname': 'stripe_section', 'fieldtype': 'Section Break', 'label': 'Stripe — Paiements'}, {'fieldname': 'stripe_mode', 'fieldtype': 'Select', 'label': 'Mode', 'options': 'test\nlive', 'default': 'test'}, {'fieldname': 'stripe_publishable_key','fieldtype': 'Data', 'label': 'Clé publique (pk_)'}, {'fieldname': 'stripe_secret_key', 'fieldtype': 'Password', 'label': 'Clé secrète (sk_)'}, {'fieldname': 'stripe_webhook_secret', 'fieldtype': 'Password', 'label': 'Webhook Secret (whsec_)'}, # ── n8n ────────────────────────────────────────────────────────────────── {'fieldname': 'n8n_section', 'fieldtype': 'Section Break', 'label': 'n8n — Automatisation'}, {'fieldname': 'n8n_url', 'fieldtype': 'Data', 'label': 'URL n8n', 'default': 'http://localhost:5678'}, {'fieldname': 'n8n_api_key', 'fieldtype': 'Password', 'label': 'API Key n8n'}, {'fieldname': 'n8n_webhook_base','fieldtype': 'Data', 'label': 'Base URL webhooks', 'description': 'Ex: http://localhost:5678/webhook — préfixe des webhooks ERPNext → n8n', 'default': 'http://localhost:5678/webhook'}, # ── Templates SMS ──────────────────────────────────────────────────────── {'fieldname': 'sms_section', 'fieldtype': 'Section Break', 'label': 'Templates SMS'}, {'fieldname': 'sms_enroute', 'fieldtype': 'Text', 'label': 'Technicien en route', 'default': 'Bonjour {client_name}, votre technicien {tech_name} est en route et arrivera dans environ {eta} minutes. Réf: {job_id}'}, {'fieldname': 'sms_completed', 'fieldtype': 'Text', 'label': 'Service complété', 'default': 'Bonjour {client_name}, votre service ({job_id}) a été complété avec succès. Merci de votre confiance !'}, {'fieldname': 'sms_assigned', 'fieldtype': 'Text', 'label': 'Job assigné (technicien)', 'default': 'Nouveau job assigné : {job_id} — {client_name}, {address}. Durée estimée : {duration}h.'}, ] PERMISSIONS = [ {'role': 'System Manager', 'read': 1, 'write': 1, 'create': 1, 'delete': 1}, {'role': 'Administrator', 'read': 1, 'write': 1, 'create': 1, 'delete': 1}, ] def create_dispatch_settings(): if frappe.db.exists('DocType', 'Dispatch Settings'): print("✓ DocType 'Dispatch Settings' existe déjà") print(" UI : ERPNext Desk → Dispatch Settings") print(" API : /api/resource/Dispatch Settings/Dispatch Settings") return doc = frappe.new_doc('DocType') doc.update({ 'name': 'Dispatch Settings', 'module': 'Core', 'custom': 1, 'is_single': 1, 'track_changes': 0, 'fields': FIELDS, 'permissions': PERMISSIONS, }) doc.insert(ignore_permissions=True) frappe.db.commit() print("✓ DocType 'Dispatch Settings' créé avec succès") print(" UI : ERPNext Desk → Dispatch Settings") print(" API : /api/resource/Dispatch Settings/Dispatch Settings") create_dispatch_settings()