Mexico - SAT Connection

l10n_mx_sat
REPOSITORY
REPOSITORYOCA/l10n-mexico
GIT
GIThttps://github.com/OCA/l10n-mexico.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/l10n-mexico/tree/18.0/l10n_mx_sat
VERSION
VERSION 1.0.0
CATEGORY
CATEGORYAccounting/Localizations
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Gray Matter Logic, Asociacion Mexicana de Odoo (AMOdoo), Cloud Lotus
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Gray Matter Logic, Asociacion Mexicana de Odoo (AMOdoo), Cloud Lotus
COMMITTERS
COMMITTERSOCA-git-bot, oca-ci, Roberto
WEBSITE
WEBSITEhttps://github.com/OCA/l10n-mexico
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:30:17
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Description
===========

Base module to connect Odoo to the Mexican Tax Administration (SAT)
portal using FIEL electronic signature credentials.

It provides:

- Multi-company FIEL credentials stored on each `res.company` record.
- A SAT tab on the company form to configure download flows, sync dates,
  and manual synchronization.
- A secure FIEL credentials wizard that stores certificate, key, and
  password without exposing saved values in the UI.
- Generic SAT document storage (`l10n_mx_sat.document`) for CFDIs and
  retentions, both issued and received.
- A download orchestration layer (`l10n_mx_sat.download.request`) that
  handles XML mass downloads via `satcfdi`.
- Configurable XML download flows per company: CFDI issued/received and
  retentions issued/received.
- An adapter (`SatClient`) that wraps communication with the SAT via
  the `satcfdi` library. Other modules can use this adapter without
  depending directly on `satcfdi`.
- A factory method `company.l10n_mx_sat_get_client()` that returns an
  adapter instance. It can be overridden via `_inherit` to swap the
  underlying implementation.


This module downloads and stores SAT XML documents. Automatic metadata
synchronization is postponed for a future release. Other custom modules
may consume `l10n_mx_sat.document` records for their own business flows.

Code Analysis

Views touched (9)
XML IDNameModelTypeStatus
l10n_mx_sat_company_connection_view_list res.company.l10n_mx_sat.connection.list res.company list New
l10n_mx_sat_document_view_form l10n_mx_sat.document.form l10n_mx_sat.document form New
l10n_mx_sat_document_view_list l10n_mx_sat.document.list l10n_mx_sat.document list New
l10n_mx_sat_document_view_search l10n_mx_sat.document.search l10n_mx_sat.document search New
l10n_mx_sat_download_request_view_form l10n_mx_sat.download.request.form l10n_mx_sat.download.request form New
l10n_mx_sat_download_request_view_list l10n_mx_sat.download.request.list l10n_mx_sat.download.request list New
l10n_mx_sat_download_request_view_search l10n_mx_sat.download.request.search l10n_mx_sat.download.request search New
l10n_mx_sat_fiel_credentials_wizard_view_form l10n_mx_sat.fiel.credentials.wizard.form l10n_mx_sat.fiel.credentials.wizard form New
view_company_form_inherit_l10n_mx_sat res.company.form.inherit.l10n_mx_sat res.company xpath Inherits base.view_company_form
Models touched (5)

