diff --git a/mrp_subcontracting_purchase/__init__.py b/mrp_subcontracting_purchase/__init__.py new file mode 100644 index 0000000000..dc5e6b693d --- /dev/null +++ b/mrp_subcontracting_purchase/__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/mrp_subcontracting_purchase/__manifest__.py b/mrp_subcontracting_purchase/__manifest__.py new file mode 100644 index 0000000000..2e4ac2e70b --- /dev/null +++ b/mrp_subcontracting_purchase/__manifest__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +{ + 'name': 'Purchase and Subcontracting Management', + 'version': '0.1', + 'category': 'Manufacturing/Purchase', + 'description': """ + This bridge module adds some smart buttons between Purchase and Subcontracting + """, + 'depends': ['mrp_subcontracting', 'purchase'], + 'data': [ + 'views/purchase_order_views.xml', + 'views/stock_picking_views.xml', + ], + 'installable': True, + 'auto_install': True, + 'license': 'LGPL-3', +} diff --git a/mrp_subcontracting_purchase/models/__init__.py b/mrp_subcontracting_purchase/models/__init__.py new file mode 100644 index 0000000000..eee25d6fe2 --- /dev/null +++ b/mrp_subcontracting_purchase/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import stock_picking +from . import purchase_order diff --git a/mrp_subcontracting_purchase/models/purchase_order.py b/mrp_subcontracting_purchase/models/purchase_order.py new file mode 100644 index 0000000000..7283167c3c --- /dev/null +++ b/mrp_subcontracting_purchase/models/purchase_order.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models, fields, api + + +class PurchaseOrder(models.Model): + _inherit = 'purchase.order' + + subcontracting_resupply_picking_count = fields.Integer( + "Count of Subcontracting Resupply", compute='_compute_subcontracting_resupply_picking_count', + help="Count of Subcontracting Resupply for component") + + @api.depends('order_line.move_ids') + def _compute_subcontracting_resupply_picking_count(self): + for purchase in self: + purchase.subcontracting_resupply_picking_count = len(purchase._get_subcontracting_resupplies()) + + def action_view_subcontracting_resupply(self): + return self._get_action_view_picking(self._get_subcontracting_resupplies()) + + def _get_subcontracting_resupplies(self): + moves_subcontracted = self.order_line.move_ids.filtered(lambda m: m.is_subcontract) + subcontracted_productions = moves_subcontracted.move_orig_ids.production_id + return subcontracted_productions.picking_ids diff --git a/mrp_subcontracting_purchase/models/stock_picking.py b/mrp_subcontracting_purchase/models/stock_picking.py new file mode 100644 index 0000000000..e168034ecb --- /dev/null +++ b/mrp_subcontracting_purchase/models/stock_picking.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models, fields, api, _ + + +class StockPicking(models.Model): + _inherit = 'stock.picking' + + subcontracting_source_purchase_count = fields.Integer( + "Number of subcontracting PO Source", compute='_compute_subcontracting_source_purchase_count', + help="Number of subcontracting Purchase Order Source") + + @api.depends('move_lines.move_dest_ids.raw_material_production_id') + def _compute_subcontracting_source_purchase_count(self): + for picking in self: + picking.subcontracting_source_purchase_count = len(picking._get_subcontracting_source_purchase()) + + def action_view_subcontracting_source_purchase(self): + purchase_order_ids = self._get_subcontracting_source_purchase().ids + action = { + 'res_model': 'purchase.order', + 'type': 'ir.actions.act_window', + } + if len(purchase_order_ids) == 1: + action.update({ + 'view_mode': 'form', + 'res_id': purchase_order_ids[0], + }) + else: + action.update({ + 'name': _("Source PO of %s", self.name), + 'domain': [('id', 'in', purchase_order_ids)], + 'view_mode': 'tree,form', + }) + return action + + def _get_subcontracting_source_purchase(self): + moves_subcontracted = self.move_lines.move_dest_ids.raw_material_production_id.move_finished_ids.move_dest_ids.filtered(lambda m: m.is_subcontract) + return moves_subcontracted.purchase_line_id.order_id diff --git a/mrp_subcontracting_purchase/tests/__init__.py b/mrp_subcontracting_purchase/tests/__init__.py new file mode 100644 index 0000000000..5fb08a3fea --- /dev/null +++ b/mrp_subcontracting_purchase/tests/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import test_mrp_subcontracting_purchase diff --git a/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py b/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py new file mode 100644 index 0000000000..cfd4f253bc --- /dev/null +++ b/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import Command + +from odoo.addons.mrp_subcontracting.tests.common import TestMrpSubcontractingCommon + + +class MrpSubcontractingPurchaseTest(TestMrpSubcontractingCommon): + + def test_count_smart_buttons(self): + resupply_sub_on_order_route = self.env['stock.location.route'].search([('name', '=', 'Resupply Subcontractor on Order')]) + (self.comp1 + self.comp2).write({'route_ids': [Command.link(resupply_sub_on_order_route.id)]}) + + # I create a draft Purchase Order for first in move for 10 kg at 50 euro + po = self.env['purchase.order'].create({ + 'partner_id': self.subcontractor_partner1.id, + 'order_line': [Command.create({ + 'name': 'finished', + 'product_id': self.finished.id, + 'product_qty': 1.0, + 'product_uom': self.finished.uom_id.id, + 'price_unit': 50.0} + )], + }) + + po.button_confirm() + + self.assertEqual(po.subcontracting_resupply_picking_count, 1) + action1 = po.action_view_subcontracting_resupply() + picking = self.env[action1['res_model']].browse(action1['res_id']) + self.assertEqual(picking.subcontracting_source_purchase_count, 1) + action2 = picking.action_view_subcontracting_source_purchase() + po_action2 = self.env[action2['res_model']].browse(action2['res_id']) + self.assertEqual(po_action2, po) diff --git a/mrp_subcontracting_purchase/views/purchase_order_views.xml b/mrp_subcontracting_purchase/views/purchase_order_views.xml new file mode 100644 index 0000000000..1c783b2543 --- /dev/null +++ b/mrp_subcontracting_purchase/views/purchase_order_views.xml @@ -0,0 +1,20 @@ + + + + purchase.order.inherited.form.mrp.subcontracting.purchase + purchase.order + + + + + + + + diff --git a/mrp_subcontracting_purchase/views/stock_picking_views.xml b/mrp_subcontracting_purchase/views/stock_picking_views.xml new file mode 100644 index 0000000000..6b78a88238 --- /dev/null +++ b/mrp_subcontracting_purchase/views/stock_picking_views.xml @@ -0,0 +1,20 @@ + + + + stock.picking.inherited.form.mrp.subcontracting + stock.picking + + + + + + + +