partner_data.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. # -*- coding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # OpenERP, Open Source Management Solution
  5. # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
  6. #
  7. # This program is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU Affero General Public License as
  9. # published by the Free Software Foundation, either version 3 of the
  10. # License, or (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU Affero General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Affero General Public License
  18. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. #
  20. ##############################################################################
  21. from openerp import models, fields, tools, api, _
  22. from openerp.exceptions import ValidationError
  23. from math import floor
  24. import re
  25. import sys
  26. import logging
  27. # logger = logging.getlogger(__name__)
  28. class res_partner(models.Model):
  29. _name = 'res.partner'
  30. _inherit = 'res.partner'
  31. _description = 'Add extra data to SET'
  32. digitointer = fields.Char('RUC Internacional', size=13)
  33. dv= fields.Char('Digito Verificador', size=1)
  34. esinternacional = fields.Boolean(string='Es internacional' ,default = False)
  35. retencion = fields.Boolean(string='Retiene IVA' ,default = False)
  36. retentor_renta = fields.Boolean(string='Retentor renta' ,default = False)
  37. porcentaje_retencion = fields.Integer('Porcentaje de Retención')
  38. porcentaje_retencion_renta = fields.Integer('Porcentaje de Retención Renta')
  39. porcentaje_retencion_absorbida = fields.Integer('Porcentaje de Retención Absorbida')
  40. retiene_iva_cliente = fields.Boolean(string='Es agente retentor' ,default = False)
  41. concepto_iva = fields.Selection([('femenino','Femenino'),('masculino','Masculino')],'Concepto IVA')
  42. concepto_renta = fields.Char('Concepto renta')
  43. rucdv = fields.Char('R.U.C.', size=12)
  44. naturaleza_receptor = fields.Selection([('1','Contribuyente'),('2','No contribuyente')],'Naturaleza receptor')
  45. naturaleza_vendedor = fields.Selection([('1','No contribuyente'),('2','Extranjero')],'Naturaleza vendedor')
  46. nivel = fields.Integer('Nivel', size=2)
  47. nombre_fantasia = fields.Char('Nombre de fantasia')
  48. ci = fields.Char('CI', size=13)
  49. nro_casa = fields.Integer('Nro. Casa')
  50. nro_documento = fields.Char('Nro. Documento')
  51. timbrado = fields.Char('Timbrado')
  52. tipo_documento_identidad = fields.Char('Tipo Documento Identidad')
  53. iva_retencion_10 = fields.Integer('Porcentaje de retención sobre el IVA 10%')
  54. iva_retencion_5 = fields.Integer('Porcentaje de retención sobre el IVA 5%')
  55. 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')
  56. tipo_documento_vendedor = fields.Selection([('1','Cédula paraguaya'),('2','Pasaporte'),('3','Cédula extranjera'),('4','Carnet de residencia')],'Tipo Documento Vendedor')
  57. tipo_operacion = fields.Selection([('1','B2B'),('2','B2C'),('3','B2G'),('4','B2F')],'Tipo Operación')
  58. situacion = fields.Selection([('contribuyente','Contribuyente'),('nocontribuyente','No contribuyente')],'Situación')
  59. # activity_id = fields.Many2one("economic.activity",
  60. # string="Default Economic Activity",
  61. # context={'active_test': False})
  62. # economic_activities_ids = fields.Many2many('economic.activity',
  63. # string='Economic Activities',
  64. # context={'active_test': False})
  65. tipo_identificacion = fields.Selection([('1','Cédula paraguaya'),('2','RUC'),('3','Cédula extranjera'),('4','Carnet de residencia'),('5','Innominado')],'Tipo de Identificación')
  66. # @api.constrains("ruc")
  67. # def constrains_py_doc_number(self):
  68. # for partner in self:
  69. # if not partner.tipo_identificacion and not partner.ruc:
  70. # continue
  71. # elif not partner.tipo_identificacion and partner.ruc and not partner.parent_id:
  72. # raise ValidationError(_("Seleccione un tipo de documento"))
  73. # elif partner.tipo_identificacion and not partner.ruc:
  74. # raise ValidationError(_("El campo RUC no puede estar vacio"))
  75. # vat = partner.ruc
  76. # if partner.tipo_identificacion == '2':
  77. # check = self._validate_ruc(vat)
  78. # if not check:
  79. # raise ValidationError(_('El número de RUC [%s] no es válido' % vat))
  80. # elif partner.tipo_identificacion == '1':
  81. # check = self._validate_ci(vat)
  82. # if not check:
  83. # raise ValidationError(_('El número de identificación [%s] no es válido' % vat))
  84. # else:
  85. # continue
  86. #
  87. # @staticmethod
  88. # def _validate_ruc(vat):
  89. # factor = '43298765432'
  90. # sum = 0
  91. # dig_check = None
  92. # if len(vat) != 12:
  93. # return False
  94. # try:
  95. # int(vat)
  96. # except ValueError:
  97. # return False
  98. # for f in range(0, 11):
  99. # sum += int(factor[f]) * int(vat[f])
  100. # subtraction = 11 - floor((sum % 11))
  101. # if subtraction < 10:
  102. # dig_check = subtraction
  103. # elif subtraction == 10:
  104. # dig_check = ""
  105. # elif subtraction == 11:
  106. # dig_check = 0
  107. #
  108. # if not int(vat[11]) == dig_check:
  109. # return False
  110. # return True
  111. #
  112. # @staticmethod
  113. # # def _validate_ci(vat):
  114. #
  115. # def _validate_ci(vat):
  116. # logging.warning(vat)
  117. # ruc = ''
  118. # basemax = 7
  119. # for c in str(vat).replace('-', ''):
  120. # ruc += c.isdigit() and c or str(ord(c))
  121. # k = 2
  122. # total = 0
  123. #
  124. # for c in reversed(ruc[:-1]):
  125. # n = int(c)
  126. # if n > basemax:
  127. # k = 2
  128. # total += n * k
  129. # k += 1
  130. # resto = total % basemax
  131. # if resto > 1:
  132. # n = basemax - resto
  133. # else:
  134. # n = 0
  135. # return n == int(ruc[-1])
  136. # vat = vat.replace("-", "").replace('.', '')
  137. # sum = 0
  138. # if not vat:
  139. # return False
  140. # try:
  141. # int(vat)
  142. # except ValueError:
  143. # return False
  144. # vat = "%08d" % int(vat)
  145. # long = len(vat)
  146. # if long > 8:
  147. # return False
  148. # code = [2, 9, 8, 7, 6, 3, 4]
  149. # for f in range(0, long - 1):
  150. # sum += int(vat[f]) * int(code[f])
  151. # total = sum + int(vat[-1])
  152. # subtraction = total % 10
  153. # if subtraction != 0:
  154. # return False
  155. # return True
  156. # """
  157. # El numero de una cédula de identidad tiene exactamente 7 dígitos al cual se le adiciona
  158. # un dígito verificador.
  159. #
  160. # Es así que un número valido debe respetar el siguiente formato:
  161. #
  162. # a.bcd.efg-h
  163. #
  164. # El dígito posterior al guión (h) es también llamado dígito verificador.
  165. #
  166. # Para obtener h debemos:
  167. #
  168. # Multiplicar a,b,c,d,e,f,g por las siguientes constantes:
  169. # (a; b; c; d; e; f; g) .* (2; 9; 8; 7; 6; 3; 4)
  170. #
  171. # El resultado de la suma s = 2*a + 9*b + 8*c + 7*d + 6*e + 3*f + 4*g es dividido por 10
  172. # quedándonos con resto (M = s modulo 10)
  173. #
  174. # Finalmente h = (10 - M) % 10
  175. #
  176. # Ejemplo practico:
  177. # Si la CI es 1.234.567:
  178. #
  179. # s = 2*1 + 9*2 + 8*3 + 7*4 + 6*5 + 3*6 + 4*7 = 148
  180. # M = 148 % 10 = 8
  181. # h = (10 - 8) % 10 = 2
  182. # Obteniendo que 1.234.567-2 es un número de CI valido.
  183. # """
  184. # class res_partner(models.Model):
  185. # _inherit = 'res.partner'
  186. # code = [2, 9, 8, 7, 6, 3, 4]
  187. #
  188. # # def __init__(self, vat):
  189. # """ Inicializa la clase
  190. # Asigna un numero de cedula a la propiedad publica numero
  191. #
  192. # Args:
  193. # numero: un numero de cedula entre 6 y 7 digitos, puede ser int o string
  194. # """
  195. # self.ruc = vat
  196. # self._verifier = ""
  197. #
  198. # @property
  199. # def numero(self):
  200. # """ propiedad de lectura
  201. #
  202. # Returns:
  203. # _numero: la propiedad privada de numero de cedula ya normalizada
  204. # """
  205. # return self._ruc
  206. #
  207. # @numero.setter
  208. # def numero(self, val):
  209. # """ asigna a la propiedad privada el numero de cedula asignado a numero,
  210. # lo normaliza y valida
  211. # Args:
  212. # val (int o string): el numero de cedula
  213. #
  214. # """
  215. # try:
  216. # if isinstance(val, str):
  217. # # si la cedula es un string, le saco el formato (puntos y guiones)
  218. # numUpdated = re.sub(r"[\.|\-]", "", val)
  219. # self._ruc = numUpdated
  220. # else:
  221. # self._ruc = str(val)
  222. #
  223. # if not self._ruc.isnumeric():
  224. # sys.exit("cedula should be only numbers")
  225. #
  226. # if (len(self._ruc) < 6 or len(self._ruc) > 7):
  227. # sys.exit("invalid cedula length...")
  228. #
  229. # except:
  230. # sys.exit(
  231. # "Cedula conversion error, check cedula length, value or format.")
  232. #
  233. # @property
  234. # def verifier(self):
  235. # """propiedad de lectura del digito verificador
  236. #
  237. # Returns:
  238. # int: digito verificador
  239. # """
  240. # return self._verifier
  241. #
  242. # def __acumSequence(self, seq, index):
  243. # """ funcion recursiva privada que suma los digitos de una cedula
  244. #
  245. # Args:
  246. # seq: el numero en la constante SEQUENCE
  247. # index (int): la posicion en ambos arrays (secuencia y cedula)
  248. # Deben matchear en posicion
  249. #
  250. # ** NOTA: como la correspondencia debe ser 1:1 seq y _numero, en caso de ser
  251. # una cedula de 6 digitos se podia haber agregado un 0 al inicio de _numero para comenzar
  252. # con el mismo largo (7 digitos), pero asi es mas divertido :D
  253. #
  254. # Returns:
  255. # int: la acumulacion de la suma de digito de self._numero * digito de secuencia
  256. # """
  257. # if index < (len(seq) - 1):
  258. # return (seq[index] * int(self._ruc[index])) + self.__acumSequence(seq, index + 1)
  259. # return seq[index] * int(self._ruc[index])
  260. #
  261. # def getVerifierDigit(self):
  262. # """ calculo de digito verificador
  263. #
  264. # Returns:
  265. # int: digito verificador
  266. # """
  267. # try:
  268. # digit_diff = (len(self.code) - len(self._ruc))
  269. # if digit_diff >= 0:
  270. # acum = 0
  271. # acum = self.__acumSequence(self.code[digit_diff:], 0)
  272. # mod = (acum % 10)
  273. # verifier = ((10 - mod) % 10)
  274. # self._verifier = str(verifier)
  275. # return verifier
  276. # except:
  277. # print("ERROR: unknown error, check params!")
  278. #
  279. # def formatCedula(self):
  280. # """ formatea un numero de cedula al formato de puntos y guion
  281. # ej: 12345678 => 1.234.567-8
  282. #
  283. # Returns:
  284. # string: el numero de cedula completo y formateado
  285. # """
  286. # self.getVerifierDigit()
  287. # if len(self.ruc) == 6:
  288. # return self.ruc[:3] + '.' + self.ruc[3:] + '-' + self.verifier
  289. # return self.ruc[:1] + '.' + self.ruc[1:4] + '.' + self.ruc[4:] + '-' + self.verifier