Complete Dominican IFRS base localization

Align the Dominican chart with the reviewed NIIF documentation by typing impairment and control accounts correctly, adding off-balance closing/control account types, and documenting the structural IFRS coverage boundary. Extend tests with fiscal audit matrices, IFRS account/type coverage, policy coverage, tax code signs, date-sensitive rules, and real chart validations.
This commit is contained in:
José Arturo García
2026-08-09 13:13:22 -04:00
parent fa3712bbfc
commit 1e05afd8bb
4 changed files with 439 additions and 91 deletions
+41
View File
@@ -7,6 +7,7 @@ Cobertura funcional
------------------- -------------------
* Plan de cuentas base para República Dominicana. * Plan de cuentas base para República Dominicana.
* Catálogo de cuentas preparado para operar bajo NIIF completas en República Dominicana, basado en la matriz documental ``catalogo_cuentas_niif_rd_tryton_completo.xlsx`` y validado contra cuentas reales del XML.
* Catálogo de impuestos y códigos fiscales. * Catálogo de impuestos y códigos fiscales.
* Reglas fiscales de venta, compra, tasas especiales y retenciones para escenarios dominicanos comunes. * Reglas fiscales de venta, compra, tasas especiales y retenciones para escenarios dominicanos comunes.
* Campo ``tax_kind`` para clasificar ITBIS, retenciones, ISC, CDT, propina legal y otros impuestos. * Campo ``tax_kind`` para clasificar ITBIS, retenciones, ISC, CDT, propina legal y otros impuestos.
@@ -20,3 +21,43 @@ Pruebas
------- -------
Las pruebas validan la instalación del módulo, la creación del plan para una compañía, la integridad de referencias XML, la clasificación contable principal, los códigos fiscales y las categorías fiscales dominicanas. Las pruebas validan la instalación del módulo, la creación del plan para una compañía, la integridad de referencias XML, la clasificación contable principal, los códigos fiscales y las categorías fiscales dominicanas.
Cumplimiento base NIIF
---------------------
``account_do`` cubre el 100% de la base estructural que corresponde a una localización contable: catálogo NIIF/RD, tipos de presentación, cuentas fiscales dominicanas, impuestos, reglas, metadata legal y pruebas de instalación. La medición NIIF, estimaciones, cierres, estados financieros, notas y revelaciones dependen de políticas contables y módulos operativos complementarios.
=============================== ===============================================
Área NIIF Cobertura en el plan
=============================== ===============================================
NIC 1 Corriente/no corriente, patrimonio, ORI y cierre/control separado
NIC 2 Inventarios, costo de ventas y deterioro
NIIF 9 / NIIF 7 / NIC 32 Cuentas por cobrar, ECL, instrumentos financieros y ORI
NIIF 15 Ingresos, descuentos, activos y pasivos contractuales
NIIF 16 Activos por derecho de uso, pasivos, depreciación e intereses
NIC 12 Impuesto corriente e impuesto diferido activo/pasivo
NIC 16 PPE, depreciación acumulada y deterioro
NIC 36 Deterioro de inventarios, PPE, ROU, propiedades de inversión e intangibles
NIC 37 Provisiones corrientes/no corrientes y reversión
NIC 38 Intangibles, amortización y deterioro
NIC 40 / NIIF 13 Propiedades de inversión, valor razonable y modelo de costo
NIIF 5 Activos mantenidos para la venta y pasivos asociados
=============================== ===============================================
Matriz de auditoría
-------------------
La cobertura de auditoría fiscal queda formalizada en pruebas para evitar cambios silenciosos en cuentas, clasificación o vigencias.
=============================== =============================================== ==============================================
Área Cobertura Prueba
=============================== =============================================== ==============================================
Impuesto contra cuenta 55 plantillas de ``tax_do.xml`` contra cuenta ``account_do.tests.test_module.TAX_TEMPLATE_AUDIT``
Clasificación fiscal ``tax_kind``, ``tax_fiscal_type`` y aplicación ``test_tax_templates_are_classified``
Metadata legal y vigencia Referencia, artículo, formulario, estado y fecha ``test_tax_templates_are_classified``
Signos de tax codes Plantillas y códigos reales creados por compañía ``test_tax_code_templates_use_expected_signs`` y chart real
Reglas con sustitución Impuesto cheques 0.15% hasta 2026-07-02 y 0.20% desde 2026-07-03 ``test_tax_rule_templates_include_date_sensitive_bank_tax``
Documentación contra XML La matriz apunta a XML real y falla ante ids/campos faltantes ``test_xml_references_are_resolved_inside_module``
Plan NIIF contra XML Códigos NIIF críticos, tipos y políticas ``test_ifrs_chart_is_complete_and_typed`` y ``test_ifrs_policy_matrix_is_represented_in_chart``
Facturas reales Factura venta/compra posteada con ITBIS 18% ``account_invoice_do.tests.test_module``
=============================== =============================================== ==============================================
+17 -4
View File
@@ -233,6 +233,12 @@
<field name="statement">income</field> <field name="statement">income</field>
<field name="expense" eval="True"/> <field name="expense" eval="True"/>
</record> </record>
<record id="do_type_control" model="account.account.type.template">
<field name="name">Cuentas de cierre y control</field>
<field name="parent" ref="do_type_root"/>
<field name="sequence" eval="100"/>
<field name="statement">off-balance</field>
</record>
</data> </data>
<data> <data>
<!-- ===== Cuenta raíz del plan ===== --> <!-- ===== Cuenta raíz del plan ===== -->
@@ -898,13 +904,13 @@
<field name="code">7101</field> <field name="code">7101</field>
<field name="name">Resultado antes de impuesto</field> <field name="name">Resultado antes de impuesto</field>
<field name="parent" ref="do_account_7"/> <field name="parent" ref="do_account_7"/>
<field name="type" ref="do_type_income_tax"/> <field name="type" ref="do_type_control"/>
</record> </record>
<record id="do_account_7102" model="account.account.template"> <record id="do_account_7102" model="account.account.template">
<field name="code">7102</field> <field name="code">7102</field>
<field name="name">Resultado después de impuesto</field> <field name="name">Resultado después de impuesto</field>
<field name="parent" ref="do_account_7"/> <field name="parent" ref="do_account_7"/>
<field name="type" ref="do_type_income_tax"/> <field name="type" ref="do_type_control"/>
</record> </record>
</data> </data>
<data grouped="1"> <data grouped="1">
@@ -1125,6 +1131,7 @@
<field name="code">111002</field> <field name="code">111002</field>
<field name="name">Deterioro de activos mantenidos para la venta</field> <field name="name">Deterioro de activos mantenidos para la venta</field>
<field name="parent" ref="do_account_1110"/> <field name="parent" ref="do_account_1110"/>
<field name="type" ref="do_type_current_asset"/>
</record> </record>
<record id="do_account_120101" model="account.account.template"> <record id="do_account_120101" model="account.account.template">
<field name="code">120101</field> <field name="code">120101</field>
@@ -1148,6 +1155,7 @@
<field name="code">120192</field> <field name="code">120192</field>
<field name="name">Deterioro acumulado edificaciones</field> <field name="name">Deterioro acumulado edificaciones</field>
<field name="parent" ref="do_account_1201"/> <field name="parent" ref="do_account_1201"/>
<field name="type" ref="do_type_fixed_asset"/>
</record> </record>
<record id="do_account_120201" model="account.account.template"> <record id="do_account_120201" model="account.account.template">
<field name="code">120201</field> <field name="code">120201</field>
@@ -1183,6 +1191,7 @@
<field name="code">120292</field> <field name="code">120292</field>
<field name="name">Deterioro acumulado mobiliario y equipos</field> <field name="name">Deterioro acumulado mobiliario y equipos</field>
<field name="parent" ref="do_account_1202"/> <field name="parent" ref="do_account_1202"/>
<field name="type" ref="do_type_fixed_asset"/>
</record> </record>
<record id="do_account_120301" model="account.account.template"> <record id="do_account_120301" model="account.account.template">
<field name="code">120301</field> <field name="code">120301</field>
@@ -1200,6 +1209,7 @@
<field name="code">120392</field> <field name="code">120392</field>
<field name="name">Deterioro acumulado vehículos</field> <field name="name">Deterioro acumulado vehículos</field>
<field name="parent" ref="do_account_1203"/> <field name="parent" ref="do_account_1203"/>
<field name="type" ref="do_type_fixed_asset"/>
</record> </record>
<record id="do_account_120401" model="account.account.template"> <record id="do_account_120401" model="account.account.template">
<field name="code">120401</field> <field name="code">120401</field>
@@ -1237,12 +1247,13 @@
<field name="code">120591</field> <field name="code">120591</field>
<field name="name">Depreciación acumulada activos por derecho de uso</field> <field name="name">Depreciación acumulada activos por derecho de uso</field>
<field name="parent" ref="do_account_1205"/> <field name="parent" ref="do_account_1205"/>
<field name="type" ref="do_type_fixed_asset"/> <field name="type" ref="do_type_rou_asset"/>
</record> </record>
<record id="do_account_120592" model="account.account.template"> <record id="do_account_120592" model="account.account.template">
<field name="code">120592</field> <field name="code">120592</field>
<field name="name">Deterioro acumulado activos por derecho de uso</field> <field name="name">Deterioro acumulado activos por derecho de uso</field>
<field name="parent" ref="do_account_1205"/> <field name="parent" ref="do_account_1205"/>
<field name="type" ref="do_type_rou_asset"/>
</record> </record>
<record id="do_account_120601" model="account.account.template"> <record id="do_account_120601" model="account.account.template">
<field name="code">120601</field> <field name="code">120601</field>
@@ -1278,12 +1289,13 @@
<field name="code">120891</field> <field name="code">120891</field>
<field name="name">Depreciación acumulada propiedades de inversión</field> <field name="name">Depreciación acumulada propiedades de inversión</field>
<field name="parent" ref="do_account_1208"/> <field name="parent" ref="do_account_1208"/>
<field name="type" ref="do_type_fixed_asset"/> <field name="type" ref="do_type_investment_property"/>
</record> </record>
<record id="do_account_120892" model="account.account.template"> <record id="do_account_120892" model="account.account.template">
<field name="code">120892</field> <field name="code">120892</field>
<field name="name">Deterioro acumulado propiedades de inversión</field> <field name="name">Deterioro acumulado propiedades de inversión</field>
<field name="parent" ref="do_account_1208"/> <field name="parent" ref="do_account_1208"/>
<field name="type" ref="do_type_investment_property"/>
</record> </record>
<record id="do_account_120901" model="account.account.template"> <record id="do_account_120901" model="account.account.template">
<field name="code">120901</field> <field name="code">120901</field>
@@ -1313,6 +1325,7 @@
<field name="code">120992</field> <field name="code">120992</field>
<field name="name">Deterioro acumulado de intangibles</field> <field name="name">Deterioro acumulado de intangibles</field>
<field name="parent" ref="do_account_1209"/> <field name="parent" ref="do_account_1209"/>
<field name="type" ref="do_type_intangible"/>
</record> </record>
<record id="do_account_210101" model="account.account.template"> <record id="do_account_210101" model="account.account.template">
<field name="code">210101</field> <field name="code">210101</field>
+35 -4
View File
@@ -7,6 +7,9 @@ Tryton.
It includes: It includes:
* An IFRS-oriented chart of accounts for Dominican companies; * An IFRS-oriented chart of accounts for Dominican companies;
* IFRS structural coverage for current/non-current presentation, financial
instruments, revenue contracts, leases, deferred tax, PPE, impairment,
provisions, intangibles, investment property, OCI, and held-for-sale items;
* Dominican tax groups and tax templates for ITBIS, ISR withholdings, ISC, * Dominican tax groups and tax templates for ITBIS, ISR withholdings, ISC,
CDT, legal tip, and other taxes; CDT, legal tip, and other taxes;
* tax code templates for DGII-oriented fiscal balances; * tax code templates for DGII-oriented fiscal balances;
@@ -16,10 +19,38 @@ It includes:
* granular ``tax_fiscal_type`` and ``tax_application`` fields for fiscal * granular ``tax_fiscal_type`` and ``tax_application`` fields for fiscal
reporting, validation, and account mapping. reporting, validation, and account mapping.
The chart is intended as a base localization. Companies should review account The chart is intended as a base localization. It provides the account
names, sector-specific taxes, and DGII filing mappings before using it in structure and Tryton account types required to operate under IFRS in the
production. The 16% and 8% ITBIS templates are kept as special-rate templates Dominican Republic, but it does not replace accounting policies, measurement
for cases where those rates apply. models, estimates, closing procedures, financial statements, notes, or
disclosures. Companies should review account names, sector-specific taxes, and
DGII filing mappings before using it in production. The 16% and 8% ITBIS
templates are kept as special-rate templates for cases where those rates apply.
IFRS base coverage
------------------
The base chart covers the structural account requirements identified in the
NIIF documentation reviewed for the Dominican Republic:
* IAS/NIC 1: current and non-current presentation, equity, OCI, and separate
closing/control accounts;
* IAS/NIC 2: inventories, cost of sales, and inventory impairment;
* IFRS/NIIF 9, IFRS/NIIF 7, and IAS/NIC 32: receivables, expected credit
losses, financial assets, fair value through profit or loss, fair value
through OCI, and OCI reserves;
* IFRS/NIIF 15: revenue, discounts, contract assets, and contract liabilities;
* IFRS/NIIF 16: right-of-use assets, lease liabilities, depreciation, and
finance expense;
* IAS/NIC 12: current income tax and deferred tax assets/liabilities;
* IAS/NIC 16: property, plant and equipment, accumulated depreciation, and
impairment;
* IAS/NIC 36: impairment accounts for held-for-sale assets, PPE, ROU assets,
investment property, and intangibles;
* IAS/NIC 37: current and non-current provisions;
* IAS/NIC 38: intangible assets, amortization, and impairment;
* IAS/NIC 40 and IFRS/NIIF 13: investment property and fair value effects;
* IFRS/NIIF 5: held-for-sale assets and associated liabilities.
DGII account mapping DGII account mapping
-------------------- --------------------
+346 -83
View File
@@ -13,6 +13,216 @@ from trytond.transaction import Transaction
MODULE_DIR = Path(__file__).resolve().parent.parent MODULE_DIR = Path(__file__).resolve().parent.parent
TAX_TEMPLATE_AUDIT = {
'do_tax_itbis_18_venta': ('do_account_21020101', 'itbis',
'itbis_sale_18', 'sale_invoice', 'current', '', ''),
'do_tax_itbis_16_venta': ('do_account_21020102', 'itbis',
'itbis_sale_16', 'sale_invoice', 'special', '', ''),
'do_tax_itbis_9_venta': ('do_account_21020103', 'itbis',
'itbis_sale_9', 'sale_invoice', 'special', '', ''),
'do_tax_itbis_18_compra': ('do_account_11040101', 'itbis',
'itbis_purchase_18', 'purchase_invoice', 'current', '', ''),
'do_tax_itbis_16_compra': ('do_account_11040102', 'itbis',
'itbis_purchase_16', 'purchase_invoice', 'special', '', ''),
'do_tax_itbis_9_compra': ('do_account_11040103', 'itbis',
'itbis_purchase_9', 'purchase_invoice', 'special', '', ''),
'do_tax_itbis_8_venta': ('do_account_21020104', 'itbis',
'itbis_sale_8', 'sale_invoice', 'special', '', ''),
'do_tax_itbis_8_compra': ('do_account_11040104', 'itbis',
'itbis_purchase_8', 'purchase_invoice', 'special', '', ''),
'do_tax_itbis_exento': ('', 'itbis',
'itbis_exempt', 'sale_invoice', 'current', '', ''),
'do_tax_itbis_tasa_cero': ('do_account_21020105', 'itbis',
'itbis_zero_rate', 'sale_invoice', 'current', '', ''),
'do_tax_ret_itbis_30': ('do_account_21021101', 'itbis_withholding',
'itbis_withholding_30', 'purchase_invoice', 'current', '', ''),
'do_tax_ret_itbis_2_adq': ('do_account_11040601',
'itbis_withholding_acquirer', 'itbis_withholding_acquirer_2',
'payment_withholding', 'current', '', ''),
'do_tax_ret_isr_hon_5': ('do_account_21021301', 'isr_withholding',
'isr_legal_entity_services_5', 'purchase_invoice', 'current', '', ''),
'do_tax_ret_isr_serv_10': ('do_account_21021302', 'isr_withholding',
'isr_individual_services_10', 'purchase_invoice', 'current', '', ''),
'do_tax_ret_isr_div_10': ('do_account_21020601', 'isr_withholding',
'isr_dividends_10', 'payment_withholding', 'current', '', ''),
'do_tax_ret_isr_int_10': ('do_account_21021501', 'isr_withholding',
'isr_interest_individual_10', 'payment_withholding', 'current', '', ''),
'do_tax_ret_isr_alq_10': ('do_account_21021401', 'isr_withholding',
'isr_rent_10', 'purchase_invoice', 'current', '', ''),
'do_tax_ret_isr_est_15': ('do_account_11040801', 'isr_withholding',
'isr_state_1_5', 'sale_invoice', 'current', '', ''),
'do_tax_ret_isr_est_5': ('do_account_11040802', 'isr_withholding',
'isr_state_5', 'sale_invoice', 'current', '', ''),
'do_tax_ret_isr_bovine_1': ('do_account_21021801', 'isr_withholding',
'isr_bovine_meat_1', 'purchase_invoice', 'current', '', ''),
'do_tax_ret_isr_exporter_25': ('do_account_11040803', 'isr_withholding',
'isr_exporter_sales_2_5', 'sale_invoice', 'current', '', ''),
'do_tax_ret_isr_int_pj_1': ('do_account_21021502', 'isr_withholding',
'isr_interest_legal_entity_1', 'payment_withholding', 'current', '', ''),
'do_tax_ret_isr_premios_25': ('do_account_21021701', 'isr_withholding',
'isr_prizes_25', 'payment_withholding', 'current', '', ''),
'do_tax_ret_isr_premios_10': ('do_account_21021702', 'isr_withholding',
'isr_prizes_10', 'payment_withholding', 'current', '', ''),
'do_tax_ret_isr_premios_15': ('do_account_21021703', 'isr_withholding',
'isr_prizes_15', 'payment_withholding', 'current', '', ''),
'do_tax_ret_isr_tragamonedas_10': ('do_account_21021704',
'isr_withholding', 'isr_slot_machine_prizes_10',
'payment_withholding', 'current', '', ''),
'do_tax_ret_isr_other_income_10': ('do_account_21020301',
'isr_withholding', 'isr_other_income_10', 'purchase_invoice',
'current', '', ''),
'do_tax_ret_isr_ext_27': ('do_account_21020701', 'isr_withholding',
'isr_foreign_services_27', 'purchase_invoice', 'current', '', ''),
'do_tax_ret_isr_ext_10': ('do_account_21020702', 'isr_withholding',
'isr_foreign_interest_10', 'purchase_invoice', 'current', '', ''),
'do_tax_ret_itbis_100_inf': ('do_account_21020201',
'itbis_withholding', 'itbis_withholding_100_services',
'purchase_invoice', 'current', '', ''),
'do_tax_ret_itbis_75_inf': ('do_account_21021201',
'itbis_withholding', 'itbis_withholding_75_informal',
'purchase_invoice', 'current', '', ''),
'do_tax_ret_itbis_75_inf_16': ('do_account_21021202',
'itbis_withholding', 'itbis_withholding_75_informal_16',
'purchase_invoice', 'current', '', ''),
'do_tax_ret_itbis_100_goods_18': ('do_account_21021203',
'itbis_withholding', 'itbis_withholding_100_informal_goods_18',
'purchase_invoice', 'current', '', ''),
'do_tax_ret_itbis_100_goods_16': ('do_account_21021204',
'itbis_withholding', 'itbis_withholding_100_informal_goods_16',
'purchase_invoice', 'current', '', ''),
'do_tax_ret_itbis_rst_18': ('do_account_21020202',
'itbis_withholding', 'itbis_withholding_rst_18',
'purchase_invoice', 'current', '', ''),
'do_tax_ret_itbis_rst_16': ('do_account_21020203',
'itbis_withholding', 'itbis_withholding_rst_16',
'purchase_invoice', 'current', '', ''),
'do_tax_ret_itbis_insurance_100': ('do_account_21020204',
'itbis_withholding', 'itbis_withholding_insurance_100',
'purchase_invoice', 'current', '', ''),
'do_tax_ret_itbis_airline_100': ('do_account_11040701',
'itbis_withholding', 'itbis_withholding_airline_100',
'sale_invoice', 'current', '', ''),
'do_tax_ret_itbis_society_30_suf': ('do_account_11040702',
'itbis_withholding', 'itbis_withholding_society_30_suffered',
'sale_invoice', 'current', '', ''),
'do_tax_ret_itbis_hotel_100': ('do_account_11040703',
'itbis_withholding', 'itbis_withholding_hotel_100',
'sale_invoice', 'current', '', ''),
'do_tax_ret_itbis_state_100': ('do_account_11040704',
'itbis_withholding', 'itbis_withholding_state_100',
'sale_invoice', 'current', '', ''),
'do_tax_isc_bebidas_alc': ('do_account_21020801', 'isc',
'isc_alcohol_10', 'sale_invoice', 'current', '', ''),
'do_tax_isc_tabaco': ('do_account_21020802', 'isc',
'isc_tobacco_20', 'sale_invoice', 'current', '', ''),
'do_tax_isc_telecom': ('do_account_21020803', 'isc',
'isc_telecom_10', 'sale_invoice', 'current', '', ''),
'do_tax_isc_combustibles_16': ('do_account_21020804', 'isc',
'isc_fossil_fuel_16', 'sale_invoice', 'current', '', ''),
'do_tax_isc_avtur_65': ('do_account_21020807', 'isc',
'isc_avtur_6_5', 'sale_invoice', 'current', '', ''),
'do_tax_isc_fuel_rd2_gallon': ('do_account_21020808', 'isc',
'isc_fuel_rd2_gallon', 'sale_invoice', 'current', '', ''),
'do_tax_ret_isc_insurance_100': ('do_account_21020806', 'isc',
'isc_insurance_withholding_100', 'purchase_invoice', 'current', '', ''),
'do_tax_isc_vehiculos': ('do_account_21020805', 'isc',
'isc_vehicle_17', 'asset_transfer', 'current', '', ''),
'do_tax_cdt_indotel': ('do_account_21020901', 'cdt',
'cdt_indotel_2', 'sale_invoice', 'current', '', ''),
'do_tax_propina_10': ('do_account_21020501', 'tip',
'legal_tip_10', 'sale_invoice', 'current', '', ''),
'do_tax_cheques_015': ('do_account_21021901', 'others',
'check_transfer_tax_015', 'bank_charge', 'historical', '',
'datetime.date(2026, 7, 2)'),
'do_tax_cheques_020': ('do_account_21021902', 'others',
'check_transfer_tax_020', 'bank_charge', 'current',
'datetime.date(2026, 7, 3)', ''),
'do_tax_activos_1': ('do_account_21020502', 'others',
'asset_tax_1', 'annual_declaration', 'current', '', ''),
'do_tax_iti_3': ('do_account_21021001', 'others',
'real_estate_transfer_3', 'asset_transfer', 'current', '', ''),
}
TAX_CODE_LINE_AUDIT = {
'do_tcl_itbis18v_inv': '+',
'do_tcl_itbis18v_cr': '-',
'do_tcl_itbis18c_inv': '-',
'do_tcl_itbis18c_cr': '+',
'do_tcl_ret_itbis_inv': '-',
'do_tcl_ret_itbis_cr': '+',
'do_tcl_ret_itbis_adq_inv': '+',
'do_tcl_ret_itbis_adq_cr': '-',
'do_tcl_ret_itbis_inf75_inv': '-',
'do_tcl_ret_itbis_inf75_cr': '+',
'do_tcl_isr_hon_inv': '-',
'do_tcl_isr_hon_cr': '+',
'do_tcl_isr_est_inv': '+',
'do_tcl_isr_est_cr': '-',
'do_tcl_isc_comb_inv': '+',
'do_tcl_isc_comb_cr': '-',
'do_tcl_chq_inv': '+',
'do_tcl_chq_cr': '-',
'do_tcl_chq020_inv': '+',
'do_tcl_chq020_cr': '-',
}
IFRS_REQUIRED_ACCOUNT_CODES = {
'1', '11', '12',
'1101', '1102', '1103', '1104', '1105', '1106', '1107', '1110',
'110101', '110103', '110104', '110201', '110205', '110301',
'110305', '110601', '110701', '110702', '110703', '111001',
'111002',
'1201', '1205', '1206', '1207', '1208', '1209',
'120101', '120191', '120192', '120501', '120591', '120592',
'120601', '120701', '120702', '120703', '120801', '120891',
'120892', '120901', '120991', '120992',
'2', '21', '22', '23',
'2101', '2104', '2105', '2106', '2201', '2301', '2302', '2303',
'2304',
'210101', '210401', '210501', '210601', '220101', '230201',
'230202', '230301', '230401',
'3', '31', '3101', '3104', '3105', '3106', '310601', '310604',
'4', '41', '42', '4101', '4102', '4103', '4104', '4201', '4208',
'4209', '4210',
'5', '51', '5101', '5102', '5106',
'6', '61', '62', '63', '6101', '6103', '6111', '6112', '6115',
'6116', '6117', '6118', '6119', '6120', '6201', '6203', '6206',
'6207', '6301', '6302', '6303',
'7', '7101', '7102',
}
IFRS_ACCOUNT_TYPE_AUDIT = {
'111002': 'do_type_current_asset',
'120192': 'do_type_fixed_asset',
'120292': 'do_type_fixed_asset',
'120392': 'do_type_fixed_asset',
'120591': 'do_type_rou_asset',
'120592': 'do_type_rou_asset',
'120891': 'do_type_investment_property',
'120892': 'do_type_investment_property',
'120992': 'do_type_intangible',
'7101': 'do_type_control',
'7102': 'do_type_control',
}
IFRS_POLICY_COVERAGE = {
'NIC 1': {'11', '12', '21', '23', '3106', '7101', '7102'},
'NIC 2': {'1103', '110305', '5101', '5106'},
'NIIF 9': {'110205', '110701', '110702', '110703', '120701',
'120702', '120703', '4208', '6206', '310604'},
'NIIF 15': {'110601', '210501', '4101', '4102', '4103', '4104'},
'NIIF 16': {'120501', '120591', '120592', '230201', '230202',
'6112', '6203'},
'NIC 12': {'120601', '230301', '6301', '6302', '6303'},
'NIC 16': {'120101', '120191', '120192', '6110', '6116'},
'NIC 36': {'111002', '120192', '120292', '120392', '120592',
'120892', '120992', '6116', '6117', '4206'},
'NIC 37': {'220101', '230401', '6118', '4207'},
'NIC 38': {'120901', '120991', '120992', '6111', '6117'},
'NIC 40': {'120801', '120891', '120892', '4209', '6207'},
'NIIF 5': {'111001', '111002', '210601', '4210', '6120'},
}
def _iter_xml_records(*filenames): def _iter_xml_records(*filenames):
for filename in filenames: for filename in filenames:
@@ -51,6 +261,7 @@ class AccountDoTestCase(ModuleTestCase):
Party = pool.get('party.party') Party = pool.get('party.party')
Tax = pool.get('account.tax') Tax = pool.get('account.tax')
TaxCode = pool.get('account.tax.code') TaxCode = pool.get('account.tax.code')
TaxCodeLine = pool.get('account.tax.code.line')
TaxRule = pool.get('account.tax.rule') TaxRule = pool.get('account.tax.rule')
CreateChart = pool.get('account.create_chart', type='wizard') CreateChart = pool.get('account.create_chart', type='wizard')
@@ -92,6 +303,8 @@ class AccountDoTestCase(ModuleTestCase):
('closed', '!=', True), ('closed', '!=', True),
], limit=1) ], limit=1)
for code in [ for code in [
'111002', '120192', '120292', '120392', '120591',
'120592', '120891', '120892', '120992', '7101', '7102',
'110401', '110406', '110407', '110408', '110401', '110406', '110407', '110408',
'11040101', '11040102', '11040103', '11040104', '11040101', '11040102', '11040103', '11040104',
'11040601', '11040801', '11040802', '11040803', '11040601', '11040801', '11040802', '11040803',
@@ -113,6 +326,24 @@ class AccountDoTestCase(ModuleTestCase):
('code', '=', code), ('code', '=', code),
('closed', '!=', True), ('closed', '!=', True),
], limit=1)) ], limit=1))
company_ifrs_types = {
'111002': 'Activos corrientes',
'120591': 'Activos por derecho de uso',
'120592': 'Activos por derecho de uso',
'120891': 'Propiedades de inversión',
'120892': 'Propiedades de inversión',
'120992': 'Activos intangibles',
'7101': 'Cuentas de cierre y control',
'7102': 'Cuentas de cierre y control',
}
for code, account_type in company_ifrs_types.items():
with self.subTest(code=code, account_type=account_type):
account, = Account.search([
('company', '=', company.id),
('code', '=', code),
('closed', '!=', True),
], limit=1)
self.assertEqual(account.type.name, account_type)
self.assertGreaterEqual(len(Account.search([ self.assertGreaterEqual(len(Account.search([
('company', '=', company.id), ('company', '=', company.id),
@@ -180,6 +411,32 @@ class AccountDoTestCase(ModuleTestCase):
'date': datetime.date(2026, 7, 3), 'date': datetime.date(2026, 7, 3),
}), }),
[check_020.id]) [check_020.id])
real_tax_code_signs = {
('ITBIS 18% Ventas', 'invoice'): '+',
('ITBIS 18% Ventas', 'credit'): '-',
('ITBIS 18% Compras', 'invoice'): '-',
('ITBIS 18% Compras', 'credit'): '+',
('Retención ITBIS Gran Contribuyente 30%', 'invoice'): '-',
('Retención ITBIS Gran Contribuyente 30%', 'credit'): '+',
('Retención ISR Persona Física 10%', 'invoice'): '-',
('Retención ISR Persona Física 10%', 'credit'): '+',
('Retención ISR Estado 1.5%', 'invoice'): '+',
('Retención ISR Estado 1.5%', 'credit'): '-',
('Impuesto Cheques y Transferencias 0.20%', 'invoice'): '+',
('Impuesto Cheques y Transferencias 0.20%', 'credit'): '-',
}
for (description, line_type), operator in real_tax_code_signs.items():
with self.subTest(description=description, line_type=line_type):
tax, = Tax.search([
('company', '=', company.id),
('description', '=', description),
], limit=1)
line, = TaxCodeLine.search([
('tax', '=', tax.id),
('type', '=', line_type),
('amount', '=', 'tax'),
], limit=1)
self.assertEqual(line.operator, operator)
chart.properties.company = company chart.properties.company = company
chart.properties.account_receivable = receivable chart.properties.account_receivable = receivable
@@ -253,6 +510,53 @@ class AccountDoUnitTestCase(unittest.TestCase):
self.assertEqual( self.assertEqual(
accounts['do_account_210101']['type'], 'do_type_payable') accounts['do_account_210101']['type'], 'do_type_payable')
def test_ifrs_chart_is_complete_and_typed(self):
accounts = {
values['code']: values
for _, _, model, values in _iter_xml_records(
'account_chart_do.xml')
if model == 'account.account.template' and values.get('code')
}
types = {
record_id: values
for _, record_id, model, values in _iter_xml_records(
'account_chart_do.xml')
if model == 'account.account.type.template'
}
self.assertLessEqual(IFRS_REQUIRED_ACCOUNT_CODES, set(accounts))
self.assertEqual(types['do_type_control']['statement'], 'off-balance')
self.assertEqual(
types['do_type_deferred_tax_asset']['statement'], 'balance')
self.assertEqual(
types['do_type_deferred_tax_liability']['statement'], 'balance')
self.assertEqual(types['do_type_rou_asset']['statement'], 'balance')
self.assertEqual(
types['do_type_investment_property']['statement'], 'balance')
self.assertEqual(types['do_type_intangible']['statement'], 'balance')
missing_type = [
(code, values['name'])
for code, values in accounts.items()
if values.get('closed') != 'True' and not values.get('type')
]
self.assertEqual(missing_type, [])
for code, account_type in IFRS_ACCOUNT_TYPE_AUDIT.items():
with self.subTest(code=code):
self.assertEqual(accounts[code]['type'], account_type)
def test_ifrs_policy_matrix_is_represented_in_chart(self):
accounts = {
values['code']
for _, _, model, values in _iter_xml_records(
'account_chart_do.xml')
if model == 'account.account.template' and values.get('code')
}
for standard, codes in IFRS_POLICY_COVERAGE.items():
with self.subTest(standard=standard):
self.assertLessEqual(codes, accounts)
def test_no_spanish_technical_other_tax_ids_remain(self): def test_no_spanish_technical_other_tax_ids_remain(self):
ids = { ids = {
record_id record_id
@@ -267,92 +571,48 @@ class AccountDoUnitTestCase(unittest.TestCase):
for _, record_id, model, values in _iter_xml_records('tax_do.xml') for _, record_id, model, values in _iter_xml_records('tax_do.xml')
if model == 'account.tax.template' if model == 'account.tax.template'
} }
self.assertEqual(len(taxes), 55) accounts = {
self.assertFalse([ record_id: values
record_id for record_id, values in taxes.items() for _, record_id, model, values in _iter_xml_records(
if not values.get('tax_kind')]) 'account_chart_do.xml')
self.assertFalse([ if model == 'account.account.template'
record_id for record_id, values in taxes.items()
if not values.get('tax_fiscal_type')])
self.assertFalse([
record_id for record_id, values in taxes.items()
if not values.get('tax_application')])
for field_name in [
'dgii_legal_reference',
'dgii_legal_article',
'dgii_form_hint',
'dgii_fiscal_status',
]:
self.assertFalse([
record_id for record_id, values in taxes.items()
if not values.get(field_name)])
self.assertEqual(
taxes['do_tax_itbis_18_venta']['invoice_account'],
'do_account_21020101')
self.assertEqual(
taxes['do_tax_itbis_18_compra']['invoice_account'],
'do_account_11040101')
expected_accounts = {
'do_tax_itbis_18_venta': 'do_account_21020101',
'do_tax_itbis_16_venta': 'do_account_21020102',
'do_tax_itbis_9_venta': 'do_account_21020103',
'do_tax_itbis_8_venta': 'do_account_21020104',
'do_tax_itbis_tasa_cero': 'do_account_21020105',
'do_tax_itbis_18_compra': 'do_account_11040101',
'do_tax_itbis_16_compra': 'do_account_11040102',
'do_tax_itbis_9_compra': 'do_account_11040103',
'do_tax_itbis_8_compra': 'do_account_11040104',
'do_tax_ret_itbis_2_adq': 'do_account_11040601',
'do_tax_ret_itbis_30': 'do_account_21021101',
'do_tax_ret_itbis_100_inf': 'do_account_21020201',
'do_tax_ret_itbis_75_inf': 'do_account_21021201',
'do_tax_ret_itbis_75_inf_16': 'do_account_21021202',
'do_tax_ret_itbis_100_goods_18': 'do_account_21021203',
'do_tax_ret_itbis_100_goods_16': 'do_account_21021204',
'do_tax_ret_itbis_rst_18': 'do_account_21020202',
'do_tax_ret_itbis_rst_16': 'do_account_21020203',
'do_tax_ret_itbis_insurance_100': 'do_account_21020204',
'do_tax_ret_itbis_airline_100': 'do_account_11040701',
'do_tax_ret_itbis_society_30_suf': 'do_account_11040702',
'do_tax_ret_itbis_hotel_100': 'do_account_11040703',
'do_tax_ret_itbis_state_100': 'do_account_11040704',
'do_tax_ret_isr_hon_5': 'do_account_21021301',
'do_tax_ret_isr_serv_10': 'do_account_21021302',
'do_tax_ret_isr_div_10': 'do_account_21020601',
'do_tax_ret_isr_int_10': 'do_account_21021501',
'do_tax_ret_isr_int_pj_1': 'do_account_21021502',
'do_tax_ret_isr_alq_10': 'do_account_21021401',
'do_tax_ret_isr_est_15': 'do_account_11040801',
'do_tax_ret_isr_est_5': 'do_account_11040802',
'do_tax_ret_isr_exporter_25': 'do_account_11040803',
'do_tax_ret_isr_bovine_1': 'do_account_21021801',
'do_tax_ret_isr_premios_25': 'do_account_21021701',
'do_tax_ret_isr_premios_10': 'do_account_21021702',
'do_tax_ret_isr_premios_15': 'do_account_21021703',
'do_tax_ret_isr_tragamonedas_10': 'do_account_21021704',
'do_tax_ret_isr_other_income_10': 'do_account_21020301',
'do_tax_ret_isr_ext_27': 'do_account_21020701',
'do_tax_ret_isr_ext_10': 'do_account_21020702',
'do_tax_isc_bebidas_alc': 'do_account_21020801',
'do_tax_isc_tabaco': 'do_account_21020802',
'do_tax_isc_telecom': 'do_account_21020803',
'do_tax_isc_combustibles_16': 'do_account_21020804',
'do_tax_isc_avtur_65': 'do_account_21020807',
'do_tax_isc_fuel_rd2_gallon': 'do_account_21020808',
'do_tax_ret_isc_insurance_100': 'do_account_21020806',
'do_tax_isc_vehiculos': 'do_account_21020805',
'do_tax_cdt_indotel': 'do_account_21020901',
'do_tax_propina_10': 'do_account_21020501',
'do_tax_cheques_015': 'do_account_21021901',
'do_tax_cheques_020': 'do_account_21021902',
'do_tax_activos_1': 'do_account_21020502',
'do_tax_iti_3': 'do_account_21021001',
} }
for record_id, account_id in expected_accounts.items(): tax_kind_codes = {code for code, _ in TAX_KIND}
fiscal_type_codes = {code for code, _ in TAX_FISCAL_TYPE}
application_codes = {code for code, _ in TAX_APPLICATION}
fiscal_status_codes = {code for code, _ in DGII_FISCAL_STATUS}
self.assertEqual(len(taxes), 55)
self.assertEqual(set(taxes), set(TAX_TEMPLATE_AUDIT))
for record_id, expected in TAX_TEMPLATE_AUDIT.items():
account_id, tax_kind, fiscal_type, application, status, start, end = (
expected)
with self.subTest(record_id=record_id): with self.subTest(record_id=record_id):
self.assertEqual(taxes[record_id]['invoice_account'], account_id) values = taxes[record_id]
self.assertEqual(values.get('invoice_account', ''), account_id)
self.assertEqual( self.assertEqual(
taxes[record_id]['credit_note_account'], account_id) values.get('credit_note_account', ''), account_id)
if account_id:
self.assertIn(account_id, accounts)
else:
self.assertEqual(values['type'], 'none')
self.assertFalse(values.get('rate'))
self.assertEqual(values['tax_kind'], tax_kind)
self.assertEqual(values['tax_fiscal_type'], fiscal_type)
self.assertEqual(values['tax_application'], application)
self.assertEqual(values['dgii_fiscal_status'], status)
self.assertEqual(values.get('start_date', ''), start)
self.assertEqual(values.get('end_date', ''), end)
self.assertIn(tax_kind, tax_kind_codes)
self.assertIn(fiscal_type, fiscal_type_codes)
self.assertIn(application, application_codes)
self.assertIn(status, fiscal_status_codes)
self.assertTrue(values.get('dgii_legal_reference'))
self.assertTrue(values.get('dgii_legal_article'))
self.assertTrue(values.get('dgii_form_hint'))
self.assertTrue(values.get('legal_notice'))
self.assertEqual( self.assertEqual(
taxes['do_tax_ret_itbis_30']['tax_kind'], taxes['do_tax_ret_itbis_30']['tax_kind'],
'itbis_withholding') 'itbis_withholding')
@@ -451,6 +711,9 @@ class AccountDoUnitTestCase(unittest.TestCase):
self.assertEqual( self.assertEqual(
lines['do_tcl_chq020_cr']['code'], lines['do_tcl_chq020_cr']['code'],
'do_tc_others_checks_020') 'do_tc_others_checks_020')
for record_id, operator in TAX_CODE_LINE_AUDIT.items():
with self.subTest(record_id=record_id):
self.assertEqual(lines[record_id]['operator'], operator)
self.assertEqual(lines['do_tcl_itbis18v_inv']['operator'], '+') self.assertEqual(lines['do_tcl_itbis18v_inv']['operator'], '+')
self.assertEqual(lines['do_tcl_itbis18c_inv']['operator'], '-') self.assertEqual(lines['do_tcl_itbis18c_inv']['operator'], '-')
self.assertEqual(lines['do_tcl_itbis9v_inv']['operator'], '+') self.assertEqual(lines['do_tcl_itbis9v_inv']['operator'], '+')