From a99f75b0435bd9af33a55f0dc2be675ac1feed03 Mon Sep 17 00:00:00 2001 From: "Ahmed Khalaf (ahkh)" Date: Thu, 1 Sep 2022 15:36:46 +0000 Subject: [PATCH] [IMP] mrp_subcontracting{_dropshipping}: archive/unarchive subcontract rules This commit allows the user to archive/unarchive subcontracting rules by toggling warehouse settings `Dropship Subcontractors` and `Resupply Subcontractors`. Additionally, if there is no warehouse with a setting enabled, the corresponding global routes are archived as well. Part-of: odoo/odoo#95770 --- .../models/stock_warehouse.py | 46 +++++++++++++++- .../models/stock_warehouse.py | 54 ++++++++++++++++++- 2 files changed, 97 insertions(+), 3 deletions(-) diff --git a/addons/mrp_subcontracting/models/stock_warehouse.py b/addons/mrp_subcontracting/models/stock_warehouse.py index 3611636f8dc..4aa4f3362a6 100644 --- a/addons/mrp_subcontracting/models/stock_warehouse.py +++ b/addons/mrp_subcontracting/models/stock_warehouse.py @@ -28,6 +28,19 @@ class StockWarehouse(models.Model): def create(self, vals_list): res = super().create(vals_list) res._update_subcontracting_locations_rules() + # if new warehouse has resupply enabled, enable global route + if any([vals.get('subcontracting_to_resupply', False) for vals in vals_list]): + res._update_global_route_resupply_subcontractor() + return res + + def write(self, vals): + res = super().write(vals) + # if all warehouses have resupply disabled, disable global route, until its enabled on a warehouse + if 'subcontracting_to_resupply' in vals or 'active' in vals: + if 'subcontracting_to_resupply' in vals: + # ignore when warehouse archived since it will auto-archive all of its rules + self._update_resupply_rules() + self._update_global_route_resupply_subcontractor() return res def get_rules_dict(self): @@ -41,6 +54,14 @@ class StockWarehouse(models.Model): }) return result + def _update_global_route_resupply_subcontractor(self): + route_id = self._find_global_route('mrp_subcontracting.route_resupply_subcontractor_mto', + _('Resupply Subcontractor on Order')) + if not route_id.sudo().rule_ids.filtered(lambda r: r.active): + route_id.active = False + else: + route_id.active = True + def _get_routes_values(self): routes = super(StockWarehouse, self)._get_routes_values() routes.update({ @@ -166,6 +187,7 @@ class StockWarehouse(models.Model): 'default_location_src_id': production_location_id.id, 'default_location_dest_id': subcontract_location_id.id, 'barcode': self.code.replace(" ", "").upper() + "-RESUPPLY", + 'active': self.subcontracting_to_resupply and self.active }, }) return data @@ -173,9 +195,29 @@ class StockWarehouse(models.Model): def _get_subcontracting_location(self): return self.company_id.subcontracting_location_id - def _update_subcontracting_locations_rules(self): - subcontracting_locations = self.env['stock.location'].search([ + def _get_subcontracting_locations(self): + return self.env['stock.location'].search([ ('company_id', 'in', self.company_id.ids), ('is_subcontracting_location', '=', 'True'), ]) + + def _update_subcontracting_locations_rules(self): + subcontracting_locations = self._get_subcontracting_locations() subcontracting_locations._activate_subcontracting_location_rules() + + def _update_resupply_rules(self): + '''update (archive/unarchive) any warehouse subcontracting location resupply rules''' + subcontracting_locations = self._get_subcontracting_locations() + warehouses_to_resupply = self.filtered(lambda w: w.subcontracting_to_resupply and w.active) + if warehouses_to_resupply: + self.env['stock.rule'].with_context(active_test=False).search([ + '&', ('picking_type_id', 'in', warehouses_to_resupply.subcontracting_resupply_type_id.ids), + '|', ('location_src_id', 'in', subcontracting_locations.ids), + ('location_dest_id', 'in', subcontracting_locations.ids)]).action_unarchive() + + warehouses_not_to_resupply = self - warehouses_to_resupply + if warehouses_not_to_resupply: + self.env['stock.rule'].search([ + '&', ('picking_type_id', 'in', warehouses_not_to_resupply.subcontracting_resupply_type_id.ids), + '|', ('location_src_id', 'in', subcontracting_locations.ids), + ('location_dest_id', 'in', subcontracting_locations.ids)]).action_archive() diff --git a/addons/mrp_subcontracting_dropshipping/models/stock_warehouse.py b/addons/mrp_subcontracting_dropshipping/models/stock_warehouse.py index 8b193aa5eea..04498fb55f6 100644 --- a/addons/mrp_subcontracting_dropshipping/models/stock_warehouse.py +++ b/addons/mrp_subcontracting_dropshipping/models/stock_warehouse.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import fields, models, _ +from odoo import api, fields, models, _ class StockWarehouse(models.Model): @@ -15,6 +15,58 @@ class StockWarehouse(models.Model): 'stock.rule', 'Subcontracting-Dropshipping MTS Rule' ) + @api.model_create_multi + def create(self, vals_list): + res = super().create(vals_list) + # if new warehouse has resupply enabled, enable global route + if any([vals.get('subcontracting_dropshipping_to_resupply', False) for vals in vals_list]): + res.update_global_route_dropship_subcontractor() + return res + + def write(self, vals): + res = super().write(vals) + # if all warehouses have resupply disabled, disable global route, until its enabled on a warehouse + if 'subcontracting_dropshipping_to_resupply' in vals or 'active' in vals: + if 'subcontracting_dropshipping_to_resupply' in vals: + # ignore when warehouse archived since it will auto-archive all of its rules + self._update_dropship_subcontract_rules() + self.update_global_route_dropship_subcontractor() + return res + + def _update_dropship_subcontract_rules(self): + '''update (archive/unarchive) any warehouse subcontracting location dropship rules''' + subcontracting_locations = self._get_subcontracting_locations() + route_id = self._find_global_route('mrp_subcontracting_dropshipping.route_subcontracting_dropshipping', + _('Dropship Subcontractor on Order')) + warehouses_dropship = self.filtered(lambda w: w.subcontracting_dropshipping_to_resupply and w.active) + if warehouses_dropship: + self.env['stock.rule'].with_context(active_test=False).search([ + ('route_id', '=', route_id.id), + ('action', '=', 'pull'), + ('warehouse_id', 'in', warehouses_dropship.ids), + ('location_src_id', 'in', subcontracting_locations.ids)]).action_unarchive() + + warehouses_no_dropship = self - warehouses_dropship + if warehouses_no_dropship: + self.env['stock.rule'].search([ + ('route_id', '=', route_id.id), + ('action', '=', 'pull'), + ('warehouse_id', 'in', warehouses_no_dropship.ids), + ('location_src_id', 'in', subcontracting_locations.ids)]).action_archive() + + def update_global_route_dropship_subcontractor(self): + route_id = self._find_global_route('mrp_subcontracting_dropshipping.route_subcontracting_dropshipping', + _('Dropship Subcontractor on Order')) + # if route has no pull rules, it means all warehouses have Dropship Subcontractor disabled + # Pick type is per company so we need to check rules per company to archive it, however + # the route is global so we need to check all rules regardless of company + all_rules = route_id.sudo().rule_ids.filtered(lambda r: r.active) + for company in self.company_id: + company_rules = all_rules.filtered(lambda r: r.company_id == company) + company.dropship_subcontractor_pick_type_id.active = bool(company_rules.filtered(lambda r: r.action == 'pull')) + + route_id.active = bool(all_rules.filtered(lambda r: r.action == 'pull')) + def _get_global_route_rules_values(self): rules = super()._get_global_route_rules_values() subcontract_location_id = self._get_subcontracting_location()