diff --git a/addons/mrp_subcontracting/__init__.py b/addons/mrp_subcontracting/__init__.py index cde864bae21..35e7c9600c5 100644 --- a/addons/mrp_subcontracting/__init__.py +++ b/addons/mrp_subcontracting/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- from . import models +from . import wizard diff --git a/addons/mrp_subcontracting/__manifest__.py b/addons/mrp_subcontracting/__manifest__.py index 6c34d2ba291..146a620edac 100644 --- a/addons/mrp_subcontracting/__manifest__.py +++ b/addons/mrp_subcontracting/__manifest__.py @@ -12,6 +12,7 @@ 'data': [ 'data/mrp_subcontracting_data.xml', 'views/stock_warehouse_views.xml', + 'views/stock_move_views.xml', 'views/stock_picking_views.xml', 'views/mrp_bom_views.xml', 'views/res_partner_views.xml', diff --git a/addons/mrp_subcontracting/models/__init__.py b/addons/mrp_subcontracting/models/__init__.py index 98238bd9a1b..3e55733a730 100644 --- a/addons/mrp_subcontracting/models/__init__.py +++ b/addons/mrp_subcontracting/models/__init__.py @@ -4,6 +4,7 @@ from . import mrp_bom from . import res_company from . import res_partner from . import stock_move +from . import stock_move_line from . import stock_picking from . import stock_warehouse diff --git a/addons/mrp_subcontracting/models/stock_move.py b/addons/mrp_subcontracting/models/stock_move.py index 8e149dd2cbe..eba26222c8b 100644 --- a/addons/mrp_subcontracting/models/stock_move.py +++ b/addons/mrp_subcontracting/models/stock_move.py @@ -3,13 +3,36 @@ from collections import defaultdict -from odoo import models, _ -from odoo.exceptions import UserError +from odoo import fields, models class StockMove(models.Model): _inherit = 'stock.move' + is_subcontract = fields.Boolean(copy=False) + subcontract_components_ids = fields.One2many('stock.move.line', + compute='_compute_subcontract_move_line_ids', + inverse='_inverse_subcontract_move_line_ids', + string='Subcontracted Components', readonly=False) + + def action_show_details(self): + action = super(StockMove, self).action_show_details() + action['context'].update({ + 'show_lots_m2o': True, + 'show_lots_text': False, + }) + return action + + def _compute_subcontract_move_line_ids(self): + for move in self: + if move.is_subcontract: + move.subcontract_components_ids = move.move_orig_ids.production_id.move_raw_ids.move_line_ids + + def _inverse_subcontract_move_line_ids(self): + for move in self: + if move.is_subcontract: + (move.move_orig_ids.production_id.move_raw_ids.move_line_ids - move.subcontract_components_ids).unlink() + def _get_subcontract_bom(self): self.ensure_one() bom = self.env['mrp.bom']._bom_subcontract_find( @@ -35,6 +58,9 @@ class StockMove(models.Model): error_message += _('If there is well a BoM of type subcontracting defined, check if you have set the correct subcontractors on it.') raise UserError(error_message % (move.product_id.name, move.product_id.name)) subcontract_details_per_picking[move.picking_id].append((move, bom)) + move.write({ + 'is_subcontract': True, + }) for picking, subcontract_details in subcontract_details_per_picking.items(): picking._subcontracted_produce(subcontract_details) return super(StockMove, self)._action_confirm(merge=merge, merge_into=merge_into) diff --git a/addons/mrp_subcontracting/models/stock_move_line.py b/addons/mrp_subcontracting/models/stock_move_line.py new file mode 100644 index 00000000000..32ddade892e --- /dev/null +++ b/addons/mrp_subcontracting/models/stock_move_line.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models + + +class StockMoveLine(models.Model): + _inherit = 'stock.move.line' + + def write(self, values): + move_lines_subcontracted = self.filtered(lambda ml: ml.move_id.is_subcontract) + if not move_lines_subcontracted: + return super(StockMoveLine, self).write(values) + for ml in move_lines_subcontracted: + candidates = ml.move_id.move_orig_ids.move_line_ids + candidate = candidates.filtered(lambda c: + c.qty_done == ml.qty_done and ml.product_uom_qty == c.product_uom_qty and + ml.product_uom_id == c.product_uom_id and c.lot_id == ml.lot_id) + candidate = candidate and candidate[0] or self.env['stock.move.line'] + candidate.write(values) + return super(StockMoveLine, self).write(values) diff --git a/addons/mrp_subcontracting/models/stock_picking.py b/addons/mrp_subcontracting/models/stock_picking.py index b08eaf6d78a..4ab048ad799 100644 --- a/addons/mrp_subcontracting/models/stock_picking.py +++ b/addons/mrp_subcontracting/models/stock_picking.py @@ -8,7 +8,6 @@ class StockPicking(models.Model): _inherit = 'stock.picking' display_action_record_components = fields.Boolean(compute='_compute_display_action_record_components') - display_view_subcontracted_move_lines = fields.Boolean(compute='_compute_display_view_subcontracted_move_lines') @api.depends('state') def _compute_display_action_record_components(self): @@ -29,26 +28,6 @@ class StockPicking(models.Model): continue picking.display_action_record_components = True - @api.depends('state') - def _compute_display_view_subcontracted_move_lines(self): - for picking in self: - # Hide if not encoding state - if picking.state in ('draft', 'cancel'): - continue - if not picking._is_subcontract(): - continue - # Hide until state done if no move is tracked, if tracked until something was produced - subcontracted_productions = picking._get_subcontracted_productions() - subcontracted_moves = subcontracted_productions.mapped('move_raw_ids') - subcontracted_moves |= subcontracted_productions.mapped('move_finished_ids') - if all(subcontracted_move.has_tracking == 'none' for subcontracted_move in subcontracted_moves): - if picking.state != 'done': - continue - # Hide if nothing was produced - if all(subcontracted_move.quantity_done == 0 for subcontracted_move in subcontracted_moves): - continue - picking.display_view_subcontracted_move_lines = True - # ------------------------------------------------------------------------- # Action methods # ------------------------------------------------------------------------- @@ -60,29 +39,18 @@ class StockPicking(models.Model): subcontracted_production.button_mark_done() return res - def action_view_subcontracted_move_lines(self): - """ Returns a list view with the move lines of the subcontracted products. To find them, we - look on the origin moves of the move lines of the picking if there is a manufacturing order. - """ - self.ensure_one() - subcontracted_productions = self._get_subcontracted_productions() - subcontracted_move_lines = self.env['stock.move.line'] - for subcontracted_production in subcontracted_productions: - subcontracted_move_lines |= subcontracted_production.move_raw_ids.mapped('move_line_ids') - subcontracted_move_lines |= subcontracted_production.move_finished_ids.mapped('move_line_ids') - action = self.env.ref('stock.stock_move_line_action').read()[0] - action['context'] = {} - action['domain'] = [('id', 'in', subcontracted_move_lines.ids)] - return action - def action_record_components(self): self.ensure_one() - subcontracted_productions = self._get_subcontracted_productions() - to_register = subcontracted_productions.filtered(lambda mo: mo.state not in ('to_close', 'done')) - if to_register: - mo = to_register[0] + for move in self.move_lines: + production = move.move_orig_ids.production_id + if not production or production.state in ('done', 'to_close'): + continue action = self.env.ref('mrp.act_mrp_product_produce').read()[0] - action['context'] = dict(self.env.context, active_id=mo.id) + action['context'] = dict( + self.env.context, + active_id=production.id, + default_subcontract_move_id=move.id + ) return action # ------------------------------------------------------------------------- diff --git a/addons/mrp_subcontracting/tests/test_subcontracting.py b/addons/mrp_subcontracting/tests/test_subcontracting.py index f715f1466e6..58ad3928d44 100644 --- a/addons/mrp_subcontracting/tests/test_subcontracting.py +++ b/addons/mrp_subcontracting/tests/test_subcontracting.py @@ -188,7 +188,6 @@ class TestSubcontractingFlows(SavepointCase): # Nothing should be tracked self.assertFalse(picking_receipt.display_action_record_components) - self.assertFalse(picking_receipt.display_view_subcontracted_move_lines) # Check the created manufacturing order mo = self.env['mrp.production'].search([('bom_id', '=', self.bom.id)]) @@ -218,9 +217,6 @@ class TestSubcontractingFlows(SavepointCase): picking_receipt.button_validate() self.assertEquals(mo.state, 'done') - # Now that the picking is done, the details stat button should be visible - self.assertTrue(picking_receipt.display_view_subcontracted_move_lines) - # Available quantities should be negative at the subcontracting location for each components avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1, self.subcontractor_partner1.property_stock_supplier, allow_negative=True) avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_supplier, allow_negative=True) @@ -250,7 +246,6 @@ class TestSubcontractingFlows(SavepointCase): # Nothing should be tracked self.assertFalse(picking_receipt.display_action_record_components) - self.assertFalse(picking_receipt.display_view_subcontracted_move_lines) # Pickings should directly be created mo = self.env['mrp.production'].search([('bom_id', '=', self.bom.id)]) @@ -275,9 +270,6 @@ class TestSubcontractingFlows(SavepointCase): picking_receipt.button_validate() self.assertEquals(mo.state, 'done') - # Now that the picking is done, the details stat button should be visible - self.assertTrue(picking_receipt.display_view_subcontracted_move_lines) - # Available quantities should be negative at the subcontracting location for each components avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1, self.subcontractor_partner1.property_stock_supplier, allow_negative=True) avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_supplier, allow_negative=True) @@ -314,7 +306,6 @@ class TestSubcontractingFlows(SavepointCase): # Nothing should be tracked self.assertFalse(picking_receipt.display_action_record_components) - self.assertFalse(picking_receipt.display_view_subcontracted_move_lines) # Pickings should directly be created mo = self.env['mrp.production'].search([('bom_id', '=', self.bom.id)]) @@ -336,9 +327,6 @@ class TestSubcontractingFlows(SavepointCase): picking_receipt.button_validate() self.assertEquals(mo.state, 'done') - # Now that the picking is done, the details stat button should be visible - self.assertTrue(picking_receipt.display_view_subcontracted_move_lines) - # Available quantities should be negative at the subcontracting location for each components avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1, self.subcontractor_partner1.property_stock_supplier, allow_negative=True) avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_supplier, allow_negative=True) @@ -524,7 +512,6 @@ class TestSubcontractingTracking(TransactionCase): # We should be able to call the 'record_components' button self.assertTrue(picking_receipt.display_action_record_components) - self.assertFalse(picking_receipt.display_view_subcontracted_move_lines) # Check the created manufacturing order mo = self.env['mrp.production'].search([('bom_id', '=', self.bom_tracked.id)]) @@ -571,8 +558,6 @@ class TestSubcontractingTracking(TransactionCase): # We should not be able to call the 'record_components' button self.assertFalse(picking_receipt.display_action_record_components) - # We should see the move lines stat button - self.assertTrue(picking_receipt.display_view_subcontracted_move_lines) picking_receipt.move_lines.quantity_done = 1 picking_receipt.move_lines.move_line_ids.lot_name = 'lot00001test' diff --git a/addons/mrp_subcontracting/views/stock_move_views.xml b/addons/mrp_subcontracting/views/stock_move_views.xml new file mode 100644 index 00000000000..0f1f7a8801d --- /dev/null +++ b/addons/mrp_subcontracting/views/stock_move_views.xml @@ -0,0 +1,26 @@ + + + + stock.move.operations.form.inherit.mrp.subcontracting + stock.move + + + + +

Components

+ + + + + + + + + +
+ +

Subcontracted Product

+
+
+
+
\ No newline at end of file diff --git a/addons/mrp_subcontracting/views/stock_picking_views.xml b/addons/mrp_subcontracting/views/stock_picking_views.xml index 23145eeabbf..e5b87e618eb 100644 --- a/addons/mrp_subcontracting/views/stock_picking_views.xml +++ b/addons/mrp_subcontracting/views/stock_picking_views.xml @@ -5,14 +5,6 @@ stock.picking - - -