diff --git a/addons/l10n_latam_invoice_document/__init__.py b/addons/l10n_latam_invoice_document/__init__.py
new file mode 100644
index 00000000000..c1a9ff194cf
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/__init__.py
@@ -0,0 +1,4 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from . import models
+from . import wizards
+from . import report
diff --git a/addons/l10n_latam_invoice_document/__manifest__.py b/addons/l10n_latam_invoice_document/__manifest__.py
new file mode 100644
index 00000000000..146e2ba83e4
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/__manifest__.py
@@ -0,0 +1,33 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+{
+ "name": "LATAM Document",
+ "version": "13.0.1.0.0",
+ "author": "ADHOC SA",
+ "category": "Localization",
+ 'description': """
+LATAM Document
+==============
+
+This module is intended to be extended by localizations (like Argentina and
+Chile) in order to manage the document types that need to be reported to the
+government required by this countries.
+
+In order to do that we add a new model named Document Topes and we create
+links between this new model and another Odoo's models.
+""",
+ "depends": [
+ "account",
+ ],
+ "data": [
+ 'views/account_journal_view.xml',
+ 'views/account_move_line_view.xml',
+ 'views/account_move_view.xml',
+ 'views/l10n_latam_document_type_view.xml',
+ 'views/report_invoice.xml',
+ 'views/ir_sequence_view.xml',
+ 'report/invoice_report_view.xml',
+ 'wizards/account_move_reversal_view.xml',
+ 'security/ir.model.access.csv',
+ ],
+ 'installable': True,
+}
diff --git a/addons/l10n_latam_invoice_document/i18n/es.po b/addons/l10n_latam_invoice_document/i18n/es.po
new file mode 100644
index 00000000000..8174d2b4161
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/i18n/es.po
@@ -0,0 +1,389 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * l10n_latam_document
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 13.0alpha1+e\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-08-02 20:49+0000\n"
+"PO-Revision-Date: 2019-08-02 20:49+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_account_chart_template
+msgid "Account Chart Template"
+msgstr "Plantilla de Plan de Cuentas"
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_account_move_reversal
+msgid "Account Move Reversal"
+msgstr "Revocación de movimiento en cuenta"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__active
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Active"
+msgstr "Activo"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__internal_type
+msgid ""
+"Analog to odoo account.move.type but with more options allowing to identify "
+"the kind of document we are working with. (not only related to account.move,"
+" could be for documents of other models like stock.picking)"
+msgstr ""
+"Análogo a al campo Tipo en la factura pero con mas opciones permitiendo "
+"indentificar el tipo de documento con el que estamos trabajando (no solo "
+"relacionado a la factura, puede ser para documentos de otros modelos como "
+"los movimientos de inventario)."
+
+#. module: l10n_latam_document
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Archived"
+msgstr "Archivado"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__code
+msgid "Code"
+msgstr "Código"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__code
+msgid "Code used by different localizations"
+msgstr "Código usando por diferentes localizaciones"
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_res_company
+msgid "Companies"
+msgstr "Compañías"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__country_id
+msgid "Country"
+msgstr "País"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_journal__l10n_latam_country_code
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_country_code
+msgid "Country Code"
+msgstr "Código País"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__country_id
+msgid "Country in which this type of document is valid"
+msgstr "País donde el tipo de documento es valido"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__create_uid
+msgid "Created by"
+msgstr "Creado por"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__create_date
+msgid "Created on"
+msgstr "Creado el"
+
+#. module: l10n_latam_document
+#: selection:l10n_latam.document.type,internal_type:0
+msgid "Credit Notes"
+msgstr "Notas de Crédito"
+
+#. module: l10n_latam_document
+#: selection:l10n_latam.document.type,internal_type:0
+msgid "Debit Notes"
+msgstr "Notas de Débito"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__display_name
+msgid "Display Name"
+msgstr "Nombre a mostrar"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__doc_code_prefix
+msgid "Document Code Prefix"
+msgstr "Prefijo del código de documento"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_document_number
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_reversal__l10n_latam_document_number
+msgid "Document Number"
+msgstr "Número de Documento"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_invoice_report__l10n_latam_document_type_id
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_document_type_id
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_line__l10n_latam_document_type_id
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_reversal__l10n_latam_document_type_id
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_ir_sequence__l10n_latam_document_type_id
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_account_invoice_filter
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_account_invoice_report_search
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_account_move_filter
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_account_move_line_filter
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_form
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_tree
+msgid "Document Type"
+msgstr "Tipo de Documento"
+
+#. module: l10n_latam_document
+#: model:ir.actions.act_window,name:l10n_latam_invoice_document.action_document_type
+#: model:ir.ui.menu,name:l10n_latam_invoice_document.menu_document_type
+msgid "Document Types"
+msgstr "Tipos de Documentos"
+
+#. module: l10n_latam_document
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Group By..."
+msgstr "Agrupar por..."
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__id
+msgid "ID"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_account_journal__l10n_latam_use_documents
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_account_move__l10n_latam_use_documents
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_account_move_reversal__l10n_latam_use_documents
+msgid ""
+"If active: will be using for legal invoicing (invoices, debit/credit notes)."
+" If not set means that will be used to register accounting entries not "
+"related to invoicing legal documents. For Example: Receipts, Tax Payments, "
+"Register journal entries"
+msgstr ""
+"Si esta activo: será utilizado para facturación (facturas, notas de débito y"
+" crédito). SI esta desactivado significa que que será usado para registrar "
+"movimientos contables que no están relacionas con facturación como tal. Por "
+"ejemplo: Recibos, Pagos de Impuestos, Registrar asientos contables"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__internal_type
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Internal Type"
+msgstr "Tipo interno"
+
+#. module: l10n_latam_document
+#: selection:l10n_latam.document.type,internal_type:0
+msgid "Invoices"
+msgstr "Facturas"
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_account_invoice_report
+msgid "Invoices Statistics"
+msgstr "Estadísticas de facturas"
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_account_journal
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_ir_sequence__l10n_latam_journal_id
+msgid "Journal"
+msgstr "Diario"
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_account_move
+msgid "Journal Entries"
+msgstr "Asientos contables"
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_account_move_line
+msgid "Journal Item"
+msgstr "Apunte contable"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_amount_tax
+msgid "L10N Latam Amount Tax"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_amount_untaxed
+msgid "L10N Latam Amount Untaxed"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_available_document_type_ids
+msgid "L10N Latam Available Document Type"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_journal__l10n_latam_company_use_documents
+msgid "L10N Latam Company Use Documents"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_line__l10n_latam_price_net
+msgid "L10N Latam Price Net"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_line__l10n_latam_price_subtotal
+msgid "L10N Latam Price Subtotal"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_line__l10n_latam_price_unit
+msgid "L10N Latam Price Unit"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_sequence_id
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_reversal__l10n_latam_sequence_id
+msgid "L10N Latam Sequence"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_tax_ids
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_line__l10n_latam_tax_ids
+msgid "L10N Latam Tax"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type____last_update
+msgid "Last Modified on"
+msgstr "Última modificación en"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__write_uid
+msgid "Last Updated by"
+msgstr "Última actualización por"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__write_date
+msgid "Last Updated on"
+msgstr "Última actualización el"
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_l10n_latam_document_type
+msgid "Latam Document Type"
+msgstr "Tipo de Documento Latam"
+
+#. module: l10n_latam_document
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Localization"
+msgstr "Localización"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__name
+msgid "Name"
+msgstr "Nombre"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__report_name
+msgid "Name on Reports"
+msgstr "Nombre en Reportes"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__report_name
+msgid "Name that will be printed in reports, for example \"CREDIT NOTE\""
+msgstr "Nombre que será impreso en los reportes, por ejemplo \"NOTA DE CREDITO\""
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_move.py:87
+#, python-format
+msgid "No sequence or document number linked to invoice id %s"
+msgstr "No hay secuencia o número de documento vinculado a la factura %s"
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_move.py:102
+#, python-format
+msgid "Please set the document number on the following invoices %s."
+msgstr ""
+"Por favor asigne el número de documento en las siguientes facturas %s."
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__doc_code_prefix
+msgid ""
+"Prefix for Documents Codes on Invoices and Account Moves. For eg. 'FA ' will"
+" build 'FA 0001-0000001' Document Number"
+msgstr ""
+"Prefijo para Códigos de Documentos en Facturas y Asientos. Por eje: 'FA ' "
+"será construirá 'FA 0001-0000001' como el numero de documento"
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_ir_sequence
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__sequence
+msgid "Sequence"
+msgstr "Secuencia"
+
+#. module: l10n_latam_document
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Show active document types"
+msgstr "Mostrar tipos de documento activos"
+
+#. module: l10n_latam_document
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Show archived document types"
+msgstr "Mostrar tipos de documento archivados"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_account_journal__l10n_latam_country_code
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_account_move__l10n_latam_country_code
+msgid "Technical field used to hide/show fields regarding the localization"
+msgstr ""
+"Campo técnico usado para esconder/mostrar dependiendo de la liocalización"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__name
+msgid "The document name"
+msgstr "El nombre del documento"
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_move.py:97
+#, python-format
+msgid ""
+"The journal require a document type but not document type has been selected "
+"on invoices %s."
+msgstr ""
+"El diario requiere un tipo de documento pero no hay tipo de documento "
+"seleccionado en las facturas %s."
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__sequence
+msgid ""
+"To set in which order show the documents type taking into account the most "
+"commonly used first"
+msgstr ""
+"Para seleccionar en que orden deben mostrar los tipos de documento teniendo "
+"en cuenta los más usados comunmente"
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_journal__l10n_latam_use_documents
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_use_documents
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_reversal__l10n_latam_use_documents
+msgid "Use Documents?"
+msgstr "Usa Documentos?"
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_move.py:182
+#, python-format
+msgid "Vendor bill number must be unique per vendor and company."
+msgstr ""
+"El número de la Factura de Proveedor debe ser único por proveedor y por "
+"compañía."
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_journal.py:32
+#, python-format
+msgid ""
+"You can not modify the field \"Use Documents?\" if there are validated "
+"invoices in this journal!"
+msgstr ""
+"No puedes modificar el campo \"Usa Documentos?\" si ya existen facturas "
+"validades en este diario!"
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_move.py:113
+#, python-format
+msgid "You can not use a %s document type with a invoice"
+msgstr "No puedes utilizar el tipo de documento %s en una factura"
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_move.py:111
+#, python-format
+msgid "You can not use a %s document type with a refund invoice"
+msgstr ""
+"No puedes utilizar el tipo de documento %s en una factura de reembolso"
diff --git a/addons/l10n_latam_invoice_document/i18n/l10n_latam_invoice_document.pot b/addons/l10n_latam_invoice_document/i18n/l10n_latam_invoice_document.pot
new file mode 100644
index 00000000000..7b4fa12663e
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/i18n/l10n_latam_invoice_document.pot
@@ -0,0 +1,368 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * l10n_latam_document
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 13.0alpha1+e\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-08-02 20:54+0000\n"
+"PO-Revision-Date: 2019-08-02 20:54+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_account_chart_template
+msgid "Account Chart Template"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_account_move_reversal
+msgid "Account Move Reversal"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__active
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Active"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__internal_type
+msgid ""
+"Analog to odoo account.move.type but with more options allowing to identify "
+"the kind of document we are working with. (not only related to account.move,"
+" could be for documents of other models like stock.picking)"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Archived"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__code
+msgid "Code"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__code
+msgid "Code used by different localizations"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_res_company
+msgid "Companies"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__country_id
+msgid "Country"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_journal__l10n_latam_country_code
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_country_code
+msgid "Country Code"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__country_id
+msgid "Country in which this type of document is valid"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__create_uid
+msgid "Created by"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__create_date
+msgid "Created on"
+msgstr ""
+
+#. module: l10n_latam_document
+#: selection:l10n_latam.document.type,internal_type:0
+msgid "Credit Notes"
+msgstr ""
+
+#. module: l10n_latam_document
+#: selection:l10n_latam.document.type,internal_type:0
+msgid "Debit Notes"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__doc_code_prefix
+msgid "Document Code Prefix"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_document_number
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_reversal__l10n_latam_document_number
+msgid "Document Number"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_invoice_report__l10n_latam_document_type_id
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_document_type_id
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_line__l10n_latam_document_type_id
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_reversal__l10n_latam_document_type_id
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_ir_sequence__l10n_latam_document_type_id
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_account_invoice_filter
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_account_invoice_report_search
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_account_move_filter
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_account_move_line_filter
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_form
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_tree
+msgid "Document Type"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.actions.act_window,name:l10n_latam_invoice_document.action_document_type
+#: model:ir.ui.menu,name:l10n_latam_invoice_document.menu_document_type
+msgid "Document Types"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Group By..."
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__id
+msgid "ID"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_account_journal__l10n_latam_use_documents
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_account_move__l10n_latam_use_documents
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_account_move_reversal__l10n_latam_use_documents
+msgid ""
+"If active: will be using for legal invoicing (invoices, debit/credit notes)."
+" If not set means that will be used to register accounting entries not "
+"related to invoicing legal documents. For Example: Receipts, Tax Payments, "
+"Register journal entries"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__internal_type
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Internal Type"
+msgstr ""
+
+#. module: l10n_latam_document
+#: selection:l10n_latam.document.type,internal_type:0
+msgid "Invoices"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_account_invoice_report
+msgid "Invoices Statistics"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_account_journal
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_ir_sequence__l10n_latam_journal_id
+msgid "Journal"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_account_move
+msgid "Journal Entries"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_account_move_line
+msgid "Journal Item"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_amount_tax
+msgid "L10N Latam Amount Tax"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_amount_untaxed
+msgid "L10N Latam Amount Untaxed"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_available_document_type_ids
+msgid "L10N Latam Available Document Type"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_journal__l10n_latam_company_use_documents
+msgid "L10N Latam Company Use Documents"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_line__l10n_latam_price_net
+msgid "L10N Latam Price Net"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_line__l10n_latam_price_subtotal
+msgid "L10N Latam Price Subtotal"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_line__l10n_latam_price_unit
+msgid "L10N Latam Price Unit"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_sequence_id
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_reversal__l10n_latam_sequence_id
+msgid "L10N Latam Sequence"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_tax_ids
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_line__l10n_latam_tax_ids
+msgid "L10N Latam Tax"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type____last_update
+msgid "Last Modified on"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__write_uid
+msgid "Last Updated by"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__write_date
+msgid "Last Updated on"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_l10n_latam_document_type
+msgid "Latam Document Type"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Localization"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__name
+msgid "Name"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__report_name
+msgid "Name on Reports"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__report_name
+msgid "Name that will be printed in reports, for example \"CREDIT NOTE\""
+msgstr ""
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_move.py:87
+#, python-format
+msgid "No sequence or document number linked to invoice id %s"
+msgstr ""
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_move.py:102
+#, python-format
+msgid "Please set the document number on the following invoices %s."
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__doc_code_prefix
+msgid ""
+"Prefix for Documents Codes on Invoices and Account Moves. For eg. 'FA ' will"
+" build 'FA 0001-0000001' Document Number"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model,name:l10n_latam_invoice_document.model_ir_sequence
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_l10n_latam_document_type__sequence
+msgid "Sequence"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Show active document types"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model_terms:ir.ui.view,arch_db:l10n_latam_invoice_document.view_document_type_filter
+msgid "Show archived document types"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_account_journal__l10n_latam_country_code
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_account_move__l10n_latam_country_code
+msgid "Technical field used to hide/show fields regarding the localization"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__name
+msgid "The document name"
+msgstr ""
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_move.py:97
+#, python-format
+msgid ""
+"The journal require a document type but not document type has been selected "
+"on invoices %s."
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,help:l10n_latam_invoice_document.field_l10n_latam_document_type__sequence
+msgid ""
+"To set in which order show the documents type taking into account the most "
+"commonly used first"
+msgstr ""
+
+#. module: l10n_latam_document
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_journal__l10n_latam_use_documents
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move__l10n_latam_use_documents
+#: model:ir.model.fields,field_description:l10n_latam_invoice_document.field_account_move_reversal__l10n_latam_use_documents
+msgid "Use Documents?"
+msgstr ""
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_move.py:182
+#, python-format
+msgid "Vendor bill number must be unique per vendor and company."
+msgstr ""
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_journal.py:32
+#, python-format
+msgid ""
+"You can not modify the field \"Use Documents?\" if there are validated "
+"invoices in this journal!"
+msgstr ""
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_move.py:113
+#, python-format
+msgid "You can not use a %s document type with a invoice"
+msgstr ""
+
+#. module: l10n_latam_document
+#: code:addons/l10n_latam_document/models/account_move.py:111
+#, python-format
+msgid "You can not use a %s document type with a refund invoice"
+msgstr ""
diff --git a/addons/l10n_latam_invoice_document/models/__init__.py b/addons/l10n_latam_invoice_document/models/__init__.py
new file mode 100644
index 00000000000..cb7b480fed7
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/models/__init__.py
@@ -0,0 +1,9 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import res_company
+from . import l10n_latam_document_type
+from . import account_journal
+from . import account_move
+from . import account_move_line
+from . import account_chart_template
+from . import ir_sequence
diff --git a/addons/l10n_latam_invoice_document/models/account_chart_template.py b/addons/l10n_latam_invoice_document/models/account_chart_template.py
new file mode 100644
index 00000000000..a181655d4c1
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/models/account_chart_template.py
@@ -0,0 +1,19 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo import models, api, fields, _
+
+
+class AccountChartTemplate(models.Model):
+
+ _inherit = 'account.chart.template'
+
+ @api.model
+ def _prepare_all_journals(self, acc_template_ref, company, journals_dict=None):
+ """ We add use_documents or not depending on the context"""
+ journal_data = super()._prepare_all_journals(acc_template_ref, company, journals_dict)
+
+ # if chart has localization, then we use documents by default
+ if company._localization_use_documents():
+ for vals_journal in journal_data:
+ if vals_journal['type'] in ['sale', 'purchase']:
+ vals_journal['l10n_latam_use_documents'] = True
+ return journal_data
diff --git a/addons/l10n_latam_invoice_document/models/account_journal.py b/addons/l10n_latam_invoice_document/models/account_journal.py
new file mode 100644
index 00000000000..230aa8abd51
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/models/account_journal.py
@@ -0,0 +1,39 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models, api, _
+from odoo.exceptions import ValidationError
+
+class AccountJournal(models.Model):
+
+ _inherit = "account.journal"
+
+ l10n_latam_use_documents = fields.Boolean(
+ 'Use Documents?', help="If active: will be using for legal invoicing (invoices, debit/credit notes)."
+ " If not set means that will be used to register accounting entries not related to invoicing legal documents."
+ " For Example: Receipts, Tax Payments, Register journal entries")
+ l10n_latam_company_use_documents = fields.Boolean(compute='_compute_l10n_latam_company_use_documents')
+ l10n_latam_country_code = fields.Char(
+ related='company_id.country_id.code', help='Technical field used to hide/show fields regarding the localization')
+
+ @api.depends('company_id')
+ def _compute_l10n_latam_company_use_documents(self):
+ for rec in self:
+ rec.l10n_latam_company_use_documents = rec.company_id._localization_use_documents()
+
+ @api.onchange('company_id', 'type')
+ def _onchange_company(self):
+ self.l10n_latam_use_documents = self.type in ['sale', 'purchase'] and \
+ self.l10n_latam_company_use_documents
+
+ @api.constrains('l10n_latam_use_documents')
+ def check_use_document(self):
+ for rec in self:
+ if rec.env['account.move'].search([('journal_id', '=', rec.id), ('state', '!=', 'draft')]):
+ raise ValidationError(_(
+ 'You can not modify the field "Use Documents?" if there are validated invoices in this journal!'))
+
+ @api.model
+ def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None):
+ if self._context.get('default_type') in ('out_receipt', 'in_receipt'):
+ args += [('l10n_latam_use_documents', '=', False)]
+ return super()._search(args, offset, limit, order, count=count, access_rights_uid=access_rights_uid)
diff --git a/addons/l10n_latam_invoice_document/models/account_move.py b/addons/l10n_latam_invoice_document/models/account_move.py
new file mode 100644
index 00000000000..a9f160c53dd
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/models/account_move.py
@@ -0,0 +1,212 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import models, fields, api, _
+from odoo.exceptions import UserError, ValidationError
+from functools import partial
+from odoo.tools.misc import formatLang
+
+
+class AccountMove(models.Model):
+
+ _inherit = "account.move"
+
+ l10n_latam_amount_tax = fields.Monetary(compute='_compute_l10n_latam_amount_and_taxes')
+ l10n_latam_amount_untaxed = fields.Monetary(compute='_compute_l10n_latam_amount_and_taxes')
+ l10n_latam_tax_ids = fields.One2many(compute="_compute_l10n_latam_amount_and_taxes", comodel_name='account.move.line')
+ l10n_latam_available_document_type_ids = fields.Many2many('l10n_latam.document.type', compute='_compute_l10n_latam_documents')
+ l10n_latam_document_type_id = fields.Many2one(
+ 'l10n_latam.document.type', string='Document Type', copy=False, readonly=True, auto_join=True, index=True,
+ states={'posted': [('readonly', True)]})
+ l10n_latam_sequence_id = fields.Many2one('ir.sequence', compute='_compute_l10n_latam_sequence')
+ l10n_latam_document_number = fields.Char(
+ compute='_compute_l10n_latam_document_number', inverse='_inverse_l10n_latam_document_number',
+ string='Document Number', readonly=True, states={'draft': [('readonly', False)]})
+ l10n_latam_use_documents = fields.Boolean(related='journal_id.l10n_latam_use_documents')
+ l10n_latam_country_code = fields.Char(
+ related='company_id.country_id.code', help='Technical field used to hide/show fields regarding the localization')
+
+ def _get_sequence_prefix(self):
+ """ If we use documents we update sequences only from journal """
+ return super(AccountMove, self.filtered(lambda x: not x.l10n_latam_use_documents))._get_sequence_prefix()
+
+ @api.depends('name')
+ def _compute_l10n_latam_document_number(self):
+ recs_with_name = self.filtered(lambda x: x.name != '/')
+ for rec in recs_with_name:
+ name = rec.name
+ doc_code_prefix = rec.l10n_latam_document_type_id.doc_code_prefix
+ if doc_code_prefix and name:
+ name = name.split(" ", 1)[-1]
+ rec.l10n_latam_document_number = name
+ remaining = self - recs_with_name
+ remaining.l10n_latam_document_number = False
+
+ @api.onchange('l10n_latam_document_type_id', 'l10n_latam_document_number')
+ def _inverse_l10n_latam_document_number(self):
+ for rec in self.filtered('l10n_latam_document_type_id'):
+ if not rec.l10n_latam_document_number:
+ rec.name = '/'
+ else:
+ l10n_latam_document_number = rec.l10n_latam_document_type_id._format_document_number(rec.l10n_latam_document_number)
+ if rec.l10n_latam_document_number != l10n_latam_document_number:
+ rec.l10n_latam_document_number = l10n_latam_document_number
+ rec.name = "%s %s" % (rec.l10n_latam_document_type_id.doc_code_prefix, l10n_latam_document_number)
+
+ @api.depends('l10n_latam_document_type_id', 'journal_id')
+ def _compute_l10n_latam_sequence(self):
+ recs_with_journal_id = self.filtered('journal_id')
+ for rec in recs_with_journal_id:
+ rec.l10n_latam_sequence_id = rec._get_document_type_sequence()
+ remaining = self - recs_with_journal_id
+ remaining.l10n_latam_sequence_id = False
+
+ def _compute_l10n_latam_amount_and_taxes(self):
+ recs_invoice = self.filtered(lambda x: x.is_invoice(include_receipts=True))
+ for invoice in recs_invoice:
+ tax_lines = invoice.line_ids.filtered('tax_line_id')
+ included_taxes = invoice.l10n_latam_document_type_id and \
+ invoice.l10n_latam_document_type_id._filter_taxes_included(tax_lines.mapped('tax_line_id'))
+ if not included_taxes:
+ l10n_latam_amount_tax = invoice.amount_tax
+ l10n_latam_amount_untaxed = invoice.amount_untaxed
+ not_included_invoice_taxes = tax_lines
+ else:
+ included_invoice_taxes = tax_lines.filtered(lambda x: x.tax_line_id in included_taxes)
+ not_included_invoice_taxes = tax_lines - included_invoice_taxes
+ if invoice.is_inbound():
+ sign = -1
+ else:
+ sign = 1
+ l10n_latam_amount_tax = sign * sum(not_included_invoice_taxes.mapped('balance'))
+ l10n_latam_amount_untaxed = invoice.amount_untaxed + sign * sum(included_invoice_taxes.mapped('balance'))
+ invoice.l10n_latam_amount_tax = l10n_latam_amount_tax
+ invoice.l10n_latam_amount_untaxed = l10n_latam_amount_untaxed
+ invoice.l10n_latam_tax_ids = not_included_invoice_taxes
+ remaining = self - recs_invoice
+ remaining.l10n_latam_amount_tax = False
+ remaining.l10n_latam_amount_untaxed = False
+ remaining.l10n_latam_tax_ids = []
+
+ def _compute_invoice_sequence_number_next(self):
+ """ If journal use documents disable the next number header"""
+ with_latam_document_number = self.filtered('l10n_latam_use_documents')
+ with_latam_document_number.invoice_sequence_number_next_prefix = False
+ with_latam_document_number.invoice_sequence_number_next = False
+ return super(AccountMove, self - with_latam_document_number)._compute_invoice_sequence_number_next()
+
+ def post(self):
+ for rec in self.filtered(lambda x: x.l10n_latam_use_documents and (not x.name or x.name == '/')):
+ if not rec.l10n_latam_sequence_id:
+ raise UserError(_('No sequence or document number linked to invoice id %s') % rec.id)
+ if rec.type in ('in_receipt', 'out_receipt'):
+ raise UserError(_('We do not accept the usage of document types on receipts yet. '))
+ rec.l10n_latam_document_number = rec.l10n_latam_sequence_id.next_by_id()
+ return super().post()
+
+ @api.constrains('name', 'journal_id', 'state')
+ def _check_unique_sequence_number(self):
+ """ Do not apply unique sequence number for vendoer bills and refunds.
+ Also apply constraint when state change """
+ vendor = self.filtered(lambda x: x.type in ['in_refund', 'in_invoice'])
+ try:
+ return super(AccountMove, self - vendor)._check_unique_sequence_number()
+ except ValidationError:
+ raise ValidationError(_('Duplicated invoice number detected. You probably add twice the same customer'
+ ' invoice/debit note.'))
+
+ @api.constrains('state', 'l10n_latam_document_type_id')
+ def _check_l10n_latam_documents(self):
+ validated_invoices = self.filtered(lambda x: x.l10n_latam_use_documents and x.state in ['open', 'done'])
+ without_doc_type = validated_invoices.filtered(lambda x: not x.l10n_latam_document_type_id)
+ if without_doc_type:
+ raise ValidationError(_(
+ 'The journal require a document type but not document type has been selected on invoices %s.' % (
+ without_doc_type.ids)))
+ without_number = validated_invoices.filtered(
+ lambda x: not x.l10n_latam_document_number and not x.l10n_latam_sequence_id)
+ if without_number:
+ raise ValidationError(_('Please set the document number on the following invoices %s.' % (
+ without_number.ids)))
+
+ @api.constrains('type', 'l10n_latam_document_type_id')
+ def _check_invoice_type_document_type(self):
+ for rec in self.filtered('l10n_latam_document_type_id.internal_type'):
+ internal_type = rec.l10n_latam_document_type_id.internal_type
+ invoice_type = rec.type
+ if internal_type in ['debit_note', 'invoice'] and invoice_type in ['out_refund', 'in_refund']:
+ raise ValidationError(_('You can not use a %s document type with a refund invoice') % internal_type)
+ elif internal_type == 'credit_note' and invoice_type in ['out_invoice', 'in_invoice']:
+ raise ValidationError(_('You can not use a %s document type with a invoice') % (internal_type))
+
+ def _get_l10n_latam_documents_domain(self):
+ self.ensure_one()
+ if self.type in ['out_refund', 'in_refund']:
+ internal_types = ['credit_note']
+ else:
+ internal_types = ['invoice', 'debit_note']
+ return [('internal_type', 'in', internal_types), ('country_id', '=', self.company_id.country_id.id)]
+
+ @api.depends('journal_id', 'partner_id', 'company_id')
+ def _compute_l10n_latam_documents(self):
+ internal_type = self._context.get('internal_type', False)
+ recs_with_journal_partner = self.filtered(lambda x: x.journal_id and x.l10n_latam_use_documents and x.partner_id)
+ for rec in recs_with_journal_partner:
+ document_types = self.env['l10n_latam.document.type'].search(rec._get_l10n_latam_documents_domain())
+
+ # If internal_type is in context we try to search for an specific document. for eg used on debit notes
+ document_type = internal_type and document_types.filtered(
+ lambda x: x.internal_type == internal_type) or document_types
+
+ rec.l10n_latam_available_document_type_ids = document_types
+ rec.l10n_latam_document_type_id = document_type and document_type[0]
+ remaining = self - recs_with_journal_partner
+ remaining.l10n_latam_available_document_type_ids = []
+ remaining.l10n_latam_document_type_id = False
+
+ @api.model_create_multi
+ def create(self, vals_list):
+ recs = super().create(vals_list)
+ recs.filtered(lambda x: x.l10n_latam_use_documents and not x.l10n_latam_document_type_id)._compute_l10n_latam_documents()
+ return recs
+
+ def _compute_invoice_taxes_by_group(self):
+ move_with_doc_type = self.filtered('l10n_latam_document_type_id')
+ for move in move_with_doc_type:
+ lang_env = move.with_context(lang=move.partner_id.lang).env
+ tax_lines = move.l10n_latam_tax_ids
+ res = {}
+ for line in tax_lines:
+ res.setdefault(line.tax_line_id.tax_group_id, {'base': 0.0, 'amount': 0.0})
+ res[line.tax_line_id.tax_group_id]['amount'] += line.price_subtotal
+ res[line.tax_line_id.tax_group_id]['base'] += line.tax_base_amount
+ res = sorted(res.items(), key=lambda l: l[0].sequence)
+ move.amount_by_group = [(
+ group.name, amounts['amount'],
+ amounts['base'],
+ formatLang(lang_env, amounts['amount'], currency_obj=move.currency_id),
+ formatLang(lang_env, amounts['base'], currency_obj=move.currency_id),
+ len(res),
+ ) for group, amounts in res]
+ super(AccountMove, self - move_with_doc_type)._compute_invoice_taxes_by_group()
+
+ def _get_document_type_sequence(self):
+ """ Method to be inherited by different localizations. """
+ self.ensure_one()
+ return self.env['ir.sequence']
+
+ @api.constrains('name', 'partner_id', 'company_id')
+ def _check_unique_vendor_number(self):
+ """ The constraint _check_unique_sequence_number is valid for customer bills but not valid for us on vendor
+ bills because the uniqueness must be per partner and also because we want to validate on entry creation and
+ not on entry validation """
+ for rec in self.filtered(lambda x: x.is_purchase_document() and x.l10n_latam_use_documents and x.l10n_latam_document_number):
+ domain = [
+ ('type', '=', rec.type),
+ # by validating name we validate l10n_latam_document_number and l10n_latam_document_type_id
+ ('name', '=', rec.name),
+ ('company_id', '=', rec.company_id.id),
+ ('id', '!=', rec.id),
+ ('commercial_partner_id', '=', rec.commercial_partner_id.id)
+ ]
+ if rec.search(domain):
+ raise ValidationError(_('Vendor bill number must be unique per vendor and company.'))
diff --git a/addons/l10n_latam_invoice_document/models/account_move_line.py b/addons/l10n_latam_invoice_document/models/account_move_line.py
new file mode 100644
index 00000000000..91e4db60c91
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/models/account_move_line.py
@@ -0,0 +1,38 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import models, api, fields
+
+
+class AccountMoveLine(models.Model):
+
+ _inherit = 'account.move.line'
+
+ l10n_latam_document_type_id = fields.Many2one(
+ related='move_id.l10n_latam_document_type_id', auto_join=True, store=True, index=True)
+ l10n_latam_price_unit = fields.Monetary(compute='compute_l10n_latam_prices_and_taxes')
+ l10n_latam_price_subtotal = fields.Monetary(compute='compute_l10n_latam_prices_and_taxes')
+ l10n_latam_price_net = fields.Monetary(compute='compute_l10n_latam_prices_and_taxes')
+ l10n_latam_tax_ids = fields.One2many(compute="compute_l10n_latam_prices_and_taxes", comodel_name='account.tax')
+
+ @api.depends('price_unit', 'price_subtotal', 'move_id.l10n_latam_document_type_id')
+ def compute_l10n_latam_prices_and_taxes(self):
+ for line in self:
+ invoice = line.move_id
+ included_taxes = \
+ invoice.l10n_latam_document_type_id and invoice.l10n_latam_document_type_id._filter_taxes_included(
+ line.tax_ids)
+ if not included_taxes:
+ l10n_latam_price_unit = line.price_unit
+ l10n_latam_price_subtotal = line.price_subtotal
+ not_included_taxes = line.tax_ids
+ l10n_latam_price_net = l10n_latam_price_unit * (1 - (line.discount or 0.0) / 100.0)
+ else:
+ not_included_taxes = line.tax_ids - included_taxes
+ l10n_latam_price_unit = included_taxes.compute_all(
+ line.price_unit, invoice.currency_id, 1.0, line.product_id, invoice.partner_id)['total_included']
+ l10n_latam_price_net = l10n_latam_price_unit * (1 - (line.discount or 0.0) / 100.0)
+ l10n_latam_price_subtotal = l10n_latam_price_net * line.quantity
+ line.l10n_latam_price_subtotal = l10n_latam_price_subtotal
+ line.l10n_latam_price_unit = l10n_latam_price_unit
+ line.l10n_latam_price_net = l10n_latam_price_net
+ line.l10n_latam_tax_ids = not_included_taxes
diff --git a/addons/l10n_latam_invoice_document/models/ir_sequence.py b/addons/l10n_latam_invoice_document/models/ir_sequence.py
new file mode 100644
index 00000000000..d05ee5464ba
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/models/ir_sequence.py
@@ -0,0 +1,10 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo import fields, models
+
+
+class IrSequence(models.Model):
+
+ _inherit = 'ir.sequence'
+
+ l10n_latam_journal_id = fields.Many2one('account.journal', 'Journal')
+ l10n_latam_document_type_id = fields.Many2one('l10n_latam.document.type', 'Document Type')
diff --git a/addons/l10n_latam_invoice_document/models/l10n_latam_document_type.py b/addons/l10n_latam_invoice_document/models/l10n_latam_document_type.py
new file mode 100644
index 00000000000..e57262e6464
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/models/l10n_latam_document_type.py
@@ -0,0 +1,55 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models, api
+
+
+class L10nLatamDocumentType(models.Model):
+
+ _name = 'l10n_latam.document.type'
+ _description = 'Latam Document Type'
+ _order = 'sequence, id'
+
+ active = fields.Boolean(default=True)
+ sequence = fields.Integer(
+ default=10, required=True, help='To set in which order show the documents type taking into account the most'
+ ' commonly used first')
+ country_id = fields.Many2one(
+ 'res.country', required=True, index=True, help='Country in which this type of document is valid')
+ name = fields.Char(required=True, index=True, help='The document name')
+ doc_code_prefix = fields.Char(
+ 'Document Code Prefix', help="Prefix for Documents Codes on Invoices and Account Moves. For eg. 'FA ' will"
+ " build 'FA 0001-0000001' Document Number")
+ code = fields.Char(help='Code used by different localizations')
+ report_name = fields.Char('Name on Reports', help='Name that will be printed in reports, for example "CREDIT NOTE"')
+ internal_type = fields.Selection(
+ [('invoice', 'Invoices'), ('debit_note', 'Debit Notes'), ('credit_note', 'Credit Notes')], index=True,
+ help='Analog to odoo account.move.type but with more options allowing to identify the kind of document we are'
+ ' working with. (not only related to account.move, could be for documents of other models like stock.picking)')
+
+ def _format_document_number(self, document_number):
+ """ Method to be inherited by different localizations. The purpose of this method is to allow:
+ * making validations on the document_number. If it is wrong it should raise an exception
+ * format the document_number against a pattern and return it
+ """
+ self.ensure_one()
+ return document_number
+
+ def name_get(self):
+ result = []
+ for rec in self:
+ name = rec.name
+ if rec.code:
+ name = '(%s) %s' % (rec.code, name)
+ result.append((rec.id, name))
+ return result
+
+ def _filter_taxes_included(self, taxes):
+ """ This method is to be inherited by different localizations and must return filter the given taxes recordset
+ returning the taxes to be included on reports of this document type. All taxes are going to be discriminated
+ except the one returned by this method. """
+ self.ensure_one()
+ return self.env['account.tax']
+
+ def get_document_sequence_vals(self, journal):
+ self.ensure_one()
+ return {'name': '%s - %s' % (journal.name, self.name), 'padding': 8, 'prefix': self.code}
diff --git a/addons/l10n_latam_invoice_document/models/res_company.py b/addons/l10n_latam_invoice_document/models/res_company.py
new file mode 100644
index 00000000000..b37c24ef9ae
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/models/res_company.py
@@ -0,0 +1,12 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo import fields, models
+
+
+class ResCompany(models.Model):
+
+ _inherit = "res.company"
+
+ def _localization_use_documents(self):
+ """ This method is to be inherited by localizations and return True if localization use documents """
+ self.ensure_one()
+ return False
diff --git a/addons/l10n_latam_invoice_document/report/__init__.py b/addons/l10n_latam_invoice_document/report/__init__.py
new file mode 100644
index 00000000000..a622bd9bb6e
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/report/__init__.py
@@ -0,0 +1,3 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import invoice_report
diff --git a/addons/l10n_latam_invoice_document/report/invoice_report.py b/addons/l10n_latam_invoice_document/report/invoice_report.py
new file mode 100644
index 00000000000..105a00b305d
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/report/invoice_report.py
@@ -0,0 +1,16 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo import models, fields
+
+
+class AccountInvoiceReport(models.Model):
+
+ _inherit = 'account.invoice.report'
+
+ l10n_latam_document_type_id = fields.Many2one('l10n_latam.document.type', 'Document Type', index=True)
+ _depends = {'account.move': ['l10n_latam_document_type_id'],}
+
+ def _select(self):
+ return super()._select() + ", move.l10n_latam_document_type_id as l10n_latam_document_type_id"
+
+ def _group_by(self):
+ return super()._group_by() + ", move.l10n_latam_document_type_id"
diff --git a/addons/l10n_latam_invoice_document/report/invoice_report_view.xml b/addons/l10n_latam_invoice_document/report/invoice_report_view.xml
new file mode 100644
index 00000000000..1b38f6cfad9
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/report/invoice_report_view.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ account.invoice.report.search
+ account.invoice.report
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/l10n_latam_invoice_document/security/ir.model.access.csv b/addons/l10n_latam_invoice_document/security/ir.model.access.csv
new file mode 100644
index 00000000000..255706e3383
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_l10n_latam_document_type_all,l10n_latam.document.type.all,model_l10n_latam_document_type,,1,0,0,0
+access_l10n_latam_document_type_account_manager,l10n_latam.document.type.all,model_l10n_latam_document_type,account.group_account_manager,1,1,1,0
diff --git a/addons/l10n_latam_invoice_document/views/account_journal_view.xml b/addons/l10n_latam_invoice_document/views/account_journal_view.xml
new file mode 100644
index 00000000000..a51d4c7e2a1
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/views/account_journal_view.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ account.journal
+ account.journal.form
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/l10n_latam_invoice_document/views/account_move_line_view.xml b/addons/l10n_latam_invoice_document/views/account_move_line_view.xml
new file mode 100644
index 00000000000..5410c569f60
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/views/account_move_line_view.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ account.move.line.filter
+ account.move.line
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/l10n_latam_invoice_document/views/account_move_view.xml b/addons/l10n_latam_invoice_document/views/account_move_view.xml
new file mode 100644
index 00000000000..0b1e6ac9cc3
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/views/account_move_view.xml
@@ -0,0 +1,59 @@
+
+
+
+
+ account.move.select
+ account.move
+
+
+
+
+
+
+
+
+
+
+
+
+ account.move.filter
+ account.move
+
+
+
+
+
+
+
+
+
+
+
+
+ account.move.form
+ account.move
+
+
+
+
+
+
+
+
+
+
+ {'default_type': type}
+
+
+
+
+
+
diff --git a/addons/l10n_latam_invoice_document/views/ir_sequence_view.xml b/addons/l10n_latam_invoice_document/views/ir_sequence_view.xml
new file mode 100644
index 00000000000..2faf12d1201
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/views/ir_sequence_view.xml
@@ -0,0 +1,40 @@
+
+
+
+
+ ir.sequence.form
+ ir.sequence
+
+
+
+
+
+
+
+
+
+
+ ir.sequence.tree
+ ir.sequence
+
+
+
+
+
+
+
+
+
+
+ ir.sequence.search
+ ir.sequence
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/l10n_latam_invoice_document/views/l10n_latam_document_type_view.xml b/addons/l10n_latam_invoice_document/views/l10n_latam_document_type_view.xml
new file mode 100644
index 00000000000..ba7e6a4d893
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/views/l10n_latam_document_type_view.xml
@@ -0,0 +1,65 @@
+
+
+
+
+ l10n_latam.document.type.form
+ l10n_latam.document.type
+
+
+
+
+
+
+ l10n_latam.document.type.tree
+ l10n_latam.document.type
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ l10n_latam.document.type.filter
+ l10n_latam.document.type
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Document Types
+ l10n_latam.document.type
+ ['|', ('active', '=', True), ('active', '=', False)]
+ {"search_default_active":1}
+
+
+
+
+
diff --git a/addons/l10n_latam_invoice_document/views/report_invoice.xml b/addons/l10n_latam_invoice_document/views/report_invoice.xml
new file mode 100644
index 00000000000..b96536f02f1
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/views/report_invoice.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+ o.partner_id.l10n_latam_identification_type_id.name or o.company_id.country_id.vat_label
+
+
+
+ not o.l10n_latam_document_type_id.report_name
+
+
+
+
+
+
+
+
+
+
+ line.l10n_latam_price_unit
+
+
+
+ ', '.join(map(lambda x: (x.description or x.name), line.l10n_latam_tax_ids))
+
+
+
+
+
+
+
+
+
+
+
+ o.l10n_latam_amount_untaxed
+
+
+
+
+
diff --git a/addons/l10n_latam_invoice_document/wizards/__init__.py b/addons/l10n_latam_invoice_document/wizards/__init__.py
new file mode 100644
index 00000000000..7076207375e
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/wizards/__init__.py
@@ -0,0 +1,3 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import account_move_reversal
diff --git a/addons/l10n_latam_invoice_document/wizards/account_move_reversal.py b/addons/l10n_latam_invoice_document/wizards/account_move_reversal.py
new file mode 100644
index 00000000000..cb7036bd618
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/wizards/account_move_reversal.py
@@ -0,0 +1,65 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import models, fields, api, _
+from odoo.exceptions import UserError
+
+
+class AccountMoveReversal(models.TransientModel):
+
+ _inherit = "account.move.reversal"
+
+ l10n_latam_use_documents = fields.Boolean(
+ related='move_id.journal_id.l10n_latam_use_documents', readonly=True)
+ l10n_latam_document_type_id = fields.Many2one('l10n_latam.document.type', 'Document Type', ondelete='cascade')
+ l10n_latam_sequence_id = fields.Many2one('ir.sequence', compute='_compute_l10n_latam_sequence')
+ l10n_latam_document_number = fields.Char(string='Document Number')
+
+ @staticmethod
+ def reverse_type_map(move_type):
+ match = {
+ 'entry': 'entry',
+ 'out_invoice': 'out_refund',
+ 'in_invoice': 'in_refund',
+ 'in_refund': 'in_invoice',
+ 'out_receipt': 'in_receipt',
+ 'in_receipt': 'out_receipt'}
+ return match.get(move_type)
+
+ @api.onchange('move_id')
+ def _onchange_move_id(self):
+ if self.move_id.l10n_latam_use_documents:
+ refund = self.move_id.new({
+ 'type': self.reverse_type_map(self.move_id.type),
+ 'journal_id': self.move_id.journal_id.id,
+ 'partner_id': self.move_id.partner_id.id,
+ 'company_id': self.move_id.company_id.id,
+ })
+ refund._compute_l10n_latam_documents()
+ self.l10n_latam_document_type_id = refund.l10n_latam_document_type_id
+ return {'domain': {
+ 'l10n_latam_document_type_id': [('id', 'in', refund.l10n_latam_available_document_type_ids.ids)]}}
+
+ def reverse_moves(self):
+ return super(AccountMoveReversal, self.with_context(
+ default_l10n_latam_document_type_id=self.l10n_latam_document_type_id.id,
+ default_l10n_latam_document_number=self.l10n_latam_document_number)).reverse_moves()
+
+ @api.depends('l10n_latam_document_type_id')
+ def _compute_l10n_latam_sequence(self):
+ for rec in self:
+ refund = rec.move_id.new({
+ 'type': self.reverse_type_map(rec.move_id.type),
+ 'journal_id': rec.move_id.journal_id.id,
+ 'partner_id': rec.move_id.partner_id.id,
+ 'company_id': rec.move_id.company_id.id,
+ 'l10n_latam_document_type_id': rec.l10n_latam_document_type_id.id,
+ })
+ rec.l10n_latam_sequence_id = refund._get_document_type_sequence()
+
+ @api.onchange('l10n_latam_document_number', 'l10n_latam_document_type_id')
+ def _onchange_l10n_latam_document_number(self):
+ if self.l10n_latam_document_type_id:
+ l10n_latam_document_number = self.l10n_latam_document_type_id._format_document_number(
+ self.l10n_latam_document_number)
+ if self.l10n_latam_document_number != l10n_latam_document_number:
+ self.l10n_latam_document_number = l10n_latam_document_number
diff --git a/addons/l10n_latam_invoice_document/wizards/account_move_reversal_view.xml b/addons/l10n_latam_invoice_document/wizards/account_move_reversal_view.xml
new file mode 100644
index 00000000000..b35d1abe763
--- /dev/null
+++ b/addons/l10n_latam_invoice_document/wizards/account_move_reversal_view.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ account.move.reversal.form
+ account.move.reversal
+
+
+
+
+
+
+
+
+
+
+