Merge lp:~openbig/bigconsulting/changes_account_invoice_cash_discount into lp:bigconsulting

Proposed by gpa(OpenERP)
Status: Merged
Merged at revision: 9
Proposed branch: lp:~openbig/bigconsulting/changes_account_invoice_cash_discount
Merge into: lp:bigconsulting
Diff against target: 619 lines (+327/-213)
8 files modified
account_invoice_cash_discount/__terp__.py (+1/-1)
account_invoice_cash_discount/account_invoice_cash_discount.py (+36/-2)
account_invoice_cash_discount/account_invoice_cash_discount_view.xml (+2/-0)
account_invoice_cash_discount/account_wizard.xml (+0/-6)
account_invoice_cash_discount/wizard/__init__.py (+1/-1)
account_invoice_cash_discount/wizard/account_pay_invoice.py (+224/-0)
account_invoice_cash_discount/wizard/account_pay_invoice_view.xml (+63/-0)
account_invoice_cash_discount/wizard/wizard_pay_invoice.py (+0/-203)
To merge this branch: bzr merge lp:~openbig/bigconsulting/changes_account_invoice_cash_discount
Reviewer Review Type Date Requested Status
openbig Pending
Review via email: mp+26461@code.launchpad.net

Description of the change

convert wizard pay invoice to osv memroy wizard make onchange on Amount Paid field

To post a comment you must log in.
10. By gpa(OpenERP)

