123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- # -*- coding: utf-8 -*-
- ##############################################################################
- #
- # OpenERP, Open Source Management Solution
- # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU Affero General Public License as
- # published by the Free Software Foundation, either version 3 of the
- # License, or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU Affero General Public License for more details.
- #
- # You should have received a copy of the GNU Affero General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- #
- ##############################################################################
- from openerp import models, fields, tools, api, _
- from openerp.exceptions import ValidationError
- from math import floor
- import re
- import sys
- import logging
- # logger = logging.getlogger(__name__)
- class res_partner(models.Model):
- _name = 'res.partner'
- _inherit = 'res.partner'
- _description = 'Add extra data to SET'
- digitointer = fields.Char('RUC Internacional', size=13)
- dv= fields.Char('Digito Verificador', size=1)
- esinternacional = fields.Boolean(string='Es internacional' ,default = False)
- retencion = fields.Boolean(string='Retiene IVA' ,default = False)
- retentor_renta = fields.Boolean(string='Retentor renta' ,default = False)
- porcentaje_retencion = fields.Integer('Porcentaje de Retención')
- porcentaje_retencion_renta = fields.Integer('Porcentaje de Retención Renta')
- porcentaje_retencion_absorbida = fields.Integer('Porcentaje de Retención Absorbida')
- retiene_iva_cliente = fields.Boolean(string='Es agente retentor' ,default = False)
- concepto_iva = fields.Selection([('femenino','Femenino'),('masculino','Masculino')],'Concepto IVA')
- concepto_renta = fields.Char('Concepto renta')
- rucdv = fields.Char('R.U.C.', size=12)
- naturaleza_receptor = fields.Selection([('1','Contribuyente'),('2','No contribuyente')],'Naturaleza receptor')
- naturaleza_vendedor = fields.Selection([('1','No contribuyente'),('2','Extranjero')],'Naturaleza vendedor')
- nivel = fields.Integer('Nivel', size=2)
- nombre_fantasia = fields.Char('Nombre de fantasia')
- ci = fields.Char('CI', size=13)
- nro_casa = fields.Integer('Nro. Casa')
- nro_documento = fields.Char('Nro. Documento')
- timbrado = fields.Char('Timbrado')
- tipo_documento_identidad = fields.Char('Tipo Documento Identidad')
- iva_retencion_10 = fields.Integer('Porcentaje de retención sobre el IVA 10%')
- iva_retencion_5 = fields.Integer('Porcentaje de retención sobre el IVA 5%')
- tipo_documento_receptor = fields.Selection([('1','Cédula paraguaya'),('2','Pasaporte'),('3','Cédula extranjera'),('4','Carnet de residencia'),('5','Innominado'),('6','Tarjeta diplomática de exoneración fiscal')],'Tipo Documento Receptor')
- tipo_documento_vendedor = fields.Selection([('1','Cédula paraguaya'),('2','Pasaporte'),('3','Cédula extranjera'),('4','Carnet de residencia')],'Tipo Documento Vendedor')
- tipo_operacion = fields.Selection([('1','B2B'),('2','B2C'),('3','B2G'),('4','B2F')],'Tipo Operación')
- situacion = fields.Selection([('contribuyente','Contribuyente'),('nocontribuyente','No contribuyente')],'Situación')
- # activity_id = fields.Many2one("economic.activity",
- # string="Default Economic Activity",
- # context={'active_test': False})
- # economic_activities_ids = fields.Many2many('economic.activity',
- # string='Economic Activities',
- # context={'active_test': False})
- tipo_identificacion = fields.Selection([('1','Cédula paraguaya'),('2','RUC'),('3','Cédula extranjera'),('4','Carnet de residencia'),('5','Innominado')],'Tipo de Identificación')
- # @api.constrains("ruc")
- # def constrains_py_doc_number(self):
- # for partner in self:
- # if not partner.tipo_identificacion and not partner.ruc:
- # continue
- # elif not partner.tipo_identificacion and partner.ruc and not partner.parent_id:
- # raise ValidationError(_("Seleccione un tipo de documento"))
- # elif partner.tipo_identificacion and not partner.ruc:
- # raise ValidationError(_("El campo RUC no puede estar vacio"))
- # vat = partner.ruc
- # if partner.tipo_identificacion == '2':
- # check = self._validate_ruc(vat)
- # if not check:
- # raise ValidationError(_('El número de RUC [%s] no es válido' % vat))
- # elif partner.tipo_identificacion == '1':
- # check = self._validate_ci(vat)
- # if not check:
- # raise ValidationError(_('El número de identificación [%s] no es válido' % vat))
- # else:
- # continue
- #
- # @staticmethod
- # def _validate_ruc(vat):
- # factor = '43298765432'
- # sum = 0
- # dig_check = None
- # if len(vat) != 12:
- # return False
- # try:
- # int(vat)
- # except ValueError:
- # return False
- # for f in range(0, 11):
- # sum += int(factor[f]) * int(vat[f])
- # subtraction = 11 - floor((sum % 11))
- # if subtraction < 10:
- # dig_check = subtraction
- # elif subtraction == 10:
- # dig_check = ""
- # elif subtraction == 11:
- # dig_check = 0
- #
- # if not int(vat[11]) == dig_check:
- # return False
- # return True
- #
- # @staticmethod
- # # def _validate_ci(vat):
- #
- # def _validate_ci(vat):
- # logging.warning(vat)
- # ruc = ''
- # basemax = 7
- # for c in str(vat).replace('-', ''):
- # ruc += c.isdigit() and c or str(ord(c))
- # k = 2
- # total = 0
- #
- # for c in reversed(ruc[:-1]):
- # n = int(c)
- # if n > basemax:
- # k = 2
- # total += n * k
- # k += 1
- # resto = total % basemax
- # if resto > 1:
- # n = basemax - resto
- # else:
- # n = 0
- # return n == int(ruc[-1])
- # vat = vat.replace("-", "").replace('.', '')
- # sum = 0
- # if not vat:
- # return False
- # try:
- # int(vat)
- # except ValueError:
- # return False
- # vat = "%08d" % int(vat)
- # long = len(vat)
- # if long > 8:
- # return False
- # code = [2, 9, 8, 7, 6, 3, 4]
- # for f in range(0, long - 1):
- # sum += int(vat[f]) * int(code[f])
- # total = sum + int(vat[-1])
- # subtraction = total % 10
- # if subtraction != 0:
- # return False
- # return True
- # """
- # El numero de una cédula de identidad tiene exactamente 7 dígitos al cual se le adiciona
- # un dígito verificador.
- #
- # Es así que un número valido debe respetar el siguiente formato:
- #
- # a.bcd.efg-h
- #
- # El dígito posterior al guión (h) es también llamado dígito verificador.
- #
- # Para obtener h debemos:
- #
- # Multiplicar a,b,c,d,e,f,g por las siguientes constantes:
- # (a; b; c; d; e; f; g) .* (2; 9; 8; 7; 6; 3; 4)
- #
- # El resultado de la suma s = 2*a + 9*b + 8*c + 7*d + 6*e + 3*f + 4*g es dividido por 10
- # quedándonos con resto (M = s modulo 10)
- #
- # Finalmente h = (10 - M) % 10
- #
- # Ejemplo practico:
- # Si la CI es 1.234.567:
- #
- # s = 2*1 + 9*2 + 8*3 + 7*4 + 6*5 + 3*6 + 4*7 = 148
- # M = 148 % 10 = 8
- # h = (10 - 8) % 10 = 2
- # Obteniendo que 1.234.567-2 es un número de CI valido.
- # """
- # class res_partner(models.Model):
- # _inherit = 'res.partner'
- # code = [2, 9, 8, 7, 6, 3, 4]
- #
- # # def __init__(self, vat):
- # """ Inicializa la clase
- # Asigna un numero de cedula a la propiedad publica numero
- #
- # Args:
- # numero: un numero de cedula entre 6 y 7 digitos, puede ser int o string
- # """
- # self.ruc = vat
- # self._verifier = ""
- #
- # @property
- # def numero(self):
- # """ propiedad de lectura
- #
- # Returns:
- # _numero: la propiedad privada de numero de cedula ya normalizada
- # """
- # return self._ruc
- #
- # @numero.setter
- # def numero(self, val):
- # """ asigna a la propiedad privada el numero de cedula asignado a numero,
- # lo normaliza y valida
- # Args:
- # val (int o string): el numero de cedula
- #
- # """
- # try:
- # if isinstance(val, str):
- # # si la cedula es un string, le saco el formato (puntos y guiones)
- # numUpdated = re.sub(r"[\.|\-]", "", val)
- # self._ruc = numUpdated
- # else:
- # self._ruc = str(val)
- #
- # if not self._ruc.isnumeric():
- # sys.exit("cedula should be only numbers")
- #
- # if (len(self._ruc) < 6 or len(self._ruc) > 7):
- # sys.exit("invalid cedula length...")
- #
- # except:
- # sys.exit(
- # "Cedula conversion error, check cedula length, value or format.")
- #
- # @property
- # def verifier(self):
- # """propiedad de lectura del digito verificador
- #
- # Returns:
- # int: digito verificador
- # """
- # return self._verifier
- #
- # def __acumSequence(self, seq, index):
- # """ funcion recursiva privada que suma los digitos de una cedula
- #
- # Args:
- # seq: el numero en la constante SEQUENCE
- # index (int): la posicion en ambos arrays (secuencia y cedula)
- # Deben matchear en posicion
- #
- # ** NOTA: como la correspondencia debe ser 1:1 seq y _numero, en caso de ser
- # una cedula de 6 digitos se podia haber agregado un 0 al inicio de _numero para comenzar
- # con el mismo largo (7 digitos), pero asi es mas divertido :D
- #
- # Returns:
- # int: la acumulacion de la suma de digito de self._numero * digito de secuencia
- # """
- # if index < (len(seq) - 1):
- # return (seq[index] * int(self._ruc[index])) + self.__acumSequence(seq, index + 1)
- # return seq[index] * int(self._ruc[index])
- #
- # def getVerifierDigit(self):
- # """ calculo de digito verificador
- #
- # Returns:
- # int: digito verificador
- # """
- # try:
- # digit_diff = (len(self.code) - len(self._ruc))
- # if digit_diff >= 0:
- # acum = 0
- # acum = self.__acumSequence(self.code[digit_diff:], 0)
- # mod = (acum % 10)
- # verifier = ((10 - mod) % 10)
- # self._verifier = str(verifier)
- # return verifier
- # except:
- # print("ERROR: unknown error, check params!")
- #
- # def formatCedula(self):
- # """ formatea un numero de cedula al formato de puntos y guion
- # ej: 12345678 => 1.234.567-8
- #
- # Returns:
- # string: el numero de cedula completo y formateado
- # """
- # self.getVerifierDigit()
- # if len(self.ruc) == 6:
- # return self.ruc[:3] + '.' + self.ruc[3:] + '-' + self.verifier
- # return self.ruc[:1] + '.' + self.ruc[1:4] + '.' + self.ruc[4:] + '-' + self.verifier
|