Merge lp:~vauxoo/openerp-venezuela-localization/hbto_src_fix_islr into lp:openerp-venezuela-localization

Proposed by hbto [Vauxoo] http://www.vauxoo.com
Status: Rejected
Rejected by: hbto [Vauxoo] http://www.vauxoo.com
Proposed branch: lp:~vauxoo/openerp-venezuela-localization/hbto_src_fix_islr
Merge into: lp:openerp-venezuela-localization
Diff against target: 644 lines (+601/-2) (has conflicts)
3 files modified
l10n_ve_withholding_islr/data/l10n_ve_islr_withholding_data.xml (+1/-1)
l10n_ve_withholding_islr/model/invoice.py (+595/-0)
l10n_ve_withholding_islr/model/islr_wh_doc.py (+5/-1)
Text conflict in l10n_ve_withholding_islr/model/invoice.py
Text conflict in l10n_ve_withholding_islr/model/islr_wh_doc.py
To merge this branch: bzr merge lp:~vauxoo/openerp-venezuela-localization/hbto_src_fix_islr
Reviewer Review Type Date Requested Status
hbto [Vauxoo] http://www.vauxoo.com Needs Fixing
Aristóbulo Meneses Pending
Review via email: mp+197966@code.launchpad.net

This proposal supersedes a proposal from 2012-02-15.

Description of the change

Se reparo el subtrayendo de el 1% y se cambio la presicion decimal de ISLR a 4 digitos se agrego una validacion
y se coloco un comentario sobre el cambio

To post a comment you must log in.
Revision history for this message
hbto [Vauxoo] http://www.vauxoo.com (humbertoarocha) wrote :

Debido a que el codigo entre version 6 y 7 de la localizacion tuvo muchos cambios,

se hará una revision de los metodos, uno a uno, y se para revisar que partes del
codigo se pueden reutilizar.

review: Needs Fixing

Unmerged revisions

583. By Jose Moreno

[FIX] Se reparo el subtrayendo de el 1% y se cambio la presicion decimal de ISLR a 4 digitos se agrego una validacion
y se coloco un comentario sobre el cambio

582. By Jose Moreno

