[FIX] stock: state change tracking
The `stock.picking`.`state` field is set to track the change of values (`track_visibility='onchange'`) It's supposed to write the state changes within the picking thread. It does not work properly for function fields, as the onchange tracking is designed to work only with direct user changes, direct `write` operations on the record, while, here, the state value changes according to the picking moves changes, for instance. To solve this, the tracking changes have to be hooked within the `create` & `write` methods of the model on which this function depends on. Therefore, from now, when changes are performed in the moves, on the fields that could lead to the picking state change, we force the tracking of the picking state. In addition, we had the `mail_notrack` key in the context when creating back orders, to avoid displaying the back and forths in the state e.g. when transferring 9 units on 10, the changes were displayed as below: Draft -> Waiting availability Waiting Availability -> Ready to Transfer Ready to Transfer -> Draft Draft -> Partially available Partially Available -> Waiting availability Waiting Availability -> Transferred opw-666317
This commit is contained in:
parent
c0571d4066
commit
d349584f9d
|
@ -1435,6 +1435,7 @@ class stock_picking(osv.osv):
|
|||
"""
|
||||
if not context:
|
||||
context = {}
|
||||
notrack_context = dict(context, mail_notrack=True)
|
||||
stock_move_obj = self.pool.get('stock.move')
|
||||
for picking in self.browse(cr, uid, picking_ids, context=context):
|
||||
if not picking.pack_operation_ids:
|
||||
|
@ -1461,7 +1462,7 @@ class stock_picking(osv.osv):
|
|||
todo_move_ids.append(move.id)
|
||||
elif float_compare(remaining_qty,0, precision_rounding = move.product_id.uom_id.rounding) > 0 and \
|
||||
float_compare(remaining_qty, move.product_qty, precision_rounding = move.product_id.uom_id.rounding) < 0:
|
||||
new_move = stock_move_obj.split(cr, uid, move, remaining_qty, context=context)
|
||||
new_move = stock_move_obj.split(cr, uid, move, remaining_qty, context=notrack_context)
|
||||
todo_move_ids.append(move.id)
|
||||
#Assign move as it was assigned before
|
||||
toassign_move_ids.append(new_move)
|
||||
|
@ -1470,7 +1471,7 @@ class stock_picking(osv.osv):
|
|||
self.rereserve_quants(cr, uid, picking, move_ids=todo_move_ids, context=context)
|
||||
self.do_recompute_remaining_quantities(cr, uid, [picking.id], context=context)
|
||||
if todo_move_ids and not context.get('do_only_split'):
|
||||
self.pool.get('stock.move').action_done(cr, uid, todo_move_ids, context=context)
|
||||
self.pool.get('stock.move').action_done(cr, uid, todo_move_ids, context=notrack_context)
|
||||
elif context.get('do_only_split'):
|
||||
context = dict(context, split=todo_move_ids)
|
||||
self._create_backorder(cr, uid, picking, context=context)
|
||||
|
@ -1978,14 +1979,29 @@ class stock_move(osv.osv):
|
|||
res.append(self._create_procurement(cr, uid, move, context=context))
|
||||
return res
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
picking_obj = self.pool['stock.picking']
|
||||
track = not context.get('mail_notrack') and vals.get('picking_id')
|
||||
if track:
|
||||
picking = picking_obj.browse(cr, uid, vals['picking_id'], context=context)
|
||||
initial_values = {picking.id: {'state': picking.state}}
|
||||
res = super(stock_move, self).create(cr, uid, vals, context=context)
|
||||
if track:
|
||||
picking_obj.message_track(cr, uid, [vals['picking_id']], picking_obj.fields_get(cr, uid, ['state'], context=context), initial_values, context=context)
|
||||
return res
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
picking_obj = self.pool['stock.picking']
|
||||
# Check that we do not modify a stock.move which is done
|
||||
frozen_fields = set(['product_qty', 'product_uom', 'product_uos_qty', 'product_uos', 'location_id', 'location_dest_id', 'product_id'])
|
||||
for move in self.browse(cr, uid, ids, context=context):
|
||||
moves = self.browse(cr, uid, ids, context=context)
|
||||
for move in moves:
|
||||
if move.state == 'done':
|
||||
if frozen_fields.intersection(vals):
|
||||
raise osv.except_osv(_('Operation Forbidden!'),
|
||||
|
@ -2023,7 +2039,18 @@ class stock_move(osv.osv):
|
|||
#Note that, for pulled moves we intentionally don't propagate on the procurement.
|
||||
if propagated_changes_dict:
|
||||
self.write(cr, uid, [move.move_dest_id.id], propagated_changes_dict, context=context)
|
||||
return super(stock_move, self).write(cr, uid, ids, vals, context=context)
|
||||
track_pickings = not context.get('mail_notrack') and any(field in vals for field in ['state', 'picking_id', 'partially_available'])
|
||||
if track_pickings:
|
||||
to_track_picking_ids = set([move.picking_id.id for move in moves if move.picking_id])
|
||||
if vals.get('picking_id'):
|
||||
to_track_picking_ids.add(vals['picking_id'])
|
||||
to_track_picking_ids = list(to_track_picking_ids)
|
||||
pickings = picking_obj.browse(cr, uid, to_track_picking_ids, context=context)
|
||||
initial_values = dict((picking.id, {'state': picking.state}) for picking in pickings)
|
||||
res = super(stock_move, self).write(cr, uid, ids, vals, context=context)
|
||||
if track_pickings:
|
||||
picking_obj.message_track(cr, uid, to_track_picking_ids, picking_obj.fields_get(cr, uid, ['state'], context=context), initial_values, context=context)
|
||||
return res
|
||||
|
||||
def onchange_quantity(self, cr, uid, ids, product_id, product_qty, product_uom, product_uos):
|
||||
""" On change of product quantity finds UoM and UoS quantities
|
||||
|
@ -2229,7 +2256,7 @@ class stock_move(osv.osv):
|
|||
|
||||
for state, write_ids in states.items():
|
||||
if len(write_ids):
|
||||
self.write(cr, uid, write_ids, {'state': state})
|
||||
self.write(cr, uid, write_ids, {'state': state}, context=context)
|
||||
#assign picking in batch for all confirmed move that share the same details
|
||||
for key, move_ids in to_assign.items():
|
||||
procurement_group, location_from, location_to = key
|
||||
|
|
Loading…
Reference in New Issue