Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/TI-Sin-Problemas/erpnext_mexico_compliance/llms.txt

Use this file to discover all available pages before exploring further.

ERPNext Mexico Compliance fires two custom document event hooks around the CFDI stamping operation, allowing you to inject custom business logic before and after a CFDI is stamped. These hooks are triggered from the stamp_cfdi method in CommonController via Frappe’s run_method, which dispatches them through the standard doc_events system.

Available hooks

HookTriggeredUse case
before_stamp_cfdiBefore the CFDI is sent to the web serviceValidate custom fields, transform data, prevent stamping under certain conditions
after_stamp_cfdiAfter the CFDI is successfully stamped and XML is storedTrigger downstream actions, notify systems, update related records

How to implement hooks

Frappe document event hooks are registered in your custom app’s hooks.py under the doc_events key. The value for each event is a dotted Python path to the handler function. You can register handlers on "Sales Invoice", "Payment Entry", or both.
hooks.py
# In your custom app's hooks.py
doc_events = {
    "Sales Invoice": {
        "before_stamp_cfdi": "my_app.my_module.before_stamp_cfdi",
        "after_stamp_cfdi": "my_app.my_module.after_stamp_cfdi",
    },
    "Payment Entry": {
        "after_stamp_cfdi": "my_app.my_module.payment_after_stamp",
    },
}
After editing hooks.py, run bench migrate on your site to register the new hooks.

Hook function signature

Each hook function receives the document instance as the first argument (doc) and an optional method keyword argument (the name of the event that triggered it). When run_method dispatches the hook, doc is the live SalesInvoice or PaymentEntry document object.
my_app/my_module.py
def before_stamp_cfdi(doc, method=None):
    """Called before stamping a Sales Invoice or Payment Entry CFDI."""
    # doc is the Sales Invoice or Payment Entry document.
    # Raise frappe.throw() or frappe.ValidationError to abort stamping.
    if doc.customer == "SPECIAL-CUSTOMER":
        frappe.throw("Cannot stamp CFDI for this customer.")

def after_stamp_cfdi(doc, method=None):
    """Called after successful CFDI stamping."""
    # doc.mx_stamped_xml contains the full stamped XML string.
    # doc.mx_uuid contains the SAT-assigned CFDI UUID (TimbreFiscalDigital UUID).
    notify_erp_integration(doc.name, doc.mx_uuid)
Raising frappe.ValidationError or calling frappe.throw() inside before_stamp_cfdi will abort the entire stamping operation. The CFDI will not be sent to the web service, and no stamp credit will be consumed.

Standard Frappe hooks registered by this app

In addition to the two custom CFDI event hooks, erpnext_mexico_compliance/hooks.py registers the following standard Frappe hooks:
Hook keyValueEffect
after_migrateerpnext_mexico_compliance.migrate.execute_after_migrate_tasksRuns SAT catalog updates and data migrations automatically after every bench migrate
override_doctype_classCustomer, Employee, Payment Entry, Sales Invoice, Sales Invoice ItemReplaces the standard ERPNext controller classes with compliance-aware subclasses (erpnext_mexico_compliance.overrides.*)
scheduler_events.hourlyerpnext_mexico_compliance.tasks.check_cancellation_statusPolls the SAT to reconcile CFDI cancellation status every hour
doctype_jsSales Invoice, Payment EntryInjects custom JavaScript (Stamp CFDI / Cancel CFDI buttons) into both form views
app_include_js/assets/erpnext_mexico_compliance/js/utils.jsLoads shared client-side utilities into every Desk page
web_include_js/assets/erpnext_mexico_compliance/js/portal_invoice.jsLoads CFDI portal rendering logic into every web page
override_doctype_class means the Customer and Employee doctypes also gain compliance validation logic (RFC and CURP format checks, respectively) without any additional configuration on your part.

Build docs developers (and LLMs) love