Merge lp:~enlightx-deactivatedaccount/openobject-italia/7.0_fix_1261357 into lp:~openobject-italia-core-devs/openobject-italia/italian-addons-7.0

Proposed by Davide Corio
Status: Needs review
Proposed branch: lp:~enlightx-deactivatedaccount/openobject-italia/7.0_fix_1261357
Merge into: lp:~openobject-italia-core-devs/openobject-italia/italian-addons-7.0
Diff against target: 544 lines (+297/-94)
4 files modified
l10n_it_withholding_tax/__init__.py (+4/-4)
l10n_it_withholding_tax/__openerp__.py (+10/-12)
l10n_it_withholding_tax/account.py (+281/-78)
l10n_it_withholding_tax/account_view.xml (+2/-0)
To merge this branch: bzr merge lp:~enlightx-deactivatedaccount/openobject-italia/7.0_fix_1261357
Reviewer Review Type Date Requested Status
Lorenzo Battistini Needs Fixing
Review via email: mp+199294@code.launchpad.net

Description of the change

In questo branch ho variato alcune cose riguardanti le personalizzazioni fatte al voucher per la gestione della ritenuta d'acconto.

Sul modulo ufficiali ci sono problemi quando l'importo del pagamento differisce dal netto a pagare riportato sulla fattura.

Con questa versione dovrebbe essere possibile usare il conto di storno sul voucher pagamento per registrare eventuali sbilanci (es: commissioni bancarie).

NB: penso che ciò che ho scritto possa essere semplificato, quindi attendo miglioramenti su questo branch

To post a comment you must log in.
Revision history for this message
Davide Corio (enlightx-deactivatedaccount) wrote :

sul form del voucher ho aggiunto un campo che mostra l'ammontare di eventuale ritenuta.

possiamo comunque rimuoverlo dalla vista o renderlo visibile solo se > 0

231. By Davide Corio

[IMP] PEP8

232. By Davide Corio

[IMP] PEP8

233. By Davide Corio

[FIX] writeoff amount sign

234. By Davide Corio

[FIX] correct amount if not wht

235. By Davide Corio

[REM] wht amount from view

236. By Davide Corio

[FIX] cancel voucher if no writeoff

237. By Davide Corio

[FIX] broken get_wht_amount

Revision history for this message
Lorenzo Battistini (elbati) wrote :

Mi pare di capire che la registrazione di write-off venga scritta ogni volta che
voucher.amount != invoice.net_pay
( http://bazaar.launchpad.net/~enlightx/openobject-italia/7.0_fix_1261357/view/237/l10n_it_withholding_tax/account.py#L361 )
indipendentemente dal campo 'payment_option'.

Mi sembra sbagliato, infatti, se 'payment difference' viene lasciato su 'Keep Open' e si prova a pagare un importo diverso dal 'net pay', si ottiene

  File "/home/elbati/workspace/openerp/7.0/addons/account_voucher/account_voucher.py", line 936, in proforma_voucher
    self.action_move_line_create(cr, uid, ids, context=context)
  File "/home/elbati/workspace/openerp/7.0/server/openerp/addons/l10n_it_withholding_tax/account.py", line 385, in action_move_line_create
    cr, uid, wo_move, context=context)
  File "/home/elbati/workspace/openerp/7.0/addons/account/account.py", line 1438, in create
    result = super(account_move, self).create(cr, uid, vals, c)
  File "/home/elbati/workspace/openerp/7.0/server/openerp/osv/orm.py", line 4489, in create
    result += self._columns[field].set(cr, self, id_new, field, vals[field], user, rel_context) or []
  File "/home/elbati/workspace/openerp/7.0/server/openerp/osv/fields.py", line 559, in set
    id_new = obj.create(cr, user, act[2], context=context)
  File "/home/elbati/workspace/openerp/7.0/addons/account/account_move_line.py", line 1144, in create
    if ('account_id' in vals) and not account_obj.read(cr, uid, vals['account_id'], ['active'])['active']:
  File "/home/elbati/workspace/openerp/7.0/server/openerp/osv/orm.py", line 3623, in read
    result = self._read_flat(cr, user, select, fields, context, load)
  File "/home/elbati/workspace/openerp/7.0/server/openerp/osv/orm.py", line 3675, in _read_flat
    cr.execute(query, [tuple(sub_ids)] + rule_params)
  File "/home/elbati/workspace/openerp/7.0/server/openerp/sql_db.py", line 161, in wrapper
    return f(self, *args, **kwargs)
  File "/home/elbati/workspace/openerp/7.0/server/openerp/sql_db.py", line 226, in execute
    res = self._obj.execute(query, params)
