summaryrefslogtreecommitdiff
path: root/addons/mrp_subcontracting_dropshipping
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/mrp_subcontracting_dropshipping
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/mrp_subcontracting_dropshipping')
-rw-r--r--addons/mrp_subcontracting_dropshipping/__init__.py4
-rw-r--r--addons/mrp_subcontracting_dropshipping/__manifest__.py16
-rw-r--r--addons/mrp_subcontracting_dropshipping/models/__init__.py4
-rw-r--r--addons/mrp_subcontracting_dropshipping/models/stock_picking.py13
-rw-r--r--addons/mrp_subcontracting_dropshipping/tests/__init__.py7
-rw-r--r--addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py136
6 files changed, 180 insertions, 0 deletions
diff --git a/addons/mrp_subcontracting_dropshipping/__init__.py b/addons/mrp_subcontracting_dropshipping/__init__.py
new file mode 100644
index 00000000..dc5e6b69
--- /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 00000000..64409935
--- /dev/null
+++ b/addons/mrp_subcontracting_dropshipping/__manifest__.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+
+{
+ 'name': 'Dropship and Subcontracting Management',
+ 'version': '0.1',
+ 'category': 'Inventory/Purchase',
+ 'description': """
+ This bridge module allows to manage subcontracting with the dropshipping module.
+ """,
+ 'depends': ['mrp_subcontracting', 'stock_dropshipping'],
+ 'installable': True,
+ 'auto_install': True,
+ 'license': 'LGPL-3',
+}
diff --git a/addons/mrp_subcontracting_dropshipping/models/__init__.py b/addons/mrp_subcontracting_dropshipping/models/__init__.py
new file mode 100644
index 00000000..ac951744
--- /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 00000000..5bc45469
--- /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 00000000..76fe74ec
--- /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 00000000..9d13f6c5
--- /dev/null
+++ b/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py
@@ -0,0 +1,136 @@
+# -*- 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.
+ """
+ self.env.ref('stock.route_warehouse0_mto').active = True
+ 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)
+
+ def test_mrp_subcontracting_purchase_2(self):
+ """Let's consider a subcontracted BOM with 1 component. Tick "Resupply Subcontractor on Order" on the component and set a supplier on it.
+ Purchase 1 BOM to the subcontractor. Confirm the purchase and change the purchased quantity to 2.
+ Check that 2 components are delivered to the subcontractor
+ """
+ # Tick "resupply subconractor on order on component"
+ self.bom.bom_line_ids = [(5, 0, 0)]
+ self.bom.bom_line_ids = [(0, 0, {'product_id': self.comp1.id, 'product_qty': 1})]
+ resupply_sub_on_order_route = self.env['stock.location.route'].search([('name', '=', 'Resupply Subcontractor on Order')])
+ (self.comp1).write({'route_ids': [(4, resupply_sub_on_order_route.id, None)]})
+ # Create a supplier and set it to component
+ vendor = self.env['res.partner'].create({'name': 'AAA', 'email': 'from.test@example.com'})
+ supplier_info1 = self.env['product.supplierinfo'].create({
+ 'name': vendor.id,
+ 'price': 50,
+ })
+ self.comp1.write({'seller_ids': [(0, 0, {'name': vendor.id, 'product_code': 'COMP1'})]})
+ # Purchase 1 BOM to the subcontractor
+ po = Form(self.env['purchase.order'])
+ po.partner_id = self.subcontractor_partner1
+ with po.order_line.new() as po_line:
+ po_line.product_id = self.finished
+ po_line.product_qty = 1
+ po_line.price_unit = 100
+ po = po.save()
+ # Confirm the purchase
+ po.button_confirm()
+ # Check one delivery order with the component has been created for the subcontractor
+ mo = self.env['mrp.production'].search([('bom_id', '=', self.bom.id)])
+ self.assertEqual(mo.state, 'confirmed')
+ # Check that 1 delivery with 1 component for the subcontractor has been created
+ picking_delivery = mo.picking_ids
+ wh = picking_delivery.picking_type_id.warehouse_id
+ origin = picking_delivery.origin
+ self.assertEqual(len(picking_delivery), 1)
+ self.assertEqual(len(picking_delivery.move_ids_without_package), 1)
+ self.assertEqual(picking_delivery.picking_type_id, wh.out_type_id)
+ self.assertEqual(picking_delivery.partner_id, self.subcontractor_partner1)
+
+ # Change the purchased quantity to 2
+ po.order_line.write({'product_qty': 2})
+ # Check that two deliveries with 1 component for the subcontractor have been created
+ picking_deliveries = self.env['stock.picking'].search([('origin', '=', origin)])
+ self.assertEqual(len(picking_deliveries), 2)
+ self.assertEqual(picking_deliveries[0].picking_type_id, wh.out_type_id)
+ self.assertEqual(picking_deliveries[0].partner_id, self.subcontractor_partner1)
+ self.assertTrue(picking_deliveries[0].state != 'cancel')
+ move1 = picking_deliveries[0].move_ids_without_package
+ self.assertEqual(picking_deliveries[1].picking_type_id, wh.out_type_id)
+ self.assertEqual(picking_deliveries[1].partner_id, self.subcontractor_partner1)
+ self.assertTrue(picking_deliveries[1].state != 'cancel')
+ move2 = picking_deliveries[1].move_ids_without_package
+ self.assertEqual(move1.product_id, self.comp1)
+ self.assertEqual(move1.product_uom_qty, 1)
+ self.assertEqual(move2.product_id, self.comp1)
+ self.assertEqual(move2.product_uom_qty, 1)