Strengthen account_do tests and publishing checks
Add static coverage for module configuration, XML inventory, tax views, translations, migration metadata, and the Gitea publishing workflow. Make Gitea Actions run install, compileall, unittest, build, and twine check before publishing packages from series branches. Fix packaging documentation and RST rendering issues so package validation passes before upload.
This commit is contained in:
@@ -1,14 +1,53 @@
|
|||||||
name: Publish Package
|
name: Test and Publish Package
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "**"
|
- "**"
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- "**"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.11"
|
||||||
|
|
||||||
|
- name: Install package and test dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
python -m pip install -e '.[test]'
|
||||||
|
|
||||||
|
- name: Compile Python sources
|
||||||
|
run: |
|
||||||
|
python -m compileall .
|
||||||
|
|
||||||
|
- name: Run module tests
|
||||||
|
run: |
|
||||||
|
python -m unittest discover -s tests -p 'test*.py'
|
||||||
|
|
||||||
|
- name: Build package
|
||||||
|
run: |
|
||||||
|
python -m pip install build twine
|
||||||
|
python -m build
|
||||||
|
|
||||||
|
- name: Check package
|
||||||
|
run: |
|
||||||
|
python -m twine check dist/*
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
needs: test
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
|||||||
+31
-13
@@ -23,7 +23,7 @@ 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
|
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.
|
``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.
|
||||||
|
|
||||||
@@ -49,15 +49,33 @@ Matriz de auditoría
|
|||||||
|
|
||||||
La cobertura de auditoría fiscal queda formalizada en pruebas para evitar cambios silenciosos en cuentas, clasificación o vigencias.
|
La cobertura de auditoría fiscal queda formalizada en pruebas para evitar cambios silenciosos en cuentas, clasificación o vigencias.
|
||||||
|
|
||||||
=============================== =============================================== ==============================================
|
.. list-table::
|
||||||
Área Cobertura Prueba
|
:header-rows: 1
|
||||||
=============================== =============================================== ==============================================
|
|
||||||
Impuesto contra cuenta 55 plantillas de ``tax_do.xml`` contra cuenta ``account_do.tests.test_module.TAX_TEMPLATE_AUDIT``
|
* - Área
|
||||||
Clasificación fiscal ``tax_kind``, ``tax_fiscal_type`` y aplicación ``test_tax_templates_are_classified``
|
- Cobertura
|
||||||
Metadata legal y vigencia Referencia, artículo, formulario, estado y fecha ``test_tax_templates_are_classified``
|
- Prueba
|
||||||
Signos de tax codes Plantillas y códigos reales creados por compañía ``test_tax_code_templates_use_expected_signs`` y chart real
|
* - Impuesto contra cuenta
|
||||||
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``
|
- 55 plantillas de ``tax_do.xml`` contra cuenta.
|
||||||
Documentación contra XML La matriz apunta a XML real y falla ante ids/campos faltantes ``test_xml_references_are_resolved_inside_module``
|
- ``account_do.tests.test_module.TAX_TEMPLATE_AUDIT``
|
||||||
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``
|
* - Clasificación fiscal
|
||||||
Facturas reales Factura venta/compra posteada con ITBIS 18% ``account_invoice_do.tests.test_module``
|
- ``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``
|
||||||
|
|||||||
+12
-11
@@ -1,29 +1,30 @@
|
|||||||
Publishing
|
Publishing
|
||||||
==========
|
==========
|
||||||
|
|
||||||
Every pushed commit builds, validates, and publishes the package to the Gitea
|
Every pushed commit installs the package, compiles the Python sources, runs the
|
||||||
PyPI-compatible package registry. The workflow intentionally does not use
|
module tests, builds the distribution, and validates it with ``twine check``.
|
||||||
``actions/upload-artifact`` because current Gitea Actions runners do not support
|
Only branches named with the Tryton series, such as ``8.0``, continue to the
|
||||||
the GitHub artifact API required by ``upload-artifact@v4``.
|
publishing step after those checks pass.
|
||||||
|
|
||||||
The publishing workflow creates a CI-only package version by appending the run
|
The publishing workflow creates a CI-only package version by reading the
|
||||||
number to the module version from ``tryton.cfg``. For example, a module version
|
published versions in Gitea's PyPI-compatible package registry and assigning the
|
||||||
of ``8.0.0`` is published as ``8.0.0.post123`` on run number ``123``.
|
next patch version for the branch series. For example, branch ``8.0`` publishes
|
||||||
|
``8.0.0`` when no package exists yet, then ``8.0.1``, ``8.0.2``, and so on.
|
||||||
|
|
||||||
This is necessary because Gitea's PyPI-compatible registry is a custom package
|
This is necessary because Gitea's PyPI-compatible registry is a custom package
|
||||||
repository for Twine and does not support ``twine upload --skip-existing``.
|
repository for Twine and does not support ``twine upload --skip-existing``.
|
||||||
|
|
||||||
Required repository secrets:
|
Required repository secrets:
|
||||||
|
|
||||||
* ``GITEA_PACKAGE_USER``
|
* ``REGISTRY_USER``
|
||||||
* ``GITEA_PACKAGE_TOKEN``
|
* ``REGISTRY_PASSWORD``
|
||||||
|
|
||||||
Publish a release branch:
|
Publish a release branch:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
git switch -c 8.0.0
|
git switch 8.0
|
||||||
git push origin 8.0.0
|
git push origin 8.0
|
||||||
|
|
||||||
Install from Gitea:
|
Install from Gitea:
|
||||||
|
|
||||||
|
|||||||
@@ -1074,6 +1074,10 @@ msgctxt "model:account.account.type.template,name:do_type_income_tax"
|
|||||||
msgid "Impuesto a las ganancias"
|
msgid "Impuesto a las ganancias"
|
||||||
msgstr "Impuesto a las ganancias"
|
msgstr "Impuesto a las ganancias"
|
||||||
|
|
||||||
|
msgctxt "model:account.account.type.template,name:do_type_control"
|
||||||
|
msgid "Cuentas de cierre y control"
|
||||||
|
msgstr "Cuentas de cierre y control"
|
||||||
|
|
||||||
msgctxt "model:account.account.type.template,name:do_type_intangible"
|
msgctxt "model:account.account.type.template,name:do_type_intangible"
|
||||||
msgid "Activos intangibles"
|
msgid "Activos intangibles"
|
||||||
msgstr "Activos intangibles"
|
msgstr "Activos intangibles"
|
||||||
|
|||||||
@@ -1066,6 +1066,10 @@ msgctxt "model:account.account.type.template,name:do_type_income_tax"
|
|||||||
msgid "Impuesto a las ganancias"
|
msgid "Impuesto a las ganancias"
|
||||||
msgstr "Impuesto a las ganancias"
|
msgstr "Impuesto a las ganancias"
|
||||||
|
|
||||||
|
msgctxt "model:account.account.type.template,name:do_type_control"
|
||||||
|
msgid "Cuentas de cierre y control"
|
||||||
|
msgstr "Cuentas de cierre y control"
|
||||||
|
|
||||||
msgctxt "model:account.account.type.template,name:do_type_intangible"
|
msgctxt "model:account.account.type.template,name:do_type_intangible"
|
||||||
msgid "Activos intangibles"
|
msgid "Activos intangibles"
|
||||||
msgstr "Activos intangibles"
|
msgstr "Activos intangibles"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import unittest
|
import unittest
|
||||||
import datetime
|
import datetime
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
|
from configparser import ConfigParser
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from xml.etree import ElementTree as ET
|
from xml.etree import ElementTree as ET
|
||||||
@@ -237,6 +238,21 @@ def _iter_xml_records(*filenames):
|
|||||||
yield filename, record.get('id'), record.get('model'), values
|
yield filename, record.get('id'), record.get('model'), values
|
||||||
|
|
||||||
|
|
||||||
|
def _po_entries(filename):
|
||||||
|
entries = []
|
||||||
|
context = msgid = msgstr = None
|
||||||
|
for line in (MODULE_DIR / filename).read_text(encoding='utf-8').splitlines():
|
||||||
|
if line.startswith('msgctxt '):
|
||||||
|
context = line.split(' ', 1)[1].strip().strip('"')
|
||||||
|
elif line.startswith('msgid '):
|
||||||
|
msgid = line.split(' ', 1)[1].strip().strip('"')
|
||||||
|
elif line.startswith('msgstr '):
|
||||||
|
msgstr = line.split(' ', 1)[1].strip().strip('"')
|
||||||
|
entries.append((context, msgid, msgstr))
|
||||||
|
context = msgid = msgstr = None
|
||||||
|
return entries
|
||||||
|
|
||||||
|
|
||||||
class AccountDoTestCase(ModuleTestCase):
|
class AccountDoTestCase(ModuleTestCase):
|
||||||
"Test account_do module"
|
"Test account_do module"
|
||||||
module = 'account_do'
|
module = 'account_do'
|
||||||
@@ -448,6 +464,229 @@ class AccountDoTestCase(ModuleTestCase):
|
|||||||
|
|
||||||
class AccountDoUnitTestCase(unittest.TestCase):
|
class AccountDoUnitTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_static_project_configuration_is_complete(self):
|
||||||
|
config = ConfigParser()
|
||||||
|
config.read(MODULE_DIR / 'tryton.cfg', encoding='utf-8')
|
||||||
|
|
||||||
|
def lines(section, option):
|
||||||
|
return [
|
||||||
|
line.strip()
|
||||||
|
for line in config.get(section, option).splitlines()
|
||||||
|
if line.strip()
|
||||||
|
]
|
||||||
|
|
||||||
|
self.assertEqual(config.get('tryton', 'version'), '8.0.0')
|
||||||
|
self.assertEqual(
|
||||||
|
set(lines('tryton', 'depends')),
|
||||||
|
{'account', 'company', 'currency'})
|
||||||
|
self.assertEqual(
|
||||||
|
lines('tryton', 'xml'),
|
||||||
|
[
|
||||||
|
'account_chart_do.xml',
|
||||||
|
'tax_do.xml',
|
||||||
|
'tax_view.xml',
|
||||||
|
'tax_code_do.xml',
|
||||||
|
'tax_rule_do.xml',
|
||||||
|
])
|
||||||
|
self.assertEqual(
|
||||||
|
lines('register', 'model'),
|
||||||
|
[
|
||||||
|
'tax.TaxTemplate',
|
||||||
|
'tax.Tax',
|
||||||
|
'tax.TaxCode',
|
||||||
|
'tax.TaxCodeLine',
|
||||||
|
])
|
||||||
|
for filename in lines('tryton', 'xml'):
|
||||||
|
self.assertTrue((MODULE_DIR / filename).is_file())
|
||||||
|
|
||||||
|
pyproject = (MODULE_DIR / 'pyproject.toml').read_text(encoding='utf-8')
|
||||||
|
self.assertIn("name = 'trytond_account_do'", pyproject)
|
||||||
|
self.assertIn(
|
||||||
|
"account_do = 'trytond.modules.account_do'", pyproject)
|
||||||
|
for package_file in [
|
||||||
|
'README.rst',
|
||||||
|
'IMPUESTOS_RD.md',
|
||||||
|
'doc/**/*.rst',
|
||||||
|
'locale/**/*.po',
|
||||||
|
'tests/**/*.rst',
|
||||||
|
]:
|
||||||
|
self.assertIn(package_file, pyproject)
|
||||||
|
self.assertEqual(
|
||||||
|
(MODULE_DIR / '__init__.py').read_text(encoding='utf-8'), '')
|
||||||
|
|
||||||
|
def test_xml_record_inventory_is_explicit(self):
|
||||||
|
expected = {
|
||||||
|
'account_chart_do.xml': {
|
||||||
|
'account.account.type.template': 36,
|
||||||
|
'account.account.template': 281,
|
||||||
|
},
|
||||||
|
'tax_do.xml': {
|
||||||
|
'account.tax.group': 7,
|
||||||
|
'account.tax.template': 55,
|
||||||
|
},
|
||||||
|
'tax_code_do.xml': {
|
||||||
|
'account.tax.code.template': 49,
|
||||||
|
'account.tax.code.line.template': 103,
|
||||||
|
},
|
||||||
|
'tax_rule_do.xml': {
|
||||||
|
'account.tax.rule.template': 28,
|
||||||
|
'account.tax.rule.line.template': 35,
|
||||||
|
},
|
||||||
|
'tax_view.xml': {
|
||||||
|
'ir.ui.view': 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for filename, expected_counts in expected.items():
|
||||||
|
records = list(_iter_xml_records(filename))
|
||||||
|
with self.subTest(filename=filename):
|
||||||
|
self.assertEqual(
|
||||||
|
dict(Counter(model for _, _, model, _ in records)),
|
||||||
|
expected_counts)
|
||||||
|
self.assertFalse([
|
||||||
|
(record_id, model)
|
||||||
|
for _, record_id, model, _ in records
|
||||||
|
if not record_id or not model])
|
||||||
|
duplicate_ids = [
|
||||||
|
record_id
|
||||||
|
for record_id, count in Counter(
|
||||||
|
record_id for _, record_id, _, _ in records).items()
|
||||||
|
if count > 1]
|
||||||
|
self.assertEqual(duplicate_ids, [])
|
||||||
|
|
||||||
|
def test_gitea_workflow_tests_before_publish(self):
|
||||||
|
workflow = (
|
||||||
|
MODULE_DIR / '.gitea' / 'workflows' / 'publish.yml'
|
||||||
|
).read_text(encoding='utf-8')
|
||||||
|
|
||||||
|
self.assertIn('test:', workflow)
|
||||||
|
self.assertIn('publish:', workflow)
|
||||||
|
self.assertIn('needs: test', workflow)
|
||||||
|
self.assertIn("python -m pip install -e '.[test]'", workflow)
|
||||||
|
self.assertIn('python -m compileall .', workflow)
|
||||||
|
self.assertIn(
|
||||||
|
"python -m unittest discover -s tests -p 'test*.py'", workflow)
|
||||||
|
self.assertIn('python -m build', workflow)
|
||||||
|
self.assertLess(
|
||||||
|
workflow.index('test:'),
|
||||||
|
workflow.index('publish:'))
|
||||||
|
self.assertLess(
|
||||||
|
workflow.index("python -m unittest discover -s tests -p 'test*.py'"),
|
||||||
|
workflow.index('Set CI package version'))
|
||||||
|
|
||||||
|
def test_tax_views_expose_all_localization_fields(self):
|
||||||
|
localization_fields = [
|
||||||
|
'tax_kind',
|
||||||
|
'tax_fiscal_type',
|
||||||
|
'tax_application',
|
||||||
|
'dgii_fiscal_status',
|
||||||
|
'dgii_form_hint',
|
||||||
|
'dgii_legal_reference',
|
||||||
|
'dgii_legal_article',
|
||||||
|
]
|
||||||
|
form = ET.parse(MODULE_DIR / 'view/tax_form.xml').getroot()
|
||||||
|
list_ = ET.parse(MODULE_DIR / 'view/tax_list.xml').getroot()
|
||||||
|
form_fields = [
|
||||||
|
element.get('name')
|
||||||
|
for element in form.findall('.//field')
|
||||||
|
if element.get('name') in localization_fields
|
||||||
|
]
|
||||||
|
list_fields = [
|
||||||
|
element.get('name')
|
||||||
|
for element in list_.findall('.//field')
|
||||||
|
if element.get('name') in localization_fields
|
||||||
|
]
|
||||||
|
self.assertEqual(form_fields, localization_fields)
|
||||||
|
self.assertEqual(list_fields, localization_fields[:3])
|
||||||
|
|
||||||
|
view_records = {
|
||||||
|
(values['model'], values['name'], values['inherit'])
|
||||||
|
for _, _, model, values in _iter_xml_records('tax_view.xml')
|
||||||
|
if model == 'ir.ui.view'
|
||||||
|
}
|
||||||
|
self.assertEqual(view_records, {
|
||||||
|
('account.tax.template', 'tax_form',
|
||||||
|
'account.tax_template_view_form'),
|
||||||
|
('account.tax', 'tax_form', 'account.tax_view_form'),
|
||||||
|
('account.tax.template', 'tax_list',
|
||||||
|
'account.tax_template_view_list'),
|
||||||
|
('account.tax', 'tax_list', 'account.tax_view_list'),
|
||||||
|
})
|
||||||
|
|
||||||
|
def test_translation_catalogs_cover_module_terms(self):
|
||||||
|
type_templates = {
|
||||||
|
record_id: values['name']
|
||||||
|
for _, record_id, model, values in _iter_xml_records(
|
||||||
|
'account_chart_do.xml')
|
||||||
|
if model == 'account.account.type.template'
|
||||||
|
}
|
||||||
|
account_templates = {
|
||||||
|
record_id: values['name']
|
||||||
|
for _, record_id, model, values in _iter_xml_records(
|
||||||
|
'account_chart_do.xml')
|
||||||
|
if model == 'account.account.template'
|
||||||
|
}
|
||||||
|
required_field_contexts = {
|
||||||
|
'field:account.tax,tax_kind:',
|
||||||
|
'field:account.tax.template,tax_kind:',
|
||||||
|
'field:account.tax,tax_fiscal_type:',
|
||||||
|
'field:account.tax.template,tax_fiscal_type:',
|
||||||
|
'field:account.tax,tax_application:',
|
||||||
|
'field:account.tax.template,tax_application:',
|
||||||
|
'field:account.tax,dgii_fiscal_status:',
|
||||||
|
'field:account.tax.template,dgii_fiscal_status:',
|
||||||
|
'field:account.tax,dgii_form_hint:',
|
||||||
|
'field:account.tax.template,dgii_form_hint:',
|
||||||
|
'field:account.tax,dgii_legal_article:',
|
||||||
|
'field:account.tax.template,dgii_legal_article:',
|
||||||
|
'field:account.tax,dgii_legal_reference:',
|
||||||
|
'field:account.tax.template,dgii_legal_reference:',
|
||||||
|
}
|
||||||
|
for filename in ['locale/es.po', 'locale/es_419.po']:
|
||||||
|
entries = _po_entries(filename)
|
||||||
|
contexts = {context for context, _msgid, _msgstr in entries}
|
||||||
|
entry_keys = [(context, msgid) for context, msgid, _ in entries]
|
||||||
|
with self.subTest(filename=filename):
|
||||||
|
self.assertEqual(
|
||||||
|
[key for key, count in Counter(entry_keys).items()
|
||||||
|
if count > 1],
|
||||||
|
[])
|
||||||
|
self.assertLessEqual(required_field_contexts, contexts)
|
||||||
|
for record_id in type_templates:
|
||||||
|
self.assertIn(
|
||||||
|
'model:account.account.type.template,name:%s'
|
||||||
|
% record_id,
|
||||||
|
contexts)
|
||||||
|
for record_id in [
|
||||||
|
'do_account_110201',
|
||||||
|
'do_account_210101',
|
||||||
|
'do_account_21021901',
|
||||||
|
'do_account_21021902',
|
||||||
|
]:
|
||||||
|
self.assertIn(
|
||||||
|
'model:account.account.template,name:%s' % record_id,
|
||||||
|
contexts)
|
||||||
|
|
||||||
|
def test_migration_metadata_is_explicit(self):
|
||||||
|
from trytond.modules.account_do.tax import (
|
||||||
|
MODEL_DATA_RENAMES, ROOT_TAX_CODE_CHILDREN)
|
||||||
|
|
||||||
|
self.assertEqual(MODEL_DATA_RENAMES, {
|
||||||
|
'do_tax_group_otros': 'do_tax_group_others',
|
||||||
|
'do_tc_otros': 'do_tc_others',
|
||||||
|
'do_tc_otros_propina': 'do_tc_others_tip',
|
||||||
|
'do_tc_otros_cheques': 'do_tc_others_checks',
|
||||||
|
'do_tc_otros_activos': 'do_tc_others_assets',
|
||||||
|
'do_tc_otros_iti': 'do_tc_others_iti',
|
||||||
|
})
|
||||||
|
self.assertEqual(ROOT_TAX_CODE_CHILDREN, [
|
||||||
|
'ITBIS — Balance Neto (Débito − Crédito)',
|
||||||
|
'ISR - Retenciones',
|
||||||
|
'ISR - Retenciones en la Fuente',
|
||||||
|
'ISC - Impuesto Selectivo al Consumo',
|
||||||
|
'CDT INDOTEL 2% (Ley 153-98)',
|
||||||
|
'Otros Impuestos y Contribuciones',
|
||||||
|
])
|
||||||
|
|
||||||
def test_xml_references_are_resolved_inside_module(self):
|
def test_xml_references_are_resolved_inside_module(self):
|
||||||
records = list(_iter_xml_records(
|
records = list(_iter_xml_records(
|
||||||
'account_chart_do.xml',
|
'account_chart_do.xml',
|
||||||
|
|||||||
Reference in New Issue
Block a user