ProgrammingError: operator does not exist: integer = boolean
LINE 1: ...d FROM "account_account" WHERE account_account.id IN (false)...
                                                             ^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.

Credo che la creazione della registrazione di writeoff debba essere forzata solo nel caso 'reconcile payment balance'.

Inoltre, per la generazione della scrittura di write-off, magari si riescono a usare metodi del voucher tipo 'writeoff_move_line_get'?

review: Needs Fixing
Revision history for this message
Davide Corio (enlightx-deactivatedaccount) wrote :

Grazie Lorenzo per il feedback.
Provvedo ad apportare le migliorie

238. By Davide Corio

[FIX] bypass if without_writeoff

239. By Davide Corio

[IMP] use writeoff_move_line_get

Revision history for this message
Davide Corio (enlightx-deactivatedaccount) wrote :

dovrei aver applicato i due fix consigliati.
il problema problema era reale, infatti mi è capitato dopo poco.

per il secondo consiglio, penso sia stato utile usare la funzione apposita siccome si occupa di fare conversioni di valuta, scrive conti analitici, etc etc.

Revision history for this message
Lorenzo Battistini (elbati) wrote :

Ho lanciato i test automatici e sono andati a buon fine.

L'ideale sarebbe avere anche dei test automatici che coprono il caso d'uso descritto in questo bug.

(devo ancora fare la review visiva della nuova versione)

Revision history for this message
Lorenzo Battistini (elbati) wrote :

This project is now hosted on https://github.com/OCA/l10n-italy. Please move your proposal there. This guide may help you https://github.com/OCA/maintainers-tools/wiki/How-to-move-a-Merge-Proposal-to-GitHub

Unmerged revisions

239. By Davide Corio

[IMP] use writeoff_move_line_get

238. By Davide Corio

[FIX] bypass if without_writeoff

237. By Davide Corio

[FIX] broken get_wht_amount

236. By Davide Corio

[FIX] cancel voucher if no writeoff

235. By Davide Corio

[REM] wht amount from view

234. By Davide Corio

[FIX] correct amount if not wht

233. By Davide Corio

[FIX] writeoff amount sign

232. By Davide Corio

[IMP] PEP8

231. By Davide Corio

[IMP] PEP8

230. By Davide Corio

