2020-11-09 04:18:37 +01:00
|
|
|
|
from trytond.model import fields, ModelSQL, ModelView, Unique, sequence_ordered
|
|
|
|
|
from trytond.pool import PoolMeta, Pool
|
2020-11-20 23:27:29 +01:00
|
|
|
|
from trytond.pyson import Eval, Not, Equal, Or, And
|
|
|
|
|
from trytond.i18n import gettext
|
2020-11-09 04:18:37 +01:00
|
|
|
|
from trytond.exceptions import UserError
|
2020-11-20 23:27:29 +01:00
|
|
|
|
from .exceptions import PartyIdentifierError
|
|
|
|
|
|
|
|
|
|
import logging
|
2020-11-09 04:18:37 +01:00
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
2020-11-16 18:06:49 +01:00
|
|
|
|
__all__ = ['PartyIdentifier','Party','ContactMechanism','Address','PartyTaxLevelCode']
|
2020-11-09 04:18:37 +01:00
|
|
|
|
|
|
|
|
|
|
2020-11-16 23:41:36 +01:00
|
|
|
|
TAX_CO_IDENTIFIERS = [
|
2020-11-09 04:18:37 +01:00
|
|
|
|
(None, ''),
|
|
|
|
|
('11', 'Registro Civil'),
|
|
|
|
|
('12', 'Tarjeta de Identidad'),
|
|
|
|
|
('13', 'Cedula de Ciudadania'),
|
|
|
|
|
('21', 'Tarjeta de Extranjeria'),
|
|
|
|
|
('22', 'Cedula de Extranjeria'),
|
|
|
|
|
('31', 'NIT'),
|
|
|
|
|
('41', 'Pasaporte'),
|
2020-11-20 23:27:29 +01:00
|
|
|
|
('42', 'Tipo de Documento Extranjero'),
|
2020-11-09 04:18:37 +01:00
|
|
|
|
('43', 'Documento de identificación extranjero'),
|
|
|
|
|
('50', 'NIT de otro país'),
|
|
|
|
|
('91', 'NUIP')
|
|
|
|
|
]
|
|
|
|
|
CO_CONTACT_MECHANISM_TYPES = [
|
|
|
|
|
('sms','SMS')
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
class Party(ModelSQL,ModelView):
|
|
|
|
|
"Party Colombian"
|
|
|
|
|
|
|
|
|
|
__name__='party.party'
|
|
|
|
|
__metaclass__ = PoolMeta
|
|
|
|
|
|
|
|
|
|
first_name = fields.Char("Primer Nombre",states={
|
2020-11-20 23:27:29 +01:00
|
|
|
|
'invisible': Not(Eval('type_person') == '2'),}
|
2020-11-09 04:18:37 +01:00
|
|
|
|
)
|
|
|
|
|
second_name = fields.Char("Segundo Nombre",states={
|
2020-11-20 23:27:29 +01:00
|
|
|
|
'invisible': Not(Eval('type_person') == '2'),}
|
2020-11-09 04:18:37 +01:00
|
|
|
|
)
|
|
|
|
|
first_surname = fields.Char("Primer Apellido",states={
|
2020-11-20 23:27:29 +01:00
|
|
|
|
'invisible': Not(Eval('type_person') == '2'),}
|
2020-11-09 04:18:37 +01:00
|
|
|
|
)
|
|
|
|
|
second_surname = fields.Char("Segundo Apellido",states={
|
2020-11-20 23:27:29 +01:00
|
|
|
|
'invisible': Not(Eval('type_person') == '2'),},
|
2020-11-09 04:18:37 +01:00
|
|
|
|
depends=['type_person'])
|
|
|
|
|
birth_date = fields.Date('Fecha de nacimiento')
|
2020-11-16 23:41:36 +01:00
|
|
|
|
tax_regime = fields.Selection([
|
|
|
|
|
(None, ''),
|
|
|
|
|
('48', 'Responsable del impuesto sobre las ventas –IVA'),
|
|
|
|
|
('49', 'No responsable de IVA')
|
|
|
|
|
], 'Tax Regime')
|
|
|
|
|
type_taxpayer = fields.Selection([
|
2020-11-09 04:18:37 +01:00
|
|
|
|
(None, ''),
|
|
|
|
|
('regimen_simplificado', 'Regimen Simplificado'),
|
|
|
|
|
('regimen_comun', 'Regimen Comun'),
|
|
|
|
|
('gran_contribuyente', 'Gran Contribuyente'),
|
|
|
|
|
('entidad_estatal', 'Entidad Estatal'),
|
|
|
|
|
('domiciliado_extranjero', 'Domiciliado en Extranjero'),
|
2020-11-16 23:41:36 +01:00
|
|
|
|
], 'Type Taxpayer')
|
2020-11-09 04:18:37 +01:00
|
|
|
|
type_person = fields.Selection([
|
|
|
|
|
(None, ''),
|
2020-11-16 23:41:36 +01:00
|
|
|
|
('1', 'Persona Juridica'),
|
|
|
|
|
('2', 'Persona Natural'),
|
|
|
|
|
], 'Type Person')
|
2020-11-09 04:18:37 +01:00
|
|
|
|
self_withholding = fields.Boolean('Self Withholding')
|
|
|
|
|
declarant = fields.Boolean('Declarant')
|
2020-11-16 23:41:36 +01:00
|
|
|
|
main_ciiu = fields.Char('Main Activity', size=4)
|
|
|
|
|
secondary_ciiu = fields.Char('Secondary Activity', size=4)
|
|
|
|
|
other_ciiu = fields.Char('Other Activity', size=4)
|
2020-11-09 04:18:37 +01:00
|
|
|
|
age = fields.Function(fields.Integer('Edad'),'on_change_with_age')
|
2020-11-16 18:06:49 +01:00
|
|
|
|
type_tax_identifier = fields.Function(fields.Selection('get_types_identifier',
|
|
|
|
|
'Tipo de Identidad'),
|
|
|
|
|
'on_change_with_type_tax_identifier')
|
|
|
|
|
tax_level_code =fields.Many2Many('party.party_tax_level_code','party', 'tax_level_code', "TaxLevelCode")
|
2020-11-09 04:18:37 +01:00
|
|
|
|
|
2020-11-20 23:27:29 +01:00
|
|
|
|
@classmethod
|
|
|
|
|
def __setup__(cls):
|
|
|
|
|
super(Party, cls).__setup__()
|
|
|
|
|
cls.name.required = True
|
2020-11-09 04:18:37 +01:00
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def default_type_person():
|
2020-11-20 23:27:29 +01:00
|
|
|
|
return '2'
|
2020-11-09 04:18:37 +01:00
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def tax_identifier_types(cls):
|
2020-11-20 23:27:29 +01:00
|
|
|
|
return ['12','13','31']
|
2020-11-09 04:18:37 +01:00
|
|
|
|
|
2020-11-16 18:06:49 +01:00
|
|
|
|
@classmethod
|
|
|
|
|
def get_tax_level_code(cls):
|
|
|
|
|
pool = Pool()
|
|
|
|
|
TaxLevelCode = pool.get('party.tax_level_code')
|
|
|
|
|
return TaxLevelCode.fields_get(['code'])['code']
|
|
|
|
|
|
2020-11-09 04:18:37 +01:00
|
|
|
|
@fields.depends('birth_date')
|
|
|
|
|
def on_change_with_age(self,name=None):
|
|
|
|
|
if self.birth_date:
|
|
|
|
|
Date = Pool().get('ir.date')
|
|
|
|
|
today = Date.today()
|
|
|
|
|
age = today.year - self.birth_date.year
|
|
|
|
|
age -= (today.month, today.day) < (self.birth_date.month, self.birth_date.day)
|
|
|
|
|
return age
|
|
|
|
|
|
|
|
|
|
@fields.depends('name','first_name','second_name','first_surname',
|
|
|
|
|
'second_surname','type_person')
|
|
|
|
|
def on_change_type_person(self):
|
2020-11-20 23:27:29 +01:00
|
|
|
|
if self.type_person == '2':
|
2020-11-09 04:18:37 +01:00
|
|
|
|
self.on_change_name()
|
2020-11-20 23:27:29 +01:00
|
|
|
|
if self.type_person == '1':
|
2020-11-09 04:18:37 +01:00
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
@fields.depends('name','first_name','second_name','first_surname',
|
|
|
|
|
'second_surname','type_person')
|
|
|
|
|
def on_change_name(self):
|
|
|
|
|
self.rebuild_name()
|
|
|
|
|
|
|
|
|
|
@fields.depends('name','first_name','second_name','first_surname',
|
|
|
|
|
'second_surname','type_person')
|
|
|
|
|
def on_change_first_name(self):
|
|
|
|
|
self.rebuild_name()
|
|
|
|
|
|
|
|
|
|
@fields.depends('name','first_name','second_name','first_surname',
|
|
|
|
|
'second_surname','type_person')
|
|
|
|
|
def on_change_second_name(self):
|
|
|
|
|
self.rebuild_name()
|
|
|
|
|
|
|
|
|
|
@fields.depends('name','first_name','second_name','first_surname',
|
|
|
|
|
'second_surname','type_person')
|
|
|
|
|
def on_change_second_surname(self):
|
|
|
|
|
self.rebuild_name()
|
|
|
|
|
|
|
|
|
|
@fields.depends('name','first_name','second_name','first_surname',
|
|
|
|
|
'second_surname','type_person')
|
|
|
|
|
def on_change_first_surname(self):
|
|
|
|
|
self.rebuild_name()
|
|
|
|
|
|
|
|
|
|
def rebuild_name(self):
|
|
|
|
|
"""reconstruye los campos relacionados con el nombre dependiendo de
|
|
|
|
|
estos y del tipo de persona."""
|
|
|
|
|
|
2020-11-20 23:27:29 +01:00
|
|
|
|
if self.type_person == '2':
|
2020-11-09 04:18:37 +01:00
|
|
|
|
if not (self.first_name or self.second_name \
|
|
|
|
|
or self.first_surname or self.second_surname):
|
|
|
|
|
if self.name:
|
|
|
|
|
self.first_name, self.second_name, self.first_surname, \
|
|
|
|
|
self.second_surname = self.split_name(self.name)
|
|
|
|
|
else:
|
|
|
|
|
return
|
|
|
|
|
else:
|
|
|
|
|
self.name = self.get_full_name()
|
2020-11-20 23:27:29 +01:00
|
|
|
|
if self.type_person == '1':
|
2020-11-09 04:18:37 +01:00
|
|
|
|
if self.name:
|
|
|
|
|
self.clean_split_name()
|
|
|
|
|
else:
|
|
|
|
|
self.name = self.get_full_name()
|
|
|
|
|
|
|
|
|
|
def clean_split_name(self):
|
|
|
|
|
self.first_name = self.second_name = self.first_surname = self.second_surname = ''
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def split_name(name):
|
|
|
|
|
"""Divide un nombre completo en una lista de 4 elementos"""
|
|
|
|
|
|
|
|
|
|
second_surname = None
|
|
|
|
|
first_surname = None
|
|
|
|
|
second_name = None
|
|
|
|
|
first_name = None
|
|
|
|
|
names = name.split(' ')
|
|
|
|
|
if len(names) > 0:
|
|
|
|
|
first_name = names[0]
|
|
|
|
|
if len(names) == 2:
|
|
|
|
|
second_surname = None
|
|
|
|
|
first_surname = names[1]
|
|
|
|
|
elif len(names) == 3:
|
|
|
|
|
first_surname = names[1]
|
|
|
|
|
second_surname = names[2]
|
|
|
|
|
elif len(names) >= 4:
|
|
|
|
|
second_name = names[1]
|
|
|
|
|
first_surname = names[2]
|
|
|
|
|
second_surname = " ".join(names[3:])
|
|
|
|
|
return [first_name,second_name,first_surname, second_surname]
|
|
|
|
|
|
|
|
|
|
@fields.depends('identifiers')
|
|
|
|
|
def on_change_with_type_tax_identifier(self,name=None):
|
|
|
|
|
types = self._tax_identifier_types()
|
|
|
|
|
if self.identifiers:
|
|
|
|
|
for identifier in self.identifiers:
|
|
|
|
|
if identifier.type in types:
|
|
|
|
|
return identifier.type
|
|
|
|
|
|
|
|
|
|
@fields.depends('identifiers')
|
|
|
|
|
def on_change_with_tax_identifier(self,name=None):
|
|
|
|
|
if self.identifiers:
|
|
|
|
|
return self.get_tax_identifier(name)
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def _tax_identifier_types(cls):
|
|
|
|
|
types = super(Party, cls).tax_identifier_types()
|
|
|
|
|
types.extend(['31','13'])
|
|
|
|
|
return types
|
|
|
|
|
|
|
|
|
|
def get_full_name(self, name=None):
|
2020-11-20 23:27:29 +01:00
|
|
|
|
if self.type_person == '2':
|
2020-11-09 04:18:37 +01:00
|
|
|
|
name_list = [self.first_name, self.second_name,
|
|
|
|
|
self.first_surname,self.second_surname]
|
|
|
|
|
return " ".join([x for x in name_list if x])
|
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def get_types_identifier():
|
|
|
|
|
PartyIdentifier = Pool().get('party.identifier')
|
|
|
|
|
return PartyIdentifier.type.selection
|
|
|
|
|
|
|
|
|
|
def pre_validate(self):
|
|
|
|
|
super(Party, self).pre_validate()
|
|
|
|
|
if not self.identifiers:
|
2020-11-20 23:27:29 +01:00
|
|
|
|
raise PartyIdentifierError(gettext(
|
|
|
|
|
'account_co_co.msg_not_identifier'))
|
2020-11-09 04:18:37 +01:00
|
|
|
|
|
2020-11-20 23:27:29 +01:00
|
|
|
|
|
2020-11-09 04:18:37 +01:00
|
|
|
|
class PartyIdentifier(ModelSQL, ModelView):
|
|
|
|
|
"Party Identifier Colombian"
|
|
|
|
|
|
|
|
|
|
__name__ = "party.identifier"
|
|
|
|
|
__metaclass__ = PoolMeta
|
|
|
|
|
|
|
|
|
|
expedition_city = fields.Many2One("country.subdivision",
|
|
|
|
|
'Ciudad de Expedicion',
|
|
|
|
|
help="Lugar donde fue expedido el documento de identidad",
|
|
|
|
|
domain=[('parent', '!=', None)],
|
|
|
|
|
states = {'invisible':Not(Equal(Eval('type'),'13'))}
|
|
|
|
|
)
|
2020-11-20 23:27:29 +01:00
|
|
|
|
rut = fields.Boolean('Rut',
|
|
|
|
|
states = {'invisible':And(Not(Equal(Eval('type'),('12'))),
|
|
|
|
|
Not(Equal(Eval('type'),('13'))),
|
|
|
|
|
Not(Equal(Eval('type'),('31')))),
|
|
|
|
|
'readonly':Equal(Eval('type'),('31'))})
|
2020-11-09 04:18:37 +01:00
|
|
|
|
check_digit = fields.Function(fields.Integer('DV',
|
2020-11-20 23:27:29 +01:00
|
|
|
|
help='Digito de Verificacion colombiano',
|
|
|
|
|
states = {'invisible':~Eval('rut', False)})
|
|
|
|
|
,'on_change_with_check_digit')
|
2020-11-09 04:18:37 +01:00
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def __setup__(cls):
|
|
|
|
|
super(PartyIdentifier, cls).__setup__()
|
2020-11-16 23:41:36 +01:00
|
|
|
|
cls.type.selection = TAX_CO_IDENTIFIERS
|
2020-11-20 23:27:29 +01:00
|
|
|
|
cls.type.required = True
|
2020-11-09 04:18:37 +01:00
|
|
|
|
table = cls.__table__()
|
|
|
|
|
cls._sql_constraints += [
|
|
|
|
|
('UniqueIdentifier', Unique(table, table.code,table.type),
|
|
|
|
|
'La identificacion ya existe')
|
|
|
|
|
]
|
|
|
|
|
|
2020-11-20 23:27:29 +01:00
|
|
|
|
@fields.depends('rut','type')
|
|
|
|
|
def on_change_type(self):
|
|
|
|
|
if self.type == '31':
|
|
|
|
|
self.rut = True
|
|
|
|
|
|
2020-11-09 04:18:37 +01:00
|
|
|
|
|
|
|
|
|
@fields.depends('type','code')
|
|
|
|
|
def on_change_with_check_digit(self,name=None):
|
|
|
|
|
try:
|
|
|
|
|
import stdnum.co.nit #la version debe ser mayor a la 1.2 o 1.3
|
|
|
|
|
except:
|
2020-11-20 23:27:29 +01:00
|
|
|
|
raise PartyIdentifierError(gettext(
|
|
|
|
|
'account_co_co.msg_stdnum_error'))
|
2020-11-09 04:18:37 +01:00
|
|
|
|
if self.type and self.code:
|
2020-11-20 23:27:29 +01:00
|
|
|
|
if self.type in ('12','13','31') and self.code.isdigit():
|
2020-11-09 04:18:37 +01:00
|
|
|
|
return int(stdnum.co.nit.calc_check_digit(self.code))
|
|
|
|
|
|
2020-11-20 23:27:29 +01:00
|
|
|
|
@fields.depends('type', 'party', 'code', 'rut')
|
2020-11-09 04:18:37 +01:00
|
|
|
|
def check_code(self):
|
2020-11-20 23:27:29 +01:00
|
|
|
|
|
2020-11-09 04:18:37 +01:00
|
|
|
|
super(PartyIdentifier, self).check_code()
|
2020-11-20 23:27:29 +01:00
|
|
|
|
tax_identifiers = ['12', '13', '31']
|
|
|
|
|
|
2020-11-09 04:18:37 +01:00
|
|
|
|
if self.type == '31':
|
2020-11-20 23:27:29 +01:00
|
|
|
|
self.rut = True
|
|
|
|
|
if self.rut != False and self.type in tax_identifiers:
|
2020-11-09 04:18:37 +01:00
|
|
|
|
#generalizar multiples paises
|
|
|
|
|
#puede ser por el country del party de la company actual
|
|
|
|
|
try:
|
|
|
|
|
import stdnum.co.nit #la version debe ser mayor a la 1.2 o 1.3
|
|
|
|
|
except:
|
2020-11-20 23:27:29 +01:00
|
|
|
|
raise PartyIdentifierError(gettext(
|
|
|
|
|
'account_co_co.msg_stdnum_error'))
|
|
|
|
|
|
|
|
|
|
if self.code.isdigit() is not True:
|
|
|
|
|
raise PartyIdentifierError(gettext(
|
|
|
|
|
'account_co_co.msg_invalid_vat_str'))
|
2020-11-09 04:18:37 +01:00
|
|
|
|
|
|
|
|
|
if not stdnum.co.nit.is_valid(self.code + str(self.check_digit)):
|
|
|
|
|
if self.party and self.party.id > 0:
|
|
|
|
|
party = self.party.rec_name
|
|
|
|
|
else:
|
|
|
|
|
party = ''
|
2020-11-20 23:27:29 +01:00
|
|
|
|
raise PartyIdentifierError(
|
|
|
|
|
gettext('account_co_co.msg_invalid_vat',
|
|
|
|
|
code=self.code))
|
2020-11-21 01:30:42 +01:00
|
|
|
|
|
2020-11-20 23:27:29 +01:00
|
|
|
|
if self.type in tax_identifiers and not self.code.isdigit():
|
2020-11-09 04:18:37 +01:00
|
|
|
|
if self.party and self.party.id > 0:
|
|
|
|
|
party = self.party.rec_name
|
|
|
|
|
else:
|
|
|
|
|
party = ''
|
2020-11-20 23:27:29 +01:00
|
|
|
|
raise PartyIdentifierError(
|
|
|
|
|
gettext('account_co_co.msg_invalid_vat',
|
|
|
|
|
code=self.code))
|
2020-11-21 01:30:42 +01:00
|
|
|
|
|
2020-11-09 04:18:37 +01:00
|
|
|
|
@staticmethod
|
|
|
|
|
def default_type_document():
|
|
|
|
|
return '13'
|
2020-11-20 23:27:29 +01:00
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def default_rut():
|
|
|
|
|
return False
|
|
|
|
|
|
2020-11-09 04:18:37 +01:00
|
|
|
|
def get_rec_name(self,name=None):
|
|
|
|
|
if self.code:
|
|
|
|
|
return self.code
|
|
|
|
|
elif self.id:
|
|
|
|
|
return self.id
|
|
|
|
|
return ''
|
|
|
|
|
|
2020-11-16 18:06:49 +01:00
|
|
|
|
|
|
|
|
|
class PartyTaxLevelCode(ModelSQL, ModelView):
|
|
|
|
|
"Party Tax Level Code"
|
|
|
|
|
__name__ = 'party.party_tax_level_code'
|
|
|
|
|
|
|
|
|
|
party = fields.Many2One('party.party', 'Party', select=True)
|
|
|
|
|
tax_level_code = fields.Many2One('party.tax_level_code', 'TaxLevelCode', select=True)
|
|
|
|
|
|
|
|
|
|
|
2020-11-09 04:18:37 +01:00
|
|
|
|
class ContactMechanism(sequence_ordered(), ModelSQL, ModelView):
|
|
|
|
|
"Contact Mechanism"
|
|
|
|
|
__name__ = 'party.contact_mechanism'
|
|
|
|
|
__metaclass__ = PoolMeta
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def __setup__(cls):
|
|
|
|
|
super(ContactMechanism, cls).__setup__()
|
|
|
|
|
cls.type.selection.extend(CO_CONTACT_MECHANISM_TYPES)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Address(ModelSQL, ModelView):
|
|
|
|
|
"Address"
|
|
|
|
|
|
|
|
|
|
__metaclass__ = PoolMeta
|
|
|
|
|
__name__ = 'party.address'
|
|
|
|
|
|
2020-11-15 22:06:16 +01:00
|
|
|
|
subdivision_municipality = fields.Many2One("country.subdivision",
|
|
|
|
|
'Municipality',
|
2020-11-09 04:18:37 +01:00
|
|
|
|
domain=[
|
2020-11-15 01:57:10 +01:00
|
|
|
|
('country', '=', Eval('country', -1)),
|
|
|
|
|
('parent', '=', Eval('subdivision', -1)),
|
2020-11-15 22:06:16 +01:00
|
|
|
|
('type', '=', 'municipality')
|
2020-11-15 01:57:10 +01:00
|
|
|
|
],
|
|
|
|
|
depends=['country', 'subdivision', 'city'],
|
2020-11-21 01:30:42 +01:00
|
|
|
|
required=True
|
2020-11-15 01:57:10 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2020-11-15 22:06:16 +01:00
|
|
|
|
@fields.depends('subdivision', 'subdivision_municipality', 'country')
|
2020-11-15 01:57:10 +01:00
|
|
|
|
def on_change_country(self):
|
|
|
|
|
super(Address, self).on_change_country()
|
2020-11-15 22:06:16 +01:00
|
|
|
|
if (self.subdivision_municipality
|
|
|
|
|
and self.subdivision_municipality.parent != self.subdivision):
|
|
|
|
|
self.subdivision_municipality = None
|
2020-11-15 01:57:10 +01:00
|
|
|
|
|
2020-11-15 22:06:16 +01:00
|
|
|
|
@fields.depends('subdivision', 'subdivision_municipality')
|
2020-11-15 01:57:10 +01:00
|
|
|
|
def on_change_subdivision(self):
|
|
|
|
|
if hasattr(super(Address, self), 'on_change_subdivision'):
|
|
|
|
|
super(Address, self).on_change_subdivision()
|
2020-11-15 22:06:16 +01:00
|
|
|
|
if (self.subdivision_municipality
|
|
|
|
|
and self.subdivision_municipality.parent != self.subdivision):
|
|
|
|
|
self.subdivision_municipality = None
|
2020-11-15 01:57:10 +01:00
|
|
|
|
|
|
|
|
|
|
2020-11-15 22:06:16 +01:00
|
|
|
|
@fields.depends('city', 'subdivision_municipality')
|
|
|
|
|
def on_change_subdivision_municipality(self):
|
|
|
|
|
if self.subdivision_municipality:
|
|
|
|
|
self.city = self.subdivision_municipality.name
|
2020-11-15 01:57:10 +01:00
|
|
|
|
else:
|
|
|
|
|
self.city = None
|