diff --git a/addons/mrp_subcontracting/models/stock_picking.py b/addons/mrp_subcontracting/models/stock_picking.py index 012282ec98b..13526ad2e5a 100644 --- a/addons/mrp_subcontracting/models/stock_picking.py +++ b/addons/mrp_subcontracting/models/stock_picking.py @@ -64,6 +64,9 @@ class StockPicking(models.Model): self.ensure_one() return self.move_lines.mapped('move_orig_ids.production_id') + def _get_warehouse(self, subcontract_move): + return subcontract_move.warehouse_id or self.picking_type_id.warehouse_id + def _prepare_subcontract_mo_vals(self, subcontract_move, bom): subcontract_move.ensure_one() group = self.env['procurement.group'].create({ @@ -71,7 +74,7 @@ class StockPicking(models.Model): 'partner_id': self.partner_id.id, }) product = subcontract_move.product_id - warehouse = subcontract_move.warehouse_id or self.picking_type_id.warehouse_id + warehouse = self._get_warehouse(subcontract_move) vals = { 'procurement_group_id': group.id, 'product_id': product.id, diff --git a/addons/mrp_subcontracting_dropshipping/__init__.py b/addons/mrp_subcontracting_dropshipping/__init__.py new file mode 100644 index 00000000000..dc5e6b693d1 --- /dev/null +++ b/addons/mrp_subcontracting_dropshipping/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import models diff --git a/addons/mrp_subcontracting_dropshipping/__manifest__.py b/addons/mrp_subcontracting_dropshipping/__manifest__.py new file mode 100644 index 00000000000..6d69eb4afe5 --- /dev/null +++ b/addons/mrp_subcontracting_dropshipping/__manifest__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + + +{ + 'name': 'Dropship and Subcontracting Management', + 'version': '0.1', + 'category': 'Hidden', + 'description': """ + This bridge module allows to manage subcontracting with the dropshipping module. + """, + 'depends': ['mrp_subcontracting', 'stock_dropshipping'], + 'installable': True, + 'auto_install': True, +} diff --git a/addons/mrp_subcontracting_dropshipping/models/__init__.py b/addons/mrp_subcontracting_dropshipping/models/__init__.py new file mode 100644 index 00000000000..ac9517445ae --- /dev/null +++ b/addons/mrp_subcontracting_dropshipping/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import stock_picking diff --git a/addons/mrp_subcontracting_dropshipping/models/stock_picking.py b/addons/mrp_subcontracting_dropshipping/models/stock_picking.py new file mode 100644 index 00000000000..5bc45469407 --- /dev/null +++ b/addons/mrp_subcontracting_dropshipping/models/stock_picking.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models + + +class StockPicking(models.Model): + _inherit = 'stock.picking' + + def _get_warehouse(self, subcontract_move): + if subcontract_move.sale_line_id: + return subcontract_move.sale_line_id.order_id.warehouse_id + return super(StockPicking, self)._get_warehouse(subcontract_move) diff --git a/addons/mrp_subcontracting_dropshipping/tests/__init__.py b/addons/mrp_subcontracting_dropshipping/tests/__init__.py new file mode 100644 index 00000000000..76fe74ec58b --- /dev/null +++ b/addons/mrp_subcontracting_dropshipping/tests/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import test_purchase_subcontracting + diff --git a/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py b/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py new file mode 100644 index 00000000000..b68341e3b8c --- /dev/null +++ b/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.tests import Form +from odoo.addons.mrp_subcontracting.tests.common import TestMrpSubcontractingCommon + + +class TestSubcontractingDropshippingFlows(TestMrpSubcontractingCommon): + + def test_mrp_subcontracting_dropshipping_1(self): + """ Mark the subcontracted product with the route dropship and add the + subcontractor as seller. The component has the routes 'MTO', 'Replenish + on order' and 'Buy'. Also another partner is set as vendor on the comp. + Create a SO and check that: + - Delivery between subcontractor and customer for subcontracted product. + - Delivery for the component to the subcontractor for the specified wh. + - Po created for the component. + """ + mto_route = self.env['stock.location.route'].search([('name', '=', 'Replenish on Order (MTO)')]) + resupply_route = self.env['stock.location.route'].search([('name', '=', 'Resupply Subcontractor on Order')]) + buy_route = self.env['stock.location.route'].search([('name', '=', 'Buy')]) + dropship_route = self.env['stock.location.route'].search([('name', '=', 'Dropship')]) + self.comp2.write({'route_ids': [(4, buy_route.id), (4, mto_route.id), (4, resupply_route.id)]}) + self.finished.write({'route_ids': [(4, dropship_route.id)]}) + + warehouse = self.env['stock.warehouse'].create({ + 'name': 'Warehouse For subcontract', + 'code': 'WFS' + }) + + self.env['product.supplierinfo'].create({ + 'product_tmpl_id': self.finished.product_tmpl_id.id, + 'name': self.subcontractor_partner1.id + }) + + partner = self.env['res.partner'].create({ + 'name': 'Toto' + }) + self.env['product.supplierinfo'].create({ + 'product_tmpl_id': self.comp2.product_tmpl_id.id, + 'name': partner.id + }) + + # Create a receipt picking from the subcontractor + so_form = Form(self.env['sale.order']) + so_form.partner_id = partner + so_form.warehouse_id = warehouse + with so_form.order_line.new() as line: + line.product_id = self.finished + line.product_uom_qty = 1 + so = so_form.save() + so.action_confirm() + + # Pickings should directly be created + po = self.env['purchase.order'].search([('origin', 'ilike', so.name)]) + self.assertTrue(po) + + po.button_approve() + + picking_finished = po.picking_ids + self.assertEqual(len(picking_finished), 1.0) + self.assertEqual(picking_finished.location_dest_id, partner.property_stock_customer) + self.assertEqual(picking_finished.location_id, self.subcontractor_partner1.property_stock_supplier) + self.assertEqual(picking_finished.state, 'assigned') + + picking_delivery = self.env['stock.move'].search([ + ('product_id', '=', self.comp2.id), + ('location_id', '=', warehouse.lot_stock_id.id), + ('location_dest_id', '=', self.subcontractor_partner1.property_stock_subcontractor.id), + ]).picking_id + self.assertTrue(picking_delivery) + self.assertEqual(picking_delivery.state, 'waiting') + + po = self.env['purchase.order.line'].search([ + ('product_id', '=', self.comp2.id), + ('partner_id', '=', partner.id), + ]).order_id + self.assertTrue(po)