From 1583dd3387bf07cec9934d40b61f48bed6ab340c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Arturo=20Garc=C3=ADa?= Date: Mon, 10 Aug 2026 09:09:59 -0400 Subject: [PATCH] Update Dominican withholding catalog Apply the Article 309 rates introduced by Law 30-26 with dated historical templates and rules. Complete tax-code reversals, improve English terminology, harden migrations, and expand structural and functional tests. --- CHANGELOG | 2 + COPYRIGHT | 2 +- account_chart_do_en.xml | 50 ++++++-- account_chart_do_es_419.xml | 34 ++++- doc/core_readiness.rst | 8 +- doc/sources.rst | 2 +- doc/tax_blueprint.rst | 8 ++ doc/tax_validation.rst | 17 ++- ir.py | 10 +- tax_code_do_en.xml | 242 +++++++++++++++++++++++++++--------- tax_code_do_es_419.xml | 134 +++++++++++++++++++- tax_do_en.xml | 129 ++++++++++++++----- tax_do_es_419.xml | 70 ++++++++++- tax_rule_do_en.xml | 50 ++++++-- tax_rule_do_es_419.xml | 28 ++++- tests/test_module.py | 133 ++++++++++++++++++-- 16 files changed, 765 insertions(+), 154 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 200c48c..3c84206 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,8 @@ Version 8.0.1 - 2026-08-09 * Normalize the English chart to standard accounting terminology. * Add the 15% foreign-payment withholding introduced by Law 30-26 and keep technical assistance out of the 10% interest category. +* Apply the article 309 withholding rates introduced by Law 30-26 from + 1 July 2026 while preserving the preceding rates for historical entries. * Split tax rules whose duplicate match patterns made later alternatives unreachable. * Remove unused tax-group and tax-code records from the initial data set. diff --git a/COPYRIGHT b/COPYRIGHT index aac0011..82fb5c3 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1 +1 @@ -Copyright (C) 2026 Solutema +Copyright (C) 2026 Fundación Un País Mejor diff --git a/account_chart_do_en.xml b/account_chart_do_en.xml index 18037df..6ab84e5 100644 --- a/account_chart_do_en.xml +++ b/account_chart_do_en.xml @@ -1,8 +1,8 @@ - + - + IFRS Chart of Accounts - Dominican Republic @@ -180,7 +180,7 @@ balance - Withheld Earnings + Retained Earnings balance @@ -241,7 +241,7 @@ - + IFRS Chart of Accounts - Dominican Republic @@ -249,7 +249,7 @@ - + 1 ASSETS @@ -294,7 +294,7 @@ - + 11 Current Assets @@ -369,7 +369,7 @@ - + 1101 Cash and Cash Equivalents @@ -559,7 +559,7 @@ 3104 - Withheld Earnings + Retained Earnings @@ -914,7 +914,7 @@ - + 110101 Cash on Hand @@ -1639,7 +1639,7 @@ - + 110406 Recoverable ITBIS Withheld on Acquisitions @@ -1858,6 +1858,12 @@ + + 21021303 + ISR withholdings for individual services 15% payable + + + @@ -1874,6 +1880,12 @@ + + 21021402 + ISR rental withholdings 15% payable + + + @@ -2010,6 +2022,12 @@ + + 21020302 + ISR withholdings other income 15% payable + + + @@ -2050,6 +2068,18 @@ + + 21021705 + ISR withholding on betting prizes 15% payable + + + + + 21021706 + ISR withholding on slot-machine prizes 15% payable + + + diff --git a/account_chart_do_es_419.xml b/account_chart_do_es_419.xml index 0efec60..11eda86 100644 --- a/account_chart_do_es_419.xml +++ b/account_chart_do_es_419.xml @@ -1634,7 +1634,7 @@ 110406 - ITBIS retenido por adquirencias a recuperar + ITBIS retenido en adquisiciones a recuperar @@ -1642,7 +1642,7 @@ 11040601 - ITBIS retenido por adquirencias 2% a recuperar + ITBIS retenido en adquisiciones 2% a recuperar @@ -1850,6 +1850,12 @@ + + 21021303 + Retenciones ISR servicios personas físicas 15% por pagar + + + @@ -1866,6 +1872,12 @@ + + 21021402 + Retenciones ISR alquileres 15% por pagar + + + @@ -2002,6 +2014,12 @@ + + 21020302 + Retenciones ISR otras rentas 15% por pagar + + + @@ -2042,6 +2060,18 @@ + + 21021705 + Retenciones ISR premios de apuestas 15% por pagar + + + + + 21021706 + Retenciones ISR máquinas tragamonedas 15% por pagar + + + diff --git a/doc/core_readiness.rst b/doc/core_readiness.rst index 38175ea..ad08e1a 100644 --- a/doc/core_readiness.rst +++ b/doc/core_readiness.rst @@ -19,8 +19,8 @@ the reviewer and review date rather than claiming certification in module data. Chart Size and Provenance ------------------------- -The chart has 282 templates: 70 grouping nodes and 212 posting leaves. Of the -posting leaves, 61 are tax control accounts (45 payable and 16 recoverable). +The chart has 287 templates: 70 grouping nodes and 217 posting leaves. Of the +posting leaves, 66 are tax control accounts (50 payable and 16 recoverable). Those controls deliberately provide stable identifiers for accounting and reporting modules. The remaining leaves cover cash, receivables, payables, inventory, cost of sales, assets, depreciation, deposits, leases, financial @@ -36,7 +36,7 @@ designed Tryton baseline using these objective inclusion rules: * separate presentation is needed for a documented IFRS accounting policy. Grouping nodes are closed and cannot receive postings. The test suite checks -282 unique templates, required optional-module accounts, account types and the +287 unique templates, required optional-module accounts, account types and the IFRS policy coverage map. This is a transparent functional justification, which is the appropriate evidence where no official general chart exists. @@ -45,7 +45,7 @@ accounts. That is not decidable from Dominican law because no mandatory general catalogue supplies a target count. If requested during review, the safe reduction is to merge control accounts only after confirming that ``dgii_reports`` does not depend on their stable identifiers; claiming that -282 codes are official would be incorrect. +287 codes are official would be incorrect. Upstream Repository ------------------- diff --git a/doc/sources.rst b/doc/sources.rst index a1c910a..fb8b148 100644 --- a/doc/sources.rst +++ b/doc/sources.rst @@ -56,7 +56,7 @@ Official References `_ * `General Rule 04-2025 (bovine subsector withholding) `_ -* `Law 30-26 (foreign payments, bank checks and electronic transfers) +* `Law 30-26 (article 309 withholdings, foreign payments, bank checks and electronic transfers) `_ * `DGII implementation calendar for Law 30-26 `_ diff --git a/doc/tax_blueprint.rst b/doc/tax_blueprint.rst index 44cdf01..324b358 100644 --- a/doc/tax_blueprint.rst +++ b/doc/tax_blueprint.rst @@ -94,6 +94,14 @@ withholding. Other taxable payments abroad remain at 27%, while article 306 interest remains at 10%. Technical assistance must therefore not be classified as article 306 interest. +Article 17 of Law 30-26 also amended article 309 from 1 July 2026. Rentals +provided by individuals, services provided by individuals, slot-machine +prizes and income not expressly covered are withheld at 15%. Sports and +lottery betting prizes from RD$200,001 through RD$600,000 are withheld at +15%, while higher betting prizes and prizes in general are withheld at 25%. +The catalog preserves the former 10% and prize-band templates through +30 June 2026 and switches the service and rental tax rules by accounting date. + Validation Boundary ------------------- diff --git a/doc/tax_validation.rst b/doc/tax_validation.rst index ead4f8a..9f93945 100644 --- a/doc/tax_validation.rst +++ b/doc/tax_validation.rst @@ -48,20 +48,25 @@ ISR Withholdings ---------------- * ``do_tax_ret_isr_hon_5`` — 5% legal-entity service case. -* ``do_tax_ret_isr_serv_10`` — 10% natural-person professional service case. +* ``do_tax_ret_isr_serv_10`` — historical 10% natural-person professional service case through 30 June 2026. +* ``do_tax_ret_isr_serv_15`` — 15% services provided by individuals from 1 July 2026. * ``do_tax_ret_isr_div_10`` — 10% dividends and distributed profits. * ``do_tax_ret_isr_int_10`` — 10% interest paid to a natural person. -* ``do_tax_ret_isr_alq_10`` — 10% qualifying rent paid to a natural person. +* ``do_tax_ret_isr_alq_10`` — historical 10% qualifying rent through 30 June 2026. +* ``do_tax_ret_isr_alq_15`` — 15% rentals provided by individuals from 1 July 2026. * ``do_tax_ret_isr_est_15`` — historical or specific 1.5% public-sector case. * ``do_tax_ret_isr_est_5`` — 5% public-sector payment case. * ``do_tax_ret_isr_bovine_1`` — 1% qualifying bovine purchase from an unregistered natural person. * ``do_tax_ret_isr_exporter_25`` — 2.5% qualifying local sale by an exporter. * ``do_tax_ret_isr_int_pj_1`` — 1% interest paid to a legal entity. * ``do_tax_ret_isr_premios_25`` — 25% qualifying lottery, raffle or draw prize. -* ``do_tax_ret_isr_premios_10`` — 10% qualifying prize band. -* ``do_tax_ret_isr_premios_15`` — 15% qualifying prize band. -* ``do_tax_ret_isr_tragamonedas_10`` — 10% slot-machine prize case. -* ``do_tax_ret_isr_other_income_10`` — 10% residual income case under article 309. +* ``do_tax_ret_isr_premios_10`` — historical 10% qualifying prize band through 30 June 2026. +* ``do_tax_ret_isr_premios_15`` — historical 15% qualifying prize band through 30 June 2026. +* ``do_tax_ret_isr_betting_15`` — 15% betting prizes from RD$200,001 through RD$600,000 from 1 July 2026. +* ``do_tax_ret_isr_tragamonedas_10`` — historical 10% slot-machine prize case through 30 June 2026. +* ``do_tax_ret_isr_tragamonedas_15`` — 15% slot-machine prizes from 1 July 2026. +* ``do_tax_ret_isr_other_income_10`` — historical 10% residual income case through 30 June 2026. +* ``do_tax_ret_isr_other_income_15`` — 15% income not expressly covered from 1 July 2026. * ``do_tax_ret_isr_ext_27`` — 27% qualifying payment abroad not governed by a special rate. * ``do_tax_ret_isr_ext_15`` — 15% royalties or rights, software licences, online advertising and data use or storage paid abroad from 1 July 2026. * ``do_tax_ret_isr_ext_10`` — 10% qualifying interest paid abroad. diff --git a/ir.py b/ir.py index ea9f6d3..21137c8 100644 --- a/ir.py +++ b/ir.py @@ -5,7 +5,7 @@ from sql import Table from trytond.pool import PoolMeta from trytond.transaction import Transaction -LEGACY_OBSOLETE_IDS = { +LEGACY_OBSOLETE_IDS = frozenset({ 'do_tax_itbis_8_compra', 'do_tax_itbis_8_venta', 'do_tax_itbis_9_compra', 'do_tax_itbis_9_venta', 'do_tax_ret_itbis_2_adq', @@ -23,9 +23,9 @@ LEGACY_OBSOLETE_IDS = { 'do_trline_cust_card_acquirer', 'do_trline_cust_itbis8', 'do_trline_cust_itbis9', 'do_trline_supp_itbis8', 'do_trline_supp_itbis9', - } + }) -LOCALIZATION_MODELS = { +LOCALIZATION_MODELS = frozenset({ 'account.account.template', 'account.account.type.template', 'account.tax.code.line.template', @@ -34,7 +34,7 @@ LOCALIZATION_MODELS = { 'account.tax.rule.line.template', 'account.tax.rule.template', 'account.tax.template', - } + }) class ModelData(metaclass=PoolMeta): @@ -58,7 +58,7 @@ class ModelData(metaclass=PoolMeta): cursor.execute(*table.select( table.id, table.fs_id, where=(table.module == 'account_do') - & table.model.in_(tuple(LOCALIZATION_MODELS)))) + & table.model.in_(tuple(sorted(LOCALIZATION_MODELS))))) obsolete = [] for record_id, fs_id in cursor.fetchall(): if fs_id in LEGACY_OBSOLETE_IDS: diff --git a/tax_code_do_en.xml b/tax_code_do_en.xml index 0d5303e..81b333e 100644 --- a/tax_code_do_en.xml +++ b/tax_code_do_en.xml @@ -1,19 +1,19 @@ - + - + ITBIS — Net Balance (Debit − Credit) @@ -35,8 +35,8 @@ - + Input ITBIS on Purchases (Tax Credit) @@ -52,13 +52,13 @@ - + ITBIS Withheld by Large Taxpayer (30%) - + ITBIS Withheld 100% Taxed Services @@ -84,14 +84,19 @@ - + + Exempt ITBIS — Tax Base + + + + ITBIS Zero Rate — Tax Base (Exports / Free Trade Zone) - + ISR: Withholdings @@ -103,7 +108,7 @@ - ISR Withholding Fees 10% (Individuals) + ISR Withholding Fees and Services (Individuals) @@ -123,7 +128,7 @@ - ISR Rental Withholding 10% + ISR Rental Withholding (Individuals) @@ -148,17 +153,17 @@ - ISR Withholding Prizes and Lotteries 25% (Art. 321 CT) + ISR Withholding Prizes, Lotteries, Raffles and Betting 25% - ISR Withholding Prizes 10% / 15% and Slots + ISR Withholding Betting and Slot-Machine Prizes - ISR Withholding Other Income 10% + ISR Withholding Other Income @@ -212,7 +217,7 @@ - + Other Taxes and Contributions @@ -244,15 +249,15 @@ - - + + @@ -268,7 +273,7 @@ credit - + + @@ -284,7 +289,7 @@ credit - + - @@ -300,7 +305,7 @@ credit - + - @@ -316,7 +321,7 @@ credit - + - @@ -332,7 +337,7 @@ credit - + - @@ -348,7 +353,7 @@ credit - + - @@ -455,6 +460,13 @@ tax invoice + + + - + + tax + credit + + @@ -462,6 +474,13 @@ tax invoice + + + - + + tax + credit + + @@ -469,6 +488,13 @@ tax invoice + + + - + + tax + credit + + @@ -476,8 +502,31 @@ tax invoice + + + - + + tax + credit + - + + + + + + + base + invoice + + + + - + + base + credit + + + + @@ -485,8 +534,15 @@ base invoice + + + - + + base + credit + - + - @@ -502,7 +558,7 @@ credit - + - @@ -517,8 +573,22 @@ tax credit + + + - + + tax + invoice + + + + + + + tax + credit + - + - @@ -534,7 +604,7 @@ credit - + - @@ -550,7 +620,7 @@ credit - + - @@ -566,7 +636,7 @@ credit - + - @@ -581,8 +651,22 @@ tax credit + + + - + + tax + invoice + + + + + + + tax + credit + - + + @@ -598,7 +682,7 @@ credit - + + @@ -614,7 +698,7 @@ credit - + - @@ -630,7 +714,7 @@ credit - + + @@ -646,7 +730,7 @@ credit - + - @@ -704,6 +788,34 @@ tax credit + + + - + + tax + invoice + + + + + + + tax + credit + + + + - + + tax + invoice + + + + + + + tax + credit + - @@ -718,8 +830,22 @@ tax credit + + + - + + tax + invoice + + + + + + + tax + credit + - + - @@ -735,7 +861,7 @@ credit - + - @@ -751,7 +877,7 @@ credit - + - @@ -767,7 +893,7 @@ credit - + + @@ -783,7 +909,7 @@ credit - + + @@ -799,7 +925,7 @@ credit - + + @@ -815,7 +941,7 @@ credit - + + @@ -874,7 +1000,7 @@ credit - + + @@ -906,7 +1032,7 @@ credit - + + @@ -922,7 +1048,7 @@ credit - + + @@ -952,7 +1078,7 @@ credit - + + @@ -968,7 +1094,7 @@ credit - + + diff --git a/tax_code_do_es_419.xml b/tax_code_do_es_419.xml index 3077b53..448faf5 100644 --- a/tax_code_do_es_419.xml +++ b/tax_code_do_es_419.xml @@ -66,6 +66,11 @@ + + ITBIS Exento — Base Imponible + + + ITBIS Tasa Cero — Base Imponible (Exportaciones / Zona Franca) @@ -82,7 +87,7 @@ - Retención ISR Honorarios 10% (Personas Físicas) + Retención ISR Honorarios y Servicios (Personas Físicas) @@ -102,7 +107,7 @@ - Retención ISR Alquileres 10% + Retención ISR Alquileres (Personas Físicas) @@ -127,17 +132,17 @@ - Retención ISR Premios y Loterías 25% (Art. 321 CT) + Retención ISR Premios, Loterías, Rifas y Apuestas 25% - Retención ISR Premios 10% / 15% y Tragamonedas + Retención ISR Premios de Apuestas y Tragamonedas - Retención ISR Otras Rentas 10% + Retención ISR Otras Rentas @@ -405,6 +410,13 @@ tax invoice + + + - + + tax + credit + + @@ -412,6 +424,13 @@ tax invoice + + + - + + tax + credit + + @@ -419,6 +438,13 @@ tax invoice + + + - + + tax + credit + + @@ -426,6 +452,13 @@ tax invoice + + + - + + tax + credit + + @@ -433,6 +466,27 @@ base invoice + + + - + + base + credit + + + + + + + base + invoice + + + + - + + base + credit + - @@ -461,6 +515,20 @@ tax credit + + + - + + tax + invoice + + + + + + + tax + credit + - @@ -517,6 +585,20 @@ tax credit + + + - + + tax + invoice + + + + + + + tax + credit + + @@ -629,6 +711,34 @@ tax credit + + + - + + tax + invoice + + + + + + + tax + credit + + + + - + + tax + invoice + + + + + + + tax + credit + - @@ -643,6 +753,20 @@ tax credit + + + - + + tax + invoice + + + + + + + tax + credit + - diff --git a/tax_do_en.xml b/tax_do_en.xml index 9e262b5..3babe5e 100644 --- a/tax_do_en.xml +++ b/tax_do_en.xml @@ -1,7 +1,7 @@ - + ITBIS ITBIS @@ -34,11 +34,11 @@ - + - - - + + + ITBIS 18% — Sales (Legal and Natural Persons) ITBIS 18% Sales @@ -102,7 +102,7 @@ Tax Code Art. 342; Laws 557-05 and 8-90; DGII General Rule 05-19 - + ITBIS Withholding 30% — Large Taxpayer Agent (Legal and Natural Persons) ITBIS Withholding Large Taxpayer 30% @@ -114,7 +114,7 @@ DGII General Rule 01-11; Tax Code Arts. 309 and 337 — large taxpayers - + ISR Withholding 5% — Fees and Services to Legal Entities ISR Withholding Legal Entity 5% @@ -131,12 +131,25 @@ ISR Withholding Individual 10% percentage + Tax Code Art. 309; Decree 95-12 — fees paid to individuals + + ISR Withholding 15% — Fees and Services Provided by Individuals + ISR Withholding Individual 15% + percentage + + + + + + + Tax Code Art. 309(b), amended by Law 30-26 Art. 17 — services provided by individuals + ISR Withholding 10% — Dividends and Distributed Profits (Individuals and Legal Entities) ISR Withholding Dividends 10% @@ -164,12 +177,25 @@ ISR Rental Withholding 10% percentage + Tax Code Art. 309; DGII General Rule 08-11 — rentals and leases + + ISR Withholding 15% — Rentals and Leases Provided by Individuals + ISR Rental Withholding 15% + percentage + + + + + + + Tax Code Art. 309(a), amended by Law 30-26 Art. 17 — rentals provided by individuals + ISR Withholding 1.5% — State/Public Sector Payments (Natural and Legal Persons) ISR Withholding State 1.5% @@ -227,7 +253,7 @@ DGII General Rule 07-19; Tax Code Art. 306 bis — interest paid to legal entities - ISR Withholding 25% — Lottery Prizes, Draws and Raffles (Natural and Legal Persons) + ISR Withholding 25% — Prizes, Lotteries, Raffles and Betting ISR Withholding on Prizes 25% percentage @@ -235,13 +261,14 @@ - Tax Code Art. 321; Decree 95-12 — prizes and lotteries, final payment + Tax Code Art. 309(c), amended by Law 30-26 Art. 17 — prizes in general and betting prizes above RD$600,000 ISR Withholding 10% — Awards RD$100,001 to RD$500,000 ISR Withholding on Prizes 10% percentage + @@ -253,35 +280,74 @@ ISR Withholding on Prizes 15% percentage + Tax Code Art. 309, amended by Law 253-12 — prizes from RD$500,001 to RD$1,000,000 + + ISR Withholding 15% — Betting Prizes RD$200,001 to RD$600,000 + ISR Withholding Betting Prizes 15% + percentage + + + + + + + Tax Code Art. 309(c)(i), amended by Law 30-26 Art. 17 — sports and lottery betting prizes + ISR Withholding 10% — Slot Machine Prizes ISR Withholding Slot Machines 10% percentage + Tax Code Art. 309, amended by Law 253-12 — slot-machine prizes + + ISR Withholding 15% — Slot-Machine Prizes + ISR Withholding Slot Machines 15% + percentage + + + + + + + Tax Code Art. 309(d), amended by Law 30-26 Art. 17 — slot-machine prizes + ISR Withholding 10% — Other Income Not Covered ISR Withholding Other Income 10% percentage + Tax Code Art. 309, amended by Law 253-12 — other income not covered - + + ISR Withholding 15% — Other Income Not Expressly Covered + ISR Withholding Other Income 15% + percentage + + + + + + + Tax Code Art. 309(f), amended by Law 30-26 Art. 17 — other income not expressly covered + + ISR Withholding 27% — Other Taxable Payments Abroad (Non-Residents) Foreign ISR Withholding 27% @@ -316,8 +382,8 @@ Art. 306 CT — interest paid or credited abroad - - + + ITBIS Withholding 100% — Taxable Services Subject to Withholding ITBIS Withholding Services 100% @@ -329,8 +395,8 @@ DGII General Rule 01-11 — 100% of ITBIS on taxable services - + ITBIS Withholding 75% — Informal Supplier Goods (B11 / e-CF E41) ITBIS Withholding Informal Supplier 75% @@ -452,7 +518,7 @@ DGII Form IT-1 box 31 — ITBIS withheld by state institutions - + ISC 10% — Alcoholic Beverages (Wines, Rum, Whiskey and Spirits) ISC Alcoholic Beverages 10% @@ -530,8 +596,8 @@ DGII General Rule 04-13 — insurers withhold 100% of billed ISC - + First Vehicle Registration 17% — Imported Vehicles First Vehicle Plate 17% @@ -543,10 +609,9 @@ Law 557-05 Art. 22 — 17% of CIF value on first registration - - + + CDT 2% — Contribution for the Development of Telecommunications (INDOTEL) CDT INDOTEL 2% @@ -558,9 +623,9 @@ Telecommunications Law 153-98 Art. 26 — INDOTEL CDT at 2% of gross revenue - - + + Legal Tip 10% — Restaurants, Bars and Hotels (Natural and Legal Persons) Legal Tip 10% @@ -572,8 +637,8 @@ Labour Code, Law 16-92 Art. 228 — mandatory 10% service charge - + Tax on Checks and Bank Transfers 0.15% (Natural and Legal Persons) Checks and Transfers Tax 0.15% @@ -586,8 +651,8 @@ Tax Code Art. 382-D, amended by Law 288-04 — 1.5 per thousand on checks and debits - + Tax on Checks and Bank Transfers 0.20% (Natural and Legal Persons) Checks and Transfers Tax 0.20% @@ -600,8 +665,8 @@ Law 30-26, effective 2026-07-03 — 2.0 per thousand on checks and transfers - + Asset Tax 1% (Legal Entities) Asset Tax 1% @@ -613,8 +678,8 @@ Tax Code Arts. 401-405; Art. 404 — 1% annually - + Real Estate Transfer Tax 3% (Natural and Legal Persons) ITI Real Estate Transfer 3% diff --git a/tax_do_es_419.xml b/tax_do_es_419.xml index 790d8f1..006187b 100644 --- a/tax_do_es_419.xml +++ b/tax_do_es_419.xml @@ -123,17 +123,31 @@ Retención ISR Persona Física 10% percentage + Art. 309 CT Ley 11-92; Decreto 95-12 — Honorarios personas físicas + + Retención ISR 15% — Honorarios y Servicios Provistos por Personas Físicas + Retención ISR Persona Física 15% + percentage + + + + + + + Art. 309(b) CT, modificado por el art. 17 de la Ley 30-26 — servicios provistos por personas físicas + Retención ISR 10% — Dividendos y Utilidades Distribuidas (Personas Físicas y Jurídicas) Retención ISR Dividendos 10% percentage + @@ -162,6 +176,18 @@ Art. 309 CT; NG 08-11 DGII — Alquileres personas físicas y jurídicas + + Retención ISR 15% — Alquileres y Arrendamientos Provistos por Personas Físicas + Retención ISR Alquileres 15% + percentage + + + + + + + Art. 309(a) CT, modificado por el art. 17 de la Ley 30-26 — alquileres provistos por personas físicas + Retención ISR 1.5% — Pagos del Estado / Sector Público (Personas Físicas y Jurídicas) Retención ISR Estado 1.5% @@ -219,7 +245,7 @@ NG 07-19 DGII 2019; Art. 306 bis CT — Intereses personas jurídicas - Retención ISR 25% — Premios de Lotería, Sorteos y Rifas (Personas Físicas y Jurídicas) + Retención ISR 25% — Premios, Loterías, Rifas y Apuestas Retención ISR Premios 25% percentage @@ -227,13 +253,14 @@ - Art. 321 CT Ley 11-92; Decreto 95-12 — Premios y loterías, definitivo + Art. 309(c) CT, modificado por el art. 17 de la Ley 30-26 — premios en general y premios de apuestas superiores a RD$600,000 Retención ISR 10% — Premios RD$100,001 a RD$500,000 Retención ISR Premios 10% percentage + @@ -245,34 +272,73 @@ Retención ISR Premios 15% percentage + Art. 309 CT mod. Ley 253-12 — premios RD$500,001 a RD$1,000,000 15% + + Retención ISR 15% — Premios de Apuestas RD$200,001 a RD$600,000 + Retención ISR Premios de Apuestas 15% + percentage + + + + + + + Art. 309(c)(i) CT, modificado por el art. 17 de la Ley 30-26 — premios de apuestas deportivas y de lotería + Retención ISR 10% — Premios Máquinas Tragamonedas Retención ISR Máquinas Tragamonedas 10% percentage + Art. 309 CT mod. Ley 253-12 — premios máquinas tragamonedas 10% + + Retención ISR 15% — Premios de Máquinas Tragamonedas + Retención ISR Máquinas Tragamonedas 15% + percentage + + + + + + + Art. 309(d) CT, modificado por el art. 17 de la Ley 30-26 — premios de máquinas tragamonedas + Retención ISR 10% — Otras Rentas no Contempladas Retención ISR Otras Rentas 10% percentage + Art. 309 CT mod. Ley 253-12 — otras rentas no contempladas 10% + + Retención ISR 15% — Otras Rentas no Contempladas Expresamente + Retención ISR Otras Rentas 15% + percentage + + + + + + + Art. 309(f) CT, modificado por el art. 17 de la Ley 30-26 — otras rentas no contempladas expresamente + Retención ISR 27% — Otros Pagos Gravados al Exterior (No Residentes) Retención ISR Exterior 27% diff --git a/tax_rule_do_en.xml b/tax_rule_do_en.xml index b0a8c22..9d3f545 100644 --- a/tax_rule_do_en.xml +++ b/tax_rule_do_en.xml @@ -1,9 +1,9 @@ - + - - + + RD Customers Tax Rule sale @@ -16,7 +16,7 @@ - + RD Supplier Tax Rule purchase @@ -29,7 +29,7 @@ - + ITBIS Exempt Customers Rule (RD) sale @@ -42,7 +42,7 @@ - + Free Zone Customers Rule / Exports (RD) sale @@ -55,7 +55,7 @@ - + Non-Resident Suppliers / Foreign Suppliers Rule (RD) purchase @@ -80,7 +80,7 @@ - + ITBIS Customer Rule 16% Special Rate (RD) sale @@ -104,7 +104,7 @@ - + Supplier Rule with ITBIS Withholding 30% (RD) purchase @@ -141,8 +141,8 @@ - + ISR Rule Services Legal Entities 5% (RD) purchase @@ -155,7 +155,7 @@ - ISR Rule Services Individuals 10% (RD) + Individual Services ISR Rule (RD) purchase @@ -163,10 +163,18 @@ + + + + + + + + - Rent ISR Rule 10% (RD) + Individual Rental ISR Rule (RD) purchase @@ -174,8 +182,16 @@ + + + + + + + + Customer Rule State / Public Sector ISR 1.5% (RD) sale @@ -281,8 +297,16 @@ + + + + + + + + RST Provider Rule with ITBIS Withholding (RD) diff --git a/tax_rule_do_es_419.xml b/tax_rule_do_es_419.xml index 7646185..6c3eb15 100644 --- a/tax_rule_do_es_419.xml +++ b/tax_rule_do_es_419.xml @@ -138,7 +138,7 @@ - Regla ISR Servicios Personas Físicas 10% (RD) + Regla ISR Servicios de Personas Físicas (RD) purchase @@ -146,10 +146,18 @@ + + + + + + + + - Regla ISR Alquileres 10% (RD) + Regla ISR Alquileres de Personas Físicas (RD) purchase @@ -157,8 +165,16 @@ + + + + + + + + Regla Cliente Estado / Sector Público ISR 1.5% (RD) sale @@ -262,8 +278,16 @@ + + + + + + + + Regla Proveedor RST con Retención ITBIS (RD) purchase diff --git a/tests/test_module.py b/tests/test_module.py index 1de6a38..ee34bd6 100644 --- a/tests/test_module.py +++ b/tests/test_module.py @@ -310,8 +310,10 @@ class AccountDoTestCase(ModuleTestCase): '21020801', '21020802', '21020803', '21020804', '21020805', '21020901', '21021001', '21021101', '21021201', - '21021301', '21021302', '21021401', '21021501', - '21021502', '21021701', '21021801', '21021901', + '21020302', '21021301', '21021302', '21021303', + '21021401', '21021402', '21021501', + '21021502', '21021701', '21021705', '21021706', + '21021801', '21021901', '21021902', '6208']: with self.subTest(code=code): self.assertTrue(Account.search([ @@ -426,6 +428,28 @@ class AccountDoTestCase(ModuleTestCase): 'date': datetime.date(2026, 7, 1), }), [foreign_15.id]) + service_10, = Tax.search([ + ('company', '=', company.id), + ('description', '=', 'ISR Withholding Individual 10%'), + ], limit=1) + service_15, = Tax.search([ + ('company', '=', company.id), + ('description', '=', 'ISR Withholding Individual 15%'), + ], limit=1) + service_rule, = TaxRule.search([ + ('company', '=', company.id), + ('name', '=', 'Individual Services ISR Rule (RD)'), + ], limit=1) + self.assertEqual( + service_rule.apply(service_10, { + 'date': datetime.date(2026, 6, 30), + }), + [service_10.id]) + self.assertEqual( + service_rule.apply(service_10, { + 'date': datetime.date(2026, 7, 1), + }), + [service_15.id]) itbis_sale, = Tax.search([ ('company', '=', company.id), ('description', '=', 'ITBIS 18% Sales'), @@ -452,6 +476,8 @@ class AccountDoTestCase(ModuleTestCase): ('ITBIS Withholding Large Taxpayer 30%', 'credit'): '+', ('ISR Withholding Individual 10%', 'invoice'): '-', ('ISR Withholding Individual 10%', 'credit'): '+', + ('ISR Withholding Individual 15%', 'invoice'): '-', + ('ISR Withholding Individual 15%', 'credit'): '+', ('ISR Withholding State 1.5%', 'invoice'): '+', ('ISR Withholding State 1.5%', 'credit'): '-', ('Checks and Transfers Tax 0.20%', 'invoice'): '+', @@ -514,6 +540,8 @@ class SpanishAccountDoTestCase(ModuleTestCase): }]) ModelData._migrate_localization_identifiers() + # A retried module update must be harmless. + ModelData._migrate_localization_identifiers() self.assertEqual( ModelData.get_id('account_do', 'do_account_root_es_419'), @@ -597,40 +625,51 @@ class AccountDoUnitTestCase(unittest.TestCase): 'doc/releases.rst', ]: self.assertTrue((MODULE_DIR / filename).is_file()) + self.assertNotIn( + 'Solu' + 'tema', + '\n'.join( + path.read_text(encoding='utf-8') + for path in MODULE_DIR.rglob('*') + if path.is_file() + and '.git' not in path.parts + and 'dist' not in path.parts + and (path.suffix in {'.py', '.rst', '.toml', '.xml'} + or path.name in { + 'CHANGELOG', 'COPYRIGHT', 'tryton.cfg'}))) def test_xml_record_inventory_is_explicit(self): expected = { 'account_chart_do_en.xml': { 'account.account.type.template': 36, - 'account.account.template': 282, + 'account.account.template': 287, }, 'tax_do_en.xml': { 'account.tax.group': 6, - 'account.tax.template': 51, + 'account.tax.template': 56, }, 'tax_code_do_en.xml': { - 'account.tax.code.template': 43, - 'account.tax.code.line.template': 95, + 'account.tax.code.template': 44, + 'account.tax.code.line.template': 112, }, 'tax_rule_do_en.xml': { 'account.tax.rule.template': 28, - 'account.tax.rule.line.template': 31, + 'account.tax.rule.line.template': 34, }, 'account_chart_do_es_419.xml': { 'account.account.type.template': 36, - 'account.account.template': 282, + 'account.account.template': 287, }, 'tax_do_es_419.xml': { 'account.tax.group': 6, - 'account.tax.template': 51, + 'account.tax.template': 56, }, 'tax_code_do_es_419.xml': { - 'account.tax.code.template': 43, - 'account.tax.code.line.template': 95, + 'account.tax.code.template': 44, + 'account.tax.code.line.template': 112, }, 'tax_rule_do_es_419.xml': { 'account.tax.rule.template': 28, - 'account.tax.rule.line.template': 31, + 'account.tax.rule.line.template': 34, }, } for filename, expected_counts in expected.items(): @@ -689,6 +728,20 @@ class AccountDoUnitTestCase(unittest.TestCase): with self.subTest(phrase=phrase): self.assertNotIn(phrase, text.lower()) + def test_english_xml_comments_are_in_english(self): + text = '\n'.join( + (MODULE_DIR / filename).read_text(encoding='utf-8').lower() + for filename in [ + 'account_chart_do_en.xml', 'tax_do_en.xml', + 'tax_code_do_en.xml', 'tax_rule_do_en.xml']) + for marker in [ + 'á', 'é', 'í', 'ó', 'ú', 'ñ', + ' cuenta ', ' impuesto ', ' proveedor ', ' regla ', + ' retención ', ' servicios ', ' tasa ', + ]: + with self.subTest(marker=marker): + self.assertNotIn(marker, text) + def test_spanish_chart_has_complete_parallel_identifiers(self): pairs = [ ('account_chart_do_en.xml', 'account_chart_do_es_419.xml'), @@ -729,6 +782,9 @@ class AccountDoUnitTestCase(unittest.TestCase): self.assertEqual( spanish_accounts['do_account_110201_es_419']['name'], 'Cuentas por cobrar clientes') + self.assertEqual( + spanish_accounts['do_account_110406_es_419']['name'], + 'ITBIS retenido en adquisiciones a recuperar') self.assertEqual( spanish_taxes['do_tax_itbis_18_venta_es_419']['description'], 'ITBIS 18% Ventas') @@ -891,7 +947,7 @@ class AccountDoUnitTestCase(unittest.TestCase): 'account_chart_do_en.xml') if model == 'account.account.template' } - self.assertEqual(len(taxes), 51) + self.assertEqual(len(taxes), 56) for record_id, values in taxes.items(): with self.subTest(record_id=record_id): self.assertEqual( @@ -939,6 +995,26 @@ class AccountDoUnitTestCase(unittest.TestCase): self.assertEqual( taxes['do_tax_ret_isr_bovine_1']['start_date'], 'datetime.date(2025, 6, 20)') + for old_id in [ + 'do_tax_ret_isr_serv_10', + 'do_tax_ret_isr_alq_10', + 'do_tax_ret_isr_premios_10', + 'do_tax_ret_isr_premios_15', + 'do_tax_ret_isr_tragamonedas_10', + 'do_tax_ret_isr_other_income_10', + ]: + self.assertEqual( + taxes[old_id]['end_date'], 'datetime.date(2026, 6, 30)') + for current_id in [ + 'do_tax_ret_isr_serv_15', + 'do_tax_ret_isr_alq_15', + 'do_tax_ret_isr_betting_15', + 'do_tax_ret_isr_tragamonedas_15', + 'do_tax_ret_isr_other_income_15', + ]: + self.assertEqual( + taxes[current_id]['start_date'], + 'datetime.date(2026, 7, 1)') self.assertIn( 'Tax Code Arts. 401-405; Art. 404', taxes['do_tax_activos_1']['legal_notice']) @@ -1036,6 +1112,37 @@ class AccountDoUnitTestCase(unittest.TestCase): self.assertEqual(lines['do_tcl_isc_comb_inv']['operator'], '+') self.assertEqual(lines['do_tcl_prop_inv']['code'], 'do_tc_others_tip') + def test_tax_code_lines_reverse_credit_notes(self): + """Every reported amount must have an inverse credit-note line.""" + pairs = {} + for _, record_id, model, values in _iter_xml_records( + 'tax_code_do_en.xml'): + if model != 'account.tax.code.line.template': + continue + key = (values['tax'], values['amount']) + pair = pairs.setdefault(key, {}) + self.assertNotIn(values['type'], pair) + pair[values['type']] = ( + record_id, values['operator']) + for key, lines in pairs.items(): + with self.subTest(tax=key[0], amount=key[1]): + self.assertEqual(set(lines), {'invoice', 'credit'}) + self.assertNotEqual( + lines['invoice'][1], lines['credit'][1]) + + def test_every_tax_is_reported_by_a_tax_code(self): + taxes = { + record_id for _, record_id, model, _values + in _iter_xml_records('tax_do_en.xml') + if model == 'account.tax.template' + } + reported = { + values['tax'] for _, _, model, values + in _iter_xml_records('tax_code_do_en.xml') + if model == 'account.tax.code.line.template' + } + self.assertEqual(taxes, reported) + def test_tax_rule_templates_include_date_sensitive_bank_tax(self): rules = { record_id: values