Merge lp:~vauxoo/openerp-venezuela-localization/hbto_src_fix_islr into lp:openerp-venezuela-localization
- hbto_src_fix_islr
- Merge into trunk
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 |
Related bugs: |
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.
Commit message
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 : | # |
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): |
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.