changes on account_invoice_cash_discount

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'account_invoice_cash_discount/__terp__.py'
2--- account_invoice_cash_discount/__terp__.py 2010-05-28 10:52:25 +0000
3+++ account_invoice_cash_discount/__terp__.py 2010-06-01 08:53:22 +0000
4@@ -35,7 +35,7 @@
5 ],
6 "update_xml" : [
7 "account_invoice_cash_discount_view.xml",
8- "account_wizard.xml"
9+ 'wizard/account_pay_invoice_view.xml',
10 ],
11 "active": False,
12 "installable": True,
13
14=== modified file 'account_invoice_cash_discount/account_invoice_cash_discount.py'
15--- account_invoice_cash_discount/account_invoice_cash_discount.py 2010-05-28 10:52:25 +0000
16+++ account_invoice_cash_discount/account_invoice_cash_discount.py 2010-06-01 08:53:22 +0000
17@@ -49,8 +49,10 @@
18 _inherit = "account.invoice"
19
20 def _get_payment(self, cr, uid, ids, resudial_amonut, payment_term, context=None):
21-
22- #This function used to count the discount payment term
23+ """
24+ This function return the Discount according to the payment term cash discount term
25+ """
26+
27 if context is None:
28 context = {}
29
30@@ -88,6 +90,38 @@
31 ted +=rr
32 discunt = res + ted
33 return discunt
34+
35+ def _get_account(self, cr, uid, ids, resudial_amonut, payment_term, context=None):
36+ """
37+ This function return the Account according to the payment term cash discount term
38+ """
39+ if context is None:
40+ context = {}
41+
42+ tax_obj = self.pool.get('account.tax')
43+ invoice = self.browse(cr, uid, ids[0], context=context)
44+
45+ if invoice.date_due:
46+ date1 = invoice.date_due
47+ else:
48+ date1 = time.strftime('%Y-%m-%d')
49+
50+ if 'date_p' in context and context['date_p']:
51+ date2 = context['date_p']
52+ else:
53+ date2 = time.strftime('%Y-%m-%d')
54+
55+ from_dt = time.mktime(time.strptime(date1,'%Y-%m-%d'))
56+ to_dt = time.mktime(time.strptime(date2,'%Y-%m-%d'))
57+ diff_day = (from_dt-to_dt)/(3600*24)
58+ if payment_term:
59+ pt = self.pool.get('account.payment.term').browse(cr, uid, payment_term, context=context)
60+ if pt.cash_discount_ids:
61+ res = 0.0
62+ for d in pt.cash_discount_ids:
63+ if diff_day == d.delay or diff_day < d.delay:
64+ account_id = d.discount_account_id.id
65+ return account_id
66
67 def pay_and_reconcile(self, cr, uid, ids, pay_amount, pay_account_id, period_id, pay_journal_id, writeoff_acc_id, writeoff_period_id, writeoff_journal_id, context=None, name=''):
68
69
70=== modified file 'account_invoice_cash_discount/account_invoice_cash_discount_view.xml'
71--- account_invoice_cash_discount/account_invoice_cash_discount_view.xml 2010-05-26 13:32:15 +0000
72+++ account_invoice_cash_discount/account_invoice_cash_discount_view.xml 2010-06-01 08:53:22 +0000
73@@ -14,6 +14,7 @@
74 <field name="name" select="1"/>
75 <field name="delay" select="1"/>
76 <field name="discount" select="1"/>
77+ <field name="discount_account_id" />
78 </form>
79 </field>
80 </record>
81@@ -27,6 +28,7 @@
82 <field name="name" select="1"/>
83 <field name="delay" select="1"/>
84 <field name="discount" select="1"/>
85+ <field name="discount_account_id" />
86 </tree>
87 </field>
88 </record>
89
90=== removed file 'account_invoice_cash_discount/account_wizard.xml'
91--- account_invoice_cash_discount/account_wizard.xml 2010-05-26 13:32:15 +0000
92+++ account_invoice_cash_discount/account_wizard.xml 1970-01-01 00:00:00 +0000
93@@ -1,6 +0,0 @@
94-<?xml version="1.0" encoding="utf-8"?>
95-<openerp>
96- <data>
97- <wizard id="wizard_invoice_pay" model="account.invoice" name="account.invoice.pay1" string="Pay invoice" groups="base.group_user"/>
98- </data>
99-</openerp>
100
101=== modified file 'account_invoice_cash_discount/wizard/__init__.py'
102--- account_invoice_cash_discount/wizard/__init__.py 2010-05-26 13:32:15 +0000
103+++ account_invoice_cash_discount/wizard/__init__.py 2010-06-01 08:53:22 +0000
104@@ -20,7 +20,7 @@
105 #
106 ##############################################################################
107
108-import wizard_pay_invoice
109+import account_pay_invoice
110
111 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
112
113
114=== added file 'account_invoice_cash_discount/wizard/account_pay_invoice.py'
115--- account_invoice_cash_discount/wizard/account_pay_invoice.py 1970-01-01 00:00:00 +0000
116+++ account_invoice_cash_discount/wizard/account_pay_invoice.py 2010-06-01 08:53:22 +0000
117@@ -0,0 +1,224 @@
118+# -*- coding: utf-8 -*-
119+##############################################################################
120+#
121+# OpenERP, Open Source Management Solution
122+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
123+#
124+# This program is free software: you can redistribute it and/or modify
125+# it under the terms of the GNU Affero General Public License as
126+# published by the Free Software Foundation, either version 3 of the
127+# License, or (at your option) any later version.
128+#
129+# This program is distributed in the hope that it will be useful,
130+# but WITHOUT ANY WARRANTY; without even the implied warranty of
131+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
132+# GNU Affero General Public License for more details.
133+#
134+# You should have received a copy of the GNU Affero General Public License
135+# along with this program. If not, see <http://www.gnu.org/licenses/>.
136+#
137+##############################################################################
138+import time
139+
140+from osv import fields, osv
141+from tools.translate import _
142+#import decimal_precision as dp
143+
144+class account_invoice_pay_writeoff(osv.osv_memory):
145+ """
146+ Opens the write off amount pay form.
147+ """
148+ _name = "account.invoice.pay.writeoff"
149+ _description = "Pay Invoice "
150+ _columns = {
151+ 'writeoff_acc_id': fields.many2one('account.account', 'Write-Off account', required=True),
152+ 'writeoff_journal_id': fields.many2one('account.journal', 'Write-Off journal', required=True),
153+ 'comment': fields.char('Comment', size=64, required=True),
154+ 'analytic_id': fields.many2one('account.analytic.account','Analytic Account'),
155+ }
156+ _defaults = {
157+ 'comment': 'Write-Off',
158+ }
159+
160+ def pay_and_reconcile_writeoff(self, cr, uid, ids, context=None):
161+ data = self.read(cr, uid, ids,context=context)[0]
162+ context.update({'write_off':data})
163+ self.pool.get('account.invoice.pay').pay_and_reconcile(cr, uid, ids, context=context)
164+ return {}
165+
166+account_invoice_pay_writeoff()
167+
168+class account_invoice_pay(osv.osv_memory):
169+ """
170+ Generate pay invoice wizard, user can make partial or full payment for invoice.
171+ """
172+ _name = "account.invoice.pay"
173+ _description = "Pay Invoice "
174+ _columns = {
175+ 'amount': fields.float('Amount paid', required=True),
176+ 'name': fields.char('Entry Name', size=64, required=True),
177+ 'date': fields.date('Date payment', required=True),
178+ 'journal_id': fields.many2one('account.journal', 'Journal/Payment Mode', required=True),
179+ 'period_id': fields.many2one('account.period', 'Period', required=True),
180+ 'cash_amount':fields.float('Cash Discount Amount', required=True),
181+ 'account_id': fields.many2one('account.account', 'Account For Discount', required=True),
182+ }
183+
184+ def view_init(self, cr, uid, ids, context=None):
185+ invoice = self.pool.get('account.invoice').browse(cr, uid, context['active_id'], context=context)
186+ if invoice.state in ['draft', 'proforma2', 'cancel']:
187+ raise osv.except_osv(_('Error !'), _('Can not pay draft/proforma/cancel invoice.'))
188+ pass
189+
190+ def _get_period(self, cr, uid, context=None):
191+ ids = self.pool.get('account.period').find(cr, uid, context=context)
192+ period_id = False
193+ if len(ids):
194+ period_id = ids[0]
195+ return period_id
196+
197+ def _get_amount(self, cr, uid, context=None):
198+ return self.pool.get('account.invoice').browse(cr, uid, context['id'], context=context).residual
199+
200+ def on_change_ammount(self, cr, uid, ids, amount, context=None):
201+ """
202+ Function return the Discount according to the Amount paid and Payment Term Cash Discount
203+ """
204+ res = {}
205+ obj_inv = self.pool.get('account.invoice')
206+ invoice = obj_inv.browse(cr, uid, context['id'], context=context)
207+ discount = obj_inv._get_payment(cr, uid, [context['id']] , amount, invoice.payment_term.id, context=context)
208+ return {'value' : {'cash_amount':discount}}
209+
210+ def _get_discount(self, cr, uid, context=None):
211+ obj_inv = self.pool.get('account.invoice')
212+ invoice = obj_inv.browse(cr, uid, context['id'], context=context)
213+ discount = obj_inv._get_payment(cr, uid, [context['id']] , invoice.residual, invoice.payment_term.id, context=context)
214+ return discount
215+
216+ def _get_account(self, cr, uid, context=None):
217+ """
218+ This function return the Account according to the payment term cash term and map the account with fiscal position
219+ """
220+ obj_inv = self.pool.get('account.invoice')
221+ invoice = obj_inv.browse(cr, uid, context['id'], context=context)
222+ account = obj_inv._get_account(cr, uid, [context['id']] , invoice.residual, invoice.payment_term.id, context=context)
223+ fpos = invoice.fiscal_position or False
224+ account = self.pool.get('account.fiscal.position').map_account(cr, uid, fpos, account)
225+ return account
226+
227+ _defaults = {
228+ 'date': lambda *a: time.strftime('%Y-%m-%d'),
229+ 'period_id': _get_period,
230+ 'amount': _get_amount,
231+ 'cash_amount':_get_discount,
232+ 'account_id':_get_account
233+ }
234+
235+ def wo_check(self, cr, uid, ids, context=None):
236+ cur_obj = self.pool.get('res.currency')
237+ mod_obj = self.pool.get('ir.model.data')
238+ if context is None:
239+ context = {}
240+ data = self.read(cr, uid, ids,context=context)[0]
241+ invoice = self.pool.get('account.invoice').browse(cr, uid, context['id'], context)
242+ journal = self.pool.get('account.journal').browse(cr, uid, data['journal_id'], context)
243+
244+ # Here we need that:
245+ # The invoice total amount in company's currency <> paid amount in company currency
246+ # (according to the correct day rate, invoicing rate and payment rate are may be different)
247+ # => Ask to a write-off of the difference. This could happen even if both amount are equal,
248+ # because if the currency rate
249+ # Get the amount in company currency for the invoice (according to move lines)
250+ inv_amount_company_currency = 0
251+ for aml in invoice.move_id.line_id:
252+ if aml.account_id.id == invoice.account_id.id or aml.account_id.type in ('receivable', 'payable'):
253+ inv_amount_company_currency += aml.debit
254+ inv_amount_company_currency -= aml.credit
255+ inv_amount_company_currency = abs(inv_amount_company_currency)
256+
257+ # Get the current amount paid in company currency
258+ if journal.currency and invoice.company_id.currency_id.id<>journal.currency.id:
259+ ctx = {'date':data['date']}
260+ amount_paid = cur_obj.compute(cr, uid, journal.currency.id, invoice.company_id.currency_id.id, data['amount'], round=True, context=ctx)
261+ else:
262+ amount_paid = data['amount']
263+ # Get the old payment if there are some
264+ if invoice.payment_ids:
265+ debit=credit=0.0
266+ for payment in invoice.payment_ids:
267+ debit+=payment.debit
268+ credit+=payment.credit
269+ amount_paid+=abs(debit-credit)
270+
271+ # Test if there is a difference according to currency rouding setting
272+ if self.pool.get('res.currency').is_zero(cr, uid, invoice.company_id.currency_id,
273+ (amount_paid - inv_amount_company_currency)):
274+ return self.pay_and_reconcile(cr, uid, ids, context=context)
275+ else:
276+ model_data_ids = mod_obj.search(cr, uid,[('model','=','ir.ui.view'),('name','=','view_account_invoice_pay_writeoff')], context=context)
277+ resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
278+ return {
279+ 'name': _('Information addendum'),
280+ 'context': context,
281+ 'view_type': 'form',
282+ 'view_mode': 'form',
283+ 'res_model': 'account.invoice.pay.writeoff',
284+ 'views': [(resource_id,'form')],
285+ 'type': 'ir.actions.act_window',
286+ 'target': 'new',
287+ }
288+
289+ def pay_and_reconcile(self, cr, uid, ids, context=None):
290+ cur_obj = self.pool.get('res.currency')
291+ if context is None:
292+ context = {}
293+ data = self.read(cr, uid, ids,context=context)[0]
294+ writeoff_account_id = False
295+ writeoff_journal_id = False
296+ comment = False
297+
298+ if 'write_off' in context and context['write_off'] :
299+ writeoff_account_id = context['write_off']['writeoff_acc_id']
300+ writeoff_journal_id = context['write_off']['writeoff_journal_id']
301+ comment = context['write_off']['comment']
302+
303+ amount = data['amount']
304+
305+ invoice = self.pool.get('account.invoice').browse(cr, uid, context['id'], context=context)
306+ journal = self.pool.get('account.journal').browse(cr, uid, data['journal_id'], context=context)
307+ # Compute the amount in company's currency, with the journal currency (which is equal to payment currency)
308+ # when it is needed : If payment currency (according to selected journal.currency) is <> from company currency
309+ if journal.currency and invoice.company_id.currency_id.id<>journal.currency.id:
310+ ctx = {'date':data['date']}
311+ amount = cur_obj.compute(cr, uid, journal.currency.id, invoice.company_id.currency_id.id, amount, context=ctx)
312+ currency_id = journal.currency.id
313+ # Put the paid amount in currency, and the currency, in the context if currency is different from company's currency
314+ context.update({'amount_currency':data['amount'],'currency_id':currency_id})
315+
316+ if invoice.company_id.currency_id.id<>invoice.currency_id.id:
317+ ctx = {'date':data['date']}
318+ amount = cur_obj.compute(cr, uid, invoice.currency_id.id, invoice.company_id.currency_id.id, amount, context=ctx)
319+ currency_id = invoice.currency_id.id
320+ # Put the paid amount in currency, and the currency, in the context if currency is different from company's currency
321+ context.update({'amount_currency':data['amount'],'currency_id':currency_id})
322+
323+ # Take the choosen date
324+ if comment:
325+ context.update({'date_p':data['date'],'comment':comment})
326+ else:
327+ context.update({'date_p':data['date'],'comment':False})
328+
329+ context.update({'account_id':data['account_id'],'cash_amount':data['cash_amount'],'amount_currency':data['amount']})
330+
331+ acc_id = journal.default_credit_account_id and journal.default_credit_account_id.id
332+ if not acc_id:
333+ raise osv.except_osv(_('Error !'), _('Your journal must have a default credit and debit account.'))
334+ self.pool.get('account.invoice').pay_and_reconcile(cr, uid, [context['id']],
335+ amount, acc_id, data['period_id'], data['journal_id'], writeoff_account_id,
336+ data['period_id'], writeoff_journal_id, context, data['name'])
337+ return {}
338+
339+account_invoice_pay()
340+
341+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
342\ No newline at end of file
343
344=== added file 'account_invoice_cash_discount/wizard/account_pay_invoice_view.xml'
345--- account_invoice_cash_discount/wizard/account_pay_invoice_view.xml 1970-01-01 00:00:00 +0000
346+++ account_invoice_cash_discount/wizard/account_pay_invoice_view.xml 2010-06-01 08:53:22 +0000
347@@ -0,0 +1,63 @@
348+<?xml version="1.0" encoding="utf-8"?>
349+<openerp>
350+ <data>
351+ <record id="view_account_invoice_pay" model="ir.ui.view">
352+ <field name="name">account.invoice.pay.form</field>
353+ <field name="model">account.invoice.pay</field>
354+ <field name="type">form</field>
355+ <field name="arch" type="xml">
356+ <form string="Pay invoice">
357+ <group colspan="4" >
358+ <field name="amount" on_change="on_change_ammount(amount,context)"/>
359+ <newline/>
360+ <field name="name"/>
361+ <field name="date"/>
362+ <field name="journal_id"/>
363+ <field name="period_id"/>
364+ <field name="cash_amount"/>
365+ <field name="account_id"/>
366+ </group>
367+ <group colspan="4" col="6">
368+ <label string ="" colspan="2"/>
369+ <button icon="gtk-cancel" special="cancel" string="Cancel"/>
370+ <button icon="gtk-execute" string="Partial Payment" name="pay_and_reconcile" type="object"/>
371+ <button icon="gtk-execute" string="Full Payment" name="wo_check" type="object"/>
372+ </group>
373+ </form>
374+ </field>
375+ </record>
376+
377+ <act_window name="Pay Invoice"
378+ res_model="account.invoice.pay"
379+ src_model="account.invoice"
380+ view_mode="form"
381+ target="new"
382+ context="{'id': active_id}"
383+ id="action_view_account_invoice_pay"/>
384+
385+ <record id="view_account_invoice_pay_writeoff" model="ir.ui.view">
386+ <field name="name">account.invoice.pay.writeoff.form</field>
387+ <field name="model">account.invoice.pay.writeoff</field>
388+ <field name="type">form</field>
389+ <field name="arch" type="xml">
390+ <form string="Information addendum">
391+ <group colspan="4" >
392+ <separator string="Write-Off Move" colspan="4"/>
393+ <field name="writeoff_journal_id"/>
394+ <field name="writeoff_acc_id" domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation')]"/>
395+ <field name="comment"/>
396+ <separator string="Analytic" colspan="4"/>
397+ <field name="analytic_id"/>
398+ </group>
399+ <group colspan="4" col="6">
400+ <label string ="" colspan="2"/>
401+ <button icon="gtk-cancel" special="cancel" string="Cancel"/>
402+ <button icon="gtk-execute" string="Pay and reconcile" name="pay_and_reconcile_writeoff" type="object"/>
403+ </group>
404+ </form>
405+ </field>
406+ </record>
407+
408+
409+ </data>
410+</openerp>
411\ No newline at end of file
412
413=== removed file 'account_invoice_cash_discount/wizard/wizard_pay_invoice.py'
414--- account_invoice_cash_discount/wizard/wizard_pay_invoice.py 2010-05-27 07:24:45 +0000
415+++ account_invoice_cash_discount/wizard/wizard_pay_invoice.py 1970-01-01 00:00:00 +0000
416@@ -1,203 +0,0 @@
417-# -*- encoding: utf-8 -*-
418-##############################################################################
419-#
420-# OpenERP, Open Source Management Solution
421-# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
422-# $Id$
423-#
424-# This program is free software: you can redistribute it and/or modify
425-# it under the terms of the GNU General Public License as published by
426-# the Free Software Foundation, either version 3 of the License, or
427-# (at your option) any later version.
428-#
429-# This program is distributed in the hope that it will be useful,
430-# but WITHOUT ANY WARRANTY; without even the implied warranty of
431-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
432-# GNU General Public License for more details.
433-#
434-# You should have received a copy of the GNU General Public License
435-# along with this program. If not, see <http://www.gnu.org/licenses/>.
436-#
437-##############################################################################
438-
439-import wizard
440-import pooler
441-import time
442-from tools.translate import _
443-import tools
444-
445-pay_form = '''<?xml version="1.0"?>
446-<form string="Pay invoice">
447- <field name="amount"/>
448- <newline/>
449- <field name="name"/>
450- <field name="date"/>
451- <field name="journal_id"/>
452- <field name="period_id"/>
453- <field name="cash_amount"/>
454- <field name="account_id"/>
455-</form>'''
456-
457-pay_fields = {
458- 'amount': {'string': 'Amount paid', 'type':'float', 'required':True, 'digits': (16,int(tools.config['price_accuracy']))},
459- 'name': {'string': 'Entry Name', 'type':'char', 'size': 64, 'required':True},
460- 'cash_amount': {'string': 'Cash Discount Amount', 'type':'float', 'required':True, 'digits': (16,int(tools.config['price_accuracy']))},
461- 'account_id': {'string': 'Account For Discount', 'type': 'many2one', 'relation':'account.account', 'required':True},
462- 'date': {'string': 'Payment date', 'type':'date', 'required':True, 'default':lambda *args: time.strftime('%Y-%m-%d')},
463- 'journal_id': {'string': 'Journal/Payment Mode', 'type': 'many2one', 'relation':'account.journal', 'required':True, 'domain':[('type','=','cash')]},
464- 'period_id': {'string': 'Period', 'type': 'many2one', 'relation':'account.period', 'required':True},
465-}
466-
467-def _pay_and_reconcile(self, cr, uid, data, context):
468- form = data['form']
469- period_id = form.get('period_id', False)
470- journal_id = form.get('journal_id', False)
471- writeoff_account_id = form.get('writeoff_acc_id', False)
472- writeoff_journal_id = form.get('writeoff_journal_id', False)
473- pool = pooler.get_pool(cr.dbname)
474- cur_obj = pool.get('res.currency')
475- amount = form['amount']
476- context['analytic_id'] = form.get('analytic_id', False)
477-
478- invoice = pool.get('account.invoice').browse(cr, uid, data['id'], context)
479- journal = pool.get('account.journal').browse(cr, uid, data['form']['journal_id'], context)
480- # Compute the amount in company's currency, with the journal currency (which is equal to payment currency)
481- # when it is needed : If payment currency (according to selected journal.currency) is <> from company currency
482- if journal.currency and invoice.company_id.currency_id.id<>journal.currency.id:
483- ctx = {'date':data['form']['date']}
484- amount = cur_obj.compute(cr, uid, journal.currency.id, invoice.company_id.currency_id.id, amount, context=ctx)
485- currency_id = journal.currency.id
486- # Put the paid amount in currency, and the currency, in the context if currency is different from company's currency
487- context.update({'amount_currency':form['amount'],'currency_id':currency_id})
488-
489- if invoice.company_id.currency_id.id<>invoice.currency_id.id:
490- ctx = {'date':data['form']['date']}
491- amount = cur_obj.compute(cr, uid, invoice.currency_id.id, invoice.company_id.currency_id.id, amount, context=ctx)
492- currency_id = invoice.currency_id.id
493- # Put the paid amount in currency, and the currency, in the context if currency is different from company's currency
494- context.update({'amount_currency':form['amount'],'currency_id':currency_id})
495-
496- # Take the choosen date
497- if form.has_key('comment'):
498- context.update({'date_p':form['date'],'comment':form['comment']})
499- else:
500- context.update({'date_p':form['date'],'comment':False})
501-
502- context.update({'account_id':form['account_id'],'cash_amount':form['cash_amount'],'amount_currency':form['amount']})
503-
504- acc_id = journal.default_credit_account_id and journal.default_credit_account_id.id
505- if not acc_id:
506- raise wizard.except_wizard(_('Error !'), _('Your journal must have a default credit and debit account.'))
507- pool.get('account.invoice').pay_and_reconcile(cr, uid, [data['id']],
508- amount, acc_id, period_id, journal_id, writeoff_account_id,
509- period_id, writeoff_journal_id, context, data['form']['name'])
510- return {}
511-
512-def _wo_check(self, cr, uid, data, context):
513- pool = pooler.get_pool(cr.dbname)
514- invoice = pool.get('account.invoice').browse(cr, uid, data['id'], context)
515- journal = pool.get('account.journal').browse(cr, uid, data['form']['journal_id'], context)
516- cur_obj = pool.get('res.currency')
517- # Here we need that:
518- # The invoice total amount in company's currency <> paid amount in company currency
519- # (according to the correct day rate, invoicing rate and payment rate are may be different)
520- # => Ask to a write-off of the difference. This could happen even if both amount are equal,
521- # because if the currency rate
522- # Get the amount in company currency for the invoice (according to move lines)
523- inv_amount_company_currency = 0
524- for aml in invoice.move_id.line_id:
525- if aml.account_id.id == invoice.account_id.id or aml.account_id.type in ('receivable', 'payable'):
526- inv_amount_company_currency += aml.debit
527- inv_amount_company_currency -= aml.credit
528- inv_amount_company_currency = abs(inv_amount_company_currency)
529-
530- # Get the current amount paid in company currency
531- if journal.currency and invoice.company_id.currency_id.id<>journal.currency.id:
532- ctx = {'date':data['form']['date']}
533- amount_paid = cur_obj.compute(cr, uid, journal.currency.id, invoice.company_id.currency_id.id, data['form']['amount'], round=True, context=ctx)
534- else:
535- amount_paid = data['form']['amount']
536- # Get the old payment if there are some
537- if invoice.payment_ids:
538- debit=credit=0.0
539- for payment in invoice.payment_ids:
540- debit+=payment.debit
541- credit+=payment.credit
542- amount_paid+=abs(debit-credit)
543-
544- # Test if there is a difference according to currency rouding setting
545- if pool.get('res.currency').is_zero(cr, uid, invoice.company_id.currency_id,
546- (amount_paid - inv_amount_company_currency)):
547- return 'reconcile'
548- return 'addendum'
549-
550-_transaction_add_form = '''<?xml version="1.0"?>
551-<form string="Information addendum">
552- <separator string="Write-Off Move" colspan="4"/>
553- <field name="writeoff_journal_id"/>
554- <field name="writeoff_acc_id" domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation')]"/>
555- <field name="comment"/>
556- <separator string="Analytic" colspan="4"/>
557- <field name="analytic_id"/>
558-</form>'''
559-
560-_transaction_add_fields = {
561- 'writeoff_acc_id': {'string':'Write-Off account', 'type':'many2one', 'relation':'account.account', 'required':True},
562- 'writeoff_journal_id': {'string': 'Write-Off journal', 'type': 'many2one', 'relation':'account.journal', 'required':True},
563- 'comment': {'string': 'Comment', 'type':'char', 'size': 64 , 'required':True},
564- 'analytic_id': {'string':'Analytic Account', 'type': 'many2one', 'relation':'account.analytic.account'},
565-}
566-
567-def _get_value_addendum(self, cr, uid, data, context={}):
568- return {'comment': _('Write-Off')}
569-
570-def _compute(self, cr, uid, data, context={}):
571- pool = pooler.get_pool(cr.dbname)
572- invoice = pool.get('account.invoice').browse(cr, uid, data['id'], context)
573-
574-
575-def _get_period(self, cr, uid, data, context={}):
576- pool = pooler.get_pool(cr.dbname)
577- ids = pool.get('account.period').find(cr, uid, context=context)
578- period_id = False
579- if len(ids):
580- period_id = ids[0]
581- invoice = pool.get('account.invoice').browse(cr, uid, data['id'], context)
582- cash_amount = pool.get('account.invoice')._get_payment(cr, uid, [data['id']], invoice.residual, invoice.payment_term.id, context=context)
583- if invoice.state in ['draft', 'proforma2', 'cancel']:
584- raise wizard.except_wizard(_('Error !'), _('Can not pay draft/proforma/cancel invoice.'))
585- return {
586- 'period_id': period_id,
587- 'amount': invoice.residual,
588- 'date': time.strftime('%Y-%m-%d'),
589- 'cash_amount': cash_amount,
590- }
591-
592-class wizard_pay_invoice(wizard.interface):
593- states = {
594- 'init': {
595- 'actions': [_get_period],
596- 'result': {'type':'form', 'arch':pay_form, 'fields':pay_fields, 'state':[('end','Cancel'),('reconcile','Partial Payment'),('writeoff_check','Full Payment')]}
597- },
598- 'writeoff_check': {
599- 'actions': [],
600- 'result' : {'type': 'choice', 'next_state': _wo_check }
601- },
602- 'addendum': {
603- 'actions': [_get_value_addendum],
604- 'result': {'type': 'form', 'arch':_transaction_add_form, 'fields':_transaction_add_fields, 'state':[('end','Cancel'),('reconcile','Pay and reconcile')]}
605- },
606- 'reconcile': {
607- 'actions': [_pay_and_reconcile],
608- 'result': {'type':'state', 'state':'end'}
609- },
610- 'compute_dis': {
611- 'actions': [_compute],
612- 'result': {'type':'state', 'state':'end'}
613- }
614- }
615-wizard_pay_invoice('account.invoice.pay1')
616-
617-
618-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
619-

Subscribers

People subscribed via source and target branches