Classify foreign ISR withholdings separately

Assign payments to non-residents to the dedicated ISREXT group in both localization datasets and tax rules. Add regression checks for national and foreign ISR groups.
This commit is contained in:
José Arturo García
2026-08-10 02:23:14 -04:00
parent a740366693
commit 59f8dc0ede
7 changed files with 48 additions and 26 deletions
-2
View File
@@ -2,11 +2,9 @@
# this repository contains the full copyright notices and license terms. # this repository contains the full copyright notices and license terms.
from sql import Table from sql import Table
from trytond.pool import PoolMeta from trytond.pool import PoolMeta
from trytond.transaction import Transaction from trytond.transaction import Transaction
LEGACY_OBSOLETE_IDS = { LEGACY_OBSOLETE_IDS = {
'do_tax_itbis_8_compra', 'do_tax_itbis_8_venta', 'do_tax_itbis_8_compra', 'do_tax_itbis_8_venta',
'do_tax_itbis_9_compra', 'do_tax_itbis_9_venta', 'do_tax_itbis_9_compra', 'do_tax_itbis_9_venta',
+2 -2
View File
@@ -292,7 +292,7 @@
<field name="description">Foreign ISR Withholding 27%</field> <field name="description">Foreign ISR Withholding 27%</field>
<field name="type">percentage</field> <field name="type">percentage</field>
<field name="rate" eval="Decimal('-27')/100" /> <field name="rate" eval="Decimal('-27')/100" />
<field name="group" ref="do_tax_group_isr_en" /> <field name="group" ref="do_tax_group_isr_ext_en" />
<field name="account" ref="do_account_root_en" /> <field name="account" ref="do_account_root_en" />
<field name="invoice_account" ref="do_account_21020701_en" /> <field name="invoice_account" ref="do_account_21020701_en" />
<field name="credit_note_account" ref="do_account_21020701_en" /> <field name="credit_note_account" ref="do_account_21020701_en" />
@@ -303,7 +303,7 @@
<field name="description">Foreign ISR Withholding 10%</field> <field name="description">Foreign ISR Withholding 10%</field>
<field name="type">percentage</field> <field name="type">percentage</field>
<field name="rate" eval="Decimal('-10')/100" /> <field name="rate" eval="Decimal('-10')/100" />
<field name="group" ref="do_tax_group_isr_en" /> <field name="group" ref="do_tax_group_isr_ext_en" />
<field name="account" ref="do_account_root_en" /> <field name="account" ref="do_account_root_en" />
<field name="invoice_account" ref="do_account_21020702_en" /> <field name="invoice_account" ref="do_account_21020702_en" />
<field name="credit_note_account" ref="do_account_21020702_en" /> <field name="credit_note_account" ref="do_account_21020702_en" />
+3 -3
View File
@@ -283,7 +283,7 @@
<field name="description">Retención ISR Exterior 27%</field> <field name="description">Retención ISR Exterior 27%</field>
<field name="type">percentage</field> <field name="type">percentage</field>
<field name="rate" eval="Decimal('-27')/100" /> <field name="rate" eval="Decimal('-27')/100" />
<field name="group" ref="do_tax_group_isr_es_419" /> <field name="group" ref="do_tax_group_isr_ext_es_419" />
<field name="account" ref="do_account_root_es_419" /> <field name="account" ref="do_account_root_es_419" />
<field name="invoice_account" ref="do_account_21020701_es_419" /> <field name="invoice_account" ref="do_account_21020701_es_419" />
<field name="credit_note_account" ref="do_account_21020701_es_419" /> <field name="credit_note_account" ref="do_account_21020701_es_419" />
@@ -294,7 +294,7 @@
<field name="description">Retención ISR Exterior 10%</field> <field name="description">Retención ISR Exterior 10%</field>
<field name="type">percentage</field> <field name="type">percentage</field>
<field name="rate" eval="Decimal('-10')/100" /> <field name="rate" eval="Decimal('-10')/100" />
<field name="group" ref="do_tax_group_isr_es_419" /> <field name="group" ref="do_tax_group_isr_ext_es_419" />
<field name="account" ref="do_account_root_es_419" /> <field name="account" ref="do_account_root_es_419" />
<field name="invoice_account" ref="do_account_21020702_es_419" /> <field name="invoice_account" ref="do_account_21020702_es_419" />
<field name="credit_note_account" ref="do_account_21020702_es_419" /> <field name="credit_note_account" ref="do_account_21020702_es_419" />
@@ -589,4 +589,4 @@
<field name="legal_notice">Art. 20 Ley 288-04, mod. art. 7 Ley 173-07 — tasa 3%</field> <field name="legal_notice">Art. 20 Ley 288-04, mod. art. 7 Ley 173-07 — tasa 3%</field>
</record> </record>
</data> </data>
</tryton> </tryton>
+1 -1
View File
@@ -63,7 +63,7 @@
</record> </record>
<record id="do_trline_supp_ext_isr27_en" model="account.tax.rule.line.template"> <record id="do_trline_supp_ext_isr27_en" model="account.tax.rule.line.template">
<field name="rule" ref="do_tax_rule_supplier_ext_en"/> <field name="rule" ref="do_tax_rule_supplier_ext_en"/>
<field name="group" ref="do_tax_group_isr_en"/> <field name="group" ref="do_tax_group_isr_ext_en"/>
<field name="tax" ref="do_tax_ret_isr_ext_27_en"/> <field name="tax" ref="do_tax_ret_isr_ext_27_en"/>
<field name="sequence" eval="10"/> <field name="sequence" eval="10"/>
</record> </record>
+2 -2
View File
@@ -52,7 +52,7 @@
</record> </record>
<record id="do_trline_supp_ext_isr27_es_419" model="account.tax.rule.line.template"> <record id="do_trline_supp_ext_isr27_es_419" model="account.tax.rule.line.template">
<field name="rule" ref="do_tax_rule_supplier_ext_es_419" /> <field name="rule" ref="do_tax_rule_supplier_ext_es_419" />
<field name="group" ref="do_tax_group_isr_es_419" /> <field name="group" ref="do_tax_group_isr_ext_es_419" />
<field name="tax" ref="do_tax_ret_isr_ext_27_es_419" /> <field name="tax" ref="do_tax_ret_isr_ext_27_es_419" />
<field name="sequence" eval="10" /> <field name="sequence" eval="10" />
</record> </record>
@@ -311,4 +311,4 @@
<field name="sequence" eval="40" /> <field name="sequence" eval="40" />
</record> </record>
</data> </data>
</tryton> </tryton>
-1
View File
@@ -1 +0,0 @@
+40 -15
View File
@@ -1,5 +1,5 @@
import unittest
import datetime import datetime
import unittest
from collections import Counter from collections import Counter
from configparser import ConfigParser from configparser import ConfigParser
from decimal import Decimal from decimal import Decimal
@@ -75,15 +75,18 @@ IFRS_ACCOUNT_TYPE_AUDIT = {
IFRS_POLICY_COVERAGE = { IFRS_POLICY_COVERAGE = {
'NIC 1': {'11', '12', '21', '23', '3106', '7101', '7102'}, 'NIC 1': {'11', '12', '21', '23', '3106', '7101', '7102'},
'NIC 2': {'1103', '110305', '5101', '5106'}, 'NIC 2': {'1103', '110305', '5101', '5106'},
'NIIF 9': {'110205', '110701', '110702', '110703', '120701', 'NIIF 9': {
'120702', '120703', '4208', '6206', '310604'}, '110205', '110701', '110702', '110703', '120701', '120702',
'120703', '4208', '6206', '310604'},
'NIIF 15': {'110601', '210501', '4101', '4102', '4103', '4104'}, 'NIIF 15': {'110601', '210501', '4101', '4102', '4103', '4104'},
'NIIF 16': {'120501', '120591', '120592', '230201', '230202', 'NIIF 16': {
'6112', '6203'}, '120501', '120591', '120592', '230201', '230202', '6112',
'6203'},
'NIC 12': {'120601', '230301', '6301', '6302', '6303'}, 'NIC 12': {'120601', '230301', '6301', '6302', '6303'},
'NIC 16': {'120101', '120191', '120192', '6110', '6116'}, 'NIC 16': {'120101', '120191', '120192', '6110', '6116'},
'NIC 36': {'111002', '120192', '120292', '120392', '120592', 'NIC 36': {
'120892', '120992', '6116', '6117', '4206'}, '111002', '120192', '120292', '120392', '120592', '120892',
'120992', '6116', '6117', '4206'},
'NIC 37': {'220101', '230401', '6118', '4207'}, 'NIC 37': {'220101', '230401', '6118', '4207'},
'NIC 38': {'120901', '120991', '120992', '6111', '6117'}, 'NIC 38': {'120901', '120991', '120992', '6111', '6117'},
'NIC 40': {'120801', '120891', '120892', '4209', '6207'}, 'NIC 40': {'120801', '120891', '120892', '4209', '6207'},
@@ -198,7 +201,8 @@ class AccountDoTestCase(ModuleTestCase):
template_id = ModelData.get_id( template_id = ModelData.get_id(
'account_do', 'do_account_root_es_419') 'account_do', 'do_account_root_es_419')
except KeyError: except KeyError:
self.skipTest('The es_419 chart is loaded only for es_419 databases') self.skipTest(
'The es_419 chart is loaded only for es_419 databases')
template = AccountTemplate(template_id) template = AccountTemplate(template_id)
session_id, _start, _end = CreateChart.create() session_id, _start, _end = CreateChart.create()
@@ -358,12 +362,14 @@ class AccountDoTestCase(ModuleTestCase):
], limit=1)) ], limit=1))
self.assertTrue(Tax.search([ self.assertTrue(Tax.search([
('company', '=', company.id), ('company', '=', company.id),
('description', '=', 'ITBIS Withholding Large Taxpayer 30%'), ('description', '=',
'ITBIS Withholding Large Taxpayer 30%'),
('rate', '=', Decimal('-0.054')), ('rate', '=', Decimal('-0.054')),
], limit=1)) ], limit=1))
self.assertTrue(Tax.search([ self.assertTrue(Tax.search([
('company', '=', company.id), ('company', '=', company.id),
('description', '=', 'ITBIS Withholding Informal Supplier 75%'), ('description', '=',
'ITBIS Withholding Informal Supplier 75%'),
('rate', '=', Decimal('-0.135')), ('rate', '=', Decimal('-0.135')),
], limit=1)) ], limit=1))
check_015, = Tax.search([ check_015, = Tax.search([
@@ -434,7 +440,8 @@ class SpanishAccountDoTestCase(ModuleTestCase):
language = 'es_419' language = 'es_419'
test_spanish_chart_creates_spanish_accounts_and_taxes = ( test_spanish_chart_creates_spanish_accounts_and_taxes = (
AccountDoTestCase.test_spanish_chart_creates_spanish_accounts_and_taxes) AccountDoTestCase
.test_spanish_chart_creates_spanish_accounts_and_taxes)
@with_transaction() @with_transaction()
def test_migrate_pre_language_identifiers(self): def test_migrate_pre_language_identifiers(self):
@@ -609,7 +616,8 @@ class AccountDoUnitTestCase(unittest.TestCase):
with self.subTest(filename=filename): with self.subTest(filename=filename):
self.assertTrue(root.findall('data')) self.assertTrue(root.findall('data'))
self.assertEqual( self.assertEqual(
{data.get('language') for data in root.findall('data')}, {data.get('language')
for data in root.findall('data')},
{language}) {language})
def test_english_accounting_terminology_is_consistent(self): def test_english_accounting_terminology_is_consistent(self):
@@ -710,7 +718,8 @@ class AccountDoUnitTestCase(unittest.TestCase):
ref = field.get('ref') ref = field.get('ref')
if ref and '.' not in ref and ref not in ids: if ref and '.' not in ref and ref not in ids:
missing.append( missing.append(
(filename, record.get('id'), field.get('name'), ref)) (filename, record.get('id'),
field.get('name'), ref))
self.assertEqual(missing, []) self.assertEqual(missing, [])
def test_chart_template_codes_are_unique(self): def test_chart_template_codes_are_unique(self):
@@ -804,12 +813,14 @@ class AccountDoUnitTestCase(unittest.TestCase):
for _, record_id, _, _ in _iter_xml_records( for _, record_id, _, _ in _iter_xml_records(
'tax_do_en.xml', 'tax_code_do_en.xml') 'tax_do_en.xml', 'tax_code_do_en.xml')
} }
self.assertFalse([record_id for record_id in ids if 'otros' in record_id]) self.assertFalse([
record_id for record_id in ids if 'otros' in record_id])
def test_tax_templates_are_complete(self): def test_tax_templates_are_complete(self):
taxes = { taxes = {
record_id: values record_id: values
for _, record_id, model, values in _iter_xml_records('tax_do_en.xml') for _, record_id, model, values
in _iter_xml_records('tax_do_en.xml')
if model == 'account.tax.template' if model == 'account.tax.template'
} }
accounts = { accounts = {
@@ -853,6 +864,16 @@ class AccountDoUnitTestCase(unittest.TestCase):
self.assertIn( self.assertIn(
"Decimal('10')/100", "Decimal('10')/100",
taxes['do_tax_isc_bebidas_alc']['rate']) taxes['do_tax_isc_bebidas_alc']['rate'])
self.assertEqual(
taxes['do_tax_ret_isr_hon_5']['group'], 'do_tax_group_isr')
self.assertEqual(
taxes['do_tax_ret_isr_serv_10']['group'], 'do_tax_group_isr')
self.assertEqual(
taxes['do_tax_ret_isr_ext_27']['group'],
'do_tax_group_isr_ext')
self.assertEqual(
taxes['do_tax_ret_isr_ext_10']['group'],
'do_tax_group_isr_ext')
self.assertEqual( self.assertEqual(
taxes['do_tax_ret_isr_bovine_1']['start_date'], taxes['do_tax_ret_isr_bovine_1']['start_date'],
'datetime.date(2025, 6, 20)') 'datetime.date(2025, 6, 20)')
@@ -967,6 +988,9 @@ class AccountDoUnitTestCase(unittest.TestCase):
if model == 'account.tax.rule.line.template' if model == 'account.tax.rule.line.template'
} }
self.assertIn('do_tax_rule_bank_check_transfer', rules) self.assertIn('do_tax_rule_bank_check_transfer', rules)
self.assertEqual(
lines['do_trline_supp_ext_isr27']['group'],
'do_tax_group_isr_ext')
self.assertEqual( self.assertEqual(
lines['do_trline_bank_check_transfer_015']['origin_tax'], lines['do_trline_bank_check_transfer_015']['origin_tax'],
'do_tax_cheques_015') 'do_tax_cheques_015')
@@ -986,4 +1010,5 @@ class AccountDoUnitTestCase(unittest.TestCase):
lines['do_trline_bank_check_transfer_020']['start_date'], lines['do_trline_bank_check_transfer_020']['start_date'],
'datetime.date(2026, 7, 3)') 'datetime.date(2026, 7, 3)')
del ModuleTestCase del ModuleTestCase