diff options
Diffstat (limited to 'addons/mrp_subcontracting/models')
| -rw-r--r-- | addons/mrp_subcontracting/models/mrp_production.py | 5 | ||||
| -rw-r--r-- | addons/mrp_subcontracting/models/stock_move.py | 23 | ||||
| -rw-r--r-- | addons/mrp_subcontracting/models/stock_picking.py | 86 |
3 files changed, 69 insertions, 45 deletions
diff --git a/addons/mrp_subcontracting/models/mrp_production.py b/addons/mrp_subcontracting/models/mrp_production.py index fcc77b32e63..e546bf1b034 100644 --- a/addons/mrp_subcontracting/models/mrp_production.py +++ b/addons/mrp_subcontracting/models/mrp_production.py @@ -125,3 +125,8 @@ class MrpProduction(models.Model): for ml in subcontract_move_id.move_line_ids: ml.product_uom_qty = ml.qty_done subcontract_move_id._recompute_state() + + def _subcontracting_filter_to_done(self): + """ Filter subcontracting production where composant is already recorded and should be consider to be validate """ + mos = self.filtered(lambda mo: mo.state not in ('done', 'cancel')) + return mos.filtered(lambda pro: all(line.lot_id for line in pro.move_raw_ids.filtered(lambda sm: sm.has_tracking != 'none').move_line_ids)) diff --git a/addons/mrp_subcontracting/models/stock_move.py b/addons/mrp_subcontracting/models/stock_move.py index 32817a4ca8b..45f5bcce5eb 100644 --- a/addons/mrp_subcontracting/models/stock_move.py +++ b/addons/mrp_subcontracting/models/stock_move.py @@ -51,11 +51,18 @@ class StockMove(models.Model): """ If the initial demand is updated then also update the linked subcontract order to the new quantity. """ - if 'product_uom_qty' in values: - if self.env.context.get('cancel_backorder') is False: - return super(StockMove, self).write(values) + if 'product_uom_qty' in values and self.env.context.get('cancel_backorder') is not False: self.filtered(lambda m: m.is_subcontract and m.state not in ['draft', 'cancel', 'done'])._update_subcontract_order_qty(values['product_uom_qty']) - return super(StockMove, self).write(values) + res = super().write(values) + if 'date' in values: + for move in self: + if move.state in ('done', 'cancel') or not move.is_subcontract: + continue + move.move_orig_ids.production_id.filtered(lambda p: p.state not in ('done', 'cancel')).write({ + 'date_planned_finished': move.date, + 'date_planned_start': move.date, + }) + return res def action_show_details(self): """ Open the produce wizard in order to register tracked components for @@ -97,10 +104,10 @@ class StockMove(models.Model): def _action_cancel(self): for move in self: if move.is_subcontract: - production = move.move_orig_ids.production_id + active_production = move.move_orig_ids.production_id.filtered(lambda p: p.state not in ('done', 'cancel')) moves = self.env.context.get('moves_todo') - if not moves or production not in moves.move_orig_ids.production_id: - production._action_cancel() + if not moves or active_production not in moves.move_orig_ids.production_id: + active_production.with_context(skip_activity=True).action_cancel() return super()._action_cancel() def _action_confirm(self, merge=True, merge_into=False): @@ -192,7 +199,7 @@ class StockMove(models.Model): break if quantity_to_remove >= production.product_qty: quantity_to_remove -= production.product_qty - production.action_cancel() + production.with_context(skip_activity=True).action_cancel() else: self.env['change.production.qty'].with_context(skip_activity=True).create({ 'mo_id': production.id, diff --git a/addons/mrp_subcontracting/models/stock_picking.py b/addons/mrp_subcontracting/models/stock_picking.py index 6faebd8a809..23949e6cac9 100644 --- a/addons/mrp_subcontracting/models/stock_picking.py +++ b/addons/mrp_subcontracting/models/stock_picking.py @@ -4,7 +4,7 @@ from datetime import timedelta from odoo import api, fields, models -from odoo.tools.float_utils import float_is_zero +from odoo.tools.float_utils import float_compare, float_is_zero class StockPicking(models.Model): @@ -41,39 +41,48 @@ class StockPicking(models.Model): # ------------------------------------------------------------------------- def _action_done(self): res = super(StockPicking, self)._action_done() + + for move in self.move_lines.filtered(lambda move: move.is_subcontract): + # Auto set qty_producing/lot_producing_id of MO if there isn't tracked component + # If there is tracked component, the flow use subcontracting_record_component instead + if move._has_tracked_subcontract_components(): + continue + production = move.move_orig_ids.production_id.filtered(lambda p: p.state not in ('done', 'cancel'))[-1:] + if not production: + continue + # Manage additional quantities + quantity_done_move = move.product_uom._compute_quantity(move.quantity_done, production.product_uom_id) + if float_compare(production.product_qty, quantity_done_move, precision_rounding=production.product_uom_id.rounding) == -1: + change_qty = self.env['change.production.qty'].create({ + 'mo_id': production.id, + 'product_qty': quantity_done_move + }) + change_qty.with_context(skip_activity=True).change_prod_qty() + # Create backorder MO for each move lines + for move_line in move.move_line_ids: + if move_line.lot_id: + production.lot_producing_id = move_line.lot_id + production.qty_producing = move_line.product_uom_id._compute_quantity(move_line.qty_done, production.product_uom_id) + production._set_qty_producing() + if move_line != move.move_line_ids[-1]: + backorder = production._generate_backorder_productions(close_mo=False) + # The move_dest_ids won't be set because the _split filter out done move + backorder.move_finished_ids.filtered(lambda mo: mo.product_id == move.product_id).move_dest_ids = production.move_finished_ids.filtered(lambda mo: mo.product_id == move.product_id).move_dest_ids + production.product_qty = production.qty_producing + production = backorder + for picking in self: - # Auto set qty_producing if not tracked component - for move in picking.move_lines.filtered(lambda move: move.is_subcontract): - if not move._has_tracked_subcontract_components(): - production = move.move_orig_ids.production_id.filtered(lambda p: p.state not in ('done', 'cancel')) - if production: - qty_done_production_uom = move.product_uom._compute_quantity(move.quantity_done, production.product_uom_id) - production.qty_producing += qty_done_production_uom - for move in (production.move_raw_ids | production.move_finished_ids.filtered(lambda m: m.product_id != production.product_id)): - if move.state in ('done', 'cancel'): - continue - if float_is_zero(move.product_uom_qty, precision_rounding=move.product_uom.rounding): - continue - new_qty = production.product_uom_id._compute_quantity( - (production.qty_producing - production.qty_produced) * move.unit_factor, production.product_uom_id, - rounding_method='HALF-UP') - move.move_line_ids.filtered(lambda ml: ml.state not in ('done', 'cancel')).qty_done = 0 - move.move_line_ids = move._set_quantity_done_prepare_vals(new_qty) - - productions_to_done = picking.move_lines.move_orig_ids.production_id.filtered(lambda p: p.state not in ('done', 'cancel')) - # TODO : to change in master with field on mrp - productions_to_done = productions_to_done.filtered(lambda pro: all(line.lot_id for line in pro.move_raw_ids.filtered(lambda sm: sm.has_tracking != 'none').move_line_ids)) - for subcontracted_production in productions_to_done: - if subcontracted_production.state == 'progress': - subcontracted_production._post_inventory() - else: - subcontracted_production.with_context(subcontract_move_id=True).button_mark_done() - # For concistency, set the date on production move before the date - # on picking. (Tracability report + Product Moves menu item) - minimum_date = min(picking.move_line_ids.mapped('date')) - production_moves = subcontracted_production.move_raw_ids | subcontracted_production.move_finished_ids - production_moves.write({'date': minimum_date - timedelta(seconds=1)}) - production_moves.move_line_ids.write({'date': minimum_date - timedelta(seconds=1)}) + productions_to_done = picking._get_subcontracted_productions()._subcontracting_filter_to_done() + production_ids_backorder = [] + if not self.env.context.get('cancel_backorder'): + production_ids_backorder = productions_to_done.filtered(lambda mo: mo.state == "progress").ids + productions_to_done.with_context(subcontract_move_id=True, mo_ids_to_backorder=production_ids_backorder).button_mark_done() + # For concistency, set the date on production move before the date + # on picking. (Traceability report + Product Moves menu item) + minimum_date = min(picking.move_line_ids.mapped('date')) + production_moves = productions_to_done.move_raw_ids | productions_to_done.move_finished_ids + production_moves.write({'date': minimum_date - timedelta(seconds=1)}) + production_moves.move_line_ids.write({'date': minimum_date - timedelta(seconds=1)}) return res def action_record_components(self): @@ -81,7 +90,9 @@ class StockPicking(models.Model): for move in self.move_lines: if not move._has_tracked_subcontract_components(): continue - production = move.move_orig_ids.production_id[-1:] + productions = move.move_orig_ids.production_id + productions_to_done = productions._subcontracting_filter_to_done() + production = (productions - productions_to_done)[-1:] if not production: continue return move._action_record_components() @@ -94,8 +105,7 @@ class StockPicking(models.Model): return self.picking_type_id.code == 'incoming' and any(m.is_subcontract for m in self.move_lines) def _get_subcontracted_productions(self): - self.ensure_one() - return self.move_lines.mapped('move_orig_ids.production_id') + return self.move_lines.move_orig_ids.production_id def _get_warehouse(self, subcontract_move): return subcontract_move.warehouse_id or self.picking_type_id.warehouse_id @@ -117,7 +127,8 @@ class StockPicking(models.Model): 'location_src_id': subcontract_move.picking_id.partner_id.with_company(subcontract_move.company_id).property_stock_subcontractor.id, 'location_dest_id': subcontract_move.picking_id.partner_id.with_company(subcontract_move.company_id).property_stock_subcontractor.id, 'product_qty': subcontract_move.product_uom_qty, - 'picking_type_id': warehouse.subcontracting_type_id.id + 'picking_type_id': warehouse.subcontracting_type_id.id, + 'date_planned_start': subcontract_move.date } return vals @@ -127,6 +138,7 @@ class StockPicking(models.Model): mo = self.env['mrp.production'].with_company(move.company_id).create(self._prepare_subcontract_mo_vals(move, bom)) self.env['stock.move'].create(mo._get_moves_raw_values()) self.env['stock.move'].create(mo._get_moves_finished_values()) + mo.date_planned_finished = move.date # Avoid to have the picking late depending of the MO mo.action_confirm() # Link the finished to the receipt move. |
