69
69
res[rete.id] += line.amount
72
def filter_lines_invoice(self,cr,uid,partner_id,context):
73
inv_obj = self.pool.get('account.invoice')
74
invoice_obj = self.pool.get('islr.wh.doc.invoices')
77
inv_ids = inv_obj.search(cr,uid,[('state', '=', 'open'),('partner_id','=',partner_id)],context={})
79
#~ Get only the invoices which are not in a document yet
80
inv_ids = [i.id for i in inv_obj.browse(cr,uid,inv_ids,context={}) if not i.islr_wh_doc_id]
81
inv_ids = [i for i in inv_ids if not invoice_obj.search(cr, uid, [('invoice_id', '=', i)])]
82
inv_ids = [i.id for i in inv_obj.browse(cr, uid, inv_ids, context={}) for d in i.invoice_line if d.concept_id.withholdable]
83
inv_ids = list(set(inv_ids))
86
73
_name = "islr.wh.doc"
74
_order = 'date_ret desc, number desc'
87
75
_description = 'Document Income Withholding'
89
77
'name': fields.char('Description', size=64,readonly=True, states={'draft':[('readonly',False)]}, required=True, help="Voucher description"),
112
100
'amount_total_ret':fields.function(_get_amount_total,method=True, string='Amount Total', type='float', digits_compute= dp.get_precision('Withhold ISLR'), help="Total Withheld amount"),
113
101
'concept_ids': fields.one2many('islr.wh.doc.line','islr_wh_doc_id','Income Withholding Concept', readonly=True, states={'draft':[('readonly',False)]}),
114
102
'invoice_ids':fields.one2many('islr.wh.doc.invoices','islr_wh_doc_id','Withheld Invoices'),
115
'invoice_id':fields.many2one('account.invoice','Invoice',readonly=False,help="Invoice to make the accounting entry"),
116
103
'islr_wh_doc_id': fields.one2many('account.invoice','islr_wh_doc_id','Invoices',states={'draft':[('readonly',False)]}),
117
104
'user_id': fields.many2one('res.users', 'Salesman', readonly=True, states={'draft':[('readonly',False)]}),
118
105
'automatic_income_wh' : fields.boolean('Automatic Income Withhold',
130
117
self.pool.get('res.users').browse(cr, uid, uid,
131
118
context=context).company_id.id,
132
119
'user_id': lambda s, cr, u, c: u,
133
'automatic_income_wh' : False,
120
'automatic_income_wh': False,
136
123
def check_income_wh(self, cr, uid, ids, context=None):
156
143
obj = self.browse(cr, uid, ids[0],context=context)
157
144
return obj.automatic_income_wh or False
146
def check_auto_wh_by_type(self, cr, uid, ids, context=None):
147
context = context or {}
148
ids = isinstance(ids, (int, long)) and [ids] or ids
149
brw = self.browse(cr, uid, ids[0],context=context)
150
if brw.type in ('out_invoice','out_refund'):
152
return brw.automatic_income_wh or False
159
154
def compute_amount_wh(self, cr, uid, ids, context=None):
160
155
context = context or {}
161
156
ids = isinstance(ids, (int, long)) and [ids] or ids
170
165
if args[0]in ['in_invoice','in_refund'] and args[1] and args[2]:
168
def action_done(self, cr, uid, ids, context=None):
169
context = context or {}
170
ids = isinstance(ids, (int, long)) and [ids] or ids
171
self.action_number(cr, uid, ids, context=context)
172
self.action_move_create(cr, uid, ids, context=context)
173
self.write(cr, uid, ids, {'state':'done'}, context=context)
173
176
def action_process(self,cr,uid,ids, context=None):
174
177
# TODO: ERASE THE REGARDING NODE IN THE WORKFLOW
175
178
# METHOD HAVE BEEN LEFT FOR BACKWARD COMPATIBILITY
219
222
return pool_seq._process(res['prefix']) + pool_seq._process(res['suffix'])
222
def onchange_partner_id(self, cr, uid, ids, type, partner_id):
225
def onchange_partner_id(self, cr, uid, ids, type, partner_id, context=None):
226
context = context or {}
231
inv_obj = self.pool.get('account.invoice')
232
args = [('state','=','open'), ('islr_wh_doc_id','=',False),
233
('partner_id','=',partner_id)]
235
# Unlink previous iwdi
236
iwdi_obj = self.pool.get('islr.wh.doc.invoices')
237
iwdi_ids = ids and iwdi_obj.search(cr, uid,
238
[('islr_wh_doc_id','=',ids[0])], context=context)
240
iwdi_obj.unlink(cr, uid, iwdi_ids,context=context)
243
# Unlink previous invoices
244
inv_ids = ids and inv_obj.search(cr, uid,
245
[('islr_wh_doc_id','=',ids[0])], context=context)
247
inv_obj.write(cr, uid, inv_ids, {'islr_wh_doc_id':False},
251
# Unlink previous line
252
iwdl_obj = self.pool.get('islr.wh.doc.line')
253
iwdl_ids = ids and iwdl_obj.search(cr, uid,
254
[('islr_wh_doc_id','=',ids[0])], context=context)
256
iwdl_obj.unlink(cr, uid, iwdl_ids,context=context)
227
260
p = self.pool.get('res.partner').browse(cr, uid, partner_id)
228
261
if type in ('out_invoice', 'out_refund'):
229
acc_id = p.property_account_receivable.id
230
inv_ids = self.filter_lines_invoice(cr,uid,partner_id,context=None)
262
acc_id = p.property_account_receivable and \
263
p.property_account_receivable.id
264
args+=[('type','in',('out_invoice','out_refund'))]
232
acc_id = p.property_account_payable.id
233
result = {'value': {'islr_wh_doc_id':inv_ids,'account_id': acc_id}}
266
acc_id = p.property_account_payable and \
267
p.property_account_payable.id
268
args+=[('type','in',('in_invoice','in_refund'))]
270
inv_ids = inv_obj.search(cr,uid,args,context=context)
271
inv_ids = iwdi_obj._withholdable_invoices(cr, uid, inv_ids,
274
for inv_brw in inv_obj.browse(cr,uid,inv_ids,context=context):
275
res_wh_lines += [{'invoice_id': inv_brw.id}]
278
'account_id': acc_id,
279
'invoice_ids':res_wh_lines}}
237
281
def create(self, cr, uid, vals, context=None, check=True):
244
288
def action_confirm(self, cr, uid, ids, context=None):
245
289
context = context or {}
246
290
ids = isinstance(ids, (int, long)) and [ids] or ids
247
return self.write(cr, uid, ids[0], {'state':'confirmed'})
291
check_auto_wh = self.browse(cr, uid, ids[0],
292
context=context).company_id.automatic_income_wh
293
return self.write(cr, uid, ids[0], {'state':'confirmed',
294
'automatic_income_wh':check_auto_wh}, context=context)
249
def action_number(self, cr, uid, ids, *args):
296
def action_number(self, cr, uid, ids, context=None):
297
context = context or {}
250
298
obj_ret = self.browse(cr, uid, ids)[0]
251
299
cr.execute('SELECT id, number ' \
252
300
'FROM islr_wh_doc ' \
297
345
ixwl_obj = self.pool.get('islr.xml.wh.line')
298
346
ret = self.browse(cr, uid, ids[0], context=context)
347
context.update({'income_wh':True,
348
'company_id': ret.company_id.id})
349
acc_id = ret.account_id.id
299
350
if not ret.date_uid:
300
351
self.write(cr, uid, [ret.id], {'date_uid':time.strftime('%Y-%m-%d')})
302
353
if not ret.date_ret:
303
354
self.write(cr, uid, [ret.id], {'date_ret':time.strftime('%Y-%m-%d')})
356
# Reload the browse because there have been changes into it
357
ret = self.browse(cr, uid, ids[0], context=context)
305
359
period_id = ret.period_id and ret.period_id.id or False
306
360
journal_id = ret.journal_id.id
313
367
raise osv.except_osv(_('Warning !'), _("Not found a fiscal period to date: '%s' please check!") % (ret.date_ret or time.strftime('%Y-%m-%d')))
315
for line in ret.concept_ids:
369
for line in ret.invoice_ids:
316
370
if ret.type in ('in_invoice', 'in_refund'):
317
if line.concept_id.property_retencion_islr_payable:
318
acc_id = line.concept_id.property_retencion_islr_payable.id
319
inv_id = line.invoice_id.id
321
raise osv.except_osv(_('Invalid action !'),_("Impossible income withholding, because the account for withholding of sale is not assigned to the Concept withholding '%s'!")% (line.concept_id.name))
371
name = 'COMP. RET. ISLR ' + ret.number + ' Doc. '+ (line.invoice_id.reference or '')
323
if line.concept_id.property_retencion_islr_receivable:
324
acc_id = line.concept_id.property_retencion_islr_receivable.id
325
inv_id = line.invoice_id.id
327
raise osv.except_osv(_('Invalid action !'),_("Impossible income withholding, because the account for withholding of purchase is not assigned to the Concept withholding '%s'!") % (line.concept_id.name))
373
name = 'COMP. RET. ISLR ' + ret.number + ' Doc. '+ (line.invoice_id.number or '')
329
374
writeoff_account_id = False
330
375
writeoff_journal_id = False
376
amount = line.amount_islr_ret
333
ret_move = self.wh_and_reconcile(cr, uid, [ret.id], inv_id,
378
ret_move = line.invoice_id.ret_and_reconcile(
334
379
amount, acc_id, period_id, journal_id, writeoff_account_id,
335
period_id, writeoff_journal_id, context)
380
period_id, writeoff_journal_id, ret.date_ret, name,
381
line.iwdl_ids, context=context)
337
# make the retencion line point to that move
383
# make the withholding line point to that move
339
385
'move_id': ret_move['move_id'],
341
387
#lines = [(op,id,values)] escribir en un one2many
342
388
lines = [(1, line.id, rl)]
343
self.write(cr, uid, [ret.id], {'concept_ids':lines})
389
self.write(cr, uid, [ret.id], {'invoice_ids':lines, 'period_id':period_id})
346
message = _("Income withholding voucher '%s' validated and accounting entry generated.") % self.browse(cr, uid, ids[0]).name
347
self.log(cr, uid, ids[0], message)
350
392
for line in ret.concept_ids:
351
393
xml_ids += [xml.id for xml in line.xml_ids]
473
515
'amount_islr_ret':fields.function(_amount_all, method=True, digits=(16,4), string='Withheld Amount', multi='all', help="Amount withheld from the base amount"),
474
516
'base_ret': fields.function(_amount_all, method=True, digits=(16,4), string='Base Amount', multi='all', help="Amount where a withholding is going to be compute from"),
475
517
'iwdl_ids':fields.one2many('islr.wh.doc.line','iwdi_id','Withholding Concepts'),
518
'move_id': fields.many2one('account.move', 'Journal Entry',
519
readonly=True, help="Accounting voucher"),
477
521
_rec_rame = 'invoice_id'
490
534
concept_set.add(ail.concept_id.id)
491
535
return list(concept_set)
537
def _withholdable_invoices(self, cr, uid, ids, context=None):
538
'''Given a list of invoices return only those
539
where there are withholdable concepts'''
540
context = context or {}
541
ids = isinstance(ids, (int, long)) and [ids] or ids
544
id = self._get_concepts(cr, uid, id, context=context) and id
493
548
def _get_wh(self, cr, uid, ids, concept_id, context=None):
495
550
Returns a dictionary containing all the values of the retention of an invoice line.