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