61 lines
3.0 KiB
Python
61 lines
3.0 KiB
Python
|
|
from odoo import models
|
|
from odoo.tools import float_compare
|
|
|
|
class StockMove(models.Model):
|
|
_inherit = 'stock.move'
|
|
|
|
def _get_fields_stock_barcode(self):
|
|
return [
|
|
'product_id',
|
|
'location_id',
|
|
'product_uom',
|
|
'product_uom_qty',
|
|
'move_line_ids',
|
|
'packaging_uom_id',
|
|
'packaging_uom_qty'
|
|
]
|
|
|
|
def split_uncompleted_moves(self):
|
|
""" Creates a new move for every uncompleted move in order to get one picked move
|
|
with the picked quantity, and one not picked move with the remaining quantity."""
|
|
moves_to_reset = self.filtered(lambda m: m.picked and m.quantity == 0)
|
|
moves_to_backorder = (self - moves_to_reset).filtered(lambda move: move.picked and move.state not in ['done', 'cancel'])
|
|
for move in moves_to_reset:
|
|
move.move_line_ids.unlink()
|
|
move.quantity = move.product_uom_qty
|
|
move.picked = False
|
|
new_moves = moves_to_backorder._create_backorder()
|
|
# certain moves should be assigned manually as they are not by the _action_confirm
|
|
new_moves.with_context(bypass_entire_pack=True).filtered(lambda m: m.procure_method == 'make_to_order' or not m._should_assign_at_confirm())._action_assign()
|
|
if new_moves:
|
|
# In some case, we already split the move lines in the front end.
|
|
# Those move lines are linked to the original move. If their quantity
|
|
# is 0 and they already picked, there is no reason to keep them.
|
|
moves_to_clean = self - new_moves
|
|
for move in moves_to_clean:
|
|
for move_line in move.move_line_ids:
|
|
if move_line.quantity == 0 and move_line.picked:
|
|
move_line.unlink()
|
|
group_new_moves = new_moves.grouped('picking_id')
|
|
group_moves_to_backorder = moves_to_backorder.grouped('picking_id')
|
|
for picking, moves_to_merge in group_new_moves.items():
|
|
moves_to_merge._merge_moves(merge_into=group_moves_to_backorder[picking])
|
|
return new_moves
|
|
|
|
def _truncate_overreserved_moves(self, barcode_quantities):
|
|
""" Truncate moves with an exceeding quantity due to barcode move line creations."""
|
|
for move in self:
|
|
if not move.picked or move.state in ('done', 'cancel'):
|
|
continue
|
|
move_qties = barcode_quantities.get(str(move.id), False)
|
|
if move_qties:
|
|
max_reserved_qty = max(move_qties['quantity_done'], move_qties['reserved_uom_qty'])
|
|
if float_compare(move.quantity, max_reserved_qty, precision_rounding=move.product_id.uom_id.rounding) > 0:
|
|
move.with_context({'unreserve_unpicked_only': True}).quantity = max_reserved_qty
|
|
|
|
def post_barcode_process(self, barcode_quantities):
|
|
new_moves = self.split_uncompleted_moves()
|
|
self._truncate_overreserved_moves(barcode_quantities)
|
|
return new_moves
|