Merge lp:~borjals/openobject-addons/extra-5.0-bugfix-603100 into lp:openobject-addons/extra-5.0
- extra-5.0-bugfix-603100
- Merge into stable_5.0-extra-addons
Status: | Merged |
---|---|
Merged at revision: | 4462 |
Proposed branch: | lp:~borjals/openobject-addons/extra-5.0-bugfix-603100 |
Merge into: | lp:openobject-addons/extra-5.0 |
Diff against target: |
731 lines (+515/-107) 7 files modified
purchase_tax_include/__init__.py (+15/-11) purchase_tax_include/__terp__.py (+10/-11) purchase_tax_include/i18n/es_ES.po (+89/-0) purchase_tax_include/i18n/fr_BE.po (+52/-0) purchase_tax_include/i18n/purchase_tax_include.pot (+89/-0) purchase_tax_include/purchase_tax_incl.py (+220/-57) purchase_tax_include/purchase_tax_incl.xml (+40/-28) |
To merge this branch: | bzr merge lp:~borjals/openobject-addons/extra-5.0-bugfix-603100 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
OpenERP Core Team | Pending | ||
Review via email: mp+29567@code.launchpad.net |
Commit message
Description of the change
Complete rewrite of the purchase_
- Solved "column 'amount_tax' of relation 'purchase_order' does not exist"
error when saving a purchase order (bug 603100).
The previous fields redefinitions where incompatible with the purchase
module from the 5.0 addons since Dec 2008.
- Now correct 'amount_untaxed' and 'amount_total' are shown on the
purchase order totals.
- Now 'price_
purchase order lines list of the purchase form.
- When the order is invoiced, the created invoice did not use the
price type of the order, so the amounts didn't match; fixed.
- When a picking is invoiced, the created invoice did not use the
price type of the original orders; fixed.
Borja López Soilán (NeoPolus) (borjals) wrote : | # |
Preview Diff
1 | === modified file 'purchase_tax_include/__init__.py' |
2 | --- purchase_tax_include/__init__.py 2008-11-03 19:56:05 +0000 |
3 | +++ purchase_tax_include/__init__.py 2010-07-09 15:01:37 +0000 |
4 | @@ -1,25 +1,29 @@ |
5 | # -*- encoding: utf-8 -*- |
6 | ############################################################################## |
7 | -# |
8 | -# OpenERP, Open Source Management Solution |
9 | -# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved |
10 | -# $Id$ |
11 | +# |
12 | +# OpenERP, Open Source Management Solution |
13 | +# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). |
14 | # |
15 | # This program is free software: you can redistribute it and/or modify |
16 | -# it under the terms of the GNU General Public License as published by |
17 | -# the Free Software Foundation, either version 3 of the License, or |
18 | -# (at your option) any later version. |
19 | +# it under the terms of the GNU Affero General Public License as |
20 | +# published by the Free Software Foundation, either version 3 of the |
21 | +# License, or (at your option) any later version. |
22 | # |
23 | # This program is distributed in the hope that it will be useful, |
24 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
25 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
26 | -# GNU General Public License for more details. |
27 | +# GNU Affero General Public License for more details. |
28 | # |
29 | -# You should have received a copy of the GNU General Public License |
30 | -# along with this program. If not, see <http://www.gnu.org/licenses/>. |
31 | +# You should have received a copy of the GNU Affero General Public License |
32 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
33 | # |
34 | ############################################################################## |
35 | |
36 | +__authors__ = [ |
37 | + "OpenERP S.A.", |
38 | + "Borja López Soilán (Pexego) <borjals@pexego.es>" |
39 | +] |
40 | + |
41 | import purchase_tax_incl |
42 | -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
43 | + |
44 | |
45 | |
46 | === modified file 'purchase_tax_include/__terp__.py' |
47 | --- purchase_tax_include/__terp__.py 2009-02-17 12:57:51 +0000 |
48 | +++ purchase_tax_include/__terp__.py 2010-07-09 15:01:37 +0000 |
49 | @@ -1,27 +1,26 @@ |
50 | # -*- encoding: utf-8 -*- |
51 | ############################################################################## |
52 | -# |
53 | -# OpenERP, Open Source Management Solution |
54 | -# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved |
55 | -# $Id$ |
56 | +# |
57 | +# OpenERP, Open Source Management Solution |
58 | +# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). |
59 | # |
60 | # This program is free software: you can redistribute it and/or modify |
61 | -# it under the terms of the GNU General Public License as published by |
62 | -# the Free Software Foundation, either version 3 of the License, or |
63 | -# (at your option) any later version. |
64 | +# it under the terms of the GNU Affero General Public License as |
65 | +# published by the Free Software Foundation, either version 3 of the |
66 | +# License, or (at your option) any later version. |
67 | # |
68 | # This program is distributed in the hope that it will be useful, |
69 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
70 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
71 | -# GNU General Public License for more details. |
72 | +# GNU Affero General Public License for more details. |
73 | # |
74 | -# You should have received a copy of the GNU General Public License |
75 | -# along with this program. If not, see <http://www.gnu.org/licenses/>. |
76 | +# You should have received a copy of the GNU Affero General Public License |
77 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
78 | # |
79 | ############################################################################## |
80 | { |
81 | "name" : "Purchases with taxes included", |
82 | - "version" : "1.0", |
83 | + "version" : "2.0", |
84 | "depends" : ["purchase","account_tax_include"], |
85 | "author" : "Tiny", |
86 | "website" : "http://www.openerp.com", |
87 | |
88 | === added directory 'purchase_tax_include/i18n' |
89 | === added file 'purchase_tax_include/i18n/es_ES.po' |
90 | --- purchase_tax_include/i18n/es_ES.po 1970-01-01 00:00:00 +0000 |
91 | +++ purchase_tax_include/i18n/es_ES.po 2010-07-09 15:01:37 +0000 |
92 | @@ -0,0 +1,89 @@ |
93 | +# Translation of OpenERP Server. |
94 | +# This file contains the translation of the following modules: |
95 | +# * purchase_tax_include |
96 | +# |
97 | +msgid "" |
98 | +msgstr "" |
99 | +"Project-Id-Version: OpenERP Server 6.0dev\n" |
100 | +"Report-Msgid-Bugs-To: support@openerp.com\n" |
101 | +"POT-Creation-Date: 2010-07-09 11:24:53+0000\n" |
102 | +"PO-Revision-Date: 2010-07-09 13:32+0100\n" |
103 | +"Last-Translator: Borja López Soilán (Pexego) <borjals@pexego.es>\n" |
104 | +"Language-Team: \n" |
105 | +"MIME-Version: 1.0\n" |
106 | +"Content-Type: text/plain; charset=UTF-8\n" |
107 | +"Content-Transfer-Encoding: 8bit\n" |
108 | +"Plural-Forms: \n" |
109 | + |
110 | +#. module: purchase_tax_include |
111 | +#: constraint:ir.ui.view:0 |
112 | +msgid "Invalid XML for View Architecture!" |
113 | +msgstr "¡XML inválido para la definición de la vista!" |
114 | + |
115 | +#. module: purchase_tax_include |
116 | +#: constraint:ir.model:0 |
117 | +msgid "The Object name must start with x_ and not contain any special character !" |
118 | +msgstr "¡El nombre del objeto debe empezar con x_ y no contener ningún carácter especial!" |
119 | + |
120 | +#. module: purchase_tax_include |
121 | +#: code:addons/purchase_tax_include/purchase_tax_incl.py:0 |
122 | +#, python-format |
123 | +msgid "You can't mix tax included and tax excluded purchases in one invoice!" |
124 | +msgstr "¡No puede mezclar compras con impuestos incluidos y excluidos en una factura!" |
125 | + |
126 | +#. module: purchase_tax_include |
127 | +#: field:purchase.order,price_type:0 |
128 | +msgid "Price method" |
129 | +msgstr "Método de precio" |
130 | + |
131 | +#. module: purchase_tax_include |
132 | +#: model:ir.module.module,shortdesc:purchase_tax_include.module_meta_information |
133 | +msgid "Purchases with taxes included" |
134 | +msgstr "Compras con impuestos incluidos" |
135 | + |
136 | +#. module: purchase_tax_include |
137 | +#: selection:purchase.order,price_type:0 |
138 | +msgid "Tax included" |
139 | +msgstr "Impuestos incluidos" |
140 | + |
141 | +#. module: purchase_tax_include |
142 | +#: model:ir.model,name:purchase_tax_include.model_purchase_order |
143 | +msgid "Purchase order" |
144 | +msgstr "Pedido de compra" |
145 | + |
146 | +#. module: purchase_tax_include |
147 | +#: code:addons/purchase_tax_include/purchase_tax_incl.py:0 |
148 | +#, python-format |
149 | +msgid "Error!" |
150 | +msgstr "¡Error!" |
151 | + |
152 | +#. module: purchase_tax_include |
153 | +#: selection:purchase.order,price_type:0 |
154 | +msgid "Tax excluded" |
155 | +msgstr "Impuestos excluidos" |
156 | + |
157 | +#. module: purchase_tax_include |
158 | +#: model:ir.model,name:purchase_tax_include.model_purchase_order_line |
159 | +msgid "Purchase Order lines" |
160 | +msgstr "Líneas del pedido de compra" |
161 | + |
162 | +#. module: purchase_tax_include |
163 | +#: model:ir.module.module,description:purchase_tax_include.module_meta_information |
164 | +msgid "This module allows you to use purchase order with prices including or excluding taxes." |
165 | +msgstr "Este módulo le permite usar órdenes de compra con precios con impuestos incluídos o excluidos." |
166 | + |
167 | +#. module: purchase_tax_include |
168 | +#: model:ir.model,name:purchase_tax_include.model_stock_picking |
169 | +msgid "Picking List" |
170 | +msgstr "Albarán" |
171 | + |
172 | +#. module: purchase_tax_include |
173 | +#: field:purchase.order.line,price_subtotal:0 |
174 | +msgid "Subtotal w/o tax" |
175 | +msgstr "Subtotal sin imp." |
176 | + |
177 | +#. module: purchase_tax_include |
178 | +#: field:purchase.order.line,price_subtotal_incl:0 |
179 | +msgid "Subtotal" |
180 | +msgstr "Subtotal" |
181 | + |
182 | |
183 | === added file 'purchase_tax_include/i18n/fr_BE.po' |
184 | --- purchase_tax_include/i18n/fr_BE.po 1970-01-01 00:00:00 +0000 |
185 | +++ purchase_tax_include/i18n/fr_BE.po 2010-07-09 15:01:37 +0000 |
186 | @@ -0,0 +1,52 @@ |
187 | +# Translation of OpenERP Server. |
188 | +# This file contains the translation of the following modules: |
189 | +# * purchase_tax_include |
190 | +# |
191 | +msgid "" |
192 | +msgstr "" |
193 | +"Project-Id-Version: OpenERP Server 5.0.6\n" |
194 | +"Report-Msgid-Bugs-To: support@openerp.com\n" |
195 | +"POT-Creation-Date: 2009-11-25 14:07:16+0000\n" |
196 | +"PO-Revision-Date: 2009-11-25 14:07:16+0000\n" |
197 | +"Last-Translator: <>\n" |
198 | +"Language-Team: \n" |
199 | +"MIME-Version: 1.0\n" |
200 | +"Content-Type: text/plain; charset=UTF-8\n" |
201 | +"Content-Transfer-Encoding: \n" |
202 | +"Plural-Forms: \n" |
203 | + |
204 | +#. module: purchase_tax_include |
205 | +#: constraint:ir.ui.view:0 |
206 | +msgid "Invalid XML for View Architecture!" |
207 | +msgstr "" |
208 | + |
209 | +#. module: purchase_tax_include |
210 | +#: field:purchase.order,price_type:0 |
211 | +msgid "Price method" |
212 | +msgstr "" |
213 | + |
214 | +#. module: purchase_tax_include |
215 | +#: model:ir.module.module,shortdesc:purchase_tax_include.module_meta_information |
216 | +msgid "Purchases with taxes included" |
217 | +msgstr "" |
218 | + |
219 | +#. module: purchase_tax_include |
220 | +#: selection:purchase.order,price_type:0 |
221 | +msgid "Tax included" |
222 | +msgstr "" |
223 | + |
224 | +#. module: purchase_tax_include |
225 | +#: selection:purchase.order,price_type:0 |
226 | +msgid "Tax excluded" |
227 | +msgstr "" |
228 | + |
229 | +#. module: purchase_tax_include |
230 | +#: model:ir.module.module,description:purchase_tax_include.module_meta_information |
231 | +msgid "This module allows you to use purchase order with prices including or excluding taxes." |
232 | +msgstr "" |
233 | + |
234 | +#. module: purchase_tax_include |
235 | +#: field:purchase.order.line,price_subtotal_incl:0 |
236 | +msgid "Subtotal" |
237 | +msgstr "" |
238 | + |
239 | |
240 | === added file 'purchase_tax_include/i18n/purchase_tax_include.pot' |
241 | --- purchase_tax_include/i18n/purchase_tax_include.pot 1970-01-01 00:00:00 +0000 |
242 | +++ purchase_tax_include/i18n/purchase_tax_include.pot 2010-07-09 15:01:37 +0000 |
243 | @@ -0,0 +1,89 @@ |
244 | +# Translation of OpenERP Server. |
245 | +# This file contains the translation of the following modules: |
246 | +# * purchase_tax_include |
247 | +# |
248 | +msgid "" |
249 | +msgstr "" |
250 | +"Project-Id-Version: OpenERP Server 6.0dev\n" |
251 | +"Report-Msgid-Bugs-To: support@openerp.com\n" |
252 | +"POT-Creation-Date: 2010-07-09 11:22:17+0000\n" |
253 | +"PO-Revision-Date: 2010-07-09 11:22:17+0000\n" |
254 | +"Last-Translator: <>\n" |
255 | +"Language-Team: \n" |
256 | +"MIME-Version: 1.0\n" |
257 | +"Content-Type: text/plain; charset=UTF-8\n" |
258 | +"Content-Transfer-Encoding: \n" |
259 | +"Plural-Forms: \n" |
260 | + |
261 | +#. module: purchase_tax_include |
262 | +#: constraint:ir.ui.view:0 |
263 | +msgid "Invalid XML for View Architecture!" |
264 | +msgstr "" |
265 | + |
266 | +#. module: purchase_tax_include |
267 | +#: constraint:ir.model:0 |
268 | +msgid "The Object name must start with x_ and not contain any special character !" |
269 | +msgstr "" |
270 | + |
271 | +#. module: purchase_tax_include |
272 | +#: code:addons/purchase_tax_include/purchase_tax_incl.py:0 |
273 | +#, python-format |
274 | +msgid "You can't mix tax included and tax excluded purchases in one invoice!" |
275 | +msgstr "" |
276 | + |
277 | +#. module: purchase_tax_include |
278 | +#: field:purchase.order,price_type:0 |
279 | +msgid "Price method" |
280 | +msgstr "" |
281 | + |
282 | +#. module: purchase_tax_include |
283 | +#: model:ir.module.module,shortdesc:purchase_tax_include.module_meta_information |
284 | +msgid "Purchases with taxes included" |
285 | +msgstr "" |
286 | + |
287 | +#. module: purchase_tax_include |
288 | +#: selection:purchase.order,price_type:0 |
289 | +msgid "Tax included" |
290 | +msgstr "" |
291 | + |
292 | +#. module: purchase_tax_include |
293 | +#: model:ir.model,name:purchase_tax_include.model_purchase_order |
294 | +msgid "Purchase order" |
295 | +msgstr "" |
296 | + |
297 | +#. module: purchase_tax_include |
298 | +#: code:addons/purchase_tax_include/purchase_tax_incl.py:0 |
299 | +#, python-format |
300 | +msgid "Error!" |
301 | +msgstr "" |
302 | + |
303 | +#. module: purchase_tax_include |
304 | +#: selection:purchase.order,price_type:0 |
305 | +msgid "Tax excluded" |
306 | +msgstr "" |
307 | + |
308 | +#. module: purchase_tax_include |
309 | +#: model:ir.model,name:purchase_tax_include.model_purchase_order_line |
310 | +msgid "Purchase Order lines" |
311 | +msgstr "" |
312 | + |
313 | +#. module: purchase_tax_include |
314 | +#: model:ir.module.module,description:purchase_tax_include.module_meta_information |
315 | +msgid "This module allows you to use purchase order with prices including or excluding taxes." |
316 | +msgstr "" |
317 | + |
318 | +#. module: purchase_tax_include |
319 | +#: model:ir.model,name:purchase_tax_include.model_stock_picking |
320 | +msgid "Picking List" |
321 | +msgstr "" |
322 | + |
323 | +#. module: purchase_tax_include |
324 | +#: field:purchase.order.line,price_subtotal:0 |
325 | +msgid "Subtotal w/o tax" |
326 | +msgstr "" |
327 | + |
328 | +#. module: purchase_tax_include |
329 | +#: field:purchase.order.line,price_subtotal_incl:0 |
330 | +msgid "Subtotal" |
331 | +msgstr "" |
332 | + |
333 | |
334 | === modified file 'purchase_tax_include/purchase_tax_incl.py' |
335 | --- purchase_tax_include/purchase_tax_incl.py 2008-11-03 19:56:05 +0000 |
336 | +++ purchase_tax_include/purchase_tax_incl.py 2010-07-09 15:01:37 +0000 |
337 | @@ -1,99 +1,262 @@ |
338 | # -*- encoding: utf-8 -*- |
339 | ############################################################################## |
340 | -# |
341 | -# OpenERP, Open Source Management Solution |
342 | -# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved |
343 | -# $Id$ |
344 | +# |
345 | +# OpenERP, Open Source Management Solution |
346 | +# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). |
347 | # |
348 | # This program is free software: you can redistribute it and/or modify |
349 | -# it under the terms of the GNU General Public License as published by |
350 | -# the Free Software Foundation, either version 3 of the License, or |
351 | -# (at your option) any later version. |
352 | +# it under the terms of the GNU Affero General Public License as |
353 | +# published by the Free Software Foundation, either version 3 of the |
354 | +# License, or (at your option) any later version. |
355 | # |
356 | # This program is distributed in the hope that it will be useful, |
357 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
358 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
359 | -# GNU General Public License for more details. |
360 | +# GNU Affero General Public License for more details. |
361 | # |
362 | -# You should have received a copy of the GNU General Public License |
363 | -# along with this program. If not, see <http://www.gnu.org/licenses/>. |
364 | +# You should have received a copy of the GNU Affero General Public License |
365 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
366 | # |
367 | ############################################################################## |
368 | |
369 | -import time |
370 | -import netsvc |
371 | +__authors__ = [ |
372 | + "OpenERP S.A.", |
373 | + "Borja López Soilán (Pexego) <borjals@pexego.es>" |
374 | +] |
375 | + |
376 | from osv import fields, osv |
377 | -import ir |
378 | +from tools import config |
379 | |
380 | class purchase_order(osv.osv): |
381 | + """ |
382 | + Extends the purchase order to allow using "tax included" prices. |
383 | + """ |
384 | _inherit = "purchase.order" |
385 | - def _amount_tax(self, cr, uid, ids, field_name, arg, context): |
386 | + |
387 | + def _amount_all(self, cr, uid, ids, field_name, arg, context): |
388 | + """ |
389 | + Overwrites/extends the amounts calculation to allow tax included prices. |
390 | + """ |
391 | res = {} |
392 | cur_obj=self.pool.get('res.currency') |
393 | for order in self.browse(cr, uid, ids): |
394 | - val = 0.0 |
395 | - cur=order.pricelist_id.currency_id |
396 | - for line in order.order_line: |
397 | - if order.price_type=='tax_included': |
398 | - ttt = self.pool.get('account.tax').compute_inv(cr, uid, line.taxes_id, line.price_unit, line.product_qty, order.partner_address_id.id, line.product_id, order.partner_id) |
399 | - else: |
400 | - ttt = self.pool.get('account.tax').compute(cr, uid, line.taxes_id, line.price_unit, line.product_qty, order.partner_address_id.id, line.product_id, order.partner_id) |
401 | - for c in ttt: |
402 | - val += cur_obj.round(cr, uid, cur, c['amount']) |
403 | - res[order.id]=cur_obj.round(cr, uid, cur, val) |
404 | + if order.price_type == 'tax_included': |
405 | + # |
406 | + # Use the tax included calculation |
407 | + # |
408 | + res[order.id] = { |
409 | + 'amount_untaxed': 0.0, |
410 | + 'amount_tax': 0.0, |
411 | + 'amount_total': 0.0, |
412 | + } |
413 | + val = val1 = 0.0 |
414 | + cur=order.pricelist_id.currency_id |
415 | + for line in order.order_line: |
416 | + for c in self.pool.get('account.tax').compute_inv(cr, uid, line.taxes_id, line.price_unit, line.product_qty, order.partner_address_id.id, line.product_id, order.partner_id): |
417 | + val+= c['amount'] |
418 | + val1 += line.price_subtotal |
419 | + res[order.id]['amount_tax']=cur_obj.round(cr, uid, cur, val) |
420 | + res[order.id]['amount_untaxed']=cur_obj.round(cr, uid, cur, val1) |
421 | + res[order.id]['amount_total']=res[order.id]['amount_untaxed'] + res[order.id]['amount_tax'] |
422 | + else: |
423 | + # |
424 | + # Use the default calculation |
425 | + # |
426 | + res = super(purchase_order, self)._amount_all(cr, uid, ids, field_name, arg, context) |
427 | return res |
428 | + |
429 | + |
430 | + def _get_order(self, cr, uid, ids, context={}): |
431 | + """ |
432 | + Returns the orders that must be updated when some order lines change. |
433 | + """ |
434 | + result = {} |
435 | + for line in self.pool.get('purchase.order.line').browse(cr, uid, ids, context=context): |
436 | + result[line.order_id.id] = True |
437 | + return result.keys() |
438 | + |
439 | _columns = { |
440 | 'price_type': fields.selection([ |
441 | ('tax_included','Tax included'), |
442 | ('tax_excluded','Tax excluded') |
443 | ], 'Price method', required=True), |
444 | - 'amount_tax': fields.function(_amount_tax, method=True, string='Taxes'), |
445 | + 'amount_untaxed': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])), string='Untaxed Amount', |
446 | + store={ |
447 | + 'purchase.order': (lambda self, cr, uid, ids, c={}: ids, ['price_type'], 20), |
448 | + 'purchase.order.line': (_get_order, None, 10), |
449 | + }, multi="sums"), |
450 | + 'amount_tax': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])), string='Taxes', |
451 | + store={ |
452 | + 'purchase.order': (lambda self, cr, uid, ids, c={}: ids, ['price_type'], 20), |
453 | + 'purchase.order.line': (_get_order, None, 10), |
454 | + }, multi="sums"), |
455 | + 'amount_total': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])), string='Total', |
456 | + store={ |
457 | + 'purchase.order': (lambda self, cr, uid, ids, c={}: ids, ['price_type'], 20), |
458 | + 'purchase.order.line': (_get_order, None, 10), |
459 | + }, multi="sums"), |
460 | } |
461 | + |
462 | _defaults = { |
463 | 'price_type': lambda *a: 'tax_excluded', |
464 | } |
465 | + |
466 | def _inv_get(self, cr, uid, order, context={}): |
467 | + """ |
468 | + Returns the columns as a dictionary. |
469 | + """ |
470 | return { |
471 | 'price_type': order.price_type |
472 | } |
473 | + |
474 | + |
475 | + def action_invoice_create(self, cr, uid, ids, *args): |
476 | + """ |
477 | + Extend the invoice creation action to set the price type if needed. |
478 | + """ |
479 | + # |
480 | + # Count how many orders have tax included prices. |
481 | + # |
482 | + tax_included_count = 0 |
483 | + orders = self.browse(cr, uid, ids) |
484 | + for order in orders: |
485 | + if order.price_type == 'tax_included': |
486 | + tax_included_count += 1 |
487 | + |
488 | + if tax_included_count: |
489 | + if len(orders) == tax_included_count: |
490 | + # |
491 | + # Every order has tax include prices, we must create the invoice |
492 | + # and (afterwards) set the price type and recalculate. |
493 | + # |
494 | + invoice_id = super(purchase_order, self).action_invoice_create(cr, uid, ids, args) |
495 | + self.pool.get('account.invoice').write(cr, uid, [invoice_id], { 'price_type': 'tax_included' }) |
496 | + self.pool.get('account.invoice').button_compute(cr, uid, [invoice_id], {'type': 'in_invoice'}, set_total=True) |
497 | + else: |
498 | + # We have no current way of creating an invoice mixing |
499 | + # tax included and tax excluded prices, so we just fail: |
500 | + raise osv.except_osv(_('Error!'), _("You can't mix tax included and tax excluded purchases in one invoice!")) |
501 | + else: |
502 | + # All the invoices are 'tax excluded', that's the default value |
503 | + # so we just let the default method create the invoice. |
504 | + invoice_id = super(purchase_order, self).action_invoice_create(cr, uid, ids, args) |
505 | + |
506 | + return invoice_id |
507 | + |
508 | + |
509 | purchase_order() |
510 | |
511 | class purchase_order_line(osv.osv): |
512 | + """ |
513 | + Extends the purchase order lines to alter the calculation when |
514 | + tax includes prices are used. |
515 | + """ |
516 | _inherit = 'purchase.order.line' |
517 | + |
518 | def _amount_line(self, cr, uid, ids, name, arg, context): |
519 | - res = {} |
520 | - cur_obj=self.pool.get('res.currency') |
521 | - tax_obj = self.pool.get('account.tax') |
522 | - res = super(purchase_order_line, self)._amount_line(cr, uid, ids, name, arg, context) |
523 | - res2 = res.copy() |
524 | - for line in self.browse(cr, uid, ids): |
525 | - if line.order_id.price_type == 'tax_included': |
526 | - if line.product_id: |
527 | - for tax in tax_obj.compute_inv(cr, uid, line.product_id.supplier_taxes_id, res[line.id]/line.product_qty, line.product_qty): |
528 | - res[line.id] = res[line.id] - tax['amount'] |
529 | - else: |
530 | - for tax in tax_obj.compute_inv(cr, uid, line.taxes_id, res[line.id]/line.product_qty, line.product_qty): |
531 | - res[line.id] = res[line.id] - tax['amount'] |
532 | - if name == 'price_subtotal_incl' and line.order_id.price_type == 'tax_included': |
533 | - if line.product_id: |
534 | - prod_taxe_ids = [ t.id for t in line.product_id.supplier_taxes_id ] |
535 | - prod_taxe_ids.sort() |
536 | - line_taxe_ids = [ t.id for t in line.taxes_id ] |
537 | - line_taxe_ids.sort() |
538 | - if line.product_id and prod_taxe_ids == line_taxe_ids: |
539 | - res[line.id] = res2[line.id] |
540 | - elif not line.product_id: |
541 | - res[line.id] = res2[line.id] |
542 | - else: |
543 | - for tax in tax_obj.compute(cr, uid, line.taxes_id, res[line.id]/line.product_qty, line.product_qty): |
544 | - res[line.id] = res[line.id] + tax['amount'] |
545 | - cur = line.order_id.pricelist_id.currency_id |
546 | - res[line.id] = cur_obj.round(cr, uid, cur, res[line.id]) |
547 | - return res |
548 | + """ |
549 | + Calculate the subtotal for the line without taxes. |
550 | + """ |
551 | + # Use the original method to calculate the amounts: |
552 | + res = super(purchase_order_line, self)._amount_line(cr, uid, ids, 'price_subtotal', arg, context) |
553 | + # Check if we are using 'tax_included' prices: |
554 | + if ids and self.browse(cr, uid, ids[0]).order_id.price_type == 'tax_included': |
555 | + # |
556 | + # Tax included => Remove the taxes from the line amounts. |
557 | + # |
558 | + cur_facade=self.pool.get('res.currency') |
559 | + tax_facade = self.pool.get('account.tax') |
560 | + for line in self.browse(cr, uid, ids): |
561 | + for tax in tax_facade.compute_inv(cr, uid, line.taxes_id, res[line.id]/line.product_qty, line.product_qty): |
562 | + res[line.id] = res[line.id] - tax['amount'] |
563 | + cur = line.order_id.pricelist_id.currency_id |
564 | + res[line.id] = cur_facade.round(cr, uid, cur, res[line.id]) |
565 | + return res |
566 | + |
567 | + def _amount_line_incl(self, cr, uid, ids, name, arg, context): |
568 | + """ |
569 | + Calculate the subtotal for the line with taxes. |
570 | + """ |
571 | + # Use the original method to calculate the amounts: |
572 | + res = super(purchase_order_line, self)._amount_line(cr, uid, ids, 'price_subtotal', arg, context) |
573 | + # Check if we *aren't* using 'tax_included' prices on the subtotal: |
574 | + if ids and self.browse(cr, uid, ids[0]).order_id.price_type != 'tax_included': |
575 | + # |
576 | + # Tax excluded on the subtotal => Add taxes here from the line amounts. |
577 | + # |
578 | + cur_facade=self.pool.get('res.currency') |
579 | + tax_facade = self.pool.get('account.tax') |
580 | + for line in self.browse(cr, uid, ids): |
581 | + for tax in tax_facade.compute(cr, uid, line.taxes_id, res[line.id]/line.product_qty, line.product_qty): |
582 | + res[line.id] = res[line.id] + tax['amount'] |
583 | + cur = line.order_id.pricelist_id.currency_id |
584 | + res[line.id] = cur_facade.round(cr, uid, cur, res[line.id]) |
585 | + return res |
586 | + |
587 | + |
588 | _columns = { |
589 | - 'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal w/o tax'), |
590 | - 'price_subtotal_incl': fields.function(_amount_line, method=True, string='Subtotal'), |
591 | + 'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal w/o tax', digits=(16, int(config['price_accuracy']))), |
592 | + 'price_subtotal_incl': fields.function(_amount_line_incl, method=True, string='Subtotal', digits=(16, int(config['price_accuracy']))), |
593 | } |
594 | purchase_order_line() |
595 | -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
596 | + |
597 | +class stock_picking(osv.osv): |
598 | + """ |
599 | + Extends the stock pickings to manage the creation of invoices with |
600 | + tax included prices when the original order had tax included prices. |
601 | + """ |
602 | + _inherit = 'stock.picking' |
603 | + _description = "Picking list" |
604 | + |
605 | + def action_invoice_create(self, cr, uid, ids, journal_id=False, |
606 | + group=False, type='out_invoice', context=None): |
607 | + """ |
608 | + Extend the invoice creation action to set the price type if needed. |
609 | + """ |
610 | + # |
611 | + # Count how many pickings have tax included prices. |
612 | + # |
613 | + tax_included_count = 0 |
614 | + lines_count = 0 |
615 | + pickings = self.browse(cr, uid, ids, context=context) |
616 | + for picking in pickings: |
617 | + # |
618 | + # We must find the orders associated with this picking and check |
619 | + # if they have tax included prices. |
620 | + # As picking lines may come from different orders (even if it is |
621 | + # not the usual), we must check it line by line. |
622 | + # |
623 | + for move in picking.move_lines: |
624 | + if move.purchase_line_id and move.purchase_line_id.order_id: |
625 | + lines_count += 1 |
626 | + if move.purchase_line_id.order_id.price_type == 'tax_included': |
627 | + tax_included_count += 1 |
628 | + |
629 | + if tax_included_count: |
630 | + if lines_count == tax_included_count: |
631 | + # |
632 | + # Every order has tax include prices, we must create the invoice |
633 | + # and (afterwards) set the price type and recalculate. |
634 | + # |
635 | + invoices_map = super(stock_picking, self).action_invoice_create(cr, |
636 | + uid, ids, journal_id=journal_id, |
637 | + group=group, type=type, |
638 | + context=context) |
639 | + invoice_ids = list(set(invoices_map.values())) |
640 | + self.pool.get('account.invoice').write(cr, uid, invoice_ids, { 'price_type': 'tax_included' }) |
641 | + self.pool.get('account.invoice').button_compute(cr, uid, invoice_ids, {'type': 'in_invoice'}, set_total=True) |
642 | + else: |
643 | + # We have no current way of creating an invoice mixing |
644 | + # tax included and tax excluded prices, so we just fail: |
645 | + raise osv.except_osv(_('Error!'), _("You can't mix tax included and tax excluded purchases in one invoice!")) |
646 | + else: |
647 | + # All the invoices are 'tax excluded', that's the default value |
648 | + # so we just let the default method create the invoice. |
649 | + invoices_map = super(stock_picking, self).action_invoice_create(cr, |
650 | + uid, ids, journal_id=journal_id, |
651 | + group=group, type=type, |
652 | + context=context) |
653 | + return invoices_map |
654 | + |
655 | +stock_picking() |
656 | |
657 | |
658 | === modified file 'purchase_tax_include/purchase_tax_incl.xml' |
659 | --- purchase_tax_include/purchase_tax_incl.xml 2008-09-12 22:59:35 +0000 |
660 | +++ purchase_tax_include/purchase_tax_incl.xml 2010-07-09 15:01:37 +0000 |
661 | @@ -1,31 +1,43 @@ |
662 | -<?xml version="1.0"?> |
663 | +<?xml version="1.0" encoding="utf-8"?> |
664 | <openerp> |
665 | -<data> |
666 | - |
667 | - <record model="ir.ui.view" id="account_tax_view_price"> |
668 | - <field name="name">purchase.order.exlcuded.view.form</field> |
669 | - <field name="type">form</field> |
670 | - <field name="model">purchase.order</field> |
671 | - <field name="inherit_id" ref="purchase.purchase_order_form" /> |
672 | - <field name="arch" type="xml"> |
673 | - <field name="origin" position="after"> |
674 | - <field name="price_type"/> |
675 | - </field> |
676 | - </field> |
677 | - </record> |
678 | - |
679 | - <record model="ir.ui.view" id="account_tax_view_price_subtotal_incl"> |
680 | - <field name="name">purchase.order.line.tree</field> |
681 | - <field name="type">tree</field> |
682 | - <field name="model">purchase.order.line</field> |
683 | - <field name="inherit_id" ref="purchase.purchase_order_line_tree" /> |
684 | - <field name="arch" type="xml"> |
685 | - <field name="price_subtotal" position="after"> |
686 | - <field name="price_subtotal_incl"/> |
687 | - </field> |
688 | - </field> |
689 | - </record> |
690 | - |
691 | -</data> |
692 | + <data> |
693 | + |
694 | + <record model="ir.ui.view" id="account_tax_view_price"> |
695 | + <field name="name">purchase.order.form.add_price_type</field> |
696 | + <field name="type">form</field> |
697 | + <field name="model">purchase.order</field> |
698 | + <field name="inherit_id" ref="purchase.purchase_order_form" /> |
699 | + <field name="arch" type="xml"> |
700 | + <field name="shipped" position="after"> |
701 | + <field name="price_type"/> |
702 | + </field> |
703 | + </field> |
704 | + </record> |
705 | + |
706 | + <record model="ir.ui.view" id="account_tax_view_price_subtotal_incl"> |
707 | + <field name="name">purchase.order.line.tree.add_price_subtotal_incl</field> |
708 | + <field name="type">tree</field> |
709 | + <field name="model">purchase.order.line</field> |
710 | + <field name="inherit_id" ref="purchase.purchase_order_line_tree" /> |
711 | + <field name="arch" type="xml"> |
712 | + <field name="price_subtotal" position="after"> |
713 | + <field name="price_subtotal_incl"/> |
714 | + </field> |
715 | + </field> |
716 | + </record> |
717 | + |
718 | + <record model="ir.ui.view" id="account_tax_view_price_subtotal_incl"> |
719 | + <field name="name">purchase.order.form.add_price_subtotal_incl_to_lines</field> |
720 | + <field name="type">form</field> |
721 | + <field name="model">purchase.order</field> |
722 | + <field name="inherit_id" ref="purchase.purchase_order_form" /> |
723 | + <field name="arch" type="xml"> |
724 | + <xpath expr="//field[@name='order_line']/tree/field[@name='price_subtotal']" position="after"> |
725 | + <field name="price_subtotal_incl"/> |
726 | + </xpath> |
727 | + </field> |
728 | + </record> |
729 | + |
730 | + </data> |
731 | </openerp> |
732 |
Ok, this has been waiting for a month and only Numérigraphe (thanks!) reviewed the merge proposal (on trunk). As in its current state purchase_ tax_include is not usable at all, I think I'll just merge it tomorrow.