Compare commits

12 Commits
Author SHA1 Message Date
José Arturo García 7b7553fa7d Keep party NCF types scoped per party
Publicar paquete PyPI / publish (push) Successful in 1m13s
2026-10-01 08:17:32 -04:00
José Arturo García b9379390fb Guard invoice fiscal defaults on partial records
Publicar paquete PyPI / publish (push) Successful in 2m58s
2026-10-01 00:48:18 -04:00
José Arturo García c80b4ce21b Store party NCF defaults per party
Publicar paquete PyPI / publish (push) Successful in 2m1s
2026-09-30 23:44:28 -04:00
José Arturo García c7bacddd2d Add configurable fiscal invoice defaults
Publicar paquete PyPI / publish (push) Successful in 59s
2026-09-30 23:34:22 -04:00
José Arturo García c7595022c4 Default manual fiscal sequences to current company
Publicar paquete PyPI / publish (push) Successful in 1m5s
2026-09-30 22:44:31 -04:00
José Arturo García 8dee4b753c Allow global fiscal sequences
Publicar paquete PyPI / publish (push) Successful in 1m2s
2026-09-30 22:42:04 -04:00
José Arturo García 6f1f2519fe Fix Tryton 7 model references
Publicar paquete PyPI / publish (push) Successful in 1m2s
2026-09-30 22:34:46 -04:00
José Arturo García 39505fff95 Publish package for Tryton 7.0
Publicar paquete PyPI / publish (push) Successful in 1m21s
2026-09-30 21:44:16 -04:00
José Arturo García 7b3edd3e51 Homologate fiscal management with Tryton 8.0 2026-08-30 18:28:13 -04:00
José Arturo García c68efb499b Fix invoice amount searchers and payment methods view 2026-08-30 13:58:41 -04:00
José Arturo García 7e62a9d430 feat: restore fiscal invoice as default report 2026-08-30 08:27:42 -04:00
José Arturo García 62849f7945 feat: publish Tryton 7 NCF manager without fiscal report 2026-08-29 23:44:11 -04:00
18 changed files with 401 additions and 222 deletions
+78
View File
@@ -0,0 +1,78 @@
clone:
hg:
image: plugins/hg
environment:
- HG_SHARE_POOL=/root/.cache/hg
volumes:
- cache:/root/.cache
pipeline:
tox:
image: ${IMAGE}
environment:
- CFLAGS=-O0
- DB_CACHE=/cache
- TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
- POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
commands:
- echo "[extensions]" >> /root/.hgrc
- echo "hgext.share =" >> /root/.hgrc
- echo "[share]" >> /root/.hgrc
- echo "pool = /root/.cache/hg" >> /root/.hgrc
- pip install tox
- tox -e "${TOXENV}-${DATABASE}"
volumes:
- cache:/root/.cache
check_dist:
image: ${IMAGE}
commands:
- pip install twine
- python setup.py sdist
- twine check dist/*
volumes:
- cache:/root/.cache
check_doc:
image: ${IMAGE}
commands:
- pip install sphinx
- python -m sphinx -T -E -W -n -b html doc _build/html
- python -m sphinx -T -E -W -n -b linkcheck doc _build
volumes:
- cache:/root/.cache
services:
postgresql:
image: postgres
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
when:
matrix:
DATABASE: postgresql
matrix:
include:
- IMAGE: python:3.7
TOXENV: py37
DATABASE: sqlite
- IMAGE: python:3.7
TOXENV: py37
DATABASE: postgresql
- IMAGE: python:3.8
TOXENV: py38
DATABASE: sqlite
- IMAGE: python:3.8
TOXENV: py38
DATABASE: postgresql
- IMAGE: python:3.9
TOXENV: py39
DATABASE: sqlite
- IMAGE: python:3.9
TOXENV: py39
DATABASE: postgresql
- IMAGE: python:3.10
TOXENV: py310
DATABASE: sqlite
- IMAGE: python:3.10
TOXENV: py310
DATABASE: postgresql
+5 -6
View File
@@ -2,7 +2,7 @@ name: Publicar paquete PyPI
on:
push:
branches: ["8.0"]
branches: ["7.0"]
workflow_dispatch:
permissions:
@@ -21,7 +21,7 @@ jobs:
git init .
git remote add origin http://unpaismejor-gitea-app:3000/tryton-do/ncf_manager.git
git -c http.extraHeader="Authorization: token $GITEA_TOKEN" \
fetch --depth=1 origin 8.0
fetch --depth=1 origin 7.0
git checkout --detach FETCH_HEAD
- name: Verificar Python
@@ -31,7 +31,7 @@ jobs:
run: |
python3 -m venv .ci-venv
.ci-venv/bin/python -m pip install --upgrade \
"build>=1,<2" "twine>=6,<7"
"setuptools>=68,<81" "wheel>=0.41,<1" "twine>=6,<7"
- name: Comprobar credenciales
env:
@@ -40,7 +40,7 @@ jobs:
- name: Fijar versión CI
env:
PACKAGE_VERSION: 8.0.${{ gitea.run_number }}
PACKAGE_VERSION: 7.0.${{ gitea.run_number }}
run: |
.ci-venv/bin/python - <<'PY'
from pathlib import Path
@@ -53,9 +53,8 @@ jobs:
- name: Construir y validar
run: |
.ci-venv/bin/python -m build
.ci-venv/bin/python setup.py sdist bdist_wheel
.ci-venv/bin/python -m twine check dist/*
.ci-venv/bin/python tools/check_wheel.py
- name: Publicar en Gitea PyPI
env:
-10
View File
@@ -1,10 +0,0 @@
/.coverage
/.eggs/
/.pytest_cache/
/.tox/
/build/
/dist/
/*.egg-info/
__pycache__/
*.py[cod]
.DS_Store
+12
View File
@@ -0,0 +1,12 @@
Version 7.0.3 - 2026-08-30
==========================
* Homologación funcional con la serie 8.0 manteniendo el registro y el
empaquetado propios de Tryton 7.0.
* Flujo protegido de autorizaciones y rangos NCF, importador DGII idempotente,
auditoría de activación y cierre, y restricciones por usuario.
* Validaciones de prefijo, rango, solapamiento por dirección, numeración,
notas de crédito/débito y cancelación fiscal.
* Corrección de búsquedas de montos por tipo de producto y compatibilidad con
nombres Unicode de secuencias electrónicas.
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (C) 2022-2026 Fundación Un País Mejor
Copyright (C) 2022 SOLUTEMA SRL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+5
View File
@@ -0,0 +1,5 @@
include CHANGELOG
include COPYRIGHT
include LICENSE
include README.rst
graft doc
-78
View File
@@ -1,78 +0,0 @@
NCF Manager Module
##################
The ncf_manager module manages Dominican Republic fiscal receipt numbers
for Tryton invoices.
It provides NCF/e-CF types, fiscal sequence management, invoice fiscal fields,
NCF assignment on posting, and fiscal preparation for debit and credit notes.
Installing
**********
Install the package and activate the module in the database::
pip install unpaismejor_ncf_manager
trytond-admin -d <database> -u ncf_manager
Publishing
**********
The included Gitea Actions workflow builds and publishes the package to the
Gitea PyPI registry from version-series branches such as ``8.0``.
Configure this repository secret:
* ``REGISTRY_PASSWORD``
The module assigns fiscal numbers transactionally from ``ir.sequence.strict``.
It does not sign or transmit e-CF documents; transmission remains the explicit
responsibility of an electronic invoicing connector.
Version compatibility
*********************
The 7.0 and 8.0 series share the same fiscal models, workflows, importer,
validations and tests. Only the module registration, packaging metadata and
report XML required by each Tryton series remain version-specific.
Authorization workflow
**********************
NCF authorizations follow the protected workflow ``Draft → Active →
Finished``. Create the authorization and its fiscal lines in draft, then use
the **Activate** button. A line can select an existing strict sequence or ask
the module to create one on activation from its authorized range. Activation
checks company, fiscal type, prefix, padding, validity, availability and range
overlap. Incoming supplier documents and outgoing customer documents use
independent numbering authorities, so overlap is enforced only within the
same document direction. The last issued number automatically finishes the
line. Finishing an authorization closes every remaining active line without
reusing numbers.
Legacy migration lines keep their original technical sequence immutable after
activation. Prefix selection is enforced while a line is in draft and fiscal
activation performs the same server-side validation; closing a protected
historical line therefore does not invalidate already-linked invoices.
Electronic fiscal numbers are only reserved by this module. Activating an
E-series authorization never signs or transmits an e-CF to DGII.
Importing DGII authorizations
*****************************
Use **NCF Manager → Import DGII Authorization** to load an authorization
downloaded from the DGII Virtual Office. XML, CSV and the HTML table exported
with an ``.xls`` extension are supported and detected from their content.
The importer creates an independent workflow record for every ``NUM_AUTOR``.
The same ``NUM_SOL`` may therefore appear in several records without modifying
an authorization that is already active; file names are not used as fiscal
identifiers. It validates
approval status, company name, NCF type, prefix, range and approved quantity,
and stores the original file, SHA-256, user and import date for audit.
Imports are idempotent. Reimporting an equivalent CSV, XML or XLS record does
not create another line, while different fiscal data for an existing
authorization is rejected. The safe default leaves the result in draft so
the first number can be reviewed. Immediate activation is explicit and still
does not transmit electronic documents.
Symlink
+1
View File
@@ -0,0 +1 @@
doc/index.rst
+21 -9
View File
@@ -1,3 +1,4 @@
from trytond.pool import Pool
from . import invoice
from . import importer
from . import ncf_manager
@@ -6,12 +7,23 @@ from . import configuration
from . import party
from . import user
__all__ = [
'configuration',
'invoice',
'importer',
'ncf_manager',
'party',
'sequence',
'user',
]
def register():
Pool.register(
invoice.Invoice,
ncf_manager.NCFManager,
ncf_manager.NCFManagerSequences,
sequence.Sequence,
sequence.SequenceStrict,
configuration.Configuration,
configuration.DefaultNcfType,
party.PartyNcfType,
party.Party,
user.User,
importer.ImportNCFStart,
module='ncf_manager', type_='model')
Pool.register(
importer.ImportNCF,
module='ncf_manager', type_='wizard')
Pool.register(
invoice.InvoiceReport,
module='ncf_manager', type_='report')
+55 -4
View File
@@ -12,16 +12,67 @@ Installing
Install the package and activate the module in the database::
pip install trytond_ncf_manager
pip install unpaismejor_ncf_manager
trytond-admin -d <database> -u ncf_manager
Publishing
**********
The included Gitea Actions workflow builds and publishes the package to the
Gitea PyPI registry from version-series branches such as ``8.0``.
Gitea PyPI registry from version-series branches such as ``7.0``.
Configure these repository secrets:
Configure this repository secret:
* ``REGISTRY_USER``
* ``REGISTRY_PASSWORD``
The module assigns fiscal numbers transactionally from ``ir.sequence.strict``.
It does not sign or transmit e-CF documents; transmission remains the explicit
responsibility of an electronic invoicing connector.
Version compatibility
*********************
The 7.0 and 8.0 series share the same fiscal models, workflows, importer,
validations and tests. Only the module registration, packaging metadata and
report XML required by each Tryton series remain version-specific.
Authorization workflow
**********************
NCF authorizations follow the protected workflow ``Draft → Active →
Finished``. Create the authorization and its fiscal lines in draft, then use
the **Activate** button. A line can select an existing strict sequence or ask
the module to create one on activation from its authorized range. Activation
checks company, fiscal type, prefix, padding, validity, availability and range
overlap. Incoming supplier documents and outgoing customer documents use
independent numbering authorities, so overlap is enforced only within the
same document direction. The last issued number automatically finishes the
line. Finishing an authorization closes every remaining active line without
reusing numbers.
Legacy migration lines keep their original technical sequence immutable after
activation. Prefix selection is enforced while a line is in draft and fiscal
activation performs the same server-side validation; closing a protected
historical line therefore does not invalidate already-linked invoices.
Electronic fiscal numbers are only reserved by this module. Activating an
E-series authorization never signs or transmits an e-CF to DGII.
Importing DGII authorizations
*****************************
Use **NCF Manager → Import DGII Authorization** to load an authorization
downloaded from the DGII Virtual Office. XML, CSV and the HTML table exported
with an ``.xls`` extension are supported and detected from their content.
The importer creates an independent workflow record for every ``NUM_AUTOR``.
The same ``NUM_SOL`` may therefore appear in several records without modifying
an authorization that is already active; file names are not used as fiscal
identifiers. It validates
approval status, company name, NCF type, prefix, range and approved quantity,
and stores the original file, SHA-256, user and import date for audit.
Imports are idempotent. Reimporting an equivalent CSV, XML or XLS record does
not create another line, while different fiscal data for an existing
authorization is rejected. The safe default leaves the result in draft so
the first number can be reviewed. Immediate activation is explicit and still
does not transmit electronic documents.
+5 -2
View File
@@ -15,12 +15,15 @@ this repository contains the full copyright notices and license terms. -->
<field name="inherit" ref="account_invoice.invoice_view_tree"/>
<field name="name">invoice_tree</field>
</record>
<record model="ir.action.report" id="account_invoice.report_invoice">
<field name="name">Invoice</field>
<field name="name">Factura</field>
<field name="active" eval="True"/>
<field name="model">account.invoice</field>
<field name="report_name">account.invoice</field>
<field name="report">ncf_manager/invoice.fodt</field>
<field name="template_extension">odt</field>
<field name="extension">pdf</field>
<field name="single" eval="True"/>
</record>
+8 -2
View File
@@ -307,8 +307,14 @@ class NCFManagerSequences(Workflow, ModelSQL, ModelView):
depends=_depends, sort=False)
ncf_sequences = fields.Many2One('ir.sequence.strict', 'Fiscal Sequence',
context={
'company': Eval('company', -1),
},
domain=[
('company', '=', Eval('company', -1)),
['OR',
('company', '=', Eval('company', -1)),
('company', '=', None),
],
If(Eval('state') == 'draft',
('prefix', '=', Eval('expected_prefix')),
()),
@@ -499,7 +505,7 @@ class NCFManagerSequences(Workflow, ModelSQL, ModelView):
if self.ncf_type == '99':
raise UserError(gettext(
'ncf_manager.msg_ncf_non_fiscal_sequence'))
if sequence.company != self.pos.company:
if sequence.company and sequence.company != self.pos.company:
raise UserError(gettext(
'ncf_manager.msg_ncf_sequence_company_mismatch'))
expected_prefix = ncf_prefix(self.ncf_type)
+10 -7
View File
@@ -41,7 +41,7 @@ this repository contains the full copyright notices and license terms. -->
id="menu_ncf_manager" action="act_ncf_manager"/>
<record model="ir.model.access" id="access_ncf_manager">
<field name="model">ncf.manager</field>
<field name="model" search="[('model', '=', 'ncf.manager')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
@@ -49,7 +49,7 @@ this repository contains the full copyright notices and license terms. -->
</record>
<record model="ir.model.access" id="access_ncf_manager_admin">
<field name="model">ncf.manager</field>
<field name="model" search="[('model', '=', 'ncf.manager')]"/>
<field name="group" ref="account.group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
@@ -60,7 +60,7 @@ this repository contains the full copyright notices and license terms. -->
<record model="ir.model.button" id="ncf_manager_activate_button">
<field name="name">activate</field>
<field name="string">Activate</field>
<field name="model">ncf.manager</field>
<field name="model" search="[('model', '=', 'ncf.manager')]"/>
</record>
<record model="ir.model.button-res.group"
id="ncf_manager_activate_button_group">
@@ -70,7 +70,7 @@ this repository contains the full copyright notices and license terms. -->
<record model="ir.model.button" id="ncf_manager_finish_button">
<field name="name">finish</field>
<field name="string">Finish</field>
<field name="model">ncf.manager</field>
<field name="model" search="[('model', '=', 'ncf.manager')]"/>
</record>
<record model="ir.model.button-res.group"
id="ncf_manager_finish_button_group">
@@ -91,7 +91,8 @@ this repository contains the full copyright notices and license terms. -->
</record>
<record model="ir.model.access" id="access_ncf_manager_sequences">
<field name="model">ncf.manager.sequence</field>
<field name="model"
search="[('model', '=', 'ncf.manager.sequence')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
@@ -99,7 +100,8 @@ this repository contains the full copyright notices and license terms. -->
</record>
<record model="ir.model.access" id="access_ncf_manager_sequences_admin">
<field name="model">ncf.manager.sequence</field>
<field name="model"
search="[('model', '=', 'ncf.manager.sequence')]"/>
<field name="group" ref="account.group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
@@ -110,7 +112,8 @@ this repository contains the full copyright notices and license terms. -->
<record model="ir.model.button" id="ncf_sequence_finish_button">
<field name="name">finish</field>
<field name="string">Finish Sequence</field>
<field name="model">ncf.manager.sequence</field>
<field name="model"
search="[('model', '=', 'ncf.manager.sequence')]"/>
</record>
<record model="ir.model.button-res.group"
id="ncf_sequence_finish_button_group">
-65
View File
@@ -1,65 +0,0 @@
[build-system]
requires = ['hatchling >=1,<1.31', 'hatch-tryton']
build-backend = 'hatchling.build'
[project]
name = 'unpaismejor_ncf_manager'
dynamic = ['version', 'dependencies', 'optional-dependencies', 'authors', 'readme']
requires-python = '>=3.11'
maintainers = [
{name = "Fundación Un País Mejor"},
]
description = "NCF management for Tryton"
license = 'GPL-3.0-or-later'
license-files = ["LICENSE", "COPYRIGHT"]
keywords = ["tryton", "ncf", "dominican-republic"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Plugins",
"Framework :: Tryton",
"Topic :: Office/Business",
"Topic :: Office/Business :: Financial :: Accounting",
"Topic :: Software Development :: Libraries :: Python Modules",
]
[project.entry-points.'trytond.modules']
ncf_manager = 'trytond.modules.ncf_manager'
[project.urls]
homepage = "https://code.unpaismejor.org.do/tryton-do/ncf_manager"
repository = "https://code.unpaismejor.org.do/tryton-do/ncf_manager.git"
[tool.hatch.build]
include = [
'**/tryton.cfg',
'**/*.py',
'**/*.xml',
'view/**/*.xml',
'locale/**/*.po',
'doc/**/*.rst',
'**/*.fodt',
'icons/**/*.svg',
'tests/**/*.py',
'tests/**/*.rst',
'tests/**/*.json',
]
exclude = [
'**/.ci-venv/**',
'**/.test-venv/**',
'**/.venv/**',
'**/__pycache__/**',
'**/*.py[co]',
'build/**',
'dist/**',
]
[tool.hatch.build.targets.wheel.sources]
"" = "trytond/modules/ncf_manager"
[tool.hatch.metadata.hooks.tryton]
copyright = 'COPYRIGHT'
readme = 'README.rst'
prefixes = {account_do = 'unpaismejor', account_credit_note = 'unpaismejor', account_debit_note = 'unpaismejor', account_invoice_do = 'unpaismejor'}
[tool.hatch.metadata.hooks.tryton.tryton-optional-dependencies]
test = ['proteus']
Executable
+145
View File
@@ -0,0 +1,145 @@
#!/usr/bin/env python3
import io
import os
import re
from configparser import ConfigParser
from setuptools import find_packages, setup
MODULE2PREFIX = {
'account_do': 'unpaismejor',
'account_credit_note': 'unpaismejor',
'account_debit_note': 'unpaismejor',
'account_invoice_do': 'unpaismejor',
}
def read(fname):
content = io.open(
os.path.join(os.path.dirname(__file__), fname),
'r', encoding='utf-8').read()
content = re.sub(
r'(?m)^\.\. toctree::\r?\n((^$|^\s.*$)\r?\n)*', '', content)
return content
def get_require_version(name):
if minor_version % 2:
require = '%s >= %s.%s.dev0, < %s.%s'
else:
require = '%s >= %s.%s, < %s.%s'
require %= (name, major_version, minor_version,
major_version, minor_version + 1)
return require
config = ConfigParser()
config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
info = dict(config.items('tryton'))
for key in ('depends', 'extras_depend', 'xml'):
if key in info:
info[key] = info[key].strip().splitlines()
version = info.get('version', '0.0.1')
major_version, minor_version, _ = version.split('.', 2)
major_version = int(major_version)
minor_version = int(minor_version)
name = 'unpaismejor_ncf_manager'
local_version = []
if os.environ.get('CI_JOB_ID'):
local_version.append(os.environ['CI_JOB_ID'])
else:
for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
if os.environ.get(build):
local_version.append(os.environ[build])
else:
local_version = []
break
if local_version:
version += '+' + '.'.join(local_version)
requires = []
for dep in info.get('depends', []):
if not re.match(r'(ir|res)(\W|$)', dep):
prefix = MODULE2PREFIX.get(dep, 'trytond')
requires.append(get_require_version('%s_%s' % (prefix, dep)))
requires.append(get_require_version('trytond'))
tests_require = []
dependency_links = []
if minor_version % 2:
dependency_links.append(
'https://trydevpi.tryton.org/?local_version='
+ '.'.join(local_version)
+ '&mirror=github')
setup(name=name,
version=version,
description='This module implements the administration and management of tax receipt numbers.',
long_description=read('README.rst'),
long_description_content_type='text/x-rst',
author='Solutema SRL',
author_email='info@solutema.com',
url='https://www.solutema.com/',
keywords='tryton invoice',
package_dir={'trytond.modules.ncf_manager': '.'},
packages=(
['trytond.modules.ncf_manager']
+ ['trytond.modules.ncf_manager.%s' % p
for p in find_packages()]
),
package_data={
'trytond.modules.ncf_manager': (info.get('xml', [])
+ ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
'icons/*.svg', 'tests/*.rst']),
},
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Plugins',
'Framework :: Tryton',
'Intended Audience :: Developers',
'Intended Audience :: Financial and Insurance Industry',
'Intended Audience :: Legal Industry',
'License :: OSI Approved :: '
'GNU General Public License v3 or later (GPLv3+)',
'Natural Language :: Bulgarian',
'Natural Language :: Catalan',
'Natural Language :: Chinese (Simplified)',
'Natural Language :: Czech',
'Natural Language :: Dutch',
'Natural Language :: English',
'Natural Language :: Finnish',
'Natural Language :: French',
'Natural Language :: German',
'Natural Language :: Hungarian',
'Natural Language :: Indonesian',
'Natural Language :: Italian',
'Natural Language :: Persian',
'Natural Language :: Polish',
'Natural Language :: Portuguese (Brazilian)',
'Natural Language :: Romanian',
'Natural Language :: Russian',
'Natural Language :: Slovenian',
'Natural Language :: Spanish',
'Natural Language :: Turkish',
'Operating System :: OS Independent',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: Implementation :: CPython',
'Topic :: Office/Business',
],
license='GPL-3',
python_requires='>=3.7',
install_requires=requires,
extras_require={
'test': tests_require,
},
dependency_links=dependency_links,
zip_safe=False,
entry_points="""
[trytond.modules]
ncf_manager = trytond.modules.ncf_manager
""", # noqa: E501
)
+53
View File
@@ -332,6 +332,59 @@ class NcfManagerTestCase(ModuleTestCase):
self.assertEqual(manager.ncf_sequences[0].state, 'finished')
self.assertIsNotNone(manager.finished_at)
@with_transaction()
def test_global_fiscal_sequence_can_be_assigned_to_manager(self):
'Global fiscal sequences can be attached to a company authorization'
pool = Pool()
Manager = pool.get('ncf.manager')
ManagerSequence = pool.get('ncf.manager.sequence')
ModelData = pool.get('ir.model.data')
StrictSequence = pool.get('ir.sequence.strict')
SequenceType = pool.get('ir.sequence.type')
today = datetime.date.today()
company = self._create_company()
sequence_type = SequenceType(ModelData.get_id(
'ncf_manager', 'sequence_type_out_invoice_01'))
strict_sequence, = StrictSequence.create([{
'name': 'Factura de Crédito Fiscal',
'sequence_type': sequence_type.id,
'prefix': 'B01',
'padding': 8,
'number_next': 1,
'number_increment': 1,
'from_number': 1,
'until_number': 100,
'expiration_date': datetime.date(today.year, 12, 31),
}])
manager, = Manager.create([{
'company': company.id,
'app_date': today,
'app_number': 'APP0000001',
'auth_number': 'AUT0000001',
}])
line, = ManagerSequence.create([{
'pos': manager.id,
'invoice_type': 'invoice_customer',
'ncf_type': '1',
'sequence_mode': 'existing',
'ncf_sequences': strict_sequence.id,
}])
self.assertEqual(line.ncf_sequences, strict_sequence)
@with_transaction()
def test_manual_sequence_creation_defaults_to_current_company(self):
'Manual sequence creation uses the current company from context'
StrictSequence = Pool().get('ir.sequence.strict')
company = self._create_company()
with Transaction().set_context(company=company.id):
defaults = StrictSequence.default_get(['company'])
self.assertEqual(defaults['company'], company.id)
@with_transaction()
def test_overlap_is_independent_by_invoice_direction(self):
'A supplier range must not block the company outgoing authorization'
-18
View File
@@ -1,18 +0,0 @@
#!/usr/bin/env python3
"""Reject development artifacts accidentally bundled in a wheel."""
from pathlib import Path
from zipfile import ZipFile
wheel = next(Path('dist').glob('*.whl'))
forbidden = {'.ci-venv', '.test-venv', '.venv', '__pycache__'}
with ZipFile(wheel) as archive:
invalid = [
name for name in archive.namelist()
if forbidden.intersection(Path(name).parts)
or name.endswith(('.pyc', '.pyo'))
]
if invalid:
raise SystemExit(f'Forbidden wheel content: {invalid[:10]}')
print(f'Validated clean wheel: {wheel}')
+1 -1
View File
@@ -1,5 +1,5 @@
[tox]
envlist = {py311,py312,py313,py314}-{sqlite,postgresql}
envlist = {py311,py312,py313}-{sqlite,postgresql}
[testenv]
extras = test
+1 -19
View File
@@ -1,5 +1,5 @@
[tryton]
version=8.0.4
version=7.0.3
depends:
account_do
account_invoice_do
@@ -14,21 +14,3 @@ xml:
party.xml
user.xml
message.xml
[register]
model:
invoice.Invoice
ncf_manager.NCFManager
ncf_manager.NCFManagerSequences
sequence.Sequence
sequence.SequenceStrict
configuration.Configuration
configuration.DefaultNcfType
party.PartyNcfType
party.Party
user.User
importer.ImportNCFStart
wizard:
importer.ImportNCF
report:
invoice.InvoiceReport