diff --git a/configuration.py b/configuration.py
index e43644e..9f3118f 100644
--- a/configuration.py
+++ b/configuration.py
@@ -7,6 +7,8 @@ from trytond.model import fields, ModelSQL
from trytond.modules.company.model import CompanyValueMixin
from trytond.pool import PoolMeta, Pool
from trytond.transaction import Transaction
+from trytond.modules.ncf_manager.fiscal import (
+ EXPENSE_TYPE, PAYMENT_METHOD, REVENUE_TYPE)
from trytond.modules.ncf_manager.ncf_manager import NCF_TYPE
@@ -36,10 +38,37 @@ class Configuration(metaclass=PoolMeta):
help="Default supplier NCF type for new parties."
))
+ default_customer_revenue_type = fields.MultiValue(fields.Selection(
+ REVENUE_TYPE,
+ "Default Customer Revenue Type",
+ sort=False,
+ help="Default revenue type for new customer invoices."
+ ))
+
+ default_supplier_expense_type = fields.MultiValue(fields.Selection(
+ EXPENSE_TYPE,
+ "Default Supplier Expense Type",
+ sort=False,
+ help="Default expense type for new supplier invoices."
+ ))
+
+ default_payment_method = fields.MultiValue(fields.Selection(
+ PAYMENT_METHOD,
+ "Default Payment Method",
+ sort=False,
+ help="Default payment method for new invoices."
+ ))
+
@classmethod
def multivalue_model(cls, field):
pool = Pool()
- if field in {'default_customer_ncf_type', 'default_supplier_ncf_type'}:
+ if field in {
+ 'default_customer_ncf_type',
+ 'default_supplier_ncf_type',
+ 'default_customer_revenue_type',
+ 'default_supplier_expense_type',
+ 'default_payment_method',
+ }:
return pool.get('account.configuration.default_ncf_type')
return super(Configuration, cls).multivalue_model(field)
@@ -60,6 +89,24 @@ class DefaultNcfType(ModelSQL, CompanyValueMixin):
sort=False
)
+ default_customer_revenue_type = fields.Selection(
+ REVENUE_TYPE,
+ "Default Customer Revenue Type",
+ sort=False
+ )
+
+ default_supplier_expense_type = fields.Selection(
+ EXPENSE_TYPE,
+ "Default Supplier Expense Type",
+ sort=False
+ )
+
+ default_payment_method = fields.Selection(
+ PAYMENT_METHOD,
+ "Default Payment Method",
+ sort=False
+ )
+
@classmethod
def __register__(cls, module_name):
"""
diff --git a/fiscal.py b/fiscal.py
new file mode 100644
index 0000000..e0a2139
--- /dev/null
+++ b/fiscal.py
@@ -0,0 +1,38 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+REVENUE_TYPE = [
+ ('', ''),
+ ('01', "01 - Ingresos por Operaciones (No Financieros)"),
+ ('02', "02 - Ingresos Financieros"),
+ ('03', "03 - Ingresos Extraordinarios"),
+ ('04', "04 - Ingresos por Arrendamientos"),
+ ('05', "05 - Ingresos por Venta de Activo Depreciable"),
+ ('06', "06 - Otros Ingresos"),
+]
+
+EXPENSE_TYPE = [
+ ('', ''),
+ ('01', "01 - Gastos de Personal"),
+ ('02', "02 - Gastos por Trabajos, Suministros y Servicios"),
+ ('03', "03 - Arrendamientos"),
+ ('04', "04 - Gastos de Activos Fijo"),
+ ('05', "05 - Gastos de Representación"),
+ ('06', "06 - Otras Deducciones Admitidas"),
+ ('07', "07 - Gastos Financieros"),
+ ('08', "08 - Gastos Extraordinarios"),
+ ('09', "09 - Compras y Gastos que forman parte del Costo de Venta"),
+ ('10', "10 - Adquisiciones de Activos"),
+ ('11', "11 - Gastos de Seguros"),
+]
+
+PAYMENT_METHOD = [
+ ('', ''),
+ ('01', "01 - Efectivo"),
+ ('02', "02 - Cheques/Transferencias/Depósito"),
+ ('03', "03 - Tarjeta Crédito/Débito"),
+ ('04', "04 - Compra a Crédito"),
+ ('05', "05 - Permuta"),
+ ('06', "06 - Nota de Crédito"),
+ ('07', "07 - Mixto"),
+]
diff --git a/invoice.py b/invoice.py
index 715fd21..50ae30a 100755
--- a/invoice.py
+++ b/invoice.py
@@ -15,6 +15,8 @@ from trytond.transaction import Transaction
from trytond.exceptions import UserError
from trytond.i18n import gettext
from trytond.modules.ncf_manager.ncf_manager import NCF_TYPE
+from trytond.modules.ncf_manager.fiscal import (
+ EXPENSE_TYPE, PAYMENT_METHOD, REVENUE_TYPE)
from trytond.modules.currency.fields import Monetary
import logging
logger = logging.getLogger(__name__)
@@ -25,43 +27,6 @@ def _backend_name():
return name() if callable(name) else name
-_REVENUE_TYPE = [
- ('', ''),
- ('01', "01 - Ingresos por Operaciones (No Financieros)"),
- ('02', "02 - Ingresos Financieros"),
- ('03', "03 - Ingresos Extraordinarios"),
- ('04', "04 - Ingresos por Arrendamientos"),
- ('05', "05 - Ingresos por Venta de Activo Depreciable"),
- ('06', "06 - Otros Ingresos"),
-]
-
-_EXPENSE_TYPE = [
- ('', ''),
- ('01', "01 - Gastos de Personal"),
- ('02', "02 - Gastos por Trabajos, Suministros y Servicios"),
- ('03', "03 - Arrendamientos"),
- ('04', "04 - Gastos de Activos Fijo"),
- ('05', "05 - Gastos de Representación"),
- ('06', "06 - Otras Deducciones Admitidas"),
- ('07', "07 - Gastos Financieros"),
- ('08', "08 - Gastos Extraordinarios"),
- ('09', "09 - Compras y Gastos que forman parte del Costo de Venta"),
- ('10', "10 - Adquisiciones de Activos"),
- ('11', "11 - Gastos de Seguros"),
-]
-
-_PAYMENT_METHOD = [
- ('', ''),
- ('01', "01 - Efectivo"),
- ('02', "02 - Cheques/Transferencias/Depósito"),
- ('03', "03 - Tarjeta Crédito/Débito"),
- ('04', "04 - Compra a Crédito"),
- ('05', "05 - Permuta"),
- ('06', "06 - Nota de Crédito"),
- ('07', "07 - Mixto"),
-]
-
-
_ISR_WITHHOLDING_TYPE = [
('', ''),
('01', "01 - Alquileres"),
@@ -230,7 +195,7 @@ class Invoice(metaclass=PoolMeta):
"Amount Invoiced in Goods", currency='currency', digits='currency'),
'get_amount_invoiced_goods', searcher='search_amount_invoiced_goods')
- revenue_type = fields.Selection(_REVENUE_TYPE, 'Revenue Type',
+ revenue_type = fields.Selection(REVENUE_TYPE, 'Revenue Type',
states={
'readonly': Eval('state').in_(['posted', 'paid', 'cancelled']),
'invisible': Eval('type') == 'in',
@@ -239,7 +204,7 @@ class Invoice(metaclass=PoolMeta):
revenue_type_string = revenue_type.translated('revenue_type')
- expense_type = fields.Selection(_EXPENSE_TYPE, 'Expense Type',
+ expense_type = fields.Selection(EXPENSE_TYPE, 'Expense Type',
states={
'readonly': Eval('state').in_(['posted', 'paid', 'cancelled']),
'invisible': Eval('type') == 'out',
@@ -248,7 +213,7 @@ class Invoice(metaclass=PoolMeta):
expense_type_string = expense_type.translated('expense_type')
- payment_method = fields.Selection(_PAYMENT_METHOD, 'Method of Payment',
+ payment_method = fields.Selection(PAYMENT_METHOD, 'Method of Payment',
states={
'readonly': Eval('state').in_(['posted', 'paid', 'cancelled']),
},
@@ -323,6 +288,32 @@ class Invoice(metaclass=PoolMeta):
},
depends=['state', 'type', 'ncf_number'])
+ @classmethod
+ def _ncf_get_configuration_default(cls, field_name, **pattern):
+ "Return a default value from account configuration."
+ Configuration = Pool().get('account.configuration')
+ config = Configuration(1)
+ return config.get_multivalue(field_name, **pattern) or None
+
+ @classmethod
+ def default_revenue_type(cls, **pattern):
+ if Transaction().context.get('type') == 'in':
+ return None
+ return cls._ncf_get_configuration_default(
+ 'default_customer_revenue_type', **pattern)
+
+ @classmethod
+ def default_expense_type(cls, **pattern):
+ if Transaction().context.get('type') == 'out':
+ return None
+ return cls._ncf_get_configuration_default(
+ 'default_supplier_expense_type', **pattern)
+
+ @classmethod
+ def default_payment_method(cls, **pattern):
+ return cls._ncf_get_configuration_default(
+ 'default_payment_method', **pattern)
+
@classmethod
def __setup__(cls):
super().__setup__()
@@ -804,6 +795,39 @@ class Invoice(metaclass=PoolMeta):
else:
self.expiration_date = None
+ def _ncf_get_configuration_default_invoice_field(self, field_name):
+ "Return an invoice default configured on account configuration."
+ Configuration = Pool().get('account.configuration')
+ config = Configuration(1)
+ company_id = (
+ self.company.id if self.company
+ else Transaction().context.get('company'))
+
+ if company_id:
+ with Transaction().set_context(company=company_id):
+ return config.get_multivalue(field_name) or None
+
+ return config.get_multivalue(field_name) or None
+
+ def _ncf_apply_configuration_invoice_defaults(self):
+ """
+ Apply configured fiscal reporting defaults without replacing values
+ already selected by the user or copied from another invoice.
+ """
+ if self.type == 'out' and not self.revenue_type:
+ self.revenue_type = (
+ self._ncf_get_configuration_default_invoice_field(
+ 'default_customer_revenue_type'))
+ elif self.type == 'in' and not self.expense_type:
+ self.expense_type = (
+ self._ncf_get_configuration_default_invoice_field(
+ 'default_supplier_expense_type'))
+
+ if not self.payment_method:
+ self.payment_method = (
+ self._ncf_get_configuration_default_invoice_field(
+ 'default_payment_method'))
+
@fields.depends(
'party',
'company',
@@ -811,6 +835,9 @@ class Invoice(metaclass=PoolMeta):
'ncf_type',
'ncf_sequence',
'expiration_date',
+ 'revenue_type',
+ 'expense_type',
+ 'payment_method',
'_parent_party.customer_ncf_type',
'_parent_party.supplier_ncf_type',
)
@@ -827,9 +854,19 @@ class Invoice(metaclass=PoolMeta):
"""
super().on_change_party()
self._ncf_apply_party_default_ncf_type()
+ self._ncf_apply_configuration_invoice_defaults()
- @fields.depends('company', 'type', 'ncf_type', 'ncf_sequence', 'expiration_date')
+ @fields.depends(
+ 'company',
+ 'type',
+ 'ncf_type',
+ 'ncf_sequence',
+ 'expiration_date',
+ 'revenue_type',
+ 'expense_type',
+ 'payment_method',
+ )
def on_change_company(self):
if self.ncf_type:
sequence = self._ncf_get_active_sequence()
@@ -841,6 +878,7 @@ class Invoice(metaclass=PoolMeta):
self.ncf_sequence = sequence
if sequence.ncf_sequences:
self.expiration_date = sequence.ncf_sequences.expiration_date
+ self._ncf_apply_configuration_invoice_defaults()
@fields.depends(
'company',
@@ -854,6 +892,9 @@ class Invoice(metaclass=PoolMeta):
'ncf_type',
'ncf_sequence',
'expiration_date',
+ 'revenue_type',
+ 'expense_type',
+ 'payment_method',
methods=['set_journal', 'on_change_party'],
)
def on_change_type(self):
@@ -870,6 +911,7 @@ class Invoice(metaclass=PoolMeta):
the new invoice type.
"""
super().on_change_type()
+ self._ncf_apply_configuration_invoice_defaults()
if not self.ncf_sequence:
self.ncf_type = None
diff --git a/view/configuration_form.xml b/view/configuration_form.xml
index 949de48..28fa2fe 100644
--- a/view/configuration_form.xml
+++ b/view/configuration_form.xml
@@ -9,5 +9,14 @@ this repository contains the full copyright notices and license terms. -->
+
+
+
+
+
+
+
+
-
\ No newline at end of file
+