Skip to content

Commit

Permalink
[FIX] stock: state change tracking
Browse files Browse the repository at this point in the history
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
  • Loading branch information
beledouxdenis committed Jan 20, 2016
1 parent c0571d4 commit d349584
Showing 1 changed file with 32 additions and 5 deletions.
37 changes: 32 additions & 5 deletions addons/stock/stock.py
Original file line number Diff line number Diff line change
Expand Up @@ -1435,6 +1435,7 @@ def do_transfer(self, cr, uid, picking_ids, context=None):
"""
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:
Expand All @@ -1461,7 +1462,7 @@ def do_transfer(self, cr, uid, picking_ids, context=None):
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)
Expand All @@ -1470,7 +1471,7 @@ def do_transfer(self, cr, uid, picking_ids, context=None):
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)
Expand Down Expand Up @@ -1978,14 +1979,29 @@ def _create_procurements(self, cr, uid, moves, context=None):
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!'),
Expand Down Expand Up @@ -2023,7 +2039,18 @@ def write(self, cr, uid, ids, vals, context=None):
#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
Expand Down Expand Up @@ -2229,7 +2256,7 @@ def action_confirm(self, cr, uid, ids, context=None):

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
Expand Down

0 comments on commit d349584

Please sign in to comment.