Merge lp:~openerp-community-reviewer/sale-wkfl/move_sale_exception_module_from_e-commerce-addons-jge into lp:~sale-core-editors/sale-wkfl/7.0
- move_sale_exception_module_from_e-commerce-addons-jge
- Merge into 7.0
Status: | Merged |
---|---|
Merged at revision: | 21 |
Proposed branch: | lp:~openerp-community-reviewer/sale-wkfl/move_sale_exception_module_from_e-commerce-addons-jge |
Merge into: | lp:~sale-core-editors/sale-wkfl/7.0 |
Diff against target: |
994 lines (+925/-0) 13 files modified
sale_exceptions/__init__.py (+26/-0) sale_exceptions/__openerp__.py (+46/-0) sale_exceptions/i18n/fr.po (+177/-0) sale_exceptions/i18n/sale_exceptions.pot (+177/-0) sale_exceptions/sale.py (+236/-0) sale_exceptions/sale_exceptions_data.xml (+19/-0) sale_exceptions/sale_view.xml (+102/-0) sale_exceptions/sale_workflow.xml (+9/-0) sale_exceptions/security/ir.model.access.csv (+3/-0) sale_exceptions/settings/sale.exception.csv (+5/-0) sale_exceptions/wizard/__init__.py (+24/-0) sale_exceptions/wizard/sale_exception_confirm.py (+62/-0) sale_exceptions/wizard/sale_exception_confirm_view.xml (+39/-0) |
To merge this branch: | bzr merge lp:~openerp-community-reviewer/sale-wkfl/move_sale_exception_module_from_e-commerce-addons-jge |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nicolas Bessi - Camptocamp (community) | no test, code review | Approve | |
Guewen Baconnier @ Camptocamp | Approve | ||
Review via email: mp+193567@code.launchpad.net |
Commit message
[MOVE] Move here the sale_exceptions module from the lp:e-commerce-addons
Description of the change
Hi,
I suggest to move the sale_exceptions module from e-commerce-addons to here because it really concerns the sales workflow in a more generic way than just the e-commerce context.
I put the branch under the reviewer team so feel free to fix stuff if you'd like.
WARNING: Merge this proposal when this one is done : https:/
Regards,
Joël
Pedro Manuel Baeza (pedro.baeza) wrote : | # |
Sébastien BEAU - http://www.akretion.com (sebastien.beau) wrote : | # |
Hi, I am working on the split of sale_exception in two module "sale_exception" and "exception_rule". The aim is to have the exception on different object like purchase_order, stock_picking, invoice ... (already implemented on purchase_order and soon on picking).
If we put the module sale_exception here where should I put the module "exception_rule" and "purchase_
I see two solution possible
- Putting exception_rule in "server-env-tools" and than all implementation in sale-wkfl, purchase-wkfl...
- Creating a project "workflow-
What do you prefers?
Pedro Manuel Baeza (pedro.baeza) wrote : | # |
Hi, Sébastien, is there too much logic on exception_rule so that it is mandatory to split it in one module?, or it can be easily repeated in consequent other modules "purchase_
Regards.
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c) wrote : | # |
Hi,
+1 for Pedro. Having such a general module doesn't seems mandatory. The exception can IMO define in every module.
Moreover, the sale_exception module was already there like this. So I just move it. We can't assume doing both in one. Your suggestion may break back-compatibility so... My suggestion: move on to have it in the right project/branches, then when you'll be ready, make your MP so we'll have the opportunity to discuss that with something concrete !
What do you think ?
++
Joël
Sébastien BEAU - http://www.akretion.com (sebastien.beau) wrote : | # |
After my split I have around 140 ligne of python in exception_rule and around 40 in sale_exception so I really think it's worth to split it because we will avoid to duplicate the 140 ligne in every module for nothing, it's not a lot but it's always better to no duplicate the code (on improvement improve all module). Moreover we use the same pop-up wizard in sale_exception and purchase_exception so it the same interface for the end user.
Here is my work : http://
(not ready to be merge yet, I have to be sure that I do not miss any improvement done by guewen here https:/
Sébastien BEAU - http://www.akretion.com (sebastien.beau) wrote : | # |
Sorry I made a mistake around 180 line in the generic module
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c) wrote : | # |
Hi Sébastien,
Your work looks great. Can you please make another MP once this one is done with your work ? This we move forward on this one.
@Pedro : Would you add your review here please ?
Regards,
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
I approve for the move
- 46. By Nicolas Bessi - Camptocamp
-
[PEP8] and community conventions
- 47. By Nicolas Bessi - Camptocamp
-
[PEP8]
- 48. By Nicolas Bessi - Camptocamp
-
[PEP8] + removing class instantiation
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote : | # |
LGTM
I also committed PEP8 and community convention fixes.
Moving the module is OK.
- 49. By Nicolas Bessi - Camptocamp
-
[FIX] licence
- 50. By Nicolas Bessi - Camptocamp
-
[MRG] migration of sale_exceptions from original branch
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote : | # |
Hello,
I have merge back migration/fixes recently commited in lp:e-commerce-addons
Preview Diff
1 | === added directory 'sale_exceptions' | |||
2 | === added file 'sale_exceptions/__init__.py' | |||
3 | --- sale_exceptions/__init__.py 1970-01-01 00:00:00 +0000 | |||
4 | +++ sale_exceptions/__init__.py 2013-11-15 12:55:43 +0000 | |||
5 | @@ -0,0 +1,26 @@ | |||
6 | 1 | # -*- coding: utf-8 -*- | ||
7 | 2 | ############################################################################## | ||
8 | 3 | # | ||
9 | 4 | # OpenERP, Open Source Management Solution | ||
10 | 5 | # Copyright (C) 2011 Akretion LTDA. | ||
11 | 6 | # authors: Raphaël Valyi, Renato Lima | ||
12 | 7 | # Copyright (C) 2010-2012 Akretion Sébastien BEAU <sebastien.beau@akretion.com> | ||
13 | 8 | # Copyright (C) 2012 Camptocamp SA (Guewen Baconnier) | ||
14 | 9 | # | ||
15 | 10 | # This program is free software: you can redistribute it and/or modify | ||
16 | 11 | # it under the terms of the GNU Affero General Public License as | ||
17 | 12 | # published by the Free Software Foundation, either version 3 of the | ||
18 | 13 | # License, or (at your option) any later version. | ||
19 | 14 | # | ||
20 | 15 | # This program is distributed in the hope that it will be useful, | ||
21 | 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
22 | 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
23 | 18 | # GNU Affero General Public License for more details. | ||
24 | 19 | # | ||
25 | 20 | # You should have received a copy of the GNU Affero General Public License | ||
26 | 21 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
27 | 22 | # | ||
28 | 23 | ############################################################################## | ||
29 | 24 | |||
30 | 25 | from . import sale | ||
31 | 26 | from . import wizard | ||
32 | 0 | 27 | ||
33 | === added file 'sale_exceptions/__openerp__.py' | |||
34 | --- sale_exceptions/__openerp__.py 1970-01-01 00:00:00 +0000 | |||
35 | +++ sale_exceptions/__openerp__.py 2013-11-15 12:55:43 +0000 | |||
36 | @@ -0,0 +1,46 @@ | |||
37 | 1 | # -*- coding: utf-8 -*- | ||
38 | 2 | ############################################################################## | ||
39 | 3 | # | ||
40 | 4 | # OpenERP, Open Source Management Solution | ||
41 | 5 | # Copyright (C) 2011 Akretion LTDA. | ||
42 | 6 | # authors: Raphaël Valyi, Renato Lima | ||
43 | 7 | # Copyright (C) 2010-2012 Akretion Sébastien BEAU <sebastien.beau@akretion.com> | ||
44 | 8 | # Copyright (C) 2012 Camptocamp SA (Guewen Baconnier) | ||
45 | 9 | # | ||
46 | 10 | # This program is free software: you can redistribute it and/or modify | ||
47 | 11 | # it under the terms of the GNU Affero General Public License as | ||
48 | 12 | # published by the Free Software Foundation, either version 3 of the | ||
49 | 13 | # License, or (at your option) any later version. | ||
50 | 14 | # | ||
51 | 15 | # This program is distributed in the hope that it will be useful, | ||
52 | 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
53 | 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
54 | 18 | # GNU Affero General Public License for more details. | ||
55 | 19 | # | ||
56 | 20 | # You should have received a copy of the GNU Affero General Public License | ||
57 | 21 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
58 | 22 | # | ||
59 | 23 | ############################################################################## | ||
60 | 24 | {'name': 'Sale Exceptions', | ||
61 | 25 | 'version': '0.1', | ||
62 | 26 | 'category': 'Generic Modules/Sale', | ||
63 | 27 | 'description': """ | ||
64 | 28 | This module allows you attach several customizable exceptions to your sale order | ||
65 | 29 | in a way that you can filter orders by exceptions type and fix them. | ||
66 | 30 | |||
67 | 31 | This is especially useful in an order importation scenario such as with | ||
68 | 32 | the base_sale_multi_channels module, because it's likely a few orders have errors | ||
69 | 33 | when you import them (like product not found in OpenERP, wrong line format etc...) | ||
70 | 34 | """, | ||
71 | 35 | 'author': 'Akretion', | ||
72 | 36 | 'website': 'http://www.akretion.com', | ||
73 | 37 | 'depends': ['sale'], | ||
74 | 38 | 'init_xml': ['settings/sale.exception.csv'], | ||
75 | 39 | 'update_xml': ['sale_workflow.xml', | ||
76 | 40 | 'sale_view.xml', | ||
77 | 41 | 'sale_exceptions_data.xml', | ||
78 | 42 | 'wizard/sale_exception_confirm_view.xml', | ||
79 | 43 | 'security/ir.model.access.csv'], | ||
80 | 44 | 'demo_xml': [], | ||
81 | 45 | 'installable': True, | ||
82 | 46 | } | ||
83 | 0 | 47 | ||
84 | === added directory 'sale_exceptions/i18n' | |||
85 | === added file 'sale_exceptions/i18n/fr.po' | |||
86 | --- sale_exceptions/i18n/fr.po 1970-01-01 00:00:00 +0000 | |||
87 | +++ sale_exceptions/i18n/fr.po 2013-11-15 12:55:43 +0000 | |||
88 | @@ -0,0 +1,177 @@ | |||
89 | 1 | # Translation of OpenERP Server. | ||
90 | 2 | # This file contains the translation of the following modules: | ||
91 | 3 | # * sale_exceptions | ||
92 | 4 | # | ||
93 | 5 | msgid "" | ||
94 | 6 | msgstr "" | ||
95 | 7 | "Project-Id-Version: OpenERP Server 7.0\n" | ||
96 | 8 | "Report-Msgid-Bugs-To: \n" | ||
97 | 9 | "POT-Creation-Date: 2013-05-02 06:57+0000\n" | ||
98 | 10 | "PO-Revision-Date: 2013-05-02 06:57+0000\n" | ||
99 | 11 | "Last-Translator: <>\n" | ||
100 | 12 | "Language-Team: \n" | ||
101 | 13 | "MIME-Version: 1.0\n" | ||
102 | 14 | "Content-Type: text/plain; charset=UTF-8\n" | ||
103 | 15 | "Content-Transfer-Encoding: \n" | ||
104 | 16 | "Plural-Forms: \n" | ||
105 | 17 | |||
106 | 18 | #. module: sale_exceptions | ||
107 | 19 | #: model:ir.model,name:sale_exceptions.model_sale_exception_confirm | ||
108 | 20 | msgid "sale.exception.confirm" | ||
109 | 21 | msgstr "" | ||
110 | 22 | |||
111 | 23 | #. module: sale_exceptions | ||
112 | 24 | #: selection:sale.exception,model:0 | ||
113 | 25 | msgid "Sale Order Line" | ||
114 | 26 | msgstr "Ligne de commande" | ||
115 | 27 | |||
116 | 28 | #. module: sale_exceptions | ||
117 | 29 | #: field:sale.exception,model:0 | ||
118 | 30 | msgid "Apply on" | ||
119 | 31 | msgstr "Appliquer sur" | ||
120 | 32 | |||
121 | 33 | #. module: sale_exceptions | ||
122 | 34 | #: model:sale.exception,name:sale_exceptions.excep_no_stock | ||
123 | 35 | msgid "Not Enough Virtual Stock" | ||
124 | 36 | msgstr "Pas assez de quantité de stock prévue" | ||
125 | 37 | |||
126 | 38 | #. module: sale_exceptions | ||
127 | 39 | #: field:sale.exception,description:0 | ||
128 | 40 | msgid "Description" | ||
129 | 41 | msgstr "Description" | ||
130 | 42 | |||
131 | 43 | #. module: sale_exceptions | ||
132 | 44 | #: help:sale.exception,sequence:0 | ||
133 | 45 | msgid "Gives the sequence order when applying the test" | ||
134 | 46 | msgstr "Définit l'ordre d'application des contrôles" | ||
135 | 47 | |||
136 | 48 | #. module: sale_exceptions | ||
137 | 49 | #: view:sale.exception.confirm:0 | ||
138 | 50 | msgid "Sale Exceptions On Sale Order" | ||
139 | 51 | msgstr "Restrictions sur la commande" | ||
140 | 52 | |||
141 | 53 | #. module: sale_exceptions | ||
142 | 54 | #: field:sale.exception.confirm,exception_ids:0 | ||
143 | 55 | msgid "Exceptions to resolve" | ||
144 | 56 | msgstr "Restrictions à résoudre" | ||
145 | 57 | |||
146 | 58 | #. module: sale_exceptions | ||
147 | 59 | #: view:sale.exception.confirm:0 | ||
148 | 60 | msgid "_Ok" | ||
149 | 61 | msgstr "_Ok" | ||
150 | 62 | |||
151 | 63 | #. module: sale_exceptions | ||
152 | 64 | #: view:sale.exception:0 | ||
153 | 65 | #: view:sale.exception.confirm:0 | ||
154 | 66 | msgid "Sale Exception" | ||
155 | 67 | msgstr "Restriction de vente" | ||
156 | 68 | |||
157 | 69 | #. module: sale_exceptions | ||
158 | 70 | #: view:sale.order:0 | ||
159 | 71 | msgid "TO FIX" | ||
160 | 72 | msgstr "A CORRIGER" | ||
161 | 73 | |||
162 | 74 | #. module: sale_exceptions | ||
163 | 75 | #: help:sale.exception,code:0 | ||
164 | 76 | msgid "Python code executed to check if the exception apply or not. The code must apply block = True to apply the exception." | ||
165 | 77 | msgstr "Code Python exécuté pour déterminer si la restriction s'applique. The bloc de code doit retourner block = True pour appliquer la restriction." | ||
166 | 78 | |||
167 | 79 | #. module: sale_exceptions | ||
168 | 80 | #: view:sale.order:0 | ||
169 | 81 | msgid "Exception" | ||
170 | 82 | msgstr "Restriction" | ||
171 | 83 | |||
172 | 84 | #. module: sale_exceptions | ||
173 | 85 | #: view:sale.order:0 | ||
174 | 86 | msgid "Error:" | ||
175 | 87 | msgstr "Erreur :" | ||
176 | 88 | |||
177 | 89 | #. module: sale_exceptions | ||
178 | 90 | #: selection:sale.exception,model:0 | ||
179 | 91 | msgid "Sale Order" | ||
180 | 92 | msgstr "Bon de commande" | ||
181 | 93 | |||
182 | 94 | #. module: sale_exceptions | ||
183 | 95 | #: field:sale.exception.confirm,sale_id:0 | ||
184 | 96 | msgid "Sale" | ||
185 | 97 | msgstr "Commande" | ||
186 | 98 | |||
187 | 99 | #. module: sale_exceptions | ||
188 | 100 | #: field:sale.exception,active:0 | ||
189 | 101 | msgid "Active" | ||
190 | 102 | msgstr "Actif" | ||
191 | 103 | |||
192 | 104 | #. module: sale_exceptions | ||
193 | 105 | #: field:sale.exception,name:0 | ||
194 | 106 | msgid "Exception Name" | ||
195 | 107 | msgstr "Nom de la restriction" | ||
196 | 108 | |||
197 | 109 | #. module: sale_exceptions | ||
198 | 110 | #: field:sale.order,exceptions_ids:0 | ||
199 | 111 | msgid "Exceptions" | ||
200 | 112 | msgstr "Restrictions" | ||
201 | 113 | |||
202 | 114 | #. module: sale_exceptions | ||
203 | 115 | #: model:ir.actions.act_window,name:sale_exceptions.action_sale_exception_confirm | ||
204 | 116 | #: model:ir.model,name:sale_exceptions.model_sale_exception | ||
205 | 117 | #: view:sale.exception.confirm:0 | ||
206 | 118 | msgid "Sale Exceptions" | ||
207 | 119 | msgstr "Restrictions de vente" | ||
208 | 120 | |||
209 | 121 | #. module: sale_exceptions | ||
210 | 122 | #: model:ir.actions.act_window,name:sale_exceptions.action_sale_test_tree | ||
211 | 123 | #: model:ir.ui.menu,name:sale_exceptions.menu_sale_test | ||
212 | 124 | msgid "Exception Rules" | ||
213 | 125 | msgstr "Règles de restriction" | ||
214 | 126 | |||
215 | 127 | #. module: sale_exceptions | ||
216 | 128 | #: model:ir.model,name:sale_exceptions.model_sale_order | ||
217 | 129 | msgid "Sales Order" | ||
218 | 130 | msgstr "Bon de commande" | ||
219 | 131 | |||
220 | 132 | #. module: sale_exceptions | ||
221 | 133 | #: field:sale.exception,sequence:0 | ||
222 | 134 | msgid "Sequence" | ||
223 | 135 | msgstr "Séquence" | ||
224 | 136 | |||
225 | 137 | #. module: sale_exceptions | ||
226 | 138 | #: field:sale.exception,code:0 | ||
227 | 139 | msgid "Python Code" | ||
228 | 140 | msgstr "Code Python" | ||
229 | 141 | |||
230 | 142 | #. module: sale_exceptions | ||
231 | 143 | #: view:sale.order:0 | ||
232 | 144 | msgid "Sales" | ||
233 | 145 | msgstr "Bons de commande" | ||
234 | 146 | |||
235 | 147 | #. module: sale_exceptions | ||
236 | 148 | #: model:sale.exception,name:sale_exceptions.excep_no_zip | ||
237 | 149 | msgid "No ZIP code on destination" | ||
238 | 150 | msgstr "Code postal manquant sur la destination" | ||
239 | 151 | |||
240 | 152 | #. module: sale_exceptions | ||
241 | 153 | #: view:sale.exception:0 | ||
242 | 154 | msgid "Sale Exception Setup" | ||
243 | 155 | msgstr "Configuration des restrictions de vente" | ||
244 | 156 | |||
245 | 157 | #. module: sale_exceptions | ||
246 | 158 | #: view:sale.exception:0 | ||
247 | 159 | msgid "Affected Sales Orders" | ||
248 | 160 | msgstr "Bons de commande affectés" | ||
249 | 161 | |||
250 | 162 | #. module: sale_exceptions | ||
251 | 163 | #: field:sale.exception,sale_order_ids:0 | ||
252 | 164 | msgid "Sale Orders" | ||
253 | 165 | msgstr "Bons de commande" | ||
254 | 166 | |||
255 | 167 | #. module: sale_exceptions | ||
256 | 168 | #: field:sale.exception.confirm,ignore:0 | ||
257 | 169 | #: field:sale.order,ignore_exceptions:0 | ||
258 | 170 | msgid "Ignore Exceptions" | ||
259 | 171 | msgstr "Ignorer la restriction" | ||
260 | 172 | |||
261 | 173 | #. module: sale_exceptions | ||
262 | 174 | #: field:sale.order,main_exception_id:0 | ||
263 | 175 | msgid "Main Exception" | ||
264 | 176 | msgstr "Restriction principale" | ||
265 | 177 | |||
266 | 0 | 178 | ||
267 | === added file 'sale_exceptions/i18n/sale_exceptions.pot' | |||
268 | --- sale_exceptions/i18n/sale_exceptions.pot 1970-01-01 00:00:00 +0000 | |||
269 | +++ sale_exceptions/i18n/sale_exceptions.pot 2013-11-15 12:55:43 +0000 | |||
270 | @@ -0,0 +1,177 @@ | |||
271 | 1 | # Translation of OpenERP Server. | ||
272 | 2 | # This file contains the translation of the following modules: | ||
273 | 3 | # * sale_exceptions | ||
274 | 4 | # | ||
275 | 5 | msgid "" | ||
276 | 6 | msgstr "" | ||
277 | 7 | "Project-Id-Version: OpenERP Server 7.0\n" | ||
278 | 8 | "Report-Msgid-Bugs-To: \n" | ||
279 | 9 | "POT-Creation-Date: 2013-05-02 06:57+0000\n" | ||
280 | 10 | "PO-Revision-Date: 2013-05-02 06:57+0000\n" | ||
281 | 11 | "Last-Translator: <>\n" | ||
282 | 12 | "Language-Team: \n" | ||
283 | 13 | "MIME-Version: 1.0\n" | ||
284 | 14 | "Content-Type: text/plain; charset=UTF-8\n" | ||
285 | 15 | "Content-Transfer-Encoding: \n" | ||
286 | 16 | "Plural-Forms: \n" | ||
287 | 17 | |||
288 | 18 | #. module: sale_exceptions | ||
289 | 19 | #: model:ir.model,name:sale_exceptions.model_sale_exception_confirm | ||
290 | 20 | msgid "sale.exception.confirm" | ||
291 | 21 | msgstr "" | ||
292 | 22 | |||
293 | 23 | #. module: sale_exceptions | ||
294 | 24 | #: selection:sale.exception,model:0 | ||
295 | 25 | msgid "Sale Order Line" | ||
296 | 26 | msgstr "" | ||
297 | 27 | |||
298 | 28 | #. module: sale_exceptions | ||
299 | 29 | #: field:sale.exception,model:0 | ||
300 | 30 | msgid "Apply on" | ||
301 | 31 | msgstr "" | ||
302 | 32 | |||
303 | 33 | #. module: sale_exceptions | ||
304 | 34 | #: model:sale.exception,name:sale_exceptions.excep_no_stock | ||
305 | 35 | msgid "Not Enough Virtual Stock" | ||
306 | 36 | msgstr "" | ||
307 | 37 | |||
308 | 38 | #. module: sale_exceptions | ||
309 | 39 | #: field:sale.exception,description:0 | ||
310 | 40 | msgid "Description" | ||
311 | 41 | msgstr "" | ||
312 | 42 | |||
313 | 43 | #. module: sale_exceptions | ||
314 | 44 | #: help:sale.exception,sequence:0 | ||
315 | 45 | msgid "Gives the sequence order when applying the test" | ||
316 | 46 | msgstr "" | ||
317 | 47 | |||
318 | 48 | #. module: sale_exceptions | ||
319 | 49 | #: view:sale.exception.confirm:0 | ||
320 | 50 | msgid "Sale Exceptions On Sale Order" | ||
321 | 51 | msgstr "" | ||
322 | 52 | |||
323 | 53 | #. module: sale_exceptions | ||
324 | 54 | #: field:sale.exception.confirm,exception_ids:0 | ||
325 | 55 | msgid "Exceptions to resolve" | ||
326 | 56 | msgstr "" | ||
327 | 57 | |||
328 | 58 | #. module: sale_exceptions | ||
329 | 59 | #: view:sale.exception.confirm:0 | ||
330 | 60 | msgid "_Ok" | ||
331 | 61 | msgstr "" | ||
332 | 62 | |||
333 | 63 | #. module: sale_exceptions | ||
334 | 64 | #: view:sale.exception:0 | ||
335 | 65 | #: view:sale.exception.confirm:0 | ||
336 | 66 | msgid "Sale Exception" | ||
337 | 67 | msgstr "" | ||
338 | 68 | |||
339 | 69 | #. module: sale_exceptions | ||
340 | 70 | #: view:sale.order:0 | ||
341 | 71 | msgid "TO FIX" | ||
342 | 72 | msgstr "" | ||
343 | 73 | |||
344 | 74 | #. module: sale_exceptions | ||
345 | 75 | #: help:sale.exception,code:0 | ||
346 | 76 | msgid "Python code executed to check if the exception apply or not. The code must apply block = True to apply the exception." | ||
347 | 77 | msgstr "" | ||
348 | 78 | |||
349 | 79 | #. module: sale_exceptions | ||
350 | 80 | #: view:sale.order:0 | ||
351 | 81 | msgid "Exception" | ||
352 | 82 | msgstr "" | ||
353 | 83 | |||
354 | 84 | #. module: sale_exceptions | ||
355 | 85 | #: view:sale.order:0 | ||
356 | 86 | msgid "Error:" | ||
357 | 87 | msgstr "" | ||
358 | 88 | |||
359 | 89 | #. module: sale_exceptions | ||
360 | 90 | #: selection:sale.exception,model:0 | ||
361 | 91 | msgid "Sale Order" | ||
362 | 92 | msgstr "" | ||
363 | 93 | |||
364 | 94 | #. module: sale_exceptions | ||
365 | 95 | #: field:sale.exception.confirm,sale_id:0 | ||
366 | 96 | msgid "Sale" | ||
367 | 97 | msgstr "" | ||
368 | 98 | |||
369 | 99 | #. module: sale_exceptions | ||
370 | 100 | #: field:sale.exception,active:0 | ||
371 | 101 | msgid "Active" | ||
372 | 102 | msgstr "" | ||
373 | 103 | |||
374 | 104 | #. module: sale_exceptions | ||
375 | 105 | #: field:sale.exception,name:0 | ||
376 | 106 | msgid "Exception Name" | ||
377 | 107 | msgstr "" | ||
378 | 108 | |||
379 | 109 | #. module: sale_exceptions | ||
380 | 110 | #: field:sale.order,exceptions_ids:0 | ||
381 | 111 | msgid "Exceptions" | ||
382 | 112 | msgstr "" | ||
383 | 113 | |||
384 | 114 | #. module: sale_exceptions | ||
385 | 115 | #: model:ir.actions.act_window,name:sale_exceptions.action_sale_exception_confirm | ||
386 | 116 | #: model:ir.model,name:sale_exceptions.model_sale_exception | ||
387 | 117 | #: view:sale.exception.confirm:0 | ||
388 | 118 | msgid "Sale Exceptions" | ||
389 | 119 | msgstr "" | ||
390 | 120 | |||
391 | 121 | #. module: sale_exceptions | ||
392 | 122 | #: model:ir.actions.act_window,name:sale_exceptions.action_sale_test_tree | ||
393 | 123 | #: model:ir.ui.menu,name:sale_exceptions.menu_sale_test | ||
394 | 124 | msgid "Exception Rules" | ||
395 | 125 | msgstr "" | ||
396 | 126 | |||
397 | 127 | #. module: sale_exceptions | ||
398 | 128 | #: model:ir.model,name:sale_exceptions.model_sale_order | ||
399 | 129 | msgid "Sales Order" | ||
400 | 130 | msgstr "" | ||
401 | 131 | |||
402 | 132 | #. module: sale_exceptions | ||
403 | 133 | #: field:sale.exception,sequence:0 | ||
404 | 134 | msgid "Sequence" | ||
405 | 135 | msgstr "" | ||
406 | 136 | |||
407 | 137 | #. module: sale_exceptions | ||
408 | 138 | #: field:sale.exception,code:0 | ||
409 | 139 | msgid "Python Code" | ||
410 | 140 | msgstr "" | ||
411 | 141 | |||
412 | 142 | #. module: sale_exceptions | ||
413 | 143 | #: view:sale.order:0 | ||
414 | 144 | msgid "Sales" | ||
415 | 145 | msgstr "" | ||
416 | 146 | |||
417 | 147 | #. module: sale_exceptions | ||
418 | 148 | #: model:sale.exception,name:sale_exceptions.excep_no_zip | ||
419 | 149 | msgid "No ZIP code on destination" | ||
420 | 150 | msgstr "" | ||
421 | 151 | |||
422 | 152 | #. module: sale_exceptions | ||
423 | 153 | #: view:sale.exception:0 | ||
424 | 154 | msgid "Sale Exception Setup" | ||
425 | 155 | msgstr "" | ||
426 | 156 | |||
427 | 157 | #. module: sale_exceptions | ||
428 | 158 | #: view:sale.exception:0 | ||
429 | 159 | msgid "Affected Sales Orders" | ||
430 | 160 | msgstr "" | ||
431 | 161 | |||
432 | 162 | #. module: sale_exceptions | ||
433 | 163 | #: field:sale.exception,sale_order_ids:0 | ||
434 | 164 | msgid "Sale Orders" | ||
435 | 165 | msgstr "" | ||
436 | 166 | |||
437 | 167 | #. module: sale_exceptions | ||
438 | 168 | #: field:sale.exception.confirm,ignore:0 | ||
439 | 169 | #: field:sale.order,ignore_exceptions:0 | ||
440 | 170 | msgid "Ignore Exceptions" | ||
441 | 171 | msgstr "" | ||
442 | 172 | |||
443 | 173 | #. module: sale_exceptions | ||
444 | 174 | #: field:sale.order,main_exception_id:0 | ||
445 | 175 | msgid "Main Exception" | ||
446 | 176 | msgstr "" | ||
447 | 177 | |||
448 | 0 | 178 | ||
449 | === added file 'sale_exceptions/sale.py' | |||
450 | --- sale_exceptions/sale.py 1970-01-01 00:00:00 +0000 | |||
451 | +++ sale_exceptions/sale.py 2013-11-15 12:55:43 +0000 | |||
452 | @@ -0,0 +1,236 @@ | |||
453 | 1 | # -*- coding: utf-8 -*- | ||
454 | 2 | ############################################################################## | ||
455 | 3 | # | ||
456 | 4 | # OpenERP, Open Source Management Solution | ||
457 | 5 | # Copyright (C) 2011 Akretion LTDA. | ||
458 | 6 | # Copyright (C) 2010-2012 Akretion Sébastien BEAU <sebastien.beau@akretion.com> | ||
459 | 7 | # Copyright (C) 2012 Camptocamp SA (Guewen Baconnier) | ||
460 | 8 | # | ||
461 | 9 | # This program is free software: you can redistribute it and/or modify | ||
462 | 10 | # it under the terms of the GNU Affero General Public License as | ||
463 | 11 | # published by the Free Software Foundation, either version 3 of the | ||
464 | 12 | # License, or (at your option) any later version. | ||
465 | 13 | # | ||
466 | 14 | # This program is distributed in the hope that it will be useful, | ||
467 | 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
468 | 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
469 | 17 | # GNU Affero General Public License for more details. | ||
470 | 18 | # | ||
471 | 19 | # You should have received a copy of the GNU Affero General Public License | ||
472 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
473 | 21 | # | ||
474 | 22 | ############################################################################## | ||
475 | 23 | |||
476 | 24 | import time | ||
477 | 25 | |||
478 | 26 | from openerp.osv import orm, fields | ||
479 | 27 | from openerp.tools.safe_eval import safe_eval | ||
480 | 28 | from openerp.tools.translate import _ | ||
481 | 29 | |||
482 | 30 | |||
483 | 31 | class sale_exception(orm.Model): | ||
484 | 32 | _name = "sale.exception" | ||
485 | 33 | _description = "Sale Exceptions" | ||
486 | 34 | _order = "active desc, sequence asc" | ||
487 | 35 | _columns = { | ||
488 | 36 | 'name': fields.char('Exception Name', required=True, translate=True), | ||
489 | 37 | 'description': fields.text('Description', translate=True), | ||
490 | 38 | 'sequence': fields.integer( | ||
491 | 39 | 'Sequence', | ||
492 | 40 | help="Gives the sequence order when applying the test"), | ||
493 | 41 | 'model': fields.selection([('sale.order', 'Sale Order'), | ||
494 | 42 | ('sale.order.line', 'Sale Order Line')], | ||
495 | 43 | string='Apply on', required=True), | ||
496 | 44 | 'active': fields.boolean('Active'), | ||
497 | 45 | 'code': fields.text( | ||
498 | 46 | 'Python Code', | ||
499 | 47 | help="Python code executed to check if the exception apply or not. " | ||
500 | 48 | "The code must apply block = True to apply the exception."), | ||
501 | 49 | 'sale_order_ids': fields.many2many( | ||
502 | 50 | 'sale.order', | ||
503 | 51 | 'sale_order_exception_rel', 'exception_id', 'sale_order_id', | ||
504 | 52 | string='Sale Orders', | ||
505 | 53 | readonly=True), | ||
506 | 54 | } | ||
507 | 55 | |||
508 | 56 | _defaults = { | ||
509 | 57 | 'code': """# Python code. Use failed = True to block the sale order. | ||
510 | 58 | # You can use the following variables : | ||
511 | 59 | # - self: ORM model of the record which is checked | ||
512 | 60 | # - order or line: browse_record of the sale order or sale order line | ||
513 | 61 | # - object: same as order or line, browse_record of the sale order or sale order line | ||
514 | 62 | # - pool: ORM model pool (i.e. self.pool) | ||
515 | 63 | # - time: Python time module | ||
516 | 64 | # - cr: database cursor | ||
517 | 65 | # - uid: current user id | ||
518 | 66 | # - context: current context | ||
519 | 67 | """ | ||
520 | 68 | } | ||
521 | 69 | |||
522 | 70 | |||
523 | 71 | class sale_order(orm.Model): | ||
524 | 72 | _inherit = "sale.order" | ||
525 | 73 | |||
526 | 74 | _order = 'main_exception_id asc, date_order desc, name desc' | ||
527 | 75 | |||
528 | 76 | def _get_main_error(self, cr, uid, ids, name, args, context=None): | ||
529 | 77 | res = {} | ||
530 | 78 | for sale_order in self.browse(cr, uid, ids, context=context): | ||
531 | 79 | if sale_order.state == 'draft' and sale_order.exceptions_ids: | ||
532 | 80 | res[sale_order.id] = sale_order.exceptions_ids[0].id | ||
533 | 81 | else: | ||
534 | 82 | res[sale_order.id] = False | ||
535 | 83 | return res | ||
536 | 84 | |||
537 | 85 | _columns = { | ||
538 | 86 | 'main_exception_id': fields.function( | ||
539 | 87 | _get_main_error, | ||
540 | 88 | type='many2one', | ||
541 | 89 | relation="sale.exception", | ||
542 | 90 | string='Main Exception', | ||
543 | 91 | store={ | ||
544 | 92 | 'sale.order': (lambda self, cr, uid, ids, c=None: ids, | ||
545 | 93 | ['exceptions_ids', 'state'], 10), | ||
546 | 94 | }), | ||
547 | 95 | 'exceptions_ids': fields.many2many( | ||
548 | 96 | 'sale.exception', | ||
549 | 97 | 'sale_order_exception_rel', 'sale_order_id', 'exception_id', | ||
550 | 98 | string='Exceptions'), | ||
551 | 99 | 'ignore_exceptions': fields.boolean('Ignore Exceptions'), | ||
552 | 100 | } | ||
553 | 101 | |||
554 | 102 | def test_all_draft_orders(self, cr, uid, context=None): | ||
555 | 103 | ids = self.search(cr, uid, [('state', '=', 'draft')], context=context) | ||
556 | 104 | self.test_exceptions(cr, uid, ids, context=context) | ||
557 | 105 | return True | ||
558 | 106 | |||
559 | 107 | def _popup_exceptions(self, cr, uid, order_id, context=None): | ||
560 | 108 | if context is None: | ||
561 | 109 | context = {} | ||
562 | 110 | model_data_obj = self.pool.get('ir.model.data') | ||
563 | 111 | list_obj = self.pool.get('sale.exception.confirm') | ||
564 | 112 | ctx = context.copy() | ||
565 | 113 | ctx.update({'active_id': order_id, | ||
566 | 114 | 'active_ids': [order_id]}) | ||
567 | 115 | list_id = list_obj.create(cr, uid, {}, context=ctx) | ||
568 | 116 | view_id = model_data_obj.get_object_reference( | ||
569 | 117 | cr, uid, 'sale_exceptions', 'view_sale_exception_confirm')[1] | ||
570 | 118 | action = { | ||
571 | 119 | 'name': _("Blocked in draft due to exceptions"), | ||
572 | 120 | 'type': 'ir.actions.act_window', | ||
573 | 121 | 'view_type': 'form', | ||
574 | 122 | 'view_mode': 'form', | ||
575 | 123 | 'res_model': 'sale.exception.confirm', | ||
576 | 124 | 'view_id': [view_id], | ||
577 | 125 | 'target': 'new', | ||
578 | 126 | 'nodestroy': True, | ||
579 | 127 | 'res_id': list_id, | ||
580 | 128 | } | ||
581 | 129 | return action | ||
582 | 130 | |||
583 | 131 | def action_button_confirm(self, cr, uid, ids, context=None): | ||
584 | 132 | exception_ids = self.detect_exceptions(cr, uid, ids, context=context) | ||
585 | 133 | if exception_ids: | ||
586 | 134 | return self._popup_exceptions(cr, uid, ids[0], context=context) | ||
587 | 135 | else: | ||
588 | 136 | return super(sale_order, self).action_button_confirm(cr, uid, ids, | ||
589 | 137 | context=context) | ||
590 | 138 | |||
591 | 139 | def test_exceptions(self, cr, uid, ids, context=None): | ||
592 | 140 | """ | ||
593 | 141 | Condition method for the workflow from draft to confirm | ||
594 | 142 | """ | ||
595 | 143 | exception_ids = self.detect_exceptions(cr, uid, ids, context=context) | ||
596 | 144 | if exception_ids: | ||
597 | 145 | return False | ||
598 | 146 | return True | ||
599 | 147 | |||
600 | 148 | def detect_exceptions(self, cr, uid, ids, context=None): | ||
601 | 149 | exception_obj = self.pool.get('sale.exception') | ||
602 | 150 | order_exception_ids = exception_obj.search( | ||
603 | 151 | cr, uid, | ||
604 | 152 | [('model', '=', 'sale.order')], | ||
605 | 153 | context=context) | ||
606 | 154 | line_exception_ids = exception_obj.search( | ||
607 | 155 | cr, uid, | ||
608 | 156 | [('model', '=', 'sale.order.line')], | ||
609 | 157 | context=context) | ||
610 | 158 | |||
611 | 159 | order_exceptions = exception_obj.browse(cr, uid, order_exception_ids, | ||
612 | 160 | context=context) | ||
613 | 161 | line_exceptions = exception_obj.browse(cr, uid, line_exception_ids, | ||
614 | 162 | context=context) | ||
615 | 163 | |||
616 | 164 | exception_ids = False | ||
617 | 165 | for order in self.browse(cr, uid, ids, context=context): | ||
618 | 166 | if order.ignore_exceptions: | ||
619 | 167 | continue | ||
620 | 168 | exception_ids = self._detect_exceptions(cr, uid, | ||
621 | 169 | order, | ||
622 | 170 | order_exceptions, | ||
623 | 171 | line_exceptions, | ||
624 | 172 | context=context) | ||
625 | 173 | |||
626 | 174 | self.write(cr, uid, [order.id], | ||
627 | 175 | {'exceptions_ids': [(6, 0, exception_ids)]}, | ||
628 | 176 | context=context) | ||
629 | 177 | return exception_ids | ||
630 | 178 | |||
631 | 179 | def _exception_rule_eval_context(self, cr, uid, obj_name, obj, context=None): | ||
632 | 180 | if context is None: | ||
633 | 181 | context = {} | ||
634 | 182 | |||
635 | 183 | user = self.pool.get('res.users').browse(cr, uid, uid, context=context) | ||
636 | 184 | return {obj_name: obj, | ||
637 | 185 | 'self': self.pool.get(obj._name), | ||
638 | 186 | 'object': obj, | ||
639 | 187 | 'obj': obj, | ||
640 | 188 | 'pool': self.pool, | ||
641 | 189 | 'cr': cr, | ||
642 | 190 | 'uid': uid, | ||
643 | 191 | 'user': user, | ||
644 | 192 | 'time': time, | ||
645 | 193 | # copy context to prevent side-effects of eval | ||
646 | 194 | 'context': context.copy()} | ||
647 | 195 | |||
648 | 196 | def _rule_eval(self, cr, uid, rule, obj_name, obj, context): | ||
649 | 197 | expr = rule.code | ||
650 | 198 | space = self._exception_rule_eval_context(cr, uid, obj_name, obj, | ||
651 | 199 | context=context) | ||
652 | 200 | try: | ||
653 | 201 | safe_eval(expr, | ||
654 | 202 | space, | ||
655 | 203 | mode='exec', | ||
656 | 204 | nocopy=True) # nocopy allows to return 'result' | ||
657 | 205 | except Exception, e: | ||
658 | 206 | raise orm.except_orm( | ||
659 | 207 | _('Error'), | ||
660 | 208 | _('Error when evaluating the sale exception ' | ||
661 | 209 | 'rule:\n %s \n(%s)') % (rule.name, e)) | ||
662 | 210 | return space.get('failed', False) | ||
663 | 211 | |||
664 | 212 | def _detect_exceptions(self, cr, uid, order, order_exceptions, | ||
665 | 213 | line_exceptions, context=None): | ||
666 | 214 | exception_ids = [] | ||
667 | 215 | for rule in order_exceptions: | ||
668 | 216 | if self._rule_eval(cr, uid, rule, 'order', order, context): | ||
669 | 217 | exception_ids.append(rule.id) | ||
670 | 218 | |||
671 | 219 | for order_line in order.order_line: | ||
672 | 220 | for rule in line_exceptions: | ||
673 | 221 | if rule.id in exception_ids: | ||
674 | 222 | # we do not matter if the exception as already been | ||
675 | 223 | # found for an order line of this order | ||
676 | 224 | continue | ||
677 | 225 | if self._rule_eval(cr, uid, rule, 'line', order_line, context): | ||
678 | 226 | exception_ids.append(rule.id) | ||
679 | 227 | |||
680 | 228 | return exception_ids | ||
681 | 229 | |||
682 | 230 | def copy(self, cr, uid, id, default=None, context=None): | ||
683 | 231 | if default is None: | ||
684 | 232 | default = {} | ||
685 | 233 | default.update({ | ||
686 | 234 | 'ignore_exceptions': False, | ||
687 | 235 | }) | ||
688 | 236 | return super(sale_order, self).copy(cr, uid, id, default=default, context=context) | ||
689 | 0 | 237 | ||
690 | === added file 'sale_exceptions/sale_exceptions_data.xml' | |||
691 | --- sale_exceptions/sale_exceptions_data.xml 1970-01-01 00:00:00 +0000 | |||
692 | +++ sale_exceptions/sale_exceptions_data.xml 2013-11-15 12:55:43 +0000 | |||
693 | @@ -0,0 +1,19 @@ | |||
694 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
695 | 2 | <openerp> | ||
696 | 3 | <data noupdate="1"> | ||
697 | 4 | |||
698 | 5 | <record forcecreate="True" id="ir_cron_test_orders" model="ir.cron"> | ||
699 | 6 | <field name="name">Test Draft Orders</field> | ||
700 | 7 | <field eval="False" name="active"/> | ||
701 | 8 | <field name="user_id" ref="base.user_root"/> | ||
702 | 9 | <field name="interval_number">20</field> | ||
703 | 10 | <field name="interval_type">minutes</field> | ||
704 | 11 | <field name="numbercall">-1</field> | ||
705 | 12 | <field eval="False" name="doall"/> | ||
706 | 13 | <field eval="'sale.order'" name="model"/> | ||
707 | 14 | <field eval="'test_all_draft_orders'" name="function"/> | ||
708 | 15 | <field eval="'()'" name="args"/> | ||
709 | 16 | </record> | ||
710 | 17 | |||
711 | 18 | </data> | ||
712 | 19 | </openerp> | ||
713 | 0 | 20 | ||
714 | === added file 'sale_exceptions/sale_view.xml' | |||
715 | --- sale_exceptions/sale_view.xml 1970-01-01 00:00:00 +0000 | |||
716 | +++ sale_exceptions/sale_view.xml 2013-11-15 12:55:43 +0000 | |||
717 | @@ -0,0 +1,102 @@ | |||
718 | 1 | <?xml version="1.0" ?> | ||
719 | 2 | <openerp> | ||
720 | 3 | <data> | ||
721 | 4 | |||
722 | 5 | <record id="view_sale_exception_tree" model="ir.ui.view"> | ||
723 | 6 | <field name="name">sale.exception.tree</field> | ||
724 | 7 | <field name="model">sale.exception</field> | ||
725 | 8 | <field name="arch" type="xml"> | ||
726 | 9 | <tree string="Sale Exception"> | ||
727 | 10 | <field name="active"/> | ||
728 | 11 | <field name="name"/> | ||
729 | 12 | <field name="description"/> | ||
730 | 13 | <field name="model"/> | ||
731 | 14 | <field name="sequence"/> | ||
732 | 15 | </tree> | ||
733 | 16 | </field> | ||
734 | 17 | </record> | ||
735 | 18 | |||
736 | 19 | <record id="view_sale_exception_form" model="ir.ui.view"> | ||
737 | 20 | <field name="name">sale.exception.form</field> | ||
738 | 21 | <field name="model">sale.exception</field> | ||
739 | 22 | <field name="arch" type="xml"> | ||
740 | 23 | <form string="Sale Exception Setup"> | ||
741 | 24 | <group colspan="4" col="2"> | ||
742 | 25 | <field name="name"/> | ||
743 | 26 | <field name="description"/> | ||
744 | 27 | </group> | ||
745 | 28 | <group col="4" colspan="4" groups="base.group_sale_manager"> | ||
746 | 29 | <field name="active"/> | ||
747 | 30 | <field name="sequence"/> | ||
748 | 31 | <group colspan="4" col="2" groups="base.group_system"> | ||
749 | 32 | <field name="model"/> | ||
750 | 33 | <field name="code"/> | ||
751 | 34 | </group> | ||
752 | 35 | </group> | ||
753 | 36 | <group colspan="4" col="2"> | ||
754 | 37 | <separator string="Affected Sales Orders"/> | ||
755 | 38 | <newline/> | ||
756 | 39 | <field name="sale_order_ids" nolabel="1" domain="[('state', '=', 'draft')]"/> | ||
757 | 40 | </group> | ||
758 | 41 | </form> | ||
759 | 42 | </field> | ||
760 | 43 | </record> | ||
761 | 44 | |||
762 | 45 | <record id="action_sale_test_tree" model="ir.actions.act_window"> | ||
763 | 46 | <field name="name">Exception Rules</field> | ||
764 | 47 | <field name="res_model">sale.exception</field> | ||
765 | 48 | <field name="view_type">form</field> | ||
766 | 49 | <field name="view_mode">tree,form</field> | ||
767 | 50 | <field name="view_id" ref="view_sale_exception_tree"/> | ||
768 | 51 | <field name="context">{'active_test': False}</field> | ||
769 | 52 | </record> | ||
770 | 53 | |||
771 | 54 | <menuitem action="action_sale_test_tree" id="menu_sale_test" parent="base.menu_sale_config_sales" /> | ||
772 | 55 | |||
773 | 56 | |||
774 | 57 | <record id="view_order_form" model="ir.ui.view"> | ||
775 | 58 | <field name="name">sale_exceptions.view_order_form</field> | ||
776 | 59 | <field name="model">sale.order</field> | ||
777 | 60 | <field name="inherit_id" ref="sale.view_order_form"/> | ||
778 | 61 | <field name="arch" type="xml"> | ||
779 | 62 | <field name="name" position="after"> | ||
780 | 63 | <group> | ||
781 | 64 | <field name="main_exception_id" options='{"no_open": True}' | ||
782 | 65 | class="oe_inline" string="Error:" | ||
783 | 66 | attrs="{'invisible':[('main_exception_id','=', False)]}"/> | ||
784 | 67 | </group> | ||
785 | 68 | </field> | ||
786 | 69 | <xpath expr="//page[@string='Other Information']/group" | ||
787 | 70 | position="inside"> | ||
788 | 71 | <group name="exception" colspan="2" col="2"> | ||
789 | 72 | <separator string="Exception" colspan="2"/> | ||
790 | 73 | <field name="exceptions_ids" colspan="2" nolabel="1"/> | ||
791 | 74 | </group> | ||
792 | 75 | </xpath> | ||
793 | 76 | </field> | ||
794 | 77 | </record> | ||
795 | 78 | |||
796 | 79 | <record id="view_order_tree" model="ir.ui.view"> | ||
797 | 80 | <field name="name">sale_exceptions.view_order_tree</field> | ||
798 | 81 | <field name="model">sale.order</field> | ||
799 | 82 | <field name="inherit_id" ref="sale.view_order_tree"/> | ||
800 | 83 | <field name="arch" type="xml"> | ||
801 | 84 | <field name="state" position="after"> | ||
802 | 85 | <field name="main_exception_id"/> | ||
803 | 86 | </field> | ||
804 | 87 | </field> | ||
805 | 88 | </record> | ||
806 | 89 | |||
807 | 90 | <record id="view_sales_order_filter" model="ir.ui.view"> | ||
808 | 91 | <field name="name">sale_exceptions.view_sales_order_filter</field> | ||
809 | 92 | <field name="model">sale.order</field> | ||
810 | 93 | <field name="inherit_id" ref="sale.view_sales_order_filter" /> | ||
811 | 94 | <field name="arch" type="xml"> | ||
812 | 95 | <filter name="sales" position="after"> | ||
813 | 96 | <separator orientation="vertical"/> | ||
814 | 97 | <filter icon="terp-emblem-important" name="tofix" string="Blocked in draft" domain="[('main_exception_id','!=',False)]"/> | ||
815 | 98 | </filter> | ||
816 | 99 | </field> | ||
817 | 100 | </record> | ||
818 | 101 | </data> | ||
819 | 102 | </openerp> | ||
820 | 0 | 103 | ||
821 | === added file 'sale_exceptions/sale_workflow.xml' | |||
822 | --- sale_exceptions/sale_workflow.xml 1970-01-01 00:00:00 +0000 | |||
823 | +++ sale_exceptions/sale_workflow.xml 2013-11-15 12:55:43 +0000 | |||
824 | @@ -0,0 +1,9 @@ | |||
825 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
826 | 2 | <openerp> | ||
827 | 3 | <data> | ||
828 | 4 | <record id="sale.trans_draft_router" model="workflow.transition"> | ||
829 | 5 | <field name="signal">order_confirm</field> | ||
830 | 6 | <field name="condition">test_exceptions()</field> | ||
831 | 7 | </record> | ||
832 | 8 | </data> | ||
833 | 9 | </openerp> | ||
834 | 0 | 10 | ||
835 | === added directory 'sale_exceptions/security' | |||
836 | === added file 'sale_exceptions/security/ir.model.access.csv' | |||
837 | --- sale_exceptions/security/ir.model.access.csv 1970-01-01 00:00:00 +0000 | |||
838 | +++ sale_exceptions/security/ir.model.access.csv 2013-11-15 12:55:43 +0000 | |||
839 | @@ -0,0 +1,3 @@ | |||
840 | 1 | "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" | ||
841 | 2 | "access_sale_exception","sale.exception","model_sale_exception","base.group_user",1,0,0,0 | ||
842 | 3 | "access_sale_exception_manager","sale.exception","model_sale_exception","base.group_sale_manager",1,1,1,1 | ||
843 | 0 | 4 | ||
844 | === added directory 'sale_exceptions/settings' | |||
845 | === added file 'sale_exceptions/settings/sale.exception.csv' | |||
846 | --- sale_exceptions/settings/sale.exception.csv 1970-01-01 00:00:00 +0000 | |||
847 | +++ sale_exceptions/settings/sale.exception.csv 2013-11-15 12:55:43 +0000 | |||
848 | @@ -0,0 +1,5 @@ | |||
849 | 1 | "id","name","description","sequence","model","code","active" | ||
850 | 2 | "excep_no_zip","No ZIP code on destination",,50,"sale.order","if not order.partner_shipping_id.zip: | ||
851 | 3 | failed=True",False | ||
852 | 4 | "excep_no_stock","Not Enough Virtual Stock",,50,"sale.order.line","if line.product_id and line.product_id.type == 'product' and line.product_id.virtual_available < line.product_uom_qty: | ||
853 | 5 | failed=True",False | ||
854 | 0 | 6 | ||
855 | === added directory 'sale_exceptions/wizard' | |||
856 | === added file 'sale_exceptions/wizard/__init__.py' | |||
857 | --- sale_exceptions/wizard/__init__.py 1970-01-01 00:00:00 +0000 | |||
858 | +++ sale_exceptions/wizard/__init__.py 2013-11-15 12:55:43 +0000 | |||
859 | @@ -0,0 +1,24 @@ | |||
860 | 1 | # -*- coding: utf-8 -*- | ||
861 | 2 | ############################################################################## | ||
862 | 3 | # | ||
863 | 4 | # OpenERP, Open Source Management Solution | ||
864 | 5 | # Copyright (C) 2011 Akretion LTDA. | ||
865 | 6 | # authors: Raphaël Valyi, Renato Lima | ||
866 | 7 | # Copyright (C) 2010-2012 Akretion Sébastien BEAU <sebastien.beau@akretion.com> | ||
867 | 8 | # Copyright (C) 2012 Camptocamp SA (Guewen Baconnier) | ||
868 | 9 | # | ||
869 | 10 | # This program is free software: you can redistribute it and/or modify | ||
870 | 11 | # it under the terms of the GNU Affero General Public License as | ||
871 | 12 | # published by the Free Software Foundation, either version 3 of the | ||
872 | 13 | # License, or (at your option) any later version. | ||
873 | 14 | # | ||
874 | 15 | # This program is distributed in the hope that it will be useful, | ||
875 | 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
876 | 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
877 | 18 | # GNU Affero General Public License for more details. | ||
878 | 19 | # | ||
879 | 20 | # You should have received a copy of the GNU Affero General Public License | ||
880 | 21 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
881 | 22 | # | ||
882 | 23 | ############################################################################## | ||
883 | 24 | from . import sale_exception_confirm | ||
884 | 0 | 25 | ||
885 | === added file 'sale_exceptions/wizard/sale_exception_confirm.py' | |||
886 | --- sale_exceptions/wizard/sale_exception_confirm.py 1970-01-01 00:00:00 +0000 | |||
887 | +++ sale_exceptions/wizard/sale_exception_confirm.py 2013-11-15 12:55:43 +0000 | |||
888 | @@ -0,0 +1,62 @@ | |||
889 | 1 | # -*- coding: utf-8 -*- | ||
890 | 2 | ############################################################################## | ||
891 | 3 | # | ||
892 | 4 | # Copyright Camptocamp SA | ||
893 | 5 | # @author: Guewen Baconnier | ||
894 | 6 | # | ||
895 | 7 | # This program is free software: you can redistribute it and/or modify | ||
896 | 8 | # it under the terms of the GNU General Public License as published by | ||
897 | 9 | # the Free Software Foundation, either version 3 of the License, or | ||
898 | 10 | # (at your option) any later version. | ||
899 | 11 | # | ||
900 | 12 | # This program is distributed in the hope that it will be useful, | ||
901 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
902 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
903 | 15 | # GNU General Public License for more details. | ||
904 | 16 | # | ||
905 | 17 | # You should have received a copy of the GNU General Public License | ||
906 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
907 | 19 | # | ||
908 | 20 | ############################################################################## | ||
909 | 21 | from openerp.osv import orm, fields | ||
910 | 22 | |||
911 | 23 | |||
912 | 24 | class SaleExceptionConfirm(orm.TransientModel): | ||
913 | 25 | |||
914 | 26 | _name = 'sale.exception.confirm' | ||
915 | 27 | |||
916 | 28 | _columns = { | ||
917 | 29 | 'sale_id': fields.many2one('sale.order', 'Sale'), | ||
918 | 30 | 'exception_ids': fields.many2many('sale.exception', | ||
919 | 31 | string='Exceptions to resolve', | ||
920 | 32 | readonly=True), | ||
921 | 33 | 'ignore': fields.boolean('Ignore Exceptions'), | ||
922 | 34 | } | ||
923 | 35 | |||
924 | 36 | def default_get(self, cr, uid, fields, context=None): | ||
925 | 37 | if context is None: | ||
926 | 38 | context = {} | ||
927 | 39 | res = super(SaleExceptionConfirm, self).default_get( | ||
928 | 40 | cr, uid, fields, context=context) | ||
929 | 41 | order_obj = self.pool.get('sale.order') | ||
930 | 42 | sale_id = context.get('active_ids') | ||
931 | 43 | assert len(sale_id) == 1, "Only 1 ID accepted, got %r" % sale_id | ||
932 | 44 | sale_id = sale_id[0] | ||
933 | 45 | sale = order_obj.browse(cr, uid, sale_id, context=context) | ||
934 | 46 | exception_ids = [e.id for e in sale.exceptions_ids] | ||
935 | 47 | res.update({'exception_ids': [(6, 0, exception_ids)]}) | ||
936 | 48 | res.update({'sale_id': sale_id}) | ||
937 | 49 | return res | ||
938 | 50 | |||
939 | 51 | def action_confirm(self, cr, uid, ids, context=None): | ||
940 | 52 | if hasattr(ids, '__iter__'): | ||
941 | 53 | assert len(ids) == 1, "Only 1 ID accepted, got %r" % ids | ||
942 | 54 | ids = ids[0] | ||
943 | 55 | form = self.browse(cr, uid, ids, context=context) | ||
944 | 56 | if form.ignore: | ||
945 | 57 | self.pool.get('sale.order').write( | ||
946 | 58 | cr, uid, | ||
947 | 59 | form.sale_id.id, | ||
948 | 60 | {'ignore_exceptions': True}, | ||
949 | 61 | context=context) | ||
950 | 62 | return {'type': 'ir.actions.act_window_close'} | ||
951 | 0 | 63 | ||
952 | === added file 'sale_exceptions/wizard/sale_exception_confirm_view.xml' | |||
953 | --- sale_exceptions/wizard/sale_exception_confirm_view.xml 1970-01-01 00:00:00 +0000 | |||
954 | +++ sale_exceptions/wizard/sale_exception_confirm_view.xml 2013-11-15 12:55:43 +0000 | |||
955 | @@ -0,0 +1,39 @@ | |||
956 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
957 | 2 | <openerp> | ||
958 | 3 | <data> | ||
959 | 4 | |||
960 | 5 | <record id="view_sale_exception_confirm" model="ir.ui.view"> | ||
961 | 6 | <field name="name">Sale Exceptions</field> | ||
962 | 7 | <field name="model">sale.exception.confirm</field> | ||
963 | 8 | <field name="arch" type="xml"> | ||
964 | 9 | <form string="Blocked in draft due to exceptions" version="7.0"> | ||
965 | 10 | <group> | ||
966 | 11 | <field name="exception_ids" nolabel="1" colspan="4"> | ||
967 | 12 | <tree string="Sale Exceptions"> | ||
968 | 13 | <field name="name"/> | ||
969 | 14 | <field name="description"/> | ||
970 | 15 | </tree> | ||
971 | 16 | </field> | ||
972 | 17 | <newline/> | ||
973 | 18 | <field name="ignore" groups='base.group_sale_manager'/> | ||
974 | 19 | </group> | ||
975 | 20 | <footer> | ||
976 | 21 | <button name="action_confirm" string="_Close" | ||
977 | 22 | colspan="1" type="object" icon="gtk-ok" /> | ||
978 | 23 | </footer> | ||
979 | 24 | </form> | ||
980 | 25 | </field> | ||
981 | 26 | </record> | ||
982 | 27 | |||
983 | 28 | <record id="action_sale_exception_confirm" model="ir.actions.act_window"> | ||
984 | 29 | <field name="name">Blocked in draft due to exceptions</field> | ||
985 | 30 | <field name="type">ir.actions.act_window</field> | ||
986 | 31 | <field name="res_model">sale.exception.confirm</field> | ||
987 | 32 | <field name="view_type">form</field> | ||
988 | 33 | <field name="view_mode">form</field> | ||
989 | 34 | <field name="view_id" ref="view_sale_exception_confirm"/> | ||
990 | 35 | <field name="target">new</field> | ||
991 | 36 | </record> | ||
992 | 37 | |||
993 | 38 | </data> | ||
994 | 39 | </openerp> |
As your reasoning on community list, I approve it blindly.
Regards.