Accumulated work on the dispatch/legacy-writeback branch: - Communications UI: CommunicationsPage, ConversationFullPage, DepartmentBoard, PipelineBoard, ReaderStack, Orchestrator/NewTicket/ServiceStatus/Outbox dialogs; hub gmail.js, ticket-collab.js, outbox.js, coupon-triage.js, client-diag.js. - Billing/sync mirror (F→ERPNext): legacy-payments.js, legacy-sync.js, sync-orchestrator.js, supplier-invoices.js, municipality.js + incremental migration scripts; LegacySyncPage, SupplierInvoices + negative-billing / terminated-active reports. - Roster/campaigns/network/voice: roster + roster-assistant, campaigns, giftbit, olt-snmp, traccar, twilio, vision, tech-absence-sms, ai/agent/config/helpers, legacy-dispatch-sync; ops PlanificationPage, RapportsPage, Settings, Tickets, ClientDetail updates. - docs/ PLATFORM_GUIDE + UI_AND_OPTIMIZATION; .gitignore __pycache__. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
70 lines
3.9 KiB
Python
70 lines
3.9 KiB
Python
"""
|
|
setup_supplier_invoice.py — Doctype « Supplier Invoice Intake » (factures fournisseurs captées par OCR).
|
|
|
|
Récolte : courriels to:factures@ → OCR (hub) → un intake par pièce jointe → revue dans OPS →
|
|
création d'un Purchase Invoice DRAFT dans ERPNext (jamais soumis auto). L'intake est le registre
|
|
auditable/permissionné de la capture ; le Purchase Invoice reste le document comptable de référence.
|
|
|
|
Exécuter dans le conteneur bench :
|
|
docker exec erpnext-backend-1 bench --site erp.gigafibre.ca execute setup_supplier_invoice.create
|
|
"""
|
|
|
|
import frappe
|
|
|
|
|
|
def create():
|
|
if frappe.db.exists("DocType", "Supplier Invoice Intake"):
|
|
print(" Supplier Invoice Intake existe déjà — skip.")
|
|
return
|
|
|
|
doc = frappe.get_doc({
|
|
"doctype": "DocType",
|
|
"name": "Supplier Invoice Intake",
|
|
"module": "Buying",
|
|
"custom": 1,
|
|
"autoname": "SII-.#####",
|
|
"track_changes": 1,
|
|
"sort_field": "modified",
|
|
"sort_order": "DESC",
|
|
"fields": [
|
|
{"fieldname": "status", "fieldtype": "Select", "label": "Statut",
|
|
"options": "New\nCreated\nIgnored\nError", "default": "New",
|
|
"in_list_view": 1, "in_standard_filter": 1, "reqd": 1},
|
|
{"fieldname": "vendor", "fieldtype": "Data", "label": "Fournisseur (OCR)", "in_list_view": 1},
|
|
{"fieldname": "supplier", "fieldtype": "Link", "label": "Fournisseur (lié)", "options": "Supplier"},
|
|
{"fieldname": "invoice_number", "fieldtype": "Data", "label": "N° facture", "in_list_view": 1},
|
|
{"fieldname": "invoice_date", "fieldtype": "Date", "label": "Date facture"},
|
|
{"fieldname": "due_date", "fieldtype": "Date", "label": "Échéance"},
|
|
{"fieldname": "cb1", "fieldtype": "Column Break"},
|
|
{"fieldname": "currency", "fieldtype": "Data", "label": "Devise", "default": "CAD"},
|
|
{"fieldname": "subtotal", "fieldtype": "Currency", "label": "Sous-total"},
|
|
{"fieldname": "tax_gst", "fieldtype": "Currency", "label": "TPS/GST"},
|
|
{"fieldname": "tax_qst", "fieldtype": "Currency", "label": "TVQ/QST"},
|
|
{"fieldname": "total", "fieldtype": "Currency", "label": "Total", "in_list_view": 1},
|
|
|
|
{"fieldname": "sb_src", "fieldtype": "Section Break", "label": "Source"},
|
|
{"fieldname": "email_from", "fieldtype": "Data", "label": "Expéditeur"},
|
|
{"fieldname": "email_subject", "fieldtype": "Data", "label": "Sujet"},
|
|
{"fieldname": "email_date", "fieldtype": "Data", "label": "Date courriel"},
|
|
{"fieldname": "gmail_msg_id", "fieldtype": "Data", "label": "Gmail message id", "read_only": 1},
|
|
{"fieldname": "cb2", "fieldtype": "Column Break"},
|
|
{"fieldname": "attachment", "fieldtype": "Attach", "label": "Pièce jointe"},
|
|
{"fieldname": "attachment_filename", "fieldtype": "Data", "label": "Nom du fichier"},
|
|
|
|
{"fieldname": "sb_link", "fieldtype": "Section Break", "label": "OCR / Comptabilité"},
|
|
{"fieldname": "purchase_invoice", "fieldtype": "Link", "label": "Purchase Invoice", "options": "Purchase Invoice"},
|
|
{"fieldname": "ocr_error", "fieldtype": "Small Text", "label": "Erreur OCR"},
|
|
{"fieldname": "raw_ocr", "fieldtype": "Long Text", "label": "OCR brut (JSON)"},
|
|
],
|
|
"permissions": [
|
|
{"role": "System Manager", "read": 1, "write": 1, "create": 1, "delete": 1,
|
|
"report": 1, "export": 1, "email": 1, "print": 1, "share": 1},
|
|
{"role": "Accounts Manager", "read": 1, "write": 1, "create": 1, "delete": 1,
|
|
"report": 1, "export": 1, "email": 1, "print": 1, "share": 1},
|
|
{"role": "Accounts User", "read": 1, "write": 1, "create": 1, "report": 1, "print": 1},
|
|
],
|
|
})
|
|
doc.insert(ignore_permissions=True)
|
|
frappe.db.commit()
|
|
print("✓ Supplier Invoice Intake créé.")
|