Portugal - Accounting (Certification)

l10n_pt_certification
REPOSITORY
REPOSITORYOCA/l10n-portugal
GIT
GIThttps://github.com/OCA/l10n-portugal.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/l10n-portugal/tree/18.0/l10n_pt_certification
VERSION
VERSION 1.0.0
CATEGORY
CATEGORYAccounting/Localizations/Account Charts
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLEYes
AUTHORS
AUTHORSOdoo
MAINTAINERS
MAINTAINERSOdoo
COMMITTERS
COMMITTERSDaniel Reis, OCA-git-bot, oca-ci
WEBSITE
WEBSITEhttps://github.com/OCA/l10n-portugal
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:09:30
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/l10n-portugal:
    - l10n_pt_future_account
odoo/odoo:
    - l10n_pt
    - base
    - account
    - base_setup
    - web
    - onboarding
    - product
    - mail
    - bus
    - web_tour
    - html_editor
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - base_vat
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This bridge module adds the technical requirements of the Portuguese Certification regulation (Administrative Decree no. 363/2010) that stipulates certain criteria concerning the inalterability and authenticity of invoicing data.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

The module adds the following features:

- AT Series: allows the creation of document series, under which documents must be emitted.
- Digital signature: documents are signed after they are emitted. After being signed, key data cannot be modified.
- QR Code: a QR Code is added to signed documents
- Hash integrity report is available based on the digital signature
    

Code Analysis