New fields (21)
  • attachment_id Many2one → ir.attachment
    comodel_name='ir.attachment' ondelete='set null' readonly=True string='XML'
  • cancellation_date Datetime
    readonly=True string='Cancellation date'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> index=True readonly=True required=True string='Company'
  • currency_code Char
    readonly=True string='Currency'
  • direction Selection
    index=True readonly=True required=True selection=[('issued', 'Issued'), ('received', 'Received')]
  • display_name Char
    compute='_compute_display_name' readonly=True store=True
  • document_kind Selection
    index=True readonly=True required=True selection=[('cfdi', 'CFDI'), ('retention', 'Retention')] string='Document kind'
  • download_request_id Many2one → l10n_mx_sat.download.request
    comodel_name='l10n_mx_sat.download.request' ondelete='set null' readonly=True string='SAT request'
  • folio_number Char
    readonly=True string='Folio'
  • has_xml Boolean
    default=False index=True readonly=True string='Has XML'
  • issue_date Datetime
    index=True readonly=True string='Issue date'
  • issuer_name Char
    readonly=True string='Issuer name'
  • issuer_rfc Char
    index=True readonly=True string='Issuer RFC'
  • receiver_name Char
    readonly=True string='Receiver name'
  • receiver_rfc Char
    index=True readonly=True string='Receiver RFC'
  • sat_status Selection
    index=True readonly=True selection=[('valid', 'Valid'), ('cancelled', 'Cancelled'), ('in_progress', 'In progress')] string='SAT status'
  • series Char
    readonly=True
  • stamp_date Datetime
    readonly=True string='Stamp date'
  • total Float
    digits=(16, 6) readonly=True
  • uuid Char
    index=True readonly=True required=True string='UUID'
  • voucher_type Char
    index=True readonly=True string='Voucher type'
Public methods (5)
  • action_download_xml(self)
  • create(self, vals_list)
    @api.model_create_multi
  • get_formview_action(self, access_uid=None)
    Always open SAT documents in readonly mode (list, menu, x2many).
  • unlink(self)
  • write(self, vals)

New fields (4)
  • company_id Many2one
    index=True related='request_id.company_id' store=True
  • request_id Many2one → l10n_mx_sat.download.request
    comodel_name='l10n_mx_sat.download.request' ondelete='cascade' required=True string='SAT request'
  • sat_package_id Char
    readonly=True required=True string='Package ID'
  • state Selection
    default='pending' readonly=True required=True selection=[('pending', 'Pending'), ('processed', 'Processed'), ('error', 'Error')]
Public methods (0)

No public methods.

New fields (17)
  • can_retry Boolean
    compute='_compute_can_retry' string='Can retry'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> index=True required=True string='Company'
  • date_from Datetime
    required=True string='From'
  • date_to Datetime
    required=True string='To'
  • direction Selection
    default='received' index=True required=True selection=[('issued', 'Issued'), ('received', 'Received')]
  • document_count Integer
    readonly=True string='Processed documents'
  • document_ids One2many → l10n_mx_sat.document
    comodel_name='l10n_mx_sat.document' inverse_name='download_request_id' readonly=True string='Documents'
  • document_kind Selection
    default='cfdi' index=True required=True selection=[('cfdi', 'CFDI'), ('retention', 'Retention')] string='Document kind'
  • error_message Text
    readonly=True string='Error message'
  • name Char
    compute='_compute_name' store=True string='Description'
  • next_process_at Datetime
    help='Earliest datetime when the cron should verify this request again after the SAT accepted it but has not finished processing.' index=True readonly=True string='Next process at'
  • package_ids One2many → l10n_mx_sat.download.package
    comodel_name='l10n_mx_sat.download.package' inverse_name='request_id' readonly=True string='Packages'
  • reported_cfdi_count Integer
    readonly=True string='SAT reported CFDIs'
  • request_fingerprint Char
    index=True readonly=True string='Request fingerprint'
  • request_type Selection
    default='xml' index=True required=True selection=[('xml', 'XML'), ('metadata', 'Metadata')] string='Request type'
  • sat_request_id Char
    readonly=True string='SAT request ID'
  • state Selection
    default='draft' index=True readonly=True required=True selection=[('draft', 'Draft'), ('requested', 'Requested'), ('processing', 'Processing'), ('ready', 'Ready'), ('downloading', 'Downloading'), ('done', 'Completed'), ('error', 'Error')]
Public methods (3)
  • action_queue(self)
    Enqueue draft requests for background processing.
  • action_retry(self)
    Retry a failed SAT download request from the appropriate step.
  • create(self, vals_list)
    @api.model_create_multi