[IMP] write-off + wht on voucher

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'l10n_it_withholding_tax/__init__.py'
2--- l10n_it_withholding_tax/__init__.py 2013-04-17 10:18:29 +0000
3+++ l10n_it_withholding_tax/__init__.py 2014-01-02 17:27:30 +0000
4@@ -1,14 +1,14 @@
5 # -*- coding: utf-8 -*-
6 ##############################################################################
7-#
8+#
9 # Copyright (C) 2012 Agile Business Group sagl (<http://www.agilebg.com>)
10 # Copyright (C) 2012 Domsense srl (<http://www.domsense.com>)
11 # Copyright (C) 2012-2013 Associazione OpenERP Italia
12-# (<http://www.openerp-italia.org>).
13+# (<http://www.openerp-italia.org>).
14 #
15 # This program is free software: you can redistribute it and/or modify
16-# it under the terms of the GNU Affero General Public License as published by
17-# the Free Software Foundation, either version 3 of the License, or
18+# it under the terms of the GNU Affero General Public License as published
19+# by the Free Software Foundation, either version 3 of the License, or
20 # (at your option) any later version.
21 #
22 # This program is distributed in the hope that it will be useful,
23
24=== modified file 'l10n_it_withholding_tax/__openerp__.py'
25--- l10n_it_withholding_tax/__openerp__.py 2013-04-17 14:19:03 +0000
26+++ l10n_it_withholding_tax/__openerp__.py 2014-01-02 17:27:30 +0000
27@@ -33,28 +33,26 @@
28 - Conto di debito per le ritenute da versare
29 - Sezionale che conterrà le registrazioni legate alla ritenuta
30
31-Durante la compilazione di una fattura fornitore con ritenuta d'acconto, l'utente dovrà specificare l'importo della ritenuta.
32+Durante la compilazione di una fattura fornitore con ritenuta d'acconto,
33+l'utente dovrà specificare l'importo della ritenuta.
34
35 Requisiti
36 ---------
37-http://wiki.openerp-italia.org/doku.php/area_utente/requisiti/ritenuta_d_acconto
38+http://wiki.openerp-italia.org/doku.php/area_utente/requisiti/\
39+ritenuta_d_acconto
40
41 Howto
42 -----
43-http://planet.domsense.com/2012/06/come-registrare-in-openerp-le-fatture-fornitore-con-ritenuta-dacconto/
44+http://planet.domsense.com/2012/06/come-registrare-in-openerp-le-fatture-\
45+fornitore-con-ritenuta-dacconto/
46 """,
47 'author': 'OpenERP Italian Community',
48 'website': 'http://www.openerp-italia.org',
49 'license': 'AGPL-3',
50- "depends" : ['account_voucher_cash_basis'],
51- "data" : [
52- 'account_view.xml',],
53- "demo" : [
54- 'account_demo.xml',
55- ],
56- 'test' : [
57- 'test/purchase_payment.yml',
58- ],
59+ "depends": ['account_voucher_cash_basis'],
60+ "data": ['account_view.xml'],
61+ "demo": ['account_demo.xml'],
62+ 'test': ['test/purchase_payment.yml'],
63 "active": False,
64 "installable": True
65 }
66
67=== modified file 'l10n_it_withholding_tax/account.py'
68--- l10n_it_withholding_tax/account.py 2013-05-09 14:30:36 +0000
69+++ l10n_it_withholding_tax/account.py 2014-01-02 17:27:30 +0000
70@@ -1,14 +1,14 @@
71 # -*- coding: utf-8 -*-
72 ##############################################################################
73-#
74+#
75 # Copyright (C) 2012 Agile Business Group sagl (<http://www.agilebg.com>)
76 # Copyright (C) 2012 Domsense srl (<http://www.domsense.com>)
77 # Copyright (C) 2012-2013 Associazione OpenERP Italia
78-# (<http://www.openerp-italia.org>).
79+# (<http://www.openerp-italia.org>).
80 #
81 # This program is free software: you can redistribute it and/or modify
82-# it under the terms of the GNU Affero General Public License as published by
83-# the Free Software Foundation, either version 3 of the License, or
84+# it under the terms of the GNU Affero General Public License as published
85+# by the Free Software Foundation, either version 3 of the License, or
86 # (at your option) any later version.
87 #
88 # This program is distributed in the hope that it will be useful,
89@@ -25,20 +25,31 @@
90 from openerp.tools.translate import _
91 import decimal_precision as dp
92
93+
94 class res_company(orm.Model):
95 _inherit = 'res.company'
96 _columns = {
97- 'withholding_payment_term_id': fields.many2one('account.payment.term',
98+ 'withholding_payment_term_id': fields.many2one(
99+ 'account.payment.term',
100 'Withholding tax Payment Term',
101- help="The withholding tax will have to be paid within this term"),
102- 'withholding_account_id': fields.many2one('account.account','Withholding account',
103+ help="The withholding tax will have to be paid within this term"
104+ ),
105+ 'withholding_account_id': fields.many2one(
106+ 'account.account', 'Withholding account',
107 help='Payable account used for amount due to tax authority',
108- domain=[('type', '=', 'payable')]),
109- 'withholding_journal_id': fields.many2one('account.journal','Withholding journal',
110- help="Journal used for registration of witholding amounts to be paid"),
111- 'authority_partner_id': fields.many2one('res.partner', 'Tax Authority Partner'),
112+ domain=[('type', '=', 'payable')]
113+ ),
114+ 'withholding_journal_id': fields.many2one(
115+ 'account.journal', 'Withholding journal',
116+ help="Journal used for registration of witholding amounts to be\
117+ paid"
118+ ),
119+ 'authority_partner_id': fields.many2one(
120+ 'res.partner', 'Tax Authority Partner'
121+ ),
122 }
123-
124+
125+
126 class account_config_settings(orm.TransientModel):
127 _inherit = 'account.config.settings'
128 _columns = {
129@@ -59,39 +70,54 @@
130 type='many2one',
131 relation="account.journal",
132 string="Withholding journal",
133- help='Journal used for registration of witholding amounts to be paid'),
134+ help='Journal used for registration of witholding amounts to be\
135+ paid'),
136 'authority_partner_id': fields.related(
137 'company_id', 'authority_partner_id',
138 type='many2one',
139 relation="res.partner",
140 string="Tax Authority Partner"),
141 }
142-
143+
144 def onchange_company_id(self, cr, uid, ids, company_id, context=None):
145- res = super(account_config_settings, self).onchange_company_id(cr, uid, ids, company_id, context=context)
146+ res = super(account_config_settings, self).onchange_company_id(
147+ cr, uid, ids, company_id, context=context
148+ )
149 if company_id:
150- company = self.pool.get('res.company').browse(cr, uid, company_id, context=context)
151+ company = self.pool.get('res.company').browse(
152+ cr, uid, company_id, context=context
153+ )
154 res['value'].update({
155- 'withholding_payment_term_id': (company.withholding_payment_term_id
156- and company.withholding_payment_term_id.id or False),
157- 'withholding_account_id': (company.withholding_account_id
158- and company.withholding_account_id.id or False),
159- 'withholding_journal_id': (company.withholding_journal_id
160- and company.withholding_journal_id.id or False),
161- 'authority_partner_id': (company.authority_partner_id
162- and company.authority_partner_id.id or False),
163+ 'withholding_payment_term_id': (
164+ company.withholding_payment_term_id
165+ and company.withholding_payment_term_id.id or False
166+ ),
167+ 'withholding_account_id': (
168+ company.withholding_account_id
169+ and company.withholding_account_id.id or False
170+ ),
171+ 'withholding_journal_id': (
172+ company.withholding_journal_id
173+ and company.withholding_journal_id.id or False
174+ ),
175+ 'authority_partner_id': (
176+ company.authority_partner_id
177+ and company.authority_partner_id.id or False
178+ ),
179 })
180- else:
181- res['value'].update({
182- 'withholding_payment_term_id': False,
183- 'withholding_account_id': False,
184- 'withholding_journal_id': False,
185- 'authority_partner_id': False,
186+ else:
187+ res['value'].update(
188+ {
189+ 'withholding_payment_term_id': False,
190+ 'withholding_account_id': False,
191+ 'withholding_journal_id': False,
192+ 'authority_partner_id': False,
193 })
194 return res
195
196+
197 class account_invoice(orm.Model):
198-
199+
200 def _net_pay(self, cr, uid, ids, field_name, arg, context=None):
201 res = {}
202 for invoice in self.browse(cr, uid, ids, context):
203@@ -101,104 +127,281 @@
204 _inherit = "account.invoice"
205
206 _columns = {
207- 'withholding_amount': fields.float('Withholding amount', digits_compute=dp.get_precision('Account'), readonly=True, states={'draft':[('readonly',False)]}),
208- 'has_withholding': fields.boolean('With withholding tax', readonly=True, states={'draft':[('readonly',False)]}),
209+ 'withholding_amount': fields.float(
210+ 'Withholding amount', digits_compute=dp.get_precision('Account'),
211+ readonly=True, states={'draft': [('readonly', False)]}
212+ ),
213+ 'has_withholding': fields.boolean(
214+ 'With withholding tax', readonly=True,
215+ states={'draft': [('readonly', False)]}
216+ ),
217 'net_pay': fields.function(_net_pay, string="Net Pay"),
218 }
219
220+
221 class account_voucher(orm.Model):
222 _inherit = "account.voucher"
223-
224+
225+ def _get_wht_amount(self, cr, uid, ids, field_name, arg, context=None):
226+ res = {}
227+ invoice_obj = self.pool.get('account.invoice')
228+ wht_amount = 0
229+ for voucher in self.browse(cr, uid, ids, context):
230+ for line in voucher.line_ids:
231+ move = line.move_line_id.move_id
232+ if move:
233+ move_id = line.move_line_id.move_id.id
234+ invoice_id = invoice_obj.search(
235+ cr, uid, [('move_id', '=', move_id)]
236+ )
237+ if invoice_id:
238+ wht_amount += invoice_obj.browse(
239+ cr, uid, invoice_id[0]
240+ ).withholding_amount
241+ res[voucher.id] = wht_amount
242+ return res
243+
244+ def _get_writeoff_amount(self, cr, uid, ids, name, args, context=None):
245+ if not ids:
246+ return {}
247+ currency_obj = self.pool.get('res.currency')
248+ res = {}
249+ debit = credit = 0.0
250+ for voucher in self.browse(cr, uid, ids, context=context):
251+ amount_unreconciled = 0.0
252+ sign = voucher.type == 'payment' and -1 or 1
253+ for l in voucher.line_dr_ids:
254+ debit += l.amount
255+ amount_unreconciled += l.amount_unreconciled
256+ for l in voucher.line_cr_ids:
257+ credit += l.amount
258+ currency = voucher.currency_id or voucher.company_id.currency_id
259+ if voucher.withholding_amount:
260+ wo_amount = currency_obj.round(
261+ cr, uid, currency,
262+ (amount_unreconciled - voucher.amount -
263+ voucher.withholding_amount)
264+ )
265+ res[voucher.id] = sign * wo_amount
266+ else:
267+ res[voucher.id] = currency_obj.round(
268+ cr, uid, currency,
269+ voucher.amount - sign * (credit - debit))
270+ return res
271+
272 _columns = {
273- 'withholding_move_ids': fields.many2many('account.move', 'voucher_withholding_move_rel', 'voucher_id', 'move_id', 'Withholding Tax Entries', readonly=True),
274+ 'withholding_move_ids': fields.many2many(
275+ 'account.move', 'voucher_withholding_move_rel', 'voucher_id',
276+ 'move_id', 'Withholding Tax Entries', readonly=True
277+ ),
278+ 'writeoff_move_id': fields.many2one(
279+ 'account.move', 'Write-off move', readonly=True
280+ ),
281+ 'withholding_amount': fields.function(
282+ _get_wht_amount, type="float", method=True,
283+ string='Withholding amount'
284+ ),
285+ 'writeoff_amount': fields.function(
286+ _get_writeoff_amount, string='Difference Amount', type='float',
287+ readonly=True, help="Computed as the difference between the\
288+ amount stated in the voucher and the sum of allocation on\
289+ the voucher lines."
290+ ),
291 }
292-
293- def reconcile_withholding_move(self, cr, uid, invoice, wh_move, context=None):
294- line_pool=self.pool.get('account.move.line')
295+
296+ def reconcile_withholding_move(
297+ self, cr, uid, invoice, wh_move, context=None):
298+ line_pool = self.pool.get('account.move.line')
299 rec_ids = []
300 for inv_move_line in invoice.move_id.line_id:
301- if inv_move_line.account_id.type == 'payable' and not inv_move_line.reconcile_id:
302+ if (inv_move_line.account_id.type == 'payable' and not
303+ inv_move_line.reconcile_id):
304 rec_ids.append(inv_move_line.id)
305 for wh_line in wh_move.line_id:
306- if wh_line.account_id.type == 'payable' and invoice.company_id.withholding_account_id and invoice.company_id.withholding_account_id.id != wh_line.account_id.id and not wh_line.reconcile_id:
307+ if (wh_line.account_id.type == 'payable' and
308+ invoice.company_id.withholding_account_id and
309+ invoice.company_id.withholding_account_id.id !=
310+ wh_line.account_id.id and not wh_line.reconcile_id):
311 rec_ids.append(wh_line.id)
312- return line_pool.reconcile_partial(cr, uid, rec_ids, type='auto', context=context)
313-
314+ return line_pool.reconcile_partial(
315+ cr, uid, rec_ids, type='auto', context=context
316+ )
317+
318+ def reconcile_writeoff_move(self, cr, uid, invoice, wo_move, context=None):
319+ line_pool = self.pool.get('account.move.line')
320+ rec_ids = []
321+ for inv_move_line in invoice.move_id.line_id:
322+ if (inv_move_line.account_id.type == 'payable' and not
323+ inv_move_line.reconcile_id):
324+ rec_ids.append(inv_move_line.id)
325+ for wo_line in wo_move.line_id:
326+ if (wo_line.account_id.type == 'payable' and not
327+ wo_line.reconcile_id):
328+ rec_ids.append(wo_line.id)
329+ return line_pool.reconcile_partial(
330+ cr, uid, rec_ids, type='auto', context=context
331+ )
332+
333 def action_move_line_create(self, cr, uid, ids, context=None):
334- res = super(account_voucher,self).action_move_line_create(cr, uid, ids, context)
335+ res = super(account_voucher, self).action_move_line_create(
336+ cr, uid, ids, context
337+ )
338 inv_pool = self.pool.get('account.invoice')
339 move_pool = self.pool.get('account.move')
340- tax_pool = self.pool.get('account.tax')
341- curr_pool = self.pool.get('res.currency')
342 term_pool = self.pool.get('account.payment.term')
343 priod_obj = self.pool.get('account.period')
344 for voucher in self.browse(cr, uid, ids, context):
345- amounts_by_invoice = super(account_voucher,self).allocated_amounts_grouped_by_invoice(cr, uid,voucher, context)
346+ amounts_by_invoice = super(
347+ account_voucher, self
348+ ).allocated_amounts_grouped_by_invoice(
349+ cr, uid, voucher, context
350+ )
351 for inv_id in amounts_by_invoice:
352 invoice = inv_pool.browse(cr, uid, inv_id, context)
353- if invoice.withholding_amount:
354+ if not invoice.withholding_amount:
355+ return res
356+ else:
357 # only for supplier payments
358 if voucher.type != 'payment':
359- raise orm.except_orm(_('Error'), _('Can\'t handle withholding tax with voucher of type other than payment'))
360+ raise orm.except_orm(
361+ _('Error'),
362+ _('Can\'t handle withholding tax with voucher of\
363+ type other than payment')
364+ )
365 if not invoice.company_id.withholding_account_id:
366- raise orm.except_orm(_('Error'), _('The company does not have an associated Withholding account') )
367+ raise orm.except_orm(
368+ _('Error'),
369+ _('The company does not have an associated\
370+ Withholding account')
371+ )
372 if not invoice.company_id.withholding_payment_term_id:
373- raise orm.except_orm(_('Error'), _('The company does not have an associated Withholding Payment Term') )
374+ raise orm.except_orm(
375+ _('Error'),
376+ _('The company does not have an associated\
377+ Withholding Payment Term')
378+ )
379 if not invoice.company_id.withholding_journal_id:
380- raise orm.except_orm(_('Error'), _('The company does not have an associated Withholding journal') )
381+ raise orm.except_orm(
382+ _('Error'),
383+ _('The company does not have an associated\
384+ Withholding journal')
385+ )
386 if not invoice.company_id.authority_partner_id:
387- raise orm.except_orm(_('Error'), _('The company does not have an associated Tax Authority partner') )
388+ raise orm.except_orm(
389+ _('Error'),
390+ _('The company does not have an associated Tax\
391+ Authority partner')
392+ )
393 # compute the new amount proportionally to paid amount
394- new_line_amount = curr_pool.round(cr, uid, voucher.company_id.currency_id, ((amounts_by_invoice[invoice.id]['allocated'] + amounts_by_invoice[invoice.id]['write-off']) / invoice.net_pay) * invoice.withholding_amount)
395-
396+ wht_amount = invoice.withholding_amount
397 # compute the due date
398 due_list = term_pool.compute(
399- cr, uid, invoice.company_id.withholding_payment_term_id.id, new_line_amount,
400- date_ref=voucher.date or invoice.date_invoice, context=context)
401+ cr, uid,
402+ invoice.company_id.withholding_payment_term_id.id,
403+ wht_amount,
404+ date_ref=voucher.date or invoice.date_invoice,
405+ context=context
406+ )
407+
408+ company = invoice.company_id
409+ payment_term = company.withholding_payment_term_id
410+ wht_acc_id = company.withholding_account_id.id
411+
412 if len(due_list) > 1:
413- raise orm.except_orm(_('Error'),
414+ raise orm.except_orm(
415+ _('Error'),
416 _('The payment term %s has too many due dates')
417- % invoice.company_id.withholding_payment_term_id.name)
418+ % payment_term.name)
419 if len(due_list) == 0:
420- raise orm.except_orm(_('Error'),
421+ raise orm.except_orm(
422+ _('Error'),
423 _('The payment term %s does not have due dates')
424- % invoice.company_id.withholding_payment_term_id.name)
425-
426- period_ids = priod_obj.find(cr, uid, dt=voucher.date, context=context)
427+ % payment_term.name)
428+
429+ period_ids = priod_obj.find(
430+ cr, uid, dt=voucher.date, context=context
431+ )
432+
433 new_move = {
434- 'journal_id': invoice.company_id.withholding_journal_id.id,
435+ 'journal_id': company.withholding_journal_id.id,
436 'period_id': period_ids and period_ids[0] or False,
437 'date': voucher.date,
438 'line_id': [
439- (0,0,{
440+ (0, 0, {
441 'name': invoice.number,
442 'account_id': invoice.account_id.id,
443 'partner_id': invoice.partner_id.id,
444- 'debit': new_line_amount,
445- 'credit': 0.0,
446+ 'debit': wht_amount, 'credit': 0.0
447 }),
448- (0,0,{
449- 'name': _('Payable withholding - ') + invoice.number,
450- 'account_id': invoice.company_id.withholding_account_id.id,
451- 'partner_id': invoice.company_id.authority_partner_id.id,
452- 'debit': 0.0,
453- 'credit': new_line_amount,
454- 'date_maturity': due_list[0][0],
455+ (0, 0, {
456+ 'name': _('Payable withholding - ') +
457+ invoice.number,
458+ 'account_id': wht_acc_id,
459+ 'partner_id': company.authority_partner_id.id,
460+ 'debit': 0.0, 'credit': wht_amount,
461+ 'date_maturity': due_list[0][0]
462 }),
463 ]
464 }
465- move_id = self.pool.get('account.move').create(cr, uid, new_move, context=context)
466- self.reconcile_withholding_move(cr, uid, invoice, move_pool.browse(cr, uid, move_id, context), context)
467+ move_id = self.pool.get('account.move').create(
468+ cr, uid, new_move, context=context
469+ )
470+ self.reconcile_withholding_move(
471+ cr, uid, invoice, move_pool.browse(
472+ cr, uid, move_id, context
473+ ), context
474+ )
475 voucher.write({'withholding_move_ids': [(4, move_id)]})
476+ amount_unreconciled = 0.0
477+ for dr_line in voucher.line_dr_ids:
478+ amount_unreconciled += dr_line.amount_unreconciled
479+ wo_amount = (
480+ amount_unreconciled - voucher.amount -
481+ voucher.withholding_amount
482+ )
483+ if (voucher.payment_option == 'with_writeoff' and
484+ voucher.amount != invoice.net_pay):
485+
486+ wo_line = self.writeoff_move_line_get(
487+ cr, uid, voucher.id, wo_amount, move_id,
488+ voucher.comment, company.currency_id.id,
489+ voucher.currency_id.id, context)
490+
491+ wo_move = {
492+ 'journal_id': voucher.journal_id.id,
493+ 'period_id': period_ids and period_ids[0] or False,
494+ 'date': voucher.date,
495+ 'line_id': [
496+ (0, 0, {
497+ 'name': invoice.number,
498+ 'account_id': invoice.account_id.id,
499+ 'partner_id': invoice.partner_id.id,
500+ 'debit': wo_amount,
501+ 'credit': 0.0,
502+ }),
503+ (0, 0, wo_line),
504+ ]
505+ }
506+ wo_move_id = move_pool.create(
507+ cr, uid, wo_move, context=context)
508+ self.reconcile_writeoff_move(
509+ cr, uid, invoice, move_pool.browse(
510+ cr, uid, wo_move_id, context
511+ ), context
512+ )
513+ voucher.write({'writeoff_move_id': wo_move_id})
514 return res
515
516 def cancel_voucher(self, cr, uid, ids, context=None):
517- res = super(account_voucher,self).cancel_voucher(cr, uid, ids, context)
518- reconcile_pool = self.pool.get('account.move.reconcile')
519+ res = super(account_voucher, self).cancel_voucher(
520+ cr, uid, ids, context
521+ )
522 move_pool = self.pool.get('account.move')
523 for voucher in self.browse(cr, uid, ids, context=context):
524- recs = []
525 for move in voucher.withholding_move_ids:
526 move_pool.button_cancel(cr, uid, [move.id])
527 move_pool.unlink(cr, uid, [move.id])
528+ if voucher.writeoff_move_id:
529+ move_pool.button_cancel(cr, uid, [voucher.writeoff_move_id.id])
530+ move_pool.unlink(cr, uid, [voucher.writeoff_move_id.id])
531 return res
532
533=== modified file 'l10n_it_withholding_tax/account_view.xml'
534--- l10n_it_withholding_tax/account_view.xml 2013-04-17 12:47:39 +0000
535+++ l10n_it_withholding_tax/account_view.xml 2014-01-02 17:27:30 +0000
536@@ -63,6 +63,8 @@
537 <field name="move_ids" position="after">
538 <separator string="Withholding tax entries" colspan="4"></separator>
539 <field name="withholding_move_ids" colspan="4" nolabel="1"/>
540+ <separator string="Write-off entries" colspan="4"></separator>
541+ <field name="writeoff_move_id" colspan="4" nolabel="1"/>
542 </field>
543 </field>
544 </record>

Subscribers

People subscribed via source and target branches