[FIX] Se reparo el subtrayendo de el 1% y se cambio la presicion decimal de ISLR a 4 digitos

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'l10n_ve_withholding_islr/data/l10n_ve_islr_withholding_data.xml'
2--- l10n_ve_withholding_islr/data/l10n_ve_islr_withholding_data.xml 2013-08-13 19:53:40 +0000
3+++ l10n_ve_withholding_islr/data/l10n_ve_islr_withholding_data.xml 2013-12-05 22:26:23 +0000
4@@ -4,7 +4,7 @@
5 <!-- Decimal Precision -->
6 <record forcecreate="True" id="decimal_withhold_islr" model="decimal.precision">
7 <field name="name">Withhold ISLR</field>
8- <field name="digits">2</field>
9+ <field name="digits">4</field>
10 </record>
11 <!-- Begin of Concepts -->
12 <record id="islr_wh_concept_no_apply_withholding" model="islr.wh.concept">
13
14=== modified file 'l10n_ve_withholding_islr/model/invoice.py'
15--- l10n_ve_withholding_islr/model/invoice.py 2013-12-04 21:17:57 +0000
16+++ l10n_ve_withholding_islr/model/invoice.py 2013-12-05 22:26:23 +0000
17@@ -215,6 +215,601 @@
18 list.append((x, y, res))
19 return list
20
21+<<<<<<< TREE
22+=======
23+ def _get_partners(self, cr, uid, invoice):
24+ '''
25+ Se obtiene: el id del vendedor, el id del comprador de la factura y el campo booleano que determina si el comprador es agente de retencion.
26+ '''
27+ if invoice.type == 'in_invoice' or invoice.type == 'in_refund':
28+ vendor = invoice.partner_id
29+ buyer = invoice.company_id.partner_id
30+ else:
31+ buyer = invoice.partner_id
32+ vendor = invoice.company_id.partner_id
33+ return (vendor, buyer, buyer.islr_withholding_agent)
34+
35+ def _get_concepts(self, cr, uid, invoice):
36+ '''
37+ Se obtienen una lista de Conceptos(concept_id), de las lineas en la factura
38+ '''
39+ service_list = []
40+ for invoice_line in invoice.invoice_line:
41+ if invoice_line.concept_id and invoice_line.concept_id.withholdable:
42+ service_list.append(invoice_line.concept_id.id)
43+ else:
44+ pass
45+ return list(set(service_list))
46+
47+ def _get_service_wh(self, cr, uid, invoice, concept_list):
48+ '''
49+ Obtiene todas las lineas de factura del vendedor, filtrando por el periodo de la factura actual y el estado de la factura = done, open.
50+ Las lineas son almacenadas en un diccionario, donde la primera clave es la lista de lineas obtenidas, la segunda es el campo que indica si alguna de esas lineas
51+ fue retenida y el tercer campo es la suma de la base de todas las lineas que no se les ha aplicado retencion.
52+ La busqueda de las lineas, se realiza buscando lineas que tengan conceptos de retencion igual a los de la factura actual.
53+ Esto se hace con el fin de verificar:
54+ 1.-Si existe el mismo concepto en otra linea de factura que no se ha retenido porque no ha superado el monto minimo, se toma para realizar la suma y verificar
55+ si con el nuevo monto si supera, en consecuencia se realiza la retencion en las facturas asociadas.
56+ 2.-Se verifica si es la primera vez que se realiza retencion sobre ese concepto, de ser la primera vez se debe aplicar el sustraendo. Esto se hace con el
57+ segundo campo del diccionario "wh"
58+ '''
59+ dict={}
60+ for key in concept_list:
61+ dict[key]={'lines':[],'wh':False,'base':0.0}
62+ inv_obj = self.pool.get('account.invoice')
63+ inv_lst = inv_obj.search(cr, uid,[('partner_id', '=', invoice.partner_id.id),('period_id','=',invoice.period_id.id),('state','in',['done','open'])]) # Lista de facturas asociadas al proveedor actual, al periodo actual y al estado de las facturas: donde, open.
64+
65+ inv_line_lst=[]
66+ for id in inv_lst:
67+ inv_line_brw = inv_obj.browse(cr, uid, id).invoice_line #lista de lineas de facturas
68+ for line in inv_line_brw:
69+ if line.concept_id and line.concept_id.id in concept_list: # Se verifica si el concepto de la linea en la que estoy buscando coincide con alguno de los conceptos de la factura actual.
70+ if not line.apply_wh: # Se verifica si a la linea no se le ha aplicado retencion, de ser asi se almacena el id de la linea y la base.
71+ dict[line.concept_id.id]['lines'].append(line.id)
72+ dict[line.concept_id.id]['base']+= line.price_subtotal
73+ else: # Si ya se le aplico retencion, no se guarda el id porque no hace falta pero se indica que ya se le aplico retencion.
74+ dict[line.concept_id.id]['wh']=True
75+ #~ dict[key]={'lines':[],'wh':False,'base':0.0}
76+ return dict
77+
78+ def _get_country_fiscal(self,cr, uid, partner_id):
79+ '''
80+ Se obtiene el pais de el vendedor o comprador, depende del parametro. A partir de de la direccion fiscal.
81+ '''
82+ for i in partner_id.address:
83+ if i.type == 'invoice':
84+ if not i.country_id:
85+ raise osv.except_osv(_('Invalid action !'),_("Impossible withholding income, because the partner '%s' country has not defined direction in fiscal!") % (partner_id.name))
86+ return False
87+ else:
88+ return i.country_id.id
89+ raise osv.except_osv(_('Invalid action !'),_("Impossible withholding income, because the partner '%s' has not fiscal direction set!.") % (partner_id.name))
90+ return False
91+
92+ def _get_residence(self, cr, uid, vendor, buyer):
93+ '''
94+ Se determina si la direccion fiscal del comprador es la misma que la del vendedor, con el fin de luego obtener la tasa asociada.
95+ Retorna True si es una persona domiciliada o residente. Retorna False si es, no Residente o No Domicialiado.
96+ '''
97+ vendor_address = self._get_country_fiscal(cr, uid, vendor)
98+ buyer_address = self._get_country_fiscal(cr, uid, buyer)
99+ if vendor_address and buyer_address:
100+ if vendor_address == buyer_address:
101+ return True
102+ else:
103+ return False
104+ return False
105+
106+ def _get_nature(self, cr, uid, partner_id):
107+ '''
108+ Se obtiene la naturaleza del vendedor a partir del RIF, retorna True si es persona de tipo natural, y False si es juridica.
109+ '''
110+ if not partner_id.vat:
111+ raise osv.except_osv(_('Invalid action !'),_("Impossible withholding income, because the partner '%s' has not vat associated!") % (partner_id.name))
112+ return False
113+ else:
114+ if partner_id.vat[2:3] in 'VvEe':
115+ return True
116+ else:
117+ return False
118+
119+ def _get_rate(self, cr, uid, concept_id, residence, nature,context):
120+ '''
121+ Se obtiene la tasa del concepto de retencion, siempre y cuando exista uno asociado a las especificaciones:
122+ La naturaleza del vendedor coincida con una tasa.
123+ La residencia del vendedor coindica con una tasa.
124+ '''
125+ ut_obj = self.pool.get('l10n.ut')
126+ rate_brw_lst = self.pool.get('islr.wh.concept').browse(cr, uid, concept_id).rate_ids
127+ for rate_brw in rate_brw_lst:
128+ if rate_brw.nature == nature and rate_brw.residence == residence:
129+ #~ (base,min,porc,sust,codigo,id_rate,name_rate)
130+ rate_brw_minimum = ut_obj.compute_ut_to_money(cr, uid, rate_brw.minimum, False, context)#metodo que transforma los UVT en pesos
131+ rate_brw_subtract = ut_obj.compute_ut_to_money(cr, uid, rate_brw.subtract, False, context)#metodo que transforma los UVT en pesos
132+ return (rate_brw.base, rate_brw_minimum, rate_brw.wh_perc, rate_brw_subtract,rate_brw.code,rate_brw.id,rate_brw.name)
133+ return ()
134+
135+ def _get_rate_dict(self, cr, uid, concept_list, residence, nature,context):
136+ '''
137+ Devuelve un diccionario con la tasa de cada concepto de retencion.
138+ '''
139+ dict = {}
140+ cont = 0
141+ for concept_id in concept_list:
142+ dict[concept_id] = self._get_rate(cr, uid, concept_id, residence, nature,context)
143+ if dict[concept_id]:
144+ cont += 1
145+ if not cont:
146+ raise osv.except_osv(_('Invalid action !'),_("Impossible withholding income, because the Concept of Withholding associated with type line is not withheld!"))
147+ return dict
148+
149+
150+ def _pop_dict(self,cr,uid,concept_list,dict_rate,wh_dict):
151+ '''
152+ Funcion para eliminar del diccionario de conceptos con tasas y del diccionario de lineas de facturas, todos aquellos elementos donde el concepto de retencion no
153+ posee una tasa asociada.
154+ '''
155+ for concept in concept_list:
156+ if not dict_rate[concept]:
157+ dict_rate.pop(concept)
158+ wh_dict.pop(concept)
159+
160+ def _get_wh_calc(self,cr,uid,line,dict_rate_concept):
161+ base = self.pool.get('account.invoice.line').browse(cr,uid,line).price_subtotal
162+ return (base * (dict_rate_concept[0]/100) * (dict_rate_concept[2]/100), base)
163+
164+ def _get_number(self,cr,uid,number,long):
165+ num1 = number[::-1]
166+ result= ''
167+ for i in num1:
168+ if i.isdigit():
169+ if len(result)<long:
170+ result = i + result
171+ else:
172+ break
173+ else:
174+ break
175+ return result.strip()
176+
177+
178+ def _get_inv_data(self,cr, uid, line):
179+ '''
180+ Se obtiene el rif de proveedor, el numero de la factura y el numero de control de la factura. Datos necesarios para el XML, entre otros.
181+ '''
182+ inv_brw = self.pool.get('account.invoice.line').browse(cr, uid, line).invoice_id
183+ vat = inv_brw.partner_id.vat[2:]
184+ if inv_brw.type == 'in_invoice' or inv_brw.type == 'in_refund':
185+ #~ number = inv_brw.reference.strip()
186+ if not inv_brw.reference:
187+ raise osv.except_osv(_('Invalid action !'),_("Impossible withholding income,because the invoice number: '%s' has not number reference free!") % (inv_brw.number))
188+ number = 0
189+ else:
190+ number = self._get_number(cr,uid,inv_brw.reference.strip(),10)
191+ else:
192+ if not inv_brw.number:
193+ number = 0
194+ else:
195+ number = self._get_number(cr,uid,inv_brw.number.strip(),10)
196+ if not inv_brw.nro_ctrl:
197+ raise osv.except_osv(_('Invalid action !'),_("Impossible withholding income, because the invoice number: '%s' has not control number associated!") % (inv_brw.number))
198+ else:
199+ control = self._get_number(cr,uid,inv_brw.nro_ctrl.strip(),8)
200+
201+ return (vat, number, control)
202+
203+ def _write_wh_apply(self,cr, uid,line,dict,apply,type):
204+ '''
205+ Si el campo wh_xml_id en la linea de la factura tiene un id de xml asociado:
206+ Se escribe sobre el campo booleano de la linea de la factura True o False, dependiendo si se retiene o no.
207+ Se escribe sobre la linea de xmls el valor de la retencion. Esto sucede porque se pudo haber creado la linea xml, pero con retencion 0, porque no aplicaba, si llega a superar en otra factura, se debe sobreescribir el valor al nuevo monto de retencion.
208+ De lo contrario:
209+ Se crea una nueva linea de xml.
210+ Se escribe en la linea de la factura, True o False y se asigna el xml_id que resulta del create.
211+ '''
212+ il_ids = self.pool.get('account.invoice.line').browse(cr, uid,line)
213+
214+ if il_ids.wh_xml_id:
215+ self.pool.get('account.invoice.line').write(cr, uid, line, {'apply_wh': apply})
216+ self.pool.get('islr.xml.wh.line').write(cr,uid,il_ids.wh_xml_id.id,{'wh':dict['wh']})
217+ else:
218+ if type in ('out_invoice', 'out_refund'):
219+ self.pool.get('account.invoice.line').write(cr, uid, line, {'apply_wh': apply})
220+ else:
221+ self.pool.get('account.invoice.line').write(cr, uid, line, {'apply_wh': apply,'wh_xml_id':self._create_islr_xml_wh_line(cr, uid,line,dict)})
222+ message = _("Withholding income xml line generated.")
223+ self.log(cr, uid, line, message)
224+
225+ def _create_islr_xml_wh_line(self,cr, uid, line, dict):
226+ '''
227+ Se crea una linea de xml
228+ '''
229+ inv_id = self.pool.get('account.invoice.line').browse(cr, uid,line).invoice_id
230+ return self.pool.get('islr.xml.wh.line').create(cr, uid, {'name': dict['name_rate'],
231+ 'concept_id': dict['concept'],
232+ 'period_id': inv_id.period_id.id,
233+ 'partner_vat':dict['vat'],
234+ 'invoice_number': dict['number'],
235+ 'control_number': dict['control'],
236+ 'concept_code':dict['code'],
237+ 'base': dict['subtotal'],
238+ 'porcent_rete':dict['perc'],
239+ 'wh':dict['wh'],
240+ 'rate_id': dict['rate_id'],
241+ 'account_invoice_line_id': line,
242+ 'account_invoice_id': inv_id.id,
243+ 'partner_id': inv_id.partner_id.id,
244+ })
245+
246+ def _get_wh(self,cr, uid, subtract,concept, wh_dict, dict_rate, apply,context=None):
247+ '''
248+ Retorna un diccionario, con todos los valores de la retencion de una linea de factura.
249+ '''
250+ if context is None:
251+ context={}
252+ res= {}
253+ inv_obj= self.pool.get('account.invoice')
254+ if apply: # Si se va a aplicar retencion.
255+ for line in wh_dict[concept]['lines']:
256+ wh_calc, subtotal = self._get_wh_calc(cr,uid,line,dict_rate[concept]) # Obtengo el monto de retencion y el monto base sobre el cual se retiene
257+ if subtract >= wh_calc:
258+ wh = 0.0
259+ subtract -= wh_calc
260+ else:
261+ wh = wh_calc - subtract
262+ subtract_write= subtract
263+ subtract=0.0
264+ inv_id = self.pool.get('account.invoice.line').browse(cr, uid,line).invoice_id.id
265+ type = inv_obj.browse(cr,uid,inv_id).type
266+ res[line]={ 'vat': self._get_inv_data(cr, uid, line)[0],
267+ 'number': self._get_inv_data(cr, uid, line)[1],
268+ 'control': self._get_inv_data(cr, uid, line)[2],
269+ 'concept': concept,
270+ 'code':dict_rate[concept][4],
271+ 'subtotal': subtotal,
272+ 'perc':dict_rate[concept][2],
273+ 'wh':wh,
274+ 'apply':apply,
275+ 'rate_id':dict_rate[concept][5],
276+ 'name_rate': dict_rate[concept][6]}
277+ if not context.get('test_from_wkf',False):
278+ self._write_wh_apply(cr,uid,line,res[line],apply,type)
279+ inv_obj.write(cr, uid, inv_id, {'status': 'pro'})
280+ else: # Si no aplica retencion
281+ for line in wh_dict[concept]['lines']:
282+ subtotal = self._get_wh_calc(cr,uid,line,dict_rate[concept])[1]
283+ inv_id = self.pool.get('account.invoice.line').browse(cr, uid,line).invoice_id.id
284+ type = inv_obj.browse(cr,uid,inv_id).type
285+ res[line]={ 'vat': self._get_inv_data(cr, uid, line)[0],
286+ 'number': self._get_inv_data(cr, uid, line)[1],
287+ 'control': self._get_inv_data(cr, uid, line)[2],
288+ 'concept': concept,
289+ 'code':dict_rate[concept][4],
290+ 'subtotal': subtotal,
291+ 'perc':dict_rate[concept][2],
292+ 'wh':0.0,
293+ 'apply':apply,
294+ 'rate_id':dict_rate[concept][5],
295+ 'name_rate': dict_rate[concept][6]}
296+ if not context.get('test_from_wkf',False):
297+ self._write_wh_apply(cr,uid,line,res[line],apply,type)
298+ inv_obj.write(cr, uid, inv_id, {'status': 'pro'})
299+ return res
300+
301+
302+ def _get_wh_apply(self,cr,uid,dict_rate,wh_dict,nature,context=None):
303+ '''
304+ Retorna el diccionario completo con todos los datos para realizar la retencion, cada elemento es una linea de la factura.
305+ '''
306+ if context is None:
307+ context={}
308+ res = {}
309+ for concept in wh_dict:
310+ if not wh_dict[concept]['wh']: #Si nunca se ha aplicado retencion con este concepto.
311+ if wh_dict[concept]['base'] >= dict_rate[concept][1]: # Si el monto base que suman todas las lineas de la factura es mayor o igual al monto minimo de la tasa.
312+ subtract = dict_rate[concept][3] # Obtengo el sustraendo a aplicar. Existe sustraendo porque es la primera vez.
313+ res.update(self._get_wh(cr, uid, subtract,concept, wh_dict, dict_rate, True,context=context))# El True sirve para asignar al campo booleano de la linea de la factura True, para asi marcar de una vez que ya fue retenida, para una posterior busqueda.
314+ else: # Si el monto base no supera el monto minimo de la tasa(de igual forma se deb declarar asi no supere.)
315+ subtract = 0.0
316+ res.update(self._get_wh(cr, uid, subtract,concept, wh_dict, dict_rate, False,context=context))
317+ else: #Si ya se aplico alguna vez la retencion, se aplica rete de una vez, sobre la base sin chequear monto minimo.(Dentro de este periodo)
318+ if nature:
319+ subtract = dict_rate[concept][3]
320+ res.update(self._get_wh(cr, uid, subtract,concept, wh_dict, dict_rate, True,context=context))
321+ else:
322+ subtract = 0.0
323+ res.update(self._get_wh(cr, uid, subtract,concept, wh_dict, dict_rate, True,context=context))# El True sirve para indicar que la linea si se va a retener.
324+ return res
325+
326+
327+ def _get_amount(self,cr,uid,dict):
328+ '''
329+ Funcion para obtener, la suma del monto retenido por concepto.
330+ '''
331+ dict_concept = {}
332+ for key in dict:
333+ x = dict[key]['concept']
334+ y = dict[key]['wh']
335+ if not dict_concept.get(x,False):
336+ dict_concept[x] = y
337+ else:
338+ dict_concept[x]+= y
339+ return dict_concept
340+
341+
342+ def _get_dict_concepts(self,cr,uid,dict):
343+ '''
344+ Funcion para obtener, el dicccionario agrupado por concepto:
345+ {1:[{64: {'control': '', 'perc': 0.050000000000000003, 'concept': 1, 'number': False, 'wh': 0.0, 'code': u'A', 'rate_id': 1, 'apply': True, 'subtotal': 500.0, 'vat': u'J123456789'}},
346+ {65: {'control': '', 'perc': 0.050000000000000003, 'concept': 1, 'number': False, 'wh': 0.0, 'code': u'A', 'rate_id': 1, 'apply': True, 'subtotal': 300.0, 'vat': u'J123456789'}}
347+ ],
348+ 2:[{63: {'control': '', 'perc': 0.029999999999999999, 'concept': 2, 'number': False, 'wh': 0.0, 'code': u'002', 'rate_id': 2, 'apply': True, 'subtotal': 1000.0, 'vat': u'J123456789'}}
349+ ]}
350+ '''
351+ dict_concepts = {}
352+ for key in dict:
353+ x = dict[key]['concept']
354+ y = dict[key]
355+ if not dict_concepts.get(x,False):
356+ if dict[key]['apply']:
357+ dict_concepts[x]=[]
358+ dict_concepts[x].append({key:y})
359+ else:
360+ if dict[key]['apply']:
361+ dict_concepts[x].append({key:y})
362+ return dict_concepts
363+
364+
365+ def get_journal(self,cr,uid,inv_brw):
366+ '''
367+ Funcion para asignar el diario correspondiente de acuerdo a cada tipo de retencion(compra, venta)
368+ los tipos de diario son creados en retencion_iva
369+ '''
370+ tipo='Sale'
371+ tipo2='islr_sale'
372+ journal_id = None
373+ journal_obj = self.pool.get('account.journal')
374+ if inv_brw.type == 'out_invoice' or inv_brw.type =='out_refund':
375+ journal_id = journal_obj.search(cr, uid, [('type', '=', 'islr_sale')], limit=1)
376+ else:
377+ journal_id = journal_obj.search(cr, uid, [('type', '=', 'islr_purchase')], limit=1)
378+ tipo = 'Purchase'
379+ tipo2 = 'islr_purchase'
380+ if not journal_id:
381+ raise osv.except_osv(_('Invalid action !'),_("Impossible withholding income, because the journal of withholding income for the '%s' has not been created with the type '%s'") % (tipo,tipo2))
382+
383+ return journal_id[0] or None
384+
385+ def button_confirm(self, cr, uid, ids, context=None):
386+ return self.write(cr, uid, ids, {'state': 'confirmed'})
387+
388+ def _create_islr_wh_doc(self,cr,uid,inv_brw,dict):
389+ '''
390+ Funcion para crear en el modelo islr_wh_doc
391+ '''
392+ islr_wh_doc_id=0
393+ wh_doc_obj = self.pool.get('islr.wh.doc')
394+ inv_obj =self.pool.get('account.invoice.line')
395+ inv_brw = inv_brw.invoice_id
396+
397+ islr_wh_doc_id = wh_doc_obj.create(cr,uid,
398+ {'name': wh_doc_obj.retencion_seq_get(cr, uid),
399+ 'partner_id': inv_brw.partner_id.id,
400+ 'invoice_id': inv_brw.id,
401+ 'period_id': inv_brw.period_id.id,
402+ 'account_id': inv_brw.account_id.id,
403+ 'type': inv_brw.type,
404+ 'journal_id': self.get_journal(cr,uid,inv_brw),})
405+
406+ wf_service = netsvc.LocalService("workflow")
407+ wf_service.trg_validate(uid, 'islr.wh.doc', islr_wh_doc_id, 'button_confirm', cr)
408+# wf_service.trg_write(uid, 'islr.wh.doc', islr_wh_doc_id, cr)
409+
410+ return islr_wh_doc_id
411+
412+
413+ def _create_doc_line(self,cr,uid, inv_brw,key2,islr_wh_doc_id,dictt,dictc):
414+ '''
415+ Funcion para crear en el modelo islr_wh_doc_line
416+ '''
417+ doc_line_obj = self.pool.get('islr.wh.doc.line')
418+ rate_obj = self.pool.get('islr.rates')
419+ ut_obj = self.pool.get('l10n.ut')
420+ dict_concept = self._get_amount(cr,uid,dictt)
421+ inv_line_id = dictc[key2][0].keys()[0]
422+ rate_id = dictc[key2][0][inv_line_id]['rate_id']
423+
424+ ut_ids = ut_obj.search(cr,uid,[])
425+ ut_brw = ut_obj.browse(cr,uid,ut_ids)
426+ reg = 0.0
427+ for ut in ut_brw:
428+ if float(ut.name) > reg:
429+ ut_amount = ut.amount
430+ reg = float(ut.name)
431+
432+ percent = rate_obj.browse(cr,uid,rate_id).wh_perc
433+ subtract = rate_obj.browse(cr,uid,rate_id).subtract
434+ valor = subtract * ut_amount
435+
436+ #Se Agrego esta Validación para las cooperativas
437+ if percent == 1.0:
438+ islr_wh_doc_line_id = doc_line_obj.create(cr,uid,
439+ {'islr_wh_doc_id':islr_wh_doc_id,
440+ 'concept_id':key2,
441+ 'islr_rates_id':rate_id,
442+ 'invoice_id': inv_brw.invoice_id.id,
443+ 'retencion_islr': rate_obj.browse(cr,uid,rate_id).wh_perc,
444+ 'amount':dict_concept[key2]-valor,})
445+ else:
446+ islr_wh_doc_line_id = doc_line_obj.create(cr,uid,
447+ {'islr_wh_doc_id':islr_wh_doc_id,
448+ 'concept_id':key2,
449+ 'islr_rates_id':rate_id,
450+ 'invoice_id': inv_brw.invoice_id.id,
451+ 'retencion_islr': rate_obj.browse(cr,uid,rate_id).wh_perc,
452+ 'amount':dict_concept[key2],})
453+
454+ return islr_wh_doc_line_id
455+
456+ def _create_doc_invoices(self,cr,uid,key,islr_wh_doc_id):
457+ '''
458+ Funcion para crear en el modelo islr_wh_doc_invoices
459+ '''
460+ doc_inv_obj = self.pool.get('islr.wh.doc.invoices')
461+ inv_id = key
462+ islr_wh_doc_invoices_id = doc_inv_obj.create(cr,uid,{'invoice_id':inv_id,'islr_wh_doc_id':islr_wh_doc_id})
463+
464+ def _write_wh_xml(self,cr,uid,key,islr_wh_doc_line_id):
465+ '''
466+ Funcion para escribir en el modelo xml_wh_line
467+ '''
468+ inv_obj =self.pool.get('account.invoice.line')
469+ xml_obj = self.pool.get('islr.xml.wh.line')
470+ xml_id = inv_obj.browse(cr,uid,key).wh_xml_id.id
471+ xml_obj.write(cr, uid, xml_id, {'islr_wh_doc_line_id':islr_wh_doc_line_id})
472+
473+
474+ def _get_inv_id(self,cr,uid,dict):
475+ '''
476+ Funcion para obtener el objeto_browse de la factura
477+ '''
478+ inv_obj =self.pool.get('account.invoice.line')
479+ line_ids = [key for key in dict if dict[key]['apply']]
480+ line_ids.sort()
481+ return line_ids and inv_obj.browse(cr,uid,line_ids[-1]) or False
482+
483+
484+ def _logic_create(self,cr,uid,dict,wh_doc_id):
485+ '''
486+ Manejo de toda la logica para la generarion de lineas en los modelos.
487+ '''
488+ dictc = self._get_dict_concepts(cr,uid,dict)
489+ inv_brw = self._get_inv_id(cr,uid,dict)
490+ inv_obj =self.pool.get('account.invoice.line')
491+ islr_wh_doc_id=None
492+
493+ if inv_brw:
494+ if dictc and not wh_doc_id:
495+ islr_wh_doc_id = self._create_islr_wh_doc(cr,uid,inv_brw,dict)
496+ else:
497+ islr_wh_doc_id = wh_doc_id
498+ key_lst = []
499+ if islr_wh_doc_id:
500+ for key2 in dictc:
501+ inv_line_id = dictc[key2][0].keys()[0]
502+ islr_wh_doc_line_id = self._create_doc_line(cr,uid,inv_brw,key2,islr_wh_doc_id,dict,dictc)
503+ for line in dictc[key2]:
504+ inv_line_id2 = dictc[key2][0].keys()[0]
505+ for key in line:
506+ key_lst.append(inv_obj.browse(cr,uid,key).invoice_id.id)
507+ if not wh_doc_id:
508+ self._write_wh_xml(cr,uid,key,islr_wh_doc_line_id)
509+ for key in set(key_lst):
510+ self._create_doc_invoices(cr,uid,key,islr_wh_doc_id)
511+
512+ self.pool.get('account.invoice').write(cr,uid,inv_brw.invoice_id.id,{'islr_wh_doc_id':islr_wh_doc_id})
513+
514+ message = _("Withholding income voucher '%s' generated.") % self.pool.get('islr.wh.doc').browse(cr,uid,islr_wh_doc_id).name
515+ self.log(cr, uid, islr_wh_doc_id, message)
516+ else:
517+ pass
518+ else:
519+ pass
520+ return islr_wh_doc_id
521+
522+ def action_ret_islr(self, cr, uid, ids, context={}):
523+ return self.pool.get('islr.wh.doc').action_ret_islr(cr,uid,ids,context)
524+
525+ def _check_wh_islr(self, cr, uid, ids, context=None):
526+ if context is None:
527+ context={}
528+
529+ wh_apply=[]
530+ # The two function being called below should undergo overhauling
531+ # right now it takes an object as and argument instead of an integer
532+ invoice = self.browse(cr, uid, ids[0], context=context)
533+ vendor, buyer, wh = self._get_partners(cr, uid, invoice)
534+ concept_list = self._get_concepts(cr, uid, invoice)
535+ wh_apply.append(wh)
536+ wh_apply.append(concept_list)
537+
538+ return invoice, vendor, buyer, concept_list, all(wh_apply)
539+
540+ def _check_do_wh(self, cr, uid, ids, invoice, vendor, buyer, concept_list, context=None):
541+ if context is None:
542+ context={}
543+ wh_dict = self._get_service_wh(cr, uid, invoice, concept_list)
544+ residence = self._get_residence(cr, uid, vendor, buyer)
545+ nature = self._get_nature(cr, uid, vendor)
546+ dict_rate = self._get_rate_dict(cr, uid, concept_list, residence, nature,context=context)
547+ self._pop_dict(cr,uid,concept_list,dict_rate,wh_dict)
548+ dict_completo = self._get_wh_apply(cr,uid,dict_rate,wh_dict,nature,context=context)
549+ inv_brw = self._get_inv_id(cr,uid,dict_completo)
550+
551+ return bool(inv_brw)
552+
553+ def check_wh_islr_apply(self, cr, uid, ids, context=None):
554+ '''
555+ This Method test if given certain conditions it is
556+ possible to create a new withholding document
557+ '''
558+ #TODO: Este metodo deberia devolver true ya que es un metodo "check"
559+ if context is None:
560+ context={}
561+
562+ invoice, vendor, buyer, concept_list, wh_apply = self._check_wh_islr(cr, uid, ids, context=context)
563+
564+ do_wh = False
565+ if wh_apply:
566+ context.update({'test_from_wkf':True})
567+ do_wh = self._check_do_wh(cr, uid, ids, invoice, vendor, buyer, concept_list, context=context)
568+
569+ return all([wh_apply,do_wh])
570+
571+ def check_wh_islr_xml(self, cr, uid, ids, context=None):
572+ '''
573+ This Method test if given certain conditions it is
574+ __not__ possible to create a new withholding document
575+ but the xml elements needed to create a legal report
576+ '''
577+ if context is None:
578+ context={}
579+
580+ invoice, vendor, buyer, concept_list, wh_apply = self._check_wh_islr(cr, uid, ids, context=context)
581+
582+ do_wh = True
583+ if wh_apply:
584+ context.update({'test_from_wkf':True})
585+ do_wh = self._check_do_wh(cr, uid, ids, invoice, vendor, buyer, concept_list, context=context)
586+
587+ return all([wh_apply,not do_wh])
588+
589+ def action_islr_xml(self, cr, uid, ids, context=None):
590+ '''
591+ This Method creates the xml elements needed to provide a legal report
592+ '''
593+ if context is None:
594+ context={}
595+
596+ invoice, vendor, buyer, concept_list, wh_apply = self._check_wh_islr(cr, uid, ids, context=context)
597+
598+ if wh_apply:
599+ self._check_do_wh(cr, uid, ids, invoice, vendor, buyer, concept_list, context=context)
600+
601+ return True
602+
603+ def check_invoice_type(self, cr, uid, ids, context=None):
604+ '''
605+ This method test the invoice types to create a new withholding document
606+ '''
607+ #TODO: change on workflow
608+ if context is None:
609+ context={}
610+ obj = self.browse(cr, uid, ids[0],context=context)
611+ if obj.type in ('in_invoice', 'in_refund'):
612+ return True
613+ return False
614+
615+>>>>>>> MERGE-SOURCE
616 def validate_wh_income_done(self, cr, uid, ids, context=None):
617 """ Method that check if wh income is validated in invoice refund.
618 @params: ids: list of invoices.
619
620=== modified file 'l10n_ve_withholding_islr/model/islr_wh_doc.py'
621--- l10n_ve_withholding_islr/model/islr_wh_doc.py 2013-12-05 20:57:09 +0000
622+++ l10n_ve_withholding_islr/model/islr_wh_doc.py 2013-12-05 22:26:23 +0000
623@@ -93,7 +93,7 @@
624 for rete in self.browse(cr, uid, ids, context):
625 res[rete.id] = 0.0
626 for line in rete.concept_ids:
627- res[rete.id] += line.amount
628+ res[rete.id] += line.amount
629 return res
630
631 _name = "islr.wh.doc"
632@@ -678,8 +678,12 @@
633 if default is None:
634 default = {}
635 default = default.copy()
636+<<<<<<< TREE
637 default.update({'islr_wh_doc_id': 0})
638
639+=======
640+ default.update({'islr_wh_doc_id':0 })
641+>>>>>>> MERGE-SOURCE
642 return super(account_invoice, self).copy(cr, uid, id, default, context)
643
644 class islr_wh_doc_invoices(osv.osv):