RUT in Identifier and message/exceptions
This commit is contained in:
parent
0c38c5dbfe
commit
aa909bbffc
6 changed files with 129 additions and 35 deletions
|
@ -2,6 +2,7 @@ from trytond.pool import Pool
|
|||
from . import party
|
||||
from . import country
|
||||
from . import rut
|
||||
|
||||
__all__ = ['register']
|
||||
|
||||
|
||||
|
|
9
exceptions.py
Normal file
9
exceptions.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
# This file is part of 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.model.exceptions import ValidationError
|
||||
|
||||
|
||||
class PartyIdentifierError(ValidationError):
|
||||
pass
|
23
locale/es.po
23
locale/es.po
|
@ -54,3 +54,26 @@ msgctxt "view:party.party:"
|
|||
msgid "Economic Activity"
|
||||
msgstr "Actividad Económica"
|
||||
|
||||
msgctxt "model:ir.message,text:msg_invalid_vat"
|
||||
msgid ""
|
||||
"The value of the code \"%(code)s\" is not valid"
|
||||
msgstr ""
|
||||
"El valor del código \"%(code)s\" no es valido"
|
||||
|
||||
msgctxt "model:ir.message,text:msg_invalid_vat_str"
|
||||
msgid ""
|
||||
"The value of the code can only be numbers"
|
||||
msgstr ""
|
||||
"El valor del código solo pueden ser números"
|
||||
|
||||
msgctxt "model:ir.message,text:msg_not_identifier"
|
||||
msgid ""
|
||||
"The party has to have a identifier"
|
||||
msgstr ""
|
||||
"El tercero debe tener un identificador"
|
||||
|
||||
msgctxt "model:ir.message,text:msg_stdnum_error"
|
||||
msgid ""
|
||||
"Is required module stdnum"
|
||||
msgstr ""
|
||||
"El módulo stdnum es requerido"
|
19
message.xml
Normal file
19
message.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data grouped="1">
|
||||
<record model="ir.message" id="msg_invalid_vat">
|
||||
<field name="text">The value of the code "%(code)s" is not valid</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_not_identifier">
|
||||
<field name="text">The party has to have a identifier</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_stdnum_error">
|
||||
<field name="text">Is required module stdnum</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_invalid_vat_str">
|
||||
<field name="text">The value of the code can only be numbers</field>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
111
party.py
111
party.py
|
@ -1,8 +1,11 @@
|
|||
from trytond.model import fields, ModelSQL, ModelView, Unique, sequence_ordered
|
||||
from trytond.pool import PoolMeta, Pool
|
||||
from trytond.pyson import Eval, Not, Equal
|
||||
import logging
|
||||
from trytond.pyson import Eval, Not, Equal, Or, And
|
||||
from trytond.i18n import gettext
|
||||
from trytond.exceptions import UserError
|
||||
from .exceptions import PartyIdentifierError
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -18,7 +21,7 @@ TAX_CO_IDENTIFIERS = [
|
|||
('22', 'Cedula de Extranjeria'),
|
||||
('31', 'NIT'),
|
||||
('41', 'Pasaporte'),
|
||||
('42', 'Tipo de Documento Extrangero'),
|
||||
('42', 'Tipo de Documento Extranjero'),
|
||||
('43', 'Documento de identificación extranjero'),
|
||||
('50', 'NIT de otro país'),
|
||||
('91', 'NUIP')
|
||||
|
@ -34,16 +37,16 @@ class Party(ModelSQL,ModelView):
|
|||
__metaclass__ = PoolMeta
|
||||
|
||||
first_name = fields.Char("Primer Nombre",states={
|
||||
'invisible': Not(Eval('type_person') == 'persona_natural'),}
|
||||
'invisible': Not(Eval('type_person') == '2'),}
|
||||
)
|
||||
second_name = fields.Char("Segundo Nombre",states={
|
||||
'invisible': Not(Eval('type_person') == 'persona_natural'),}
|
||||
'invisible': Not(Eval('type_person') == '2'),}
|
||||
)
|
||||
first_surname = fields.Char("Primer Apellido",states={
|
||||
'invisible': Not(Eval('type_person') == 'persona_natural'),}
|
||||
'invisible': Not(Eval('type_person') == '2'),}
|
||||
)
|
||||
second_surname = fields.Char("Segundo Apellido",states={
|
||||
'invisible': Not(Eval('type_person') == 'persona_natural'),},
|
||||
'invisible': Not(Eval('type_person') == '2'),},
|
||||
depends=['type_person'])
|
||||
birth_date = fields.Date('Fecha de nacimiento')
|
||||
tax_regime = fields.Selection([
|
||||
|
@ -75,21 +78,23 @@ class Party(ModelSQL,ModelView):
|
|||
'on_change_with_type_tax_identifier')
|
||||
tax_level_code =fields.Many2Many('party.party_tax_level_code','party', 'tax_level_code', "TaxLevelCode")
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Party, cls).__setup__()
|
||||
cls.name.required = True
|
||||
|
||||
@staticmethod
|
||||
def default_type_person():
|
||||
return 'persona_natural'
|
||||
return '2'
|
||||
|
||||
@classmethod
|
||||
def tax_identifier_types(cls):
|
||||
#return ['11', '12', '13', '21', '22', '31', '41', '42', '43', '50', '91']
|
||||
return ['31']
|
||||
return ['12','13','31']
|
||||
|
||||
@classmethod
|
||||
def get_tax_level_code(cls):
|
||||
pool = Pool()
|
||||
TaxLevelCode = pool.get('party.tax_level_code')
|
||||
#raise UserError(str(TaxLevelCode.fields_get(['code'])['code']))
|
||||
return TaxLevelCode.fields_get(['code'])['code']
|
||||
|
||||
@fields.depends('birth_date')
|
||||
|
@ -104,9 +109,9 @@ class Party(ModelSQL,ModelView):
|
|||
@fields.depends('name','first_name','second_name','first_surname',
|
||||
'second_surname','type_person')
|
||||
def on_change_type_person(self):
|
||||
if self.type_person == 'persona_natural':
|
||||
if self.type_person == '2':
|
||||
self.on_change_name()
|
||||
if self.type_person == 'persona_juridica':
|
||||
if self.type_person == '1':
|
||||
pass
|
||||
|
||||
@fields.depends('name','first_name','second_name','first_surname',
|
||||
|
@ -138,7 +143,7 @@ class Party(ModelSQL,ModelView):
|
|||
"""reconstruye los campos relacionados con el nombre dependiendo de
|
||||
estos y del tipo de persona."""
|
||||
|
||||
if self.type_person == 'persona_natural':
|
||||
if self.type_person == '2':
|
||||
if not (self.first_name or self.second_name \
|
||||
or self.first_surname or self.second_surname):
|
||||
if self.name:
|
||||
|
@ -148,7 +153,7 @@ class Party(ModelSQL,ModelView):
|
|||
return
|
||||
else:
|
||||
self.name = self.get_full_name()
|
||||
if self.type_person == 'persona_juridica':
|
||||
if self.type_person == '1':
|
||||
if self.name:
|
||||
self.clean_split_name()
|
||||
else:
|
||||
|
@ -200,7 +205,7 @@ class Party(ModelSQL,ModelView):
|
|||
return types
|
||||
|
||||
def get_full_name(self, name=None):
|
||||
if self.type_person == 'persona_natural':
|
||||
if self.type_person == '2':
|
||||
name_list = [self.first_name, self.second_name,
|
||||
self.first_surname,self.second_surname]
|
||||
return " ".join([x for x in name_list if x])
|
||||
|
@ -214,8 +219,10 @@ class Party(ModelSQL,ModelView):
|
|||
def pre_validate(self):
|
||||
super(Party, self).pre_validate()
|
||||
if not self.identifiers:
|
||||
self.raise_user_error("El tercero debe tener un documento de identidad")
|
||||
raise PartyIdentifierError(gettext(
|
||||
'account_co_co.msg_not_identifier'))
|
||||
|
||||
|
||||
class PartyIdentifier(ModelSQL, ModelView):
|
||||
"Party Identifier Colombian"
|
||||
|
||||
|
@ -228,67 +235,101 @@ class PartyIdentifier(ModelSQL, ModelView):
|
|||
domain=[('parent', '!=', None)],
|
||||
states = {'invisible':Not(Equal(Eval('type'),'13'))}
|
||||
)
|
||||
rut = fields.Boolean('Rut')
|
||||
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'))})
|
||||
check_digit = fields.Function(fields.Integer('DV',
|
||||
help='Digito de Verificacion colombiano',
|
||||
states = {'invisible':Not(Equal(Eval('type'),'31'))})
|
||||
,'on_change_with_check_digit')
|
||||
help='Digito de Verificacion colombiano',
|
||||
states = {'invisible':~Eval('rut', False)})
|
||||
,'on_change_with_check_digit')
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(PartyIdentifier, cls).__setup__()
|
||||
cls.type.selection = TAX_CO_IDENTIFIERS
|
||||
cls.type.required = True
|
||||
table = cls.__table__()
|
||||
cls._sql_constraints += [
|
||||
('UniqueIdentifier', Unique(table, table.code,table.type),
|
||||
'La identificacion ya existe')
|
||||
]
|
||||
|
||||
@fields.depends('rut','type')
|
||||
def on_change_type(self):
|
||||
if self.type == '31':
|
||||
self.rut = True
|
||||
|
||||
|
||||
@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:
|
||||
self.raise_user_error('Se requiere modulo stdnum.co.nit')
|
||||
raise PartyIdentifierError(gettext(
|
||||
'account_co_co.msg_stdnum_error'))
|
||||
if self.type and self.code:
|
||||
if self.type in ('31'):
|
||||
if self.type in ('12','13','31') and self.code.isdigit():
|
||||
return int(stdnum.co.nit.calc_check_digit(self.code))
|
||||
|
||||
@fields.depends('type', 'party', 'code')
|
||||
@fields.depends('type', 'party', 'code', 'rut')
|
||||
def check_code(self):
|
||||
|
||||
#if self.code.isdigit() is not True:
|
||||
#raise UserError(str('33333'))
|
||||
super(PartyIdentifier, self).check_code()
|
||||
tax_identifiers = ['12', '13', '31']
|
||||
|
||||
if self.type == '31':
|
||||
self.rut = True
|
||||
if self.rut != False and self.type in tax_identifiers:
|
||||
#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:
|
||||
self.raise_user_error('Se requiere modulo stdnum.co.nit')
|
||||
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'))
|
||||
|
||||
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 = ''
|
||||
self.raise_user_error('invalid_vat', {
|
||||
'code': self.code,
|
||||
'party': party,
|
||||
})
|
||||
if self.type in ['12','13','31'] and not self.code.isdigit():
|
||||
raise PartyIdentifierError(
|
||||
gettext('account_co_co.msg_invalid_vat',
|
||||
code=self.code))
|
||||
#raise UserError(str('sdfsd'))
|
||||
#self.raise_user_error('invalid_vat', {
|
||||
#'code': self.code,
|
||||
#'party': party,
|
||||
#})
|
||||
if self.type in tax_identifiers and not self.code.isdigit():
|
||||
if self.party and self.party.id > 0:
|
||||
party = self.party.rec_name
|
||||
else:
|
||||
party = ''
|
||||
self.raise_user_error('invalid_vat',{
|
||||
'code':self.code,
|
||||
'party':party
|
||||
})
|
||||
raise PartyIdentifierError(
|
||||
gettext('account_co_co.msg_invalid_vat',
|
||||
code=self.code))
|
||||
#self.raise_user_error('invalid_vat',{
|
||||
#code=self.code,
|
||||
#'party':party
|
||||
#})
|
||||
|
||||
@staticmethod
|
||||
def default_type_document():
|
||||
return '13'
|
||||
|
||||
|
||||
@staticmethod
|
||||
def default_rut():
|
||||
return False
|
||||
|
||||
def get_rec_name(self,name=None):
|
||||
if self.code:
|
||||
return self.code
|
||||
|
|
|
@ -8,6 +8,7 @@ xml:
|
|||
party.xml
|
||||
address.xml
|
||||
rut.xml
|
||||
message.xml
|
||||
subdivisions_colombia.xml
|
||||
municipalities_colombia.xml
|
||||
address_subdivision_types_colombia.xml
|
||||
|
|
Loading…
Reference in a new issue