New fields (4)
  • company_id Many2one → res.company
    comodel_name='res.company' readonly=True required=True string='Company'
  • fiel_cer Binary
    attachment=False string='FIEL certificate (.cer)'
  • fiel_key Binary
    attachment=False string='FIEL private key (.key)'
  • fiel_password Char
    default='' string='FIEL password'
Public methods (1)
  • action_apply(self)
    Store new FIEL credentials on the company.

New fields (18)
  • l10n_mx_sat_auto_download Boolean
    default=True help='Enables daily creation and processing of bulk download requests for this company.' string='Automatic SAT download'
  • l10n_mx_sat_document_count Integer
    compute='_compute_l10n_mx_sat_document_count' string='SAT documents'
  • l10n_mx_sat_download_cfdi_issued Boolean
    default=True string='Download issued CFDIs'
  • l10n_mx_sat_download_cfdi_received Boolean
    default=True string='Download received CFDIs'
  • l10n_mx_sat_download_request_count Integer
    compute='_compute_l10n_mx_sat_download_request_count' string='SAT download requests'
  • l10n_mx_sat_download_retention_issued Boolean
    default=True string='Download issued retentions'
  • l10n_mx_sat_download_retention_received Boolean
    default=True string='Download received retentions'
  • l10n_mx_sat_fiel_cer Binary
    attachment=False groups='base.group_system' string='FIEL certificate (.cer)'
  • l10n_mx_sat_fiel_certificate_configured Boolean
    compute='_compute_l10n_mx_sat_fiel_status' string='FIEL certificate configured'
  • l10n_mx_sat_fiel_configured Boolean
    compute='_compute_l10n_mx_sat_fiel_status' string='FIEL configured'
  • l10n_mx_sat_fiel_key Binary
    attachment=False groups='base.group_system' string='FIEL private key (.key)'
  • l10n_mx_sat_fiel_key_configured Boolean
    compute='_compute_l10n_mx_sat_fiel_status' string='Llave FIEL configured'
  • l10n_mx_sat_fiel_password Char
    groups='base.group_system' string='FIEL password'
  • l10n_mx_sat_fiel_rfc Char
    compute='_compute_l10n_mx_sat_fiel_status' string='RFC FIEL'
  • l10n_mx_sat_last_metadata_sync Datetime
    readonly=True string='Last metadata sync'
  • l10n_mx_sat_last_sync Datetime
    readonly=True string='Last XML sync'
  • l10n_mx_sat_metadata_sync_from Date
    help='Initial date for bulk metadata download (SAT status). If empty, the same date as XML sync is used.' string='Sync metadata from'
  • l10n_mx_sat_sync_from Date
    help='Initial date for the first bulk XML download. After the first successful sync, the system continues incrementally from the last completed range.' string='Sync documents from'
Public methods (12)
  • action_l10n_mx_sat_open_fiel_wizard(self)
    Open wizard to upload new FIEL credentials.
  • action_l10n_mx_sat_view_documents(self)
  • action_l10n_mx_sat_view_download_requests(self)
  • l10n_mx_sat_get_client(self)
    Factory: return a SatClient instance.
  • l10n_mx_sat_get_credentials(self)
    Return decoded FIEL credentials.
  • l10n_mx_sat_get_rfc(self, client=None)
    Return the RFC used for SAT download requests.
  • l10n_mx_sat_get_token(self)
    Authenticate with the SAT and return a token.
  • l10n_mx_sat_get_xml_download_flows(self)
    Return enabled XML download flows for this company.
  • l10n_mx_sat_has_credentials(self)
  • l10n_mx_sat_sync_now(self)
    Manual trigger for SAT download and metadata sync.
  • l10n_mx_sat_test_connection(self)
    Button to test the SAT connection.
  • write(self, vals)
STATUS
STATUSOpen migration PR - not merged yet for this version
REPOSITORY
REPOSITORYOCA/l10n-mexico
PULL REQUEST
PULL REQUEST[19.0][MIG] l10n_mx_sat: Migration to 19.0 (#95)