Files
enterprise-addons/stock_barcode/models/stock_move.py
T

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