Merge lp:~openerp-community-reviewer/e-commerce-addons/move_sale_exception_to_sale_wkfl_branches-jge into lp:~extra-addons-commiter/e-commerce-addons/7.0
- move_sale_exception_to_sale_wkfl_branches-jge
- Merge into 7.0
Status: | Merged |
---|---|
Merged at revision: | 286 |
Proposed branch: | lp:~openerp-community-reviewer/e-commerce-addons/move_sale_exception_to_sale_wkfl_branches-jge |
Merge into: | lp:~extra-addons-commiter/e-commerce-addons/7.0 |
Diff against target: |
582 lines (+0/-524) 11 files modified
sale_exceptions/__init__.py (+0/-25) sale_exceptions/__openerp__.py (+0/-48) sale_exceptions/sale.py (+0/-208) sale_exceptions/sale_exceptions_data.xml (+0/-19) sale_exceptions/sale_view.xml (+0/-106) sale_exceptions/sale_workflow.xml (+0/-9) sale_exceptions/security/ir.model.access.csv (+0/-3) sale_exceptions/settings/sale.exception.csv (+0/-5) sale_exceptions/wizard/__init__.py (+0/-1) sale_exceptions/wizard/sale_exception_confirm.py (+0/-56) sale_exceptions/wizard/sale_exception_confirm_view.xml (+0/-44) |
To merge this branch: | bzr merge lp:~openerp-community-reviewer/e-commerce-addons/move_sale_exception_to_sale_wkfl_branches-jge |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nicolas Bessi - Camptocamp (community) | Approve | ||
Guewen Baconnier @ Camptocamp | Approve | ||
Pedro Manuel Baeza (community) | Approve | ||
Review via email: mp+193570@code.launchpad.net |
Commit message
[MOVE] Move here the sale_exceptions module to the lp:sale-wkfl branch
Description of the change
Hi,
I suggest to move the sale_exceptions module from e-commerce-addons to lp:sale-wkfl branch because it concern 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. This depends on this merge : https:/
WARNING : Do not merge this one before ensuring the first one is merged !!!
Regards,
Joël
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?
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c) wrote : | # |
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
I approve for the move.
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote : | # |
LGTM
Preview Diff
1 | === removed directory 'sale_exceptions' | |||
2 | === removed file 'sale_exceptions/__init__.py' | |||
3 | --- sale_exceptions/__init__.py 2012-02-24 09:31:32 +0000 | |||
4 | +++ sale_exceptions/__init__.py 1970-01-01 00:00:00 +0000 | |||
5 | @@ -1,25 +0,0 @@ | |||
6 | 1 | # -*- coding: utf-8 -*- | ||
7 | 2 | ############################################################################## | ||
8 | 3 | # | ||
9 | 4 | # OpenERP, Open Source Management Solution | ||
10 | 5 | # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). | ||
11 | 6 | # | ||
12 | 7 | # This program is free software: you can redistribute it and/or modify | ||
13 | 8 | # it under the terms of the GNU Affero General Public License as | ||
14 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
15 | 10 | # License, or (at your option) any later version. | ||
16 | 11 | # | ||
17 | 12 | # This program is distributed in the hope that it will be useful, | ||
18 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | 15 | # GNU Affero General Public License for more details. | ||
21 | 16 | # | ||
22 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
23 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
24 | 19 | # | ||
25 | 20 | ############################################################################## | ||
26 | 21 | |||
27 | 22 | import sale | ||
28 | 23 | import wizard | ||
29 | 24 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
30 | 25 | |||
31 | 26 | 0 | ||
32 | === removed file 'sale_exceptions/__openerp__.py' | |||
33 | --- sale_exceptions/__openerp__.py 2012-12-26 13:05:09 +0000 | |||
34 | +++ sale_exceptions/__openerp__.py 1970-01-01 00:00:00 +0000 | |||
35 | @@ -1,48 +0,0 @@ | |||
36 | 1 | # -*- coding: utf-8 -*- | ||
37 | 2 | ############################################################################## | ||
38 | 3 | # | ||
39 | 4 | # OpenERP, Open Source Management Solution | ||
40 | 5 | # Copyright (C) 2011 Akretion LTDA. | ||
41 | 6 | # authors: Raphaël Valyi, Renato Lima | ||
42 | 7 | # Copyright (C) 2010-2012 Akretion Sébastien BEAU <sebastien.beau@akretion.com> | ||
43 | 8 | # Copyright (C) 2012 Camptocamp SA (Guewen Baconnier) | ||
44 | 9 | # | ||
45 | 10 | # This program is free software: you can redistribute it and/or modify | ||
46 | 11 | # it under the terms of the GNU Affero General Public License as | ||
47 | 12 | # published by the Free Software Foundation, either version 3 of the | ||
48 | 13 | # License, or (at your option) any later version. | ||
49 | 14 | # | ||
50 | 15 | # This program is distributed in the hope that it will be useful, | ||
51 | 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
52 | 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
53 | 18 | # GNU Affero General Public License for more details. | ||
54 | 19 | # | ||
55 | 20 | # You should have received a copy of the GNU Affero General Public License | ||
56 | 21 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
57 | 22 | # | ||
58 | 23 | ############################################################################## | ||
59 | 24 | |||
60 | 25 | |||
61 | 26 | { | ||
62 | 27 | 'name': 'Sale Exceptions', | ||
63 | 28 | 'version': '0.1', | ||
64 | 29 | 'category': 'Generic Modules/Sale', | ||
65 | 30 | 'description': """ | ||
66 | 31 | This module allows you attach several customizable exceptions to your sale order in a way that you can filter orders by exceptions type and fix them. | ||
67 | 32 | This is especially useful in an order importation scenario such as with the base_sale_multi_channels module, because it's likely a few orders have errors when you import them (like product not found in OpenERP, wrong line format etc...) | ||
68 | 33 | """, | ||
69 | 34 | 'author': 'Akretion', | ||
70 | 35 | 'website': 'http://www.akretion.com', | ||
71 | 36 | 'depends': ['sale'], | ||
72 | 37 | 'init_xml': [ | ||
73 | 38 | 'settings/sale.exception.csv', | ||
74 | 39 | ], | ||
75 | 40 | 'update_xml': ['sale_workflow.xml', | ||
76 | 41 | 'sale_view.xml', | ||
77 | 42 | 'sale_exceptions_data.xml', | ||
78 | 43 | 'wizard/sale_exception_confirm_view.xml', | ||
79 | 44 | 'security/ir.model.access.csv'], | ||
80 | 45 | 'demo_xml': [], | ||
81 | 46 | 'installable': True, | ||
82 | 47 | } | ||
83 | 48 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
84 | 49 | 0 | ||
85 | === removed file 'sale_exceptions/sale.py' | |||
86 | --- sale_exceptions/sale.py 2012-12-26 13:05:09 +0000 | |||
87 | +++ sale_exceptions/sale.py 1970-01-01 00:00:00 +0000 | |||
88 | @@ -1,208 +0,0 @@ | |||
89 | 1 | # -*- coding: utf-8 -*- | ||
90 | 2 | ############################################################################## | ||
91 | 3 | # | ||
92 | 4 | # OpenERP, Open Source Management Solution | ||
93 | 5 | # Copyright (C) 2011 Akretion LTDA. | ||
94 | 6 | # Copyright (C) 2010-2012 Akretion Sébastien BEAU <sebastien.beau@akretion.com> | ||
95 | 7 | # Copyright (C) 2012 Camptocamp SA (Guewen Baconnier) | ||
96 | 8 | # | ||
97 | 9 | # This program is free software: you can redistribute it and/or modify | ||
98 | 10 | # it under the terms of the GNU Affero General Public License as | ||
99 | 11 | # published by the Free Software Foundation, either version 3 of the | ||
100 | 12 | # License, or (at your option) any later version. | ||
101 | 13 | # | ||
102 | 14 | # This program is distributed in the hope that it will be useful, | ||
103 | 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
104 | 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
105 | 17 | # GNU Affero General Public License for more details. | ||
106 | 18 | # | ||
107 | 19 | # You should have received a copy of the GNU Affero General Public License | ||
108 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
109 | 21 | # | ||
110 | 22 | ############################################################################## | ||
111 | 23 | |||
112 | 24 | import time | ||
113 | 25 | import netsvc | ||
114 | 26 | |||
115 | 27 | from openerp.osv.orm import Model | ||
116 | 28 | from openerp.osv import fields | ||
117 | 29 | from openerp.osv.osv import except_osv | ||
118 | 30 | from tools.safe_eval import safe_eval as eval | ||
119 | 31 | from tools.translate import _ | ||
120 | 32 | |||
121 | 33 | class sale_exception(Model): | ||
122 | 34 | _name = "sale.exception" | ||
123 | 35 | _description = "Sale Exceptions" | ||
124 | 36 | _order="active desc, sequence asc" | ||
125 | 37 | _columns = { | ||
126 | 38 | 'name': fields.char('Exception Name', size=64, required=True, translate=True), | ||
127 | 39 | 'description': fields.text('Description', translate=True), | ||
128 | 40 | 'sequence': fields.integer('Sequence', help="Gives the sequence order when applying the test"), | ||
129 | 41 | 'model': fields.selection([('sale.order', 'Sale Order'), | ||
130 | 42 | ('sale.order.line', 'Sale Order Line')], | ||
131 | 43 | string='Apply on', required=True), | ||
132 | 44 | 'active': fields.boolean('Active'), | ||
133 | 45 | 'code': fields.text('Python Code', | ||
134 | 46 | help="Python code executed to check if the exception apply or not. " \ | ||
135 | 47 | "The code must apply block = True to apply the exception."), | ||
136 | 48 | 'sale_order_ids': fields.many2many('sale.order', 'sale_order_exception_rel', | ||
137 | 49 | 'exception_id', 'sale_order_id', | ||
138 | 50 | string='Sale Orders', readonly=True), | ||
139 | 51 | } | ||
140 | 52 | |||
141 | 53 | _defaults = { | ||
142 | 54 | 'code': """# Python code. Use failed = True to block the sale order. | ||
143 | 55 | # You can use the following variables : | ||
144 | 56 | # - self: ORM model of the record which is checked | ||
145 | 57 | # - order or line: browse_record of the sale order or sale order line | ||
146 | 58 | # - object: same as order or line, browse_record of the sale order or sale order line | ||
147 | 59 | # - pool: ORM model pool (i.e. self.pool) | ||
148 | 60 | # - time: Python time module | ||
149 | 61 | # - cr: database cursor | ||
150 | 62 | # - uid: current user id | ||
151 | 63 | # - context: current context | ||
152 | 64 | """ | ||
153 | 65 | } | ||
154 | 66 | |||
155 | 67 | class sale_order(Model): | ||
156 | 68 | _inherit = "sale.order" | ||
157 | 69 | |||
158 | 70 | _order = 'main_exception_id asc, date_order desc, name desc' | ||
159 | 71 | |||
160 | 72 | def _get_main_error(self, cr, uid, ids, name, args, context=None): | ||
161 | 73 | res = {} | ||
162 | 74 | for sale_order in self.browse(cr, uid, ids, context=context): | ||
163 | 75 | if sale_order.state == 'draft' and sale_order.exceptions_ids: | ||
164 | 76 | res[sale_order.id] = sale_order.exceptions_ids[0].id | ||
165 | 77 | else: | ||
166 | 78 | res[sale_order.id] = False | ||
167 | 79 | return res | ||
168 | 80 | |||
169 | 81 | _columns = { | ||
170 | 82 | 'main_exception_id': fields.function(_get_main_error, | ||
171 | 83 | type='many2one', | ||
172 | 84 | relation="sale.exception", | ||
173 | 85 | string='Main Exception', | ||
174 | 86 | store={ | ||
175 | 87 | 'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['exceptions_ids', 'state'], 10), | ||
176 | 88 | }), | ||
177 | 89 | 'exceptions_ids': fields.many2many('sale.exception', 'sale_order_exception_rel', | ||
178 | 90 | 'sale_order_id', 'exception_id', | ||
179 | 91 | string='Exceptions'), | ||
180 | 92 | 'ignore_exceptions': fields.boolean('Ignore Exceptions'), | ||
181 | 93 | } | ||
182 | 94 | |||
183 | 95 | def test_all_draft_orders(self, cr, uid, context=None): | ||
184 | 96 | ids = self.search(cr, uid, [('state', '=', 'draft')]) | ||
185 | 97 | self.test_exceptions(cr, uid, ids) | ||
186 | 98 | return True | ||
187 | 99 | |||
188 | 100 | def _popup_exceptions(self, cr, uid, order_id, context=None): | ||
189 | 101 | model_data_obj = self.pool.get('ir.model.data') | ||
190 | 102 | list_obj = self.pool.get('sale.exception.confirm') | ||
191 | 103 | ctx = context.copy() | ||
192 | 104 | ctx.update({'active_id': order_id, | ||
193 | 105 | 'active_ids': [order_id]}) | ||
194 | 106 | list_id = list_obj.create(cr, uid, {}, context=ctx) | ||
195 | 107 | view_id = model_data_obj.get_object_reference( | ||
196 | 108 | cr, uid, 'sale_exceptions', 'view_sale_exception_confirm')[1] | ||
197 | 109 | action = { | ||
198 | 110 | 'name': _("Exceptions On Sale Order"), | ||
199 | 111 | 'type': 'ir.actions.act_window', | ||
200 | 112 | 'view_type': 'form', | ||
201 | 113 | 'view_mode': 'form', | ||
202 | 114 | 'res_model': 'sale.exception.confirm', | ||
203 | 115 | 'view_id': [view_id], | ||
204 | 116 | 'target': 'new', | ||
205 | 117 | 'nodestroy': True, | ||
206 | 118 | 'res_id': list_id, | ||
207 | 119 | } | ||
208 | 120 | return action | ||
209 | 121 | |||
210 | 122 | def action_button_confirm(self, cr, uid, ids, context=None): | ||
211 | 123 | exception_ids = self.detect_exceptions(cr, uid, ids, context=context) | ||
212 | 124 | if exception_ids: | ||
213 | 125 | return self._popup_exceptions(cr, uid, ids[0], context=context) | ||
214 | 126 | else: | ||
215 | 127 | return super(sale_order, self).action_button_confirm(cr, uid, ids, context=context) | ||
216 | 128 | |||
217 | 129 | def test_exceptions(self, cr, uid, ids, context=None): | ||
218 | 130 | """ | ||
219 | 131 | Condition method for the workflow from draft to confirm | ||
220 | 132 | """ | ||
221 | 133 | exception_ids = self.detect_exceptions(cr, uid, ids, context=context) | ||
222 | 134 | if exception_ids: | ||
223 | 135 | return False | ||
224 | 136 | return True | ||
225 | 137 | |||
226 | 138 | def detect_exceptions(self, cr, uid, ids, context=None): | ||
227 | 139 | exception_obj = self.pool.get('sale.exception') | ||
228 | 140 | order_exception_ids = exception_obj.search(cr, uid, | ||
229 | 141 | [('model', '=', 'sale.order')], context=context) | ||
230 | 142 | line_exception_ids = exception_obj.search(cr, uid, | ||
231 | 143 | [('model', '=', 'sale.order.line')], context=context) | ||
232 | 144 | |||
233 | 145 | order_exceptions = exception_obj.browse(cr, uid, order_exception_ids, context=context) | ||
234 | 146 | line_exceptions = exception_obj.browse(cr, uid, line_exception_ids, context=context) | ||
235 | 147 | |||
236 | 148 | exception_ids = False | ||
237 | 149 | for order in self.browse(cr, uid, ids): | ||
238 | 150 | if order.ignore_exceptions: | ||
239 | 151 | continue | ||
240 | 152 | exception_ids = self._detect_exceptions(cr, uid, order, | ||
241 | 153 | order_exceptions, line_exceptions, context=context) | ||
242 | 154 | |||
243 | 155 | self.write(cr, uid, [order.id], {'exceptions_ids': [(6, 0, exception_ids)]}) | ||
244 | 156 | return exception_ids | ||
245 | 157 | |||
246 | 158 | def _exception_rule_eval_context(self, cr, uid, obj_name, obj, context=None): | ||
247 | 159 | if context is None: | ||
248 | 160 | context = {} | ||
249 | 161 | |||
250 | 162 | return {obj_name: obj, | ||
251 | 163 | 'self': self.pool.get(obj._name), | ||
252 | 164 | 'object': obj, | ||
253 | 165 | 'obj': obj, | ||
254 | 166 | 'pool': self.pool, | ||
255 | 167 | 'cr': cr, | ||
256 | 168 | 'uid': uid, | ||
257 | 169 | 'user': self.pool.get('res.users').browse(cr, uid, uid), | ||
258 | 170 | 'time': time, | ||
259 | 171 | # copy context to prevent side-effects of eval | ||
260 | 172 | 'context': dict(context),} | ||
261 | 173 | |||
262 | 174 | def _rule_eval(self, cr, uid, rule, obj_name, obj, context): | ||
263 | 175 | expr = rule.code | ||
264 | 176 | space = self._exception_rule_eval_context(cr, uid, obj_name, obj, | ||
265 | 177 | context=context) | ||
266 | 178 | try: | ||
267 | 179 | eval(expr, space, | ||
268 | 180 | mode='exec', nocopy=True) # nocopy allows to return 'result' | ||
269 | 181 | except Exception, e: | ||
270 | 182 | raise except_osv(_('Error'), _('Error when evaluating the sale exception rule :\n %s \n(%s)') % | ||
271 | 183 | (rule.name, e)) | ||
272 | 184 | return space.get('failed', False) | ||
273 | 185 | |||
274 | 186 | def _detect_exceptions(self, cr, uid, order, order_exceptions, line_exceptions, context=None): | ||
275 | 187 | exception_ids = [] | ||
276 | 188 | for rule in order_exceptions: | ||
277 | 189 | if self._rule_eval(cr, uid, rule, 'order', order, context): | ||
278 | 190 | exception_ids.append(rule.id) | ||
279 | 191 | |||
280 | 192 | for order_line in order.order_line: | ||
281 | 193 | for rule in line_exceptions: | ||
282 | 194 | if rule.id in exception_ids: | ||
283 | 195 | continue # we do not matter if the exception as already been | ||
284 | 196 | # found for an order line of this order | ||
285 | 197 | if self._rule_eval(cr, uid, rule, 'line', order_line, context): | ||
286 | 198 | exception_ids.append(rule.id) | ||
287 | 199 | |||
288 | 200 | return exception_ids | ||
289 | 201 | |||
290 | 202 | def copy(self, cr, uid, id, default=None, context=None): | ||
291 | 203 | if default is None: | ||
292 | 204 | default = {} | ||
293 | 205 | default.update({ | ||
294 | 206 | 'ignore_exceptions': False, | ||
295 | 207 | }) | ||
296 | 208 | return super(sale_order, self).copy(cr, uid, id, default=default, context=context) | ||
297 | 209 | 0 | ||
298 | === removed file 'sale_exceptions/sale_exceptions_data.xml' | |||
299 | --- sale_exceptions/sale_exceptions_data.xml 2012-09-06 12:34:40 +0000 | |||
300 | +++ sale_exceptions/sale_exceptions_data.xml 1970-01-01 00:00:00 +0000 | |||
301 | @@ -1,19 +0,0 @@ | |||
302 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
303 | 2 | <openerp> | ||
304 | 3 | <data noupdate="1"> | ||
305 | 4 | |||
306 | 5 | <record forcecreate="True" id="ir_cron_test_orders" model="ir.cron"> | ||
307 | 6 | <field name="name">Test Draft Orders</field> | ||
308 | 7 | <field eval="False" name="active"/> | ||
309 | 8 | <field name="user_id" ref="base.user_root"/> | ||
310 | 9 | <field name="interval_number">20</field> | ||
311 | 10 | <field name="interval_type">minutes</field> | ||
312 | 11 | <field name="numbercall">-1</field> | ||
313 | 12 | <field eval="False" name="doall"/> | ||
314 | 13 | <field eval="'sale.order'" name="model"/> | ||
315 | 14 | <field eval="'test_all_draft_orders'" name="function"/> | ||
316 | 15 | <field eval="'()'" name="args"/> | ||
317 | 16 | </record> | ||
318 | 17 | |||
319 | 18 | </data> | ||
320 | 19 | </openerp> | ||
321 | 20 | 0 | ||
322 | === removed file 'sale_exceptions/sale_view.xml' | |||
323 | --- sale_exceptions/sale_view.xml 2012-12-26 13:19:13 +0000 | |||
324 | +++ sale_exceptions/sale_view.xml 1970-01-01 00:00:00 +0000 | |||
325 | @@ -1,106 +0,0 @@ | |||
326 | 1 | <?xml version="1.0" ?> | ||
327 | 2 | <openerp> | ||
328 | 3 | <data> | ||
329 | 4 | |||
330 | 5 | <record id="view_sale_exception_tree" model="ir.ui.view"> | ||
331 | 6 | <field name="name">sale.exception.tree</field> | ||
332 | 7 | <field name="model">sale.exception</field> | ||
333 | 8 | <field name="type">tree</field> | ||
334 | 9 | <field name="arch" type="xml"> | ||
335 | 10 | <tree string="Sale Exception"> | ||
336 | 11 | <field name="active"/> | ||
337 | 12 | <field name="name"/> | ||
338 | 13 | <field name="description"/> | ||
339 | 14 | <field name="model"/> | ||
340 | 15 | <field name="sequence"/> | ||
341 | 16 | </tree> | ||
342 | 17 | </field> | ||
343 | 18 | </record> | ||
344 | 19 | |||
345 | 20 | <record id="view_sale_exception_form" model="ir.ui.view"> | ||
346 | 21 | <field name="name">sale.exception.form</field> | ||
347 | 22 | <field name="model">sale.exception</field> | ||
348 | 23 | <field name="type">form</field> | ||
349 | 24 | <field name="arch" type="xml"> | ||
350 | 25 | <form string="Sale Exception Setup"> | ||
351 | 26 | <group colspan="4" col="2"> | ||
352 | 27 | <field name="name"/> | ||
353 | 28 | <field name="description"/> | ||
354 | 29 | </group> | ||
355 | 30 | <group col="4" colspan="4" groups="base.group_sale_manager"> | ||
356 | 31 | <field name="active"/> | ||
357 | 32 | <field name="sequence"/> | ||
358 | 33 | <group colspan="4" col="2" groups="base.group_system"> | ||
359 | 34 | <field name="model"/> | ||
360 | 35 | <field name="code"/> | ||
361 | 36 | </group> | ||
362 | 37 | </group> | ||
363 | 38 | <group colspan="4" col="2"> | ||
364 | 39 | <separator string="Affected Sales Orders"/> | ||
365 | 40 | <newline/> | ||
366 | 41 | <field name="sale_order_ids" nolabel="1" domain="[('state', '=', 'draft')]"/> | ||
367 | 42 | </group> | ||
368 | 43 | </form> | ||
369 | 44 | </field> | ||
370 | 45 | </record> | ||
371 | 46 | |||
372 | 47 | <record id="action_sale_test_tree" model="ir.actions.act_window"> | ||
373 | 48 | <field name="name">Exception Rules</field> | ||
374 | 49 | <field name="res_model">sale.exception</field> | ||
375 | 50 | <field name="view_type">form</field> | ||
376 | 51 | <field name="view_mode">tree,form</field> | ||
377 | 52 | <field name="view_id" ref="view_sale_exception_tree"/> | ||
378 | 53 | <field name="context">{'active_test': False}</field> | ||
379 | 54 | </record> | ||
380 | 55 | |||
381 | 56 | <menuitem action="action_sale_test_tree" id="menu_sale_test" parent="base.menu_sale_config_sales" /> | ||
382 | 57 | |||
383 | 58 | |||
384 | 59 | <record id="view_order_form" model="ir.ui.view"> | ||
385 | 60 | <field name="name">sale_exceptions.view_order_form</field> | ||
386 | 61 | <field name="model">sale.order</field> | ||
387 | 62 | <field name="type">form</field> | ||
388 | 63 | <field name="priority">100</field> | ||
389 | 64 | <field name="inherit_id" ref="sale.view_order_form"/> | ||
390 | 65 | <field name="arch" type="xml"> | ||
391 | 66 | <field name="name" position="after"> | ||
392 | 67 | <field name="main_exception_id" nolabel="1" | ||
393 | 68 | attrs="{'invisible':[('main_exception_id','=', False)]}"/> | ||
394 | 69 | </field> | ||
395 | 70 | <xpath expr="//page[@string='Other Information']/group" | ||
396 | 71 | position="inside"> | ||
397 | 72 | <group name="exception" colspan="2" col="2"> | ||
398 | 73 | <separator string="Exception" colspan="2"/> | ||
399 | 74 | <field name="exceptions_ids" colspan="2" nolabel="1"/> | ||
400 | 75 | </group> | ||
401 | 76 | </xpath> | ||
402 | 77 | </field> | ||
403 | 78 | </record> | ||
404 | 79 | |||
405 | 80 | <record id="view_order_tree" model="ir.ui.view"> | ||
406 | 81 | <field name="name">sale_exceptions.view_order_tree</field> | ||
407 | 82 | <field name="model">sale.order</field> | ||
408 | 83 | <field name="type">tree</field> | ||
409 | 84 | <field name="inherit_id" ref="sale.view_order_tree"/> | ||
410 | 85 | <field name="arch" type="xml"> | ||
411 | 86 | <field name="state" position="after"> | ||
412 | 87 | <field name="main_exception_id"/> | ||
413 | 88 | </field> | ||
414 | 89 | </field> | ||
415 | 90 | </record> | ||
416 | 91 | |||
417 | 92 | <record id="view_sales_order_filter" model="ir.ui.view"> | ||
418 | 93 | <field name="name">sale_exceptions.view_sales_order_filter</field> | ||
419 | 94 | <field name="model">sale.order</field> | ||
420 | 95 | <field name="inherit_id" ref="sale.view_sales_order_filter" /> | ||
421 | 96 | <field name="type">search</field> | ||
422 | 97 | <field eval="32" name="priority"/> | ||
423 | 98 | <field name="arch" type="xml"> | ||
424 | 99 | <filter icon="terp-check" string="Sales" position="after"> | ||
425 | 100 | <separator orientation="vertical"/> | ||
426 | 101 | <filter icon="terp-emblem-important" name="tofix" string="TO FIX" domain="[('main_exception_id','!=',False)]"/> | ||
427 | 102 | </filter> | ||
428 | 103 | </field> | ||
429 | 104 | </record> | ||
430 | 105 | </data> | ||
431 | 106 | </openerp> | ||
432 | 107 | 0 | ||
433 | === removed file 'sale_exceptions/sale_workflow.xml' | |||
434 | --- sale_exceptions/sale_workflow.xml 2011-03-07 12:19:42 +0000 | |||
435 | +++ sale_exceptions/sale_workflow.xml 1970-01-01 00:00:00 +0000 | |||
436 | @@ -1,9 +0,0 @@ | |||
437 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
438 | 2 | <openerp> | ||
439 | 3 | <data> | ||
440 | 4 | <record id="sale.trans_draft_router" model="workflow.transition"> | ||
441 | 5 | <field name="signal">order_confirm</field> | ||
442 | 6 | <field name="condition">test_exceptions()</field> | ||
443 | 7 | </record> | ||
444 | 8 | </data> | ||
445 | 9 | </openerp> | ||
446 | 10 | 0 | ||
447 | === removed directory 'sale_exceptions/security' | |||
448 | === removed file 'sale_exceptions/security/ir.model.access.csv' | |||
449 | --- sale_exceptions/security/ir.model.access.csv 2012-02-13 09:31:57 +0000 | |||
450 | +++ sale_exceptions/security/ir.model.access.csv 1970-01-01 00:00:00 +0000 | |||
451 | @@ -1,3 +0,0 @@ | |||
452 | 1 | "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" | ||
453 | 2 | "access_sale_exception","sale.exception","model_sale_exception","base.group_user",1,0,0,0 | ||
454 | 3 | "access_sale_exception_manager","sale.exception","model_sale_exception","base.group_sale_manager",1,1,1,1 | ||
455 | 4 | 0 | ||
456 | === removed directory 'sale_exceptions/settings' | |||
457 | === removed file 'sale_exceptions/settings/sale.exception.csv' | |||
458 | --- sale_exceptions/settings/sale.exception.csv 2012-05-19 11:13:51 +0000 | |||
459 | +++ sale_exceptions/settings/sale.exception.csv 1970-01-01 00:00:00 +0000 | |||
460 | @@ -1,5 +0,0 @@ | |||
461 | 1 | "id","name","description","sequence","model","code","active" | ||
462 | 2 | "excep_no_zip","No ZIP code on destination",,50,"sale.order","if not order.partner_shipping_id.zip: | ||
463 | 3 | failed=True",False | ||
464 | 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: | ||
465 | 5 | failed=True",False | ||
466 | 6 | 0 | ||
467 | === removed directory 'sale_exceptions/wizard' | |||
468 | === removed file 'sale_exceptions/wizard/__init__.py' | |||
469 | --- sale_exceptions/wizard/__init__.py 2012-02-24 09:31:32 +0000 | |||
470 | +++ sale_exceptions/wizard/__init__.py 1970-01-01 00:00:00 +0000 | |||
471 | @@ -1,1 +0,0 @@ | |||
472 | 1 | import sale_exception_confirm | ||
473 | 2 | 0 | ||
474 | === removed file 'sale_exceptions/wizard/sale_exception_confirm.py' | |||
475 | --- sale_exceptions/wizard/sale_exception_confirm.py 2012-05-16 12:53:59 +0000 | |||
476 | +++ sale_exceptions/wizard/sale_exception_confirm.py 1970-01-01 00:00:00 +0000 | |||
477 | @@ -1,56 +0,0 @@ | |||
478 | 1 | # -*- encoding: utf-8 -*- | ||
479 | 2 | ############################################################################## | ||
480 | 3 | # | ||
481 | 4 | # Copyright Camptocamp SA | ||
482 | 5 | # @author: Guewen Baconnier | ||
483 | 6 | # | ||
484 | 7 | # This program is free software: you can redistribute it and/or modify | ||
485 | 8 | # it under the terms of the GNU General Public License as published by | ||
486 | 9 | # the Free Software Foundation, either version 3 of the License, or | ||
487 | 10 | # (at your option) any later version. | ||
488 | 11 | # | ||
489 | 12 | # This program is distributed in the hope that it will be useful, | ||
490 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
491 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
492 | 15 | # GNU General Public License for more details. | ||
493 | 16 | # | ||
494 | 17 | # You should have received a copy of the GNU General Public License | ||
495 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
496 | 19 | # | ||
497 | 20 | ############################################################################## | ||
498 | 21 | |||
499 | 22 | import netsvc | ||
500 | 23 | |||
501 | 24 | from osv import osv, fields | ||
502 | 25 | |||
503 | 26 | |||
504 | 27 | class SaleExceptionConfirm(osv.osv_memory): | ||
505 | 28 | |||
506 | 29 | _name = 'sale.exception.confirm' | ||
507 | 30 | |||
508 | 31 | _columns = { | ||
509 | 32 | 'sale_id': fields.many2one('sale.order', 'Sale'), | ||
510 | 33 | 'exception_ids': fields.many2many('sale.exception', string='Exceptions to resolve', readonly=True), | ||
511 | 34 | 'ignore': fields.boolean('Ignore Exceptions'), | ||
512 | 35 | } | ||
513 | 36 | |||
514 | 37 | def default_get(self, cr, uid, fields, context=None): | ||
515 | 38 | res = super(SaleExceptionConfirm, self).default_get(cr, uid, fields, context=context) | ||
516 | 39 | order_obj = self.pool.get('sale.order') | ||
517 | 40 | sale_id = context.get('active_id', False) | ||
518 | 41 | if sale_id: | ||
519 | 42 | sale = order_obj.browse(cr, uid, sale_id, context=context) | ||
520 | 43 | exception_ids = [e.id for e in sale.exceptions_ids] | ||
521 | 44 | res.update({'exception_ids': [(6, 0, exception_ids)]}) | ||
522 | 45 | |||
523 | 46 | res.update({'sale_id': sale_id}) | ||
524 | 47 | return res | ||
525 | 48 | |||
526 | 49 | def action_confirm(self, cr, uid, ids, context=None): | ||
527 | 50 | form = self.browse(cr, uid, ids[0], context=context) | ||
528 | 51 | if form.ignore: | ||
529 | 52 | self.pool.get('sale.order').write(cr, uid, form.sale_id.id, | ||
530 | 53 | {'ignore_exceptions': True}, context=context) | ||
531 | 54 | return {'type': 'ir.actions.act_window_close'} | ||
532 | 55 | |||
533 | 56 | SaleExceptionConfirm() | ||
534 | 57 | 0 | ||
535 | === removed file 'sale_exceptions/wizard/sale_exception_confirm_view.xml' | |||
536 | --- sale_exceptions/wizard/sale_exception_confirm_view.xml 2012-12-26 09:30:24 +0000 | |||
537 | +++ sale_exceptions/wizard/sale_exception_confirm_view.xml 1970-01-01 00:00:00 +0000 | |||
538 | @@ -1,44 +0,0 @@ | |||
539 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
540 | 2 | <openerp> | ||
541 | 3 | <data> | ||
542 | 4 | |||
543 | 5 | <record id="view_sale_exception_confirm" model="ir.ui.view"> | ||
544 | 6 | <field name="name">Sale Exceptions</field> | ||
545 | 7 | <field name="model">sale.exception.confirm</field> | ||
546 | 8 | <field name="type">form</field> | ||
547 | 9 | <field name="arch" type="xml"> | ||
548 | 10 | <form string="Sale Exceptions On Sale Order" version="7.0"> | ||
549 | 11 | <group> | ||
550 | 12 | <field name="exception_ids" nolabel="1" colspan="4"> | ||
551 | 13 | <form string="Sale Exception"> | ||
552 | 14 | <field name="name" colspan="4"/> | ||
553 | 15 | <field name="description" colspan="4"/> | ||
554 | 16 | </form> | ||
555 | 17 | <tree string="Sale Exceptions"> | ||
556 | 18 | <field name="name"/> | ||
557 | 19 | <field name="description"/> | ||
558 | 20 | </tree> | ||
559 | 21 | </field> | ||
560 | 22 | <newline/> | ||
561 | 23 | <field name="ignore" groups='base.group_sale_manager'/> | ||
562 | 24 | </group> | ||
563 | 25 | <footer> | ||
564 | 26 | <button name="action_confirm" string="_Ok" | ||
565 | 27 | colspan="1" type="object" icon="gtk-ok" /> | ||
566 | 28 | </footer> | ||
567 | 29 | </form> | ||
568 | 30 | </field> | ||
569 | 31 | </record> | ||
570 | 32 | |||
571 | 33 | <record id="action_sale_exception_confirm" model="ir.actions.act_window"> | ||
572 | 34 | <field name="name">Sale Exceptions</field> | ||
573 | 35 | <field name="type">ir.actions.act_window</field> | ||
574 | 36 | <field name="res_model">sale.exception.confirm</field> | ||
575 | 37 | <field name="view_type">form</field> | ||
576 | 38 | <field name="view_mode">form</field> | ||
577 | 39 | <field name="view_id" ref="view_sale_exception_confirm"/> | ||
578 | 40 | <field name="target">new</field> | ||
579 | 41 | </record> | ||
580 | 42 | |||
581 | 43 | </data> | ||
582 | 44 | </openerp> |
As your reasoning on community list, I approve it blindly.
Regards.