173 lines
5.6 KiB
Python
173 lines
5.6 KiB
Python
# This file is part of ncf_manager module for Tryton. The COPYRIGHT file at the top level of
|
|
# this repository contains the full copyright notices and license terms.
|
|
from trytond.exceptions import UserError
|
|
from trytond.i18n import gettext
|
|
from trytond.model import ModelView, ModelSQL, fields
|
|
from trytond.pool import Pool
|
|
from trytond.pyson import Eval
|
|
from trytond.transaction import Transaction
|
|
|
|
|
|
NCF_TYPE = [
|
|
('', ''),
|
|
('1', 'Factura de Crédito Fiscal'),
|
|
('2', 'Factura de Consumo'),
|
|
('3', 'Nota de Débito'),
|
|
('4', 'Nota de Crédito'),
|
|
('11', 'Comprobante de Compras'),
|
|
('12', 'Registro Único de Ingresos'),
|
|
('13', 'Comprobante para Gastos Menores'),
|
|
('14', 'Comprobante de Regímenes Especiales'),
|
|
('15', 'Comprobante Gubernamental'),
|
|
('16', 'Comprobante para exportaciones'),
|
|
('17', 'Comprobante para Pagos al Exterior'),
|
|
('31', 'Factura de Crédito Fiscal Electrónica'),
|
|
('32', 'Factura de Consumo Electrónica'),
|
|
('33', 'Nota de Débito Electrónica'),
|
|
('34', 'Nota de Crédito Electrónica'),
|
|
('41', 'Compras Electrónico'),
|
|
('43', 'Gastos Menores Electrónico'),
|
|
('44', 'Regímenes Especiales Electrónico'),
|
|
('45', 'Gubernamental Electrónico'),
|
|
('46', 'Exportación Electrónico'),
|
|
('47', 'Pagos al Exterior Electrónico'),
|
|
('99', 'Factura sin NCF'),
|
|
]
|
|
|
|
|
|
class NCFManager(ModelSQL, ModelView):
|
|
|
|
'NCF Manager'
|
|
__name__ = 'ncf.manager'
|
|
|
|
_states = {
|
|
'readonly': Eval('state') != 'draft',
|
|
}
|
|
|
|
_depends = ['state']
|
|
|
|
company = fields.Many2One('company.company', 'Company', required=True,
|
|
states=_states, depends=_depends)
|
|
|
|
app_date = fields.Date('Application Date', required=True,
|
|
states=_states, depends=_depends)
|
|
|
|
app_number = fields.Char('Application Number', required=True, size=10,
|
|
states=_states, depends=_depends)
|
|
|
|
auth_number = fields.Char('Authorization Number', required=True, size=10,
|
|
states=_states, depends=_depends)
|
|
|
|
ncf_sequences = fields.One2Many('ncf.manager.sequence', 'pos',
|
|
'NCF Sequences', context={'company': Eval('company', -1)},
|
|
states=_states, depends=_depends)
|
|
|
|
state = fields.Selection([
|
|
('draft', 'Draft'),
|
|
('active', 'Active'),
|
|
('finished', 'Finished'),
|
|
], "State", sort=False)
|
|
|
|
state_string = state.translated('state')
|
|
|
|
del _states, _depends
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super(NCFManager, cls).__setup__()
|
|
cls._order = [
|
|
('app_date', 'DESC'),
|
|
('id', 'DESC'),
|
|
]
|
|
|
|
def get_rec_name(self, name):
|
|
parts = []
|
|
if self.company:
|
|
parts.append(self.company.rec_name)
|
|
if self.app_number:
|
|
parts.append(self.app_number)
|
|
return ' - '.join(parts) if parts else str(self.id)
|
|
|
|
@staticmethod
|
|
def default_company():
|
|
return Transaction().context.get('company')
|
|
|
|
@staticmethod
|
|
def default_state():
|
|
return 'draft'
|
|
|
|
|
|
class NCFManagerSequences(ModelSQL, ModelView):
|
|
|
|
'NCF Manager Sequences'
|
|
__name__ = 'ncf.manager.sequence'
|
|
|
|
_states = {
|
|
'readonly': Eval('state') != 'draft',
|
|
}
|
|
|
|
_depends = ['state']
|
|
|
|
pos = fields.Many2One('ncf.manager', 'Point of Sale',
|
|
ondelete='CASCADE', required=True)
|
|
|
|
ncf_type = fields.Selection(NCF_TYPE, 'NCF Type',
|
|
required=True, sort=False,
|
|
states=_states, depends=_depends,
|
|
help='Choose a NCF Type')
|
|
|
|
ncf_type_string = ncf_type.translated('ncf_type')
|
|
|
|
ncf_sequences = fields.Many2One('ir.sequence.strict', 'NCF Sequences',
|
|
domain=[
|
|
('company', '=', Eval(
|
|
'context', {}).get('company', -1)),
|
|
], states=_states, depends=_depends)
|
|
|
|
invoice_type = fields.Selection([
|
|
('invoice_customer', 'Customer Invoice'),
|
|
('invoice_supplier', 'Supplier Invoice')
|
|
], 'Invoice Type', required=True,
|
|
states=_states, depends=_depends)
|
|
|
|
state = fields.Selection([
|
|
('draft', 'Draft'),
|
|
('active', 'Active'),
|
|
('finished', 'Finished'),
|
|
], "State", sort=False)
|
|
|
|
state_string = state.translated('state')
|
|
|
|
del _states, _depends
|
|
|
|
@staticmethod
|
|
def default_state():
|
|
return 'draft'
|
|
|
|
def get_rec_name(self, name):
|
|
if not self.ncf_type_string:
|
|
return ''
|
|
return self.ncf_type_string.split('-')[0]
|
|
|
|
@classmethod
|
|
def validate_fields(cls, records, field_names):
|
|
super().validate_fields(records, field_names)
|
|
if field_names & {'pos', 'ncf_sequences', 'ncf_type'}:
|
|
for record in records:
|
|
record._validate_fiscal_sequence()
|
|
|
|
def _validate_fiscal_sequence(self):
|
|
sequence = self.ncf_sequences
|
|
if not sequence:
|
|
return
|
|
if sequence.company != self.pos.company:
|
|
raise UserError(gettext(
|
|
'ncf_manager.msg_ncf_sequence_company_mismatch'))
|
|
expected_prefix = ('E' if self.ncf_type in {
|
|
'31', '32', '33', '34', '41', '43', '44', '45', '46', '47'
|
|
} else 'B') + self.ncf_type.zfill(2)
|
|
if self.ncf_type != '99' and sequence.prefix != expected_prefix:
|
|
raise UserError(gettext(
|
|
'ncf_manager.msg_ncf_sequence_prefix_mismatch',
|
|
prefix=expected_prefix))
|