Merge lp:~openbig/bigconsulting/changes_account_invoice_cash_discount into lp:bigconsulting
- changes_account_invoice_cash_discount
- Merge into addons
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
openbig | Pending | ||
Review via email: mp+26461@code.launchpad.net |
Commit message
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','<>','view'),('type','<>','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','<>','view'),('type','<>','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 | - |