Merge lp:~openerp-dev/openobject-addons/trunk-bug-776245-ron into lp:openobject-addons
- trunk-bug-776245-ron
- Merge into trunk
Status: | Rejected |
---|---|
Rejected by: | Fabien (Open ERP) |
Proposed branch: | lp:~openerp-dev/openobject-addons/trunk-bug-776245-ron |
Merge into: | lp:openobject-addons |
Diff against target: |
371 lines (+183/-36) 4 files modified
stock/wizard/stock_inventory_line_split.py (+32/-12) stock/wizard/stock_inventory_line_split_view.xml (+1/-1) stock/wizard/stock_move.py (+134/-23) stock/wizard/stock_move_view.xml (+16/-0) |
To merge this branch: | bzr merge lp:~openerp-dev/openobject-addons/trunk-bug-776245-ron |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Rohan Nayani(Open ERP) (community) | Needs Resubmitting | ||
Rucha (Open ERP) (community) | Needs Fixing | ||
Review via email: mp+61725@code.launchpad.net |
Commit message
Description of the change
Rohan Nayani(Open ERP) (ron-tinyerp) : | # |
Rohan Nayani(Open ERP) (ron-tinyerp) : | # |
Rucha (Open ERP) (rpa-openerp) wrote : | # |
when we are providing more quantity than move qty the warning is being displayed nicely (thats good), but when I click on ok in that form, it spits based on some another values than the specified one.
check following scenario:
Create incoming shipment for 5 PC1
spit the move (value of "Existing Lots" is False) as follows:
lots qty
A 3
B 3
the warning will appear and then if you click on "ok" it will spit like:
prodlot qty
A 3
2
which is wrong,
if you follow the same steps again for another picking, it will have more weird behaviour!
fix this please
Rohan Nayani(Open ERP) (ron-tinyerp) : | # |
Rucha (Open ERP) (rpa-openerp) wrote : | # |
1) this wizard is not working for physical inventory, its giving traceback
2) some suggestions for names of method:
lot_check_qty => check_lot_qty
get_split_line => get_split_lines
back_split => go_back/back
3) word "order" doesn't suit in the warning message, this wizard is generic and used in inventory too
4) def lot_check_qty:
why there is a search and read on ir.model.data to get view reference, we already have methods in ir.model.data to get id
5) def get_split_line:
I think we can simplify this method and remove unused arguments
6) if quantity_rest == 0 or quantity_rest < 0:
can't it be simply if quantity_rest <= 0 ?? ;-)
7) default_get of stock.move.
uom = self.pool.
will be move.product_
again check this variable is no longer used in that function
8) res.update(
will be context.get('line', [])
also its better to use 'lines' instead of 'line'
9) if possible I would like to reduce lots of code in def split and lot_check_qty, please check if there is a chance to make both common,
can't we use split_lot instead of new method lot_check_qty?
Rohan Nayani(Open ERP) (ron-tinyerp) : | # |
Fabien (Open ERP) (fp-tinyerp) wrote : | # |
I applied a simpler patch in r5224
Preview Diff
1 | === modified file 'stock/wizard/stock_inventory_line_split.py' |
2 | --- stock/wizard/stock_inventory_line_split.py 2011-02-15 12:06:58 +0000 |
3 | +++ stock/wizard/stock_inventory_line_split.py 2011-07-06 08:31:50 +0000 |
4 | @@ -22,14 +22,13 @@ |
5 | from osv import fields, osv |
6 | |
7 | from tools.translate import _ |
8 | +import decimal_precision as dp |
9 | import time |
10 | |
11 | class stock_inventory_line_split(osv.osv_memory): |
12 | - _inherit = "stock.move.split" |
13 | _name = "stock.inventory.line.split" |
14 | _description = "Split inventory lines" |
15 | |
16 | - |
17 | def default_get(self, cr, uid, fields, context=None): |
18 | """ To check the availability of production lot. |
19 | @param self: The object pointer. |
20 | @@ -48,10 +47,25 @@ |
21 | res.update({'product_id':line.product_id.id}) |
22 | if 'product_uom' in fields: |
23 | res.update({'product_uom': line.product_uom.id}) |
24 | - if 'qty' in fields: |
25 | - res.update({'qty': line.product_qty}) |
26 | + if 'product_qty' in fields: |
27 | + res.update({'product_qty': line.product_qty}) |
28 | + if context.get('lines'): |
29 | + if 'line_ids' in fields: |
30 | + res.update({'line_ids': context.get('lines', [])}) |
31 | + if ('use_exist_true' in context['lines'][0].keys()) and ('line_exist_ids' in fields): |
32 | + res.update({'use_exist': True, 'line_exist_ids': context.get('lines', [])}) |
33 | + |
34 | return res |
35 | |
36 | + _columns = { |
37 | + 'product_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product UoM')), |
38 | + 'product_id': fields.many2one('product.product', 'Product', required=True, select=True), |
39 | + 'product_uom': fields.many2one('product.uom', 'UoM'), |
40 | + 'line_ids': fields.one2many('stock.move.split.lines', 'lot_id', 'Production Lots'), |
41 | + 'line_exist_ids': fields.one2many('stock.move.split.lines.exist', 'lot_id', 'Production Lots'), |
42 | + 'use_exist' : fields.boolean('Existing Lots', help="Check this option to select existing lots in the list below, otherwise you should enter new ones line by line."), |
43 | + } |
44 | + |
45 | def split(self, cr, uid, ids, line_ids, context=None): |
46 | """ To split stock inventory lines according to production lot. |
47 | @param self: The object pointer. |
48 | @@ -71,25 +85,19 @@ |
49 | line_qty = inv_line.product_qty |
50 | quantity_rest = inv_line.product_qty |
51 | new_line = [] |
52 | - if data.use_exist: |
53 | - lines = [l for l in data.line_exist_ids if l] |
54 | - else: |
55 | - lines = [l for l in data.line_ids if l] |
56 | + lines = self.pool.get('stock.move.split').get_split_lines(cr, uid, data) |
57 | for line in lines: |
58 | quantity = line.quantity |
59 | if quantity <= 0 or line_qty == 0: |
60 | continue |
61 | quantity_rest -= quantity |
62 | - if quantity_rest < 0: |
63 | - quantity_rest = quantity |
64 | - break |
65 | default_val = { |
66 | 'product_qty': quantity, |
67 | } |
68 | if quantity_rest > 0: |
69 | current_line = line_obj.copy(cr, uid, inv_line.id, default_val) |
70 | new_line.append(current_line) |
71 | - if quantity_rest == 0: |
72 | + if quantity_rest <= 0: |
73 | current_line = inv_line.id |
74 | prodlot_id = False |
75 | if data.use_exist: |
76 | @@ -108,6 +116,18 @@ |
77 | line_obj.write(cr, uid, [inv_line.id], update_val) |
78 | |
79 | return new_line |
80 | + |
81 | + def split_lot(self, cr, uid, ids, context=None): |
82 | + """ To split a lot |
83 | + @param self: The object pointer. |
84 | + @param cr: A database cursor |
85 | + @param uid: ID of the user currently logged in |
86 | + @param ids: An ID or list of IDs if we want more than one |
87 | + @param context: A standard dictionary |
88 | + @return: |
89 | + """ |
90 | + return self.pool.get('stock.move.split').check_lot_qty(cr, uid, ids, context=context) |
91 | + |
92 | stock_inventory_line_split() |
93 | |
94 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
95 | |
96 | === modified file 'stock/wizard/stock_inventory_line_split_view.xml' |
97 | --- stock/wizard/stock_inventory_line_split_view.xml 2011-01-14 00:11:01 +0000 |
98 | +++ stock/wizard/stock_inventory_line_split_view.xml 2011-07-06 08:31:50 +0000 |
99 | @@ -15,7 +15,7 @@ |
100 | <field name="use_exist"/> |
101 | </group> |
102 | <group colspan="1" col="2"> |
103 | - <field name="qty" readonly="1"/> |
104 | + <field name="product_qty" readonly="1"/> |
105 | </group> |
106 | <group colspan="1" col="2"> |
107 | <field name="product_uom" readonly="1"/> |
108 | |
109 | === modified file 'stock/wizard/stock_move.py' |
110 | --- stock/wizard/stock_move.py 2011-05-02 18:46:43 +0000 |
111 | +++ stock/wizard/stock_move.py 2011-07-06 08:31:50 +0000 |
112 | @@ -20,6 +20,7 @@ |
113 | ############################################################################## |
114 | |
115 | from osv import fields, osv |
116 | +from tools.translate import _ |
117 | |
118 | import decimal_precision as dp |
119 | |
120 | @@ -169,6 +170,67 @@ |
121 | |
122 | stock_move_scrap() |
123 | |
124 | +class stock_move_split_message(osv.osv_memory): |
125 | + _name = "stock.move.split.message" |
126 | + _description = "You are spliting more quantity then order its give warning" |
127 | + |
128 | + def default_get(self, cr, uid, fields, context=None): |
129 | + """ Get default values |
130 | + @param self: The object pointer. |
131 | + @param cr: A database cursor |
132 | + @param uid: ID of the user currently logged in |
133 | + @param fields: List of fields for default value |
134 | + @param context: A standard dictionary |
135 | + @return: Default values of fields |
136 | + """ |
137 | + if context is None: |
138 | + context = {} |
139 | + res ={} |
140 | + obj = self.pool.get('stock.move') |
141 | + if context.get('active_model') == 'stock.inventory.line': |
142 | + obj = self.pool.get('stock.inventory.line') |
143 | + if context.get('active_id'): |
144 | + split_qty = 0.0 |
145 | + move = obj.browse(cr, uid, context['active_id'], context=context) |
146 | + if context.get('lines'): |
147 | + for qty in context.get('lines'): |
148 | + split_qty += qty['quantity'] |
149 | + if 'message' in fields: |
150 | + res.update({'message': _("Warning ! \nYou are spliting %.2f "\ |
151 | + "quantity of '%s' but you have only %.2f quantity in this line."\ |
152 | + "\nIf you continue, your information will be lost for extra quantity.") %(split_qty, move.product_id.name, move.product_qty)}) |
153 | + return res |
154 | + |
155 | + _columns = { |
156 | + 'message' : fields.text('Message', size=64, readonly=True), |
157 | + } |
158 | + |
159 | + def continue_split(self, cr, uid, ids, context=None): |
160 | + if context is None: |
161 | + context = {} |
162 | + obj = self.pool.get('stock.move.split') |
163 | + if context.get('active_model') == 'stock.inventory.line': |
164 | + obj = self.pool.get('stock.inventory.line.split') |
165 | + obj.split(cr, uid, ids, context.get('active_ids'), context=context) |
166 | + return {'type': 'ir.actions.act_window_close'} |
167 | + |
168 | + def go_back(self,cr, uid, ids, context=None): |
169 | + if context is None: |
170 | + context = {} |
171 | + model = 'stock.move.split' |
172 | + if context.get('active_model') == 'stock.inventory.line': |
173 | + model = 'stock.inventory.line.split' |
174 | + return { |
175 | + 'view_type': 'form', |
176 | + 'view_mode': 'form', |
177 | + 'res_model': model, |
178 | + 'type': 'ir.actions.act_window', |
179 | + 'target': 'new', |
180 | + 'context': context |
181 | + } |
182 | + |
183 | +stock_move_split_message() |
184 | + |
185 | |
186 | class split_in_production_lot(osv.osv_memory): |
187 | _name = "stock.move.split" |
188 | @@ -185,8 +247,7 @@ |
189 | """ |
190 | if context is None: |
191 | context = {} |
192 | - |
193 | - res = super(split_in_production_lot, self).default_get(cr, uid, fields, context=context) |
194 | + res = {} |
195 | if context.get('active_id'): |
196 | move = self.pool.get('stock.move').browse(cr, uid, context['active_id'], context=context) |
197 | if 'product_id' in fields: |
198 | @@ -197,6 +258,11 @@ |
199 | res.update({'qty': move.product_qty}) |
200 | if 'use_exist' in fields: |
201 | res.update({'use_exist': (move.picking_id and move.picking_id.type=='out' and True) or False}) |
202 | + if context.get('lines'): |
203 | + if 'line_ids' in fields: |
204 | + res.update({'line_ids': context.get('lines', [])}) |
205 | + if ('use_exist_true' in context['lines'][0].keys()) and ('line_exist_ids' in fields): |
206 | + res.update({'use_exist': True, 'line_exist_ids': context.get('lines', [])}) |
207 | return res |
208 | |
209 | _columns = { |
210 | @@ -208,6 +274,65 @@ |
211 | 'use_exist' : fields.boolean('Existing Lots', help="Check this option to select existing lots in the list below, otherwise you should enter new ones line by line."), |
212 | } |
213 | |
214 | + def get_split_lines(self, cr, uid, data): |
215 | + """ |
216 | + @param self: The object pointer. |
217 | + @param cr: A database cursor |
218 | + @param uid: ID of the user currently logged in |
219 | + @param data: data of current object |
220 | + @return: wizard move lines: |
221 | + """ |
222 | + if data.use_exist: |
223 | + lines = [l for l in data.line_exist_ids if l] |
224 | + else: |
225 | + lines = [l for l in data.line_ids if l] |
226 | + return lines |
227 | + |
228 | + def check_lot_qty(self, cr, uid, ids, context=None): |
229 | + """ To split a lot |
230 | + @param self: The object pointer. |
231 | + @param cr: A database cursor |
232 | + @param uid: ID of the user currently logged in |
233 | + @param ids: An ID or list of IDs if we want more than one |
234 | + @param context: A standard dictionary |
235 | + @return:if splitting Quantity bigger then order Quantity Its gives warning |
236 | + """ |
237 | + |
238 | + if context is None: |
239 | + context = {} |
240 | + move_obj = self.pool.get('stock.move') |
241 | + resource_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'view_stock_track_lot_wizard') |
242 | + track_qty = 0.0 |
243 | + result = [] |
244 | + obj = self.pool.get('stock.move') |
245 | + model = self |
246 | + if context.get('active_model') == 'stock.inventory.line': |
247 | + obj = self.pool.get('stock.inventory.line') |
248 | + model = self.pool.get('stock.inventory.line.split') |
249 | + for data in model.browse(cr, uid, ids, context=context): |
250 | + for move in obj.browse(cr, uid, context.get('active_ids'), context=context): |
251 | + lines = self.get_split_lines(cr, uid, data) |
252 | + for line in lines: |
253 | + track_qty += line.quantity |
254 | + if data.use_exist: |
255 | + result.append({'quantity':line.quantity, 'prodlot_id':line.prodlot_id.id, 'use_exist_true': True}) |
256 | + else: |
257 | + result.append({'quantity':line.quantity, 'name':line.name}) |
258 | + if track_qty > move.product_qty: |
259 | + context.update({'lines': result}) |
260 | + return { |
261 | + 'view_type': 'form', |
262 | + 'view_mode': 'form', |
263 | + 'res_model': 'stock.move.split.message', |
264 | + 'views': [(resource_id and resource_id[1] or False,'form')], |
265 | + 'type': 'ir.actions.act_window', |
266 | + 'target': 'new', |
267 | + 'context': context |
268 | + } |
269 | + else: |
270 | + self.split(cr, uid, ids, context.get('active_ids'), context=context) |
271 | + return {'type': 'ir.actions.act_window_close'} |
272 | + |
273 | def split_lot(self, cr, uid, ids, context=None): |
274 | """ To split a lot |
275 | @param self: The object pointer. |
276 | @@ -217,10 +342,7 @@ |
277 | @param context: A standard dictionary |
278 | @return: |
279 | """ |
280 | - if context is None: |
281 | - context = {} |
282 | - self.split(cr, uid, ids, context.get('active_ids'), context=context) |
283 | - return {'type': 'ir.actions.act_window_close'} |
284 | + return self.check_lot_qty(cr, uid, ids, context=context) |
285 | |
286 | def split(self, cr, uid, ids, move_ids, context=None): |
287 | """ To split stock moves into production lot |
288 | @@ -245,10 +367,7 @@ |
289 | quantity_rest = move.product_qty |
290 | uos_qty_rest = move.product_uos_qty |
291 | new_move = [] |
292 | - if data.use_exist: |
293 | - lines = [l for l in data.line_exist_ids if l] |
294 | - else: |
295 | - lines = [l for l in data.line_ids if l] |
296 | + lines = self.get_split_lines(cr, uid, data) |
297 | for line in lines: |
298 | quantity = line.quantity |
299 | if quantity <= 0 or move_qty == 0: |
300 | @@ -256,9 +375,6 @@ |
301 | quantity_rest -= quantity |
302 | uos_qty = quantity / move_qty * move.product_uos_qty |
303 | uos_qty_rest = quantity_rest / move_qty * move.product_uos_qty |
304 | - if quantity_rest < 0: |
305 | - quantity_rest = quantity |
306 | - break |
307 | default_val = { |
308 | 'product_qty': quantity, |
309 | 'product_uos_qty': uos_qty, |
310 | @@ -269,8 +385,7 @@ |
311 | if inventory_id and current_move: |
312 | inventory_obj.write(cr, uid, inventory_id, {'move_ids': [(4, current_move)]}, context=context) |
313 | new_move.append(current_move) |
314 | - |
315 | - if quantity_rest == 0: |
316 | + if quantity_rest <= 0: |
317 | current_move = move.id |
318 | prodlot_id = False |
319 | if data.use_exist: |
320 | @@ -280,16 +395,11 @@ |
321 | 'name': line.name, |
322 | 'product_id': move.product_id.id}, |
323 | context=context) |
324 | - |
325 | move_obj.write(cr, uid, [current_move], {'prodlot_id': prodlot_id, 'state':move.state}) |
326 | - |
327 | - update_val = {} |
328 | if quantity_rest > 0: |
329 | - update_val['product_qty'] = quantity_rest |
330 | - update_val['product_uos_qty'] = uos_qty_rest |
331 | - update_val['state'] = move.state |
332 | - move_obj.write(cr, uid, [move.id], update_val) |
333 | - |
334 | + move_obj.write(cr, uid, [move.id], |
335 | + {'product_qty': quantity_rest, 'product_uos_qty': uos_qty_rest, |
336 | + 'state': move.state }) |
337 | return new_move |
338 | |
339 | split_in_production_lot() |
340 | @@ -323,4 +433,5 @@ |
341 | 'quantity': 1.00, |
342 | 'action' : 'split', |
343 | } |
344 | + |
345 | stock_move_split_lines() |
346 | |
347 | === modified file 'stock/wizard/stock_move_view.xml' |
348 | --- stock/wizard/stock_move_view.xml 2011-03-14 10:27:42 +0000 |
349 | +++ stock/wizard/stock_move_view.xml 2011-07-06 08:31:50 +0000 |
350 | @@ -163,5 +163,21 @@ |
351 | <field name="target">new</field> |
352 | </record> |
353 | |
354 | + <record id="view_stock_track_lot_wizard" model="ir.ui.view"> |
355 | + <field name="name">Tracking a lot</field> |
356 | + <field name="model">stock.move.split.message</field> |
357 | + <field name="type">form</field> |
358 | + <field name="arch" type="xml"> |
359 | + <form string="Tracking a lot"> |
360 | + <newline/> |
361 | + <field colspan="4" name="message" nolabel="1" width="450" height="70"/> |
362 | + <newline/> |
363 | + <separator string="" colspan="4" /> |
364 | + <button name="go_back" string="Back" type="object" icon="gtk-go-back"/> |
365 | + <button name="continue_split" string="Continue" colspan="1" type="object" icon="terp-camera_test"/> |
366 | + </form> |
367 | + </field> |
368 | + </record> |
369 | + |
370 | </data> |
371 | </openerp> |
Put proper warning message, it doesn't suit for incoming shipment