diff options
| author | Josse Colpaert <jco@odoo.com> | 2016-09-26 12:06:58 +0200 |
|---|---|---|
| committer | Josse Colpaert <jco@odoo.com> | 2016-09-28 12:38:13 +0200 |
| commit | fbab021a9b3d482c438f2caf26dab1b1d8a95041 (patch) | |
| tree | c88d6a46bfea6fc49955f07ae307a1a835af1840 | |
| parent | 24a16f5db58c4dfe955f97da0a432e128ff548bd (diff) | |
[FIX] mrp: extra move should split move lots also and take into account procurement
When you produce or consume more than foreseen in a production order,
the system creates extra moves. Before, in case of tracking, it did this without
transferring the stock.move.lots resulting in a wrong stock. That is why now,
when we split moves, we also split the stock.move.lots
For the finished move, it is also important to split between the quantities
of the original procurement and what is extra as the extra might use a push rule e.g.
| -rw-r--r-- | addons/mrp/models/stock_move.py | 57 |
1 files changed, 48 insertions, 9 deletions
diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py index 742326a7f9f..3588c0d0302 100644 --- a/addons/mrp/models/stock_move.py +++ b/addons/mrp/models/stock_move.py @@ -166,6 +166,48 @@ class StockMove(models.Model): return True @api.multi + def _create_extra_move(self): + ''' Creates an extra move if necessary depending on extra quantities than foreseen or extra moves''' + self.ensure_one() + quantity_to_split = 0 + extra_move = self.env['stock.move'] + rounding = self.product_uom.rounding + link_procurement = False + if self.procurement_id and self.production_id and float_compare(self.production_id.qty_produced, self.procurement_id.product_qty, precision_rounding=rounding) > 0: + done_moves_total = sum(self.production_id.move_finished_ids.filtered(lambda x: x.product_id == self.product_id and x.state == 'done').mapped('product_uom_qty')) + if float_compare(done_moves_total, self.procurement_id.product_qty, precision_rounding=rounding) >= 0: + quantity_to_split = 0 + self.product_uom_qty = self.quantity_done #TODO: could change qty on move_dest_id also (in case of 2-step in/out) + else: + quantity_to_split = done_moves_total + self.quantity_done - self.procurement_id.product_qty + elif float_compare(self.quantity_done, self.product_uom_qty, precision_rounding=rounding) > 0: + quantity_to_split = self.quantity_done - self.product_uom_qty + link_procurement = True + if quantity_to_split: + extra_move = self.copy(default={'quantity_done': quantity_to_split, 'product_uom_qty': quantity_to_split, 'production_id': self.production_id.id, + 'raw_material_production_id': self.raw_material_production_id.id, + 'procurement_id': link_procurement and self.procurement_id.id or False}) + extra_move.action_confirm() + if self.has_tracking != 'none': + qty_todo = self.quantity_done - quantity_to_split + for movelot in self.move_lot_ids.filtered(lambda x: x.done_wo): + if movelot.quantity_done and movelot.done_wo: + if float_compare(qty_todo, movelot.quantity_done, precision_rounding=rounding) >= 0: + qty_todo -= movelot.quantity_done + elif float_compare(qty_todo, 0, precision_rounding=rounding) > 0: + #split + remaining = movelot.quantity_done - qty_todo + movelot.quantity_done = qty_todo + movelot.copy(default={'move_id': extra_move.id, 'quantity_done': remaining}) + qty_todo = 0 + else: + movelot.move_id = extra_move.id + else: + self.quantity_done = self.product_uom_qty + self.product_uom_qty = self.quantity_done - quantity_to_split + return extra_move + + @api.multi def move_validate(self): ''' Validate moves based on a production order. ''' moves = self._filter_closed_moves() @@ -173,25 +215,22 @@ class StockMove(models.Model): moves_todo = self.env['stock.move'] moves_to_unreserve = self.env['stock.move'] uom_obj = self.env['product.uom'] + # Create extra moves where necessary for move in moves: rounding = move.product_uom.rounding if float_compare(move.quantity_done, 0.0, precision_rounding=rounding) <= 0: continue moves_todo |= move - if float_compare(move.quantity_done, move.product_uom_qty, precision_rounding=rounding) > 0: - remaining_qty = move.quantity_done - move.product_uom_qty # In UoM of move - extra_move = move.copy(default={'quantity_done': remaining_qty, 'product_uom_qty': remaining_qty, 'production_id': move.production_id.id, - 'raw_material_production_id': move.raw_material_production_id.id}) - move.quantity_done = move.product_uom_qty - extra_move.action_confirm() - moves_todo |= extra_move + moves_todo |= move._create_extra_move() + # Split moves where necessary and move quants for move in moves_todo: - if float_compare(move.quantity_done, move.product_uom_qty, precision_rounding=rounding): + rounding = move.product_uom.rounding + if float_compare(move.quantity_done, move.product_uom_qty, precision_rounding=rounding) < 0: # Need to do some kind of conversion here qty_split = uom_obj._compute_qty(move.product_uom.id, move.product_uom_qty - move.quantity_done, move.product_id.uom_id.id) new_move = move.split(qty_split) # If you were already putting stock.move.lots on the next one in the work order, transfer those to the new move - move.move_lot_ids.filtered(lambda x: not x.done_wo).write({'move_id': new_move}) + move.move_lot_ids.filtered(lambda x: not x.done_wo or x.quantity_done == 0.0).write({'move_id': new_move}) self.browse(new_move).quantity_done = 0.0 main_domain = [('qty', '>', 0)] preferred_domain = [('reservation_id', '=', move.id)] |