Views touched (35)
XML IDNameModelTypeStatus
l10n_pt_external_layout_bold l10n_pt_external_layout_bold ir.ui.view qweb Inherits web.external_layout_bold
l10n_pt_external_layout_boxed l10n_pt_external_layout_boxed ir.ui.view qweb Inherits web.external_layout_boxed
l10n_pt_external_layout_bubble l10n_pt_external_layout_bubble ir.ui.view qweb Inherits web.external_layout_bubble
l10n_pt_external_layout_folder l10n_pt_external_layout_folder ir.ui.view qweb Inherits web.external_layout_folder
l10n_pt_external_layout_standard l10n_pt_external_layout_standard ir.ui.view qweb Inherits web.external_layout_standard
l10n_pt_external_layout_striped l10n_pt_external_layout_striped ir.ui.view qweb Inherits web.external_layout_striped
l10n_pt_external_layout_wave l10n_pt_external_layout_wave ir.ui.view qweb Inherits web.external_layout_wave
l10n_pt_partner_vat l10n_pt_partner_vat ir.ui.view qweb New
l10n_pt_report_payment_receipt_document_inherit l10n_pt_report_payment_receipt_document_inherit ir.ui.view qweb Inherits account.report_payment_receipt_document
l10n_pt_report_template_address_training_mode l10n_pt_report_template_address_training_mode ir.ui.view qweb New
l10n_pt_report_template_footer l10n_pt_report_template_footer ir.ui.view qweb New
l10n_pt_report_template_footer_document_type_and_number_block l10n_pt_report_template_footer_document_type_and_number_block ir.ui.view qweb New
l10n_pt_report_template_footer_document_type_and_number_oneline l10n_pt_report_template_footer_document_type_and_number_oneline ir.ui.view qweb New
l10n_pt_report_template_note_certified_program l10n_pt_report_template_note_certified_program ir.ui.view qweb New
l10n_pt_report_template_note_document_purpose l10n_pt_report_template_note_document_purpose ir.ui.view qweb New
l10n_pt_report_template_print_version_and_cancellation l10n_pt_report_template_print_version_and_cancellation ir.ui.view qweb New
pt_cancel_wizard_view Invoice Cancel l10n_pt.cancel form New
report_hash_integrity_content report_hash_integrity_content ir.ui.view qweb New
report_invoice report_invoice ir.ui.view qweb Inherits account.report_invoice
report_invoice_document report_invoice_document ir.ui.view qweb Inherits account.report_invoice_document
res_config_settings_view_form_inherit_pt res.config.settings.view.form.inherit.pt res.config.settings xpath Inherits account.res_config_settings_view_form
view_account_journal_form_inherit_pt account.journal.form.inherit.pt account.journal xpath Inherits account.view_account_journal_form
view_account_move_reversal_inherit_pt account.move.reversal.form.inherit.pt account.move.reversal xpath Inherits account.view_account_move_reversal
view_account_payment_form_inherit_pt account.payment.form.inherit.pt account.payment xpath Inherits account.view_account_payment_form
view_account_payment_register_form_inherit_pt account.payment.register.view.form.inherit.pt account.payment.register xpath Inherits account.view_account_payment_register_form
view_account_payment_tree_inherit_pt account.payment.tree.inherit.pt account.payment xpath Inherits account.view_account_payment_tree
view_l10n_pt_at_series_form at.series.form l10n_pt.at.series form New
view_l10n_pt_at_series_search at.series.search.view l10n_pt.at.series search New
view_l10n_pt_at_series_tree at.series.tree l10n_pt.at.series list New
view_l10n_pt_reprint_reason l10n_pt.reprint.reason.form l10n_pt.reprint.reason form New
view_move_form_inherit_pt account.move.form.inherit.pt account.move xpath Inherits account.view_move_form
view_out_invoice_tree_inherit_pt account.move.tree.inherit.pt account.move xpath Inherits account.view_out_invoice_tree
view_tax_form_inherit_pt account.tax.form.inherit.pt account.tax xpath Inherits account.view_tax_form
view_tax_group_form_inherit_pt account.tax.group.form.inherit.pt account.tax.group xpath Inherits account.view_tax_group_form
view_tax_group_tree_inherit_pt account.tax.group.tree.inherit.pt account.tax.group xpath Inherits account.view_tax_group_tree
Models touched (22)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (13)
  • l10n_pt_at_series_id Many2one → l10n_pt.at.series
    comodel_name='l10n_pt.at.series' compute='_compute_l10n_pt_at_series_id' readonly=False store=True string='AT Series'
  • l10n_pt_at_series_line_id Many2one → l10n_pt.at.series.line
    comodel_name='l10n_pt.at.series.line' compute='_compute_l10n_pt_at_series_line_id' string='Document-specific AT Series'
  • l10n_pt_atcud Char
    compute='_compute_l10n_pt_atcud' help='Unique document code formed by the AT series validation code and the number of the document. Only assigned once the document is secured.' store=True string='Portuguese ATCUD'
  • l10n_pt_cancel_reason Char
    copy=False help='Reason given by the user for cancelling this move' readonly=True string='Reason for Cancellation'
  • l10n_pt_document_number Char
    compute='_compute_l10n_pt_document_number' help='Internal identifier for Portuguese documents, made up of the document type code,the series name, and the number of the document within the series.' store=True string='Unique Document Number'
  • l10n_pt_document_type Selection
    compute='_compute_l10n_pt_document_type' selection=AT_SERIES_ACCOUNTING_DOCUMENT_TYPES store=True string='Portuguese Document Type'
  • l10n_pt_global_discount Float
    digits='Discount' inverse='_inverse_l10n_pt_global_discount' string='Global Discount %'
  • l10n_pt_hashed_on Datetime
    readonly=True string='Hashed On'
  • l10n_pt_inalterable_hash_short Char
    compute='_compute_l10n_pt_inalterable_hash' string='Short version of the Portuguese hash'
  • l10n_pt_inalterable_hash_version Integer
    compute='_compute_l10n_pt_inalterable_hash' string='Portuguese hash version'
  • l10n_pt_print_version Selection
    copy=False selection=[('original', 'Original print'), ('reprint', 'Reprint')] string='Version of Printed Document'
  • l10n_pt_qr_code_str Char
    compute='_compute_l10n_pt_qr_code_str' store=True args: 'Portuguese QR Code'
  • l10n_pt_show_future_date_warning Boolean
    compute='_compute_l10n_pt_show_future_date_warning'
