[IMP] stock: Hook for reservation
Before a modification on a quant, stock.move and stock.move.line check if they satisfy the condition to impact the quant. However in a new module this condition is hardly editable. The purpose of this commit is to easily add condition to bypass reservation.
This commit is contained in:
@@ -1048,6 +1048,10 @@ class StockMove(models.Model):
|
||||
self.env['stock.move.line'].create(self._prepare_move_line_vals(quantity=quantity, reserved_quant=reserved_quant))
|
||||
return taken_quantity
|
||||
|
||||
def _should_bypass_reservation(self):
|
||||
self.ensure_one()
|
||||
return self.location_id.should_bypass_reservation() or self.product_id.type != 'product'
|
||||
|
||||
def _action_assign(self):
|
||||
""" Reserve stock moves by creating their stock move lines. A stock move is
|
||||
considered reserved once the sum of `product_qty` for all its move lines is
|
||||
@@ -1064,8 +1068,7 @@ class StockMove(models.Model):
|
||||
rounding = roundings[move]
|
||||
missing_reserved_uom_quantity = move.product_uom_qty - reserved_availability[move]
|
||||
missing_reserved_quantity = move.product_uom._compute_quantity(missing_reserved_uom_quantity, move.product_id.uom_id, rounding_method='HALF-UP')
|
||||
if move.location_id.should_bypass_reservation()\
|
||||
or move.product_id.type == 'consu':
|
||||
if move._should_bypass_reservation():
|
||||
# create the move line(s) but do not impact quants
|
||||
if move.product_id.tracking == 'serial' and (move.picking_type_id.use_create_lots or move.picking_type_id.use_existing_lots):
|
||||
for i in range(0, int(missing_reserved_quantity)):
|
||||
|
||||
@@ -224,7 +224,7 @@ class StockMoveLine(models.Model):
|
||||
# TODO Move me in the update
|
||||
if 'product_uom_qty' in vals:
|
||||
for ml in self.filtered(lambda m: m.state in ('partially_available', 'assigned') and m.product_id.type == 'product'):
|
||||
if not ml.location_id.should_bypass_reservation():
|
||||
if not ml._should_bypass_reservation(ml.location_id):
|
||||
qty_to_decrease = ml.product_qty - ml.product_uom_id._compute_quantity(vals['product_uom_qty'], ml.product_id.uom_id, rounding_method='HALF-UP')
|
||||
try:
|
||||
Quant._update_reserved_quantity(ml.product_id, ml.location_id, -qty_to_decrease, lot_id=ml.lot_id, package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
|
||||
@@ -249,7 +249,7 @@ class StockMoveLine(models.Model):
|
||||
|
||||
if updates:
|
||||
for ml in self.filtered(lambda ml: ml.state in ['partially_available', 'assigned'] and ml.product_id.type == 'product'):
|
||||
if not ml.location_id.should_bypass_reservation():
|
||||
if not ml._should_bypass_reservation(ml.location_id):
|
||||
try:
|
||||
Quant._update_reserved_quantity(ml.product_id, ml.location_id, -ml.product_qty, lot_id=ml.lot_id, package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
|
||||
except UserError:
|
||||
@@ -258,7 +258,7 @@ class StockMoveLine(models.Model):
|
||||
else:
|
||||
raise
|
||||
|
||||
if not updates.get('location_id', ml.location_id).should_bypass_reservation():
|
||||
if not ml._should_bypass_reservation(updates.get('location_id', ml.location_id)):
|
||||
new_product_qty = 0
|
||||
try:
|
||||
q = Quant._update_reserved_quantity(ml.product_id, updates.get('location_id', ml.location_id), ml.product_qty, lot_id=updates.get('lot_id', ml.lot_id),
|
||||
@@ -301,7 +301,7 @@ class StockMoveLine(models.Model):
|
||||
result_package_id = updates.get('result_package_id', ml.result_package_id)
|
||||
owner_id = updates.get('owner_id', ml.owner_id)
|
||||
quantity = ml.move_id.product_uom._compute_quantity(qty_done, ml.move_id.product_id.uom_id, rounding_method='HALF-UP')
|
||||
if not location_id.should_bypass_reservation():
|
||||
if not ml._should_bypass_reservation(location_id):
|
||||
ml._free_reservation(product_id, location_id, quantity, lot_id=lot_id, package_id=package_id, owner_id=owner_id)
|
||||
if not float_is_zero(quantity, precision_digits=precision):
|
||||
available_qty, in_date = Quant._update_available_quantity(product_id, location_id, -quantity, lot_id=lot_id, package_id=package_id, owner_id=owner_id)
|
||||
@@ -312,7 +312,7 @@ class StockMoveLine(models.Model):
|
||||
taken_from_untracked_qty = min(untracked_qty, abs(available_qty))
|
||||
Quant._update_available_quantity(product_id, location_id, -taken_from_untracked_qty, lot_id=False, package_id=package_id, owner_id=owner_id)
|
||||
Quant._update_available_quantity(product_id, location_id, taken_from_untracked_qty, lot_id=lot_id, package_id=package_id, owner_id=owner_id)
|
||||
if not location_id.should_bypass_reservation():
|
||||
if not ml._should_bypass_reservation(location_id):
|
||||
ml._free_reservation(ml.product_id, location_id, untracked_qty, lot_id=False, package_id=package_id, owner_id=owner_id)
|
||||
Quant._update_available_quantity(product_id, location_dest_id, quantity, lot_id=lot_id, package_id=result_package_id, owner_id=owner_id, in_date=in_date)
|
||||
|
||||
@@ -348,7 +348,7 @@ class StockMoveLine(models.Model):
|
||||
if ml.state in ('done', 'cancel'):
|
||||
raise UserError(_('You can not delete product moves if the picking is done. You can only correct the done quantities.'))
|
||||
# Unlinking a move line should unreserve.
|
||||
if ml.product_id.type == 'product' and not ml.location_id.should_bypass_reservation() and not float_is_zero(ml.product_qty, precision_digits=precision):
|
||||
if ml.product_id.type == 'product' and not ml._should_bypass_reservation(ml.location_id) and not float_is_zero(ml.product_qty, precision_digits=precision):
|
||||
try:
|
||||
self.env['stock.quant']._update_reserved_quantity(ml.product_id, ml.location_id, -ml.product_qty, lot_id=ml.lot_id, package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
|
||||
except UserError:
|
||||
@@ -428,11 +428,11 @@ class StockMoveLine(models.Model):
|
||||
rounding = ml.product_uom_id.rounding
|
||||
|
||||
# if this move line is force assigned, unreserve elsewhere if needed
|
||||
if not ml.location_id.should_bypass_reservation() and float_compare(ml.qty_done, ml.product_qty, precision_rounding=rounding) > 0:
|
||||
if not ml._should_bypass_reservation(ml.location_id) and float_compare(ml.qty_done, ml.product_qty, precision_rounding=rounding) > 0:
|
||||
extra_qty = ml.qty_done - ml.product_qty
|
||||
ml._free_reservation(ml.product_id, ml.location_id, extra_qty, lot_id=ml.lot_id, package_id=ml.package_id, owner_id=ml.owner_id, ml_to_ignore=done_ml)
|
||||
# unreserve what's been reserved
|
||||
if not ml.location_id.should_bypass_reservation() and ml.product_id.type == 'product' and ml.product_qty:
|
||||
if not ml._should_bypass_reservation(ml.location_id) and ml.product_id.type == 'product' and ml.product_qty:
|
||||
try:
|
||||
Quant._update_reserved_quantity(ml.product_id, ml.location_id, -ml.product_qty, lot_id=ml.lot_id, package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
|
||||
except UserError:
|
||||
@@ -541,3 +541,7 @@ class StockMoveLine(models.Model):
|
||||
move_to_recompute_state |= candidate.move_id
|
||||
break
|
||||
move_to_recompute_state._recompute_state()
|
||||
|
||||
def _should_bypass_reservation(self, location):
|
||||
self.ensure_one()
|
||||
return location.should_bypass_reservation() or self.product_id.type != 'product'
|
||||
|
||||
Reference in New Issue
Block a user