Public methods (8)
  • action_open_reprint_wizard(self, action_to_return=None)
  • action_post(self)
  • action_print_pdf(self)
    PT requirement: documents being reprinted require a reprint reason
  • action_reverse(self)
    Portuguese certification requirements: "The program must not allow the creation of credit notes regarding previously cancelled documents or already fully rectified."
  • l10n_pt_verify_prerequisites_qr_code(self)
  • preview_invoice(self)
    PT requirement: "No document in a preparatory or preview state may be printed prior to its completion and signing".
  • update_l10n_pt_print_version(self)
  • write(self, vals)

New fields (1)
  • l10n_pt_line_discount Float
    default=0.0 digits='Discount' inverse='_inverse_l10n_pt_line_discount' string='Line Discount'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • reverse_moves(self, is_modify=False)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • action_open_reprint_wizard(self)
  • action_send_and_print(self, allow_fallback_pdf=False)

New fields (8)
  • l10n_pt_at_series_id Many2one → l10n_pt.at.series
    comodel_name='l10n_pt.at.series' compute='_compute_l10n_pt_at_series_id' readonly=False store=True string='AT Series'
  • l10n_pt_at_series_line_id Many2one → l10n_pt.at.series.line
    comodel_name='l10n_pt.at.series.line' compute='_compute_l10n_pt_at_series_line_id' string='Document-specific AT Series'
  • l10n_pt_atcud Char
    compute='_compute_l10n_pt_atcud' help='Unique document code formed by the AT series validation code and the number of the document.' store=True string='Portuguese ATCUD'
  • l10n_pt_cancel_reason Char
    copy=False help='Reason given by the user for cancelling this payment' readonly=True string='Reason for Cancellation'
  • l10n_pt_document_number Char
    compute='_compute_l10n_pt_document_number' help='Unique identifier for Portuguese documents, made up of the internal document type code, the series name, and the number of the document within the series.' store=True string='Unique Document Number'
  • l10n_pt_document_type Selection
    compute='_compute_l10n_pt_document_type' selection=AT_SERIES_ACCOUNTING_DOCUMENT_TYPES store=True string='Portuguese Document Type'
  • l10n_pt_print_version Selection
    copy=False selection=[('original', 'Original print'), ('reprint', 'Reprint')] string='Version of Printed Document'
  • l10n_pt_show_future_date_warning Boolean
    compute='_compute_l10n_pt_show_future_date_warning'
Public methods (5)
  • action_open_reprint_wizard(self)
    PT requirement: documents being reprinted require a reprint reason
  • action_post(self)
  • is_pt_inbound(self)
  • update_l10n_pt_print_version(self)
  • write(self, vals)

New fields (1)
  • l10n_pt_payment_mechanism Selection
    default='TB' help="This payment method's mechanism according to Portuguese requirements." selection=L10N_PT_PAYMENT_MECHANISMS string='Payment Mechanism'
Public methods (0)

No public methods.

New fields (2)
  • available_l10n_pt_at_series_ids Many2many → l10n_pt.at.series
    compute='_compute_available_l10n_pt_at_series_ids' args: 'l10n_pt.at.series'
  • l10n_pt_at_series_id Many2one → l10n_pt.at.series
    comodel_name='l10n_pt.at.series' compute='_compute_l10n_pt_at_series_id' domain="[('payment_journal_id', '=', available_l10n_pt_at_series_ids)]" readonly=False store=True string='AT Series'
Public methods (0)

No public methods.

New fields (1)
  • l10n_pt_tax_exemption_reason Selection
    selection=L10N_PT_TAX_EXEMPTION_REASONS_SELECTION string='Tax Exemption Reason'
Public methods (0)

No public methods.

New fields (2)
  • l10n_pt_tax_category Selection
    default='N' selection=L10N_PT_TAX_CATEGORIES_SELECTION string='Tax Category (PT)'
  • l10n_pt_tax_region Selection
    default='PT' selection=L10N_PT_TAX_REGIONS_SELECTION string='Region (PT)'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (7)
  • cancelled Boolean
    string='Canceled'
  • company_id Many2one → res.company
    readonly=True args: 'res.company', 'Company'
  • original Boolean
    string='Original Print'
  • report_binary Binary
    required=True string='File Binary'
  • report_name Char
    required=True string='Report'
  • res_id Many2oneReference
    model_field='res_model' required=True string='Record id'
  • res_model Char
    required=True string='Model'
Public methods (0)

No public methods.

New fields (9)
  • active Boolean
    compute='_compute_active' search='_search_active'
  • at_series_line_ids One2many → l10n_pt.at.series.line
    copy=True string='Document Types' args: 'l10n_pt.at.series.line', 'at_series_id'
  • company_exclusive_series Boolean
    help='If checked, this series will only be used by one company and not shared across branches' string='Exclusive Series'
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • date_end Date
    args: 'End Date'
  • name Char
    help='The name of the series will be part of the document number sequence.' required=True args: 'Name of the Series'
  • payment_journal_id Many2one → account.journal
    check_company=True domain="[('type', 'in', ('bank', 'credit', 'cash'))]" help='This series will be available for payments belonging to this, and only this, journal.' string='Payment Journal' args: 'account.journal'
  • sale_journal_id Many2one → account.journal
    check_company=True domain="[('type', '=', 'sale')]" help='This series will be available for account moves belonging to this, and only this, journal.' string='Sales Journal' args: 'account.journal'
  • training_series Boolean
    args: 'Training Series'
Public methods (1)
  • write(self, vals)

New fields (9)
  • at_code Char
    required=True args: 'AT Validation Code'
  • at_series_active Boolean
    related='at_series_id.active'
  • at_series_id Many2one → l10n_pt.at.series
    check_company=True ondelete='cascade' readonly=True required=True string='AT Series' args: 'l10n_pt.at.series'
  • company_exclusive_series Boolean
    related='at_series_id.company_exclusive_series'
  • company_id Many2one
    index=True precompute=True readonly=True related='at_series_id.company_id' store=True
  • document_identifier Char
    compute='_compute_document_identifier' help="The unique identification of documents of this series and type made up of the document type prefix and the series name, followed by '/' and the number of the document." args: 'Document Identifier'
  • prefix Char
    help='The internal code of the document type that will be combined with the Series Name to form the unique identification of documents.' required=True string='Document-specific Series Prefix'
  • type Selection
    help='Customer Invoices require an Invoice (FT) series, and Sales Receipts require a Simplified Invoice (FS) series.' required=True selection=AT_SERIES_ACCOUNTING_DOCUMENT_TYPES string='Document Type'
  • type_name Char
    compute='_compute_type_name' args: 'Type Name'
Public methods (1)
  • write(self, vals)

New fields (1)
  • l10n_pt_cancel_reason Char
    help='Reason to cancel this document.' required=True string='Cancel Reason'
Public methods (1)
  • button_cancel(self)

New fields (1)
  • reason Char
    required=True string='Reason for reprinting the document'
Public methods (1)
  • action_log_and_print(self)

New fields (0)

No new fields.

Public methods (1)
  • create(self, values)
    @api.model_create_multi

New fields (0)

No new fields.

Public methods (2)
  • create(self, values)
    @api.model_create_multi
  • write(self, values)

New fields (1)
  • l10n_pt_region_code Char
    compute='_compute_l10n_pt_region_code' readonly=False store=True args: 'Region Code'
Public methods (1)
  • onchange_country(self)
    @api.onchange('country_id')
    Portuguese companies use round_globally as tax_calculation_rounding_method to ensure rounding conforms with the requirements from Autoridade Tributaria

New fields (0)

No new fields.

Public methods (1)
  • write(self, values)