From ee096b365499efc9021f76789da0a70645f61c52 Mon Sep 17 00:00:00 2001 From: mreficent Date: Wed, 21 Jun 2017 14:47:43 +0200 Subject: [PATCH] [MIG] stock_removal_location_by_priority: Migration to 10.0 --- stock_removal_location_by_priority/README.rst | 11 +++- .../{__openerp__.py => __manifest__.py} | 3 +- .../models/__init__.py | 2 + .../models/res_company.py | 16 +++++ .../models/stock_config_settings.py | 13 ++++ .../models/stock_location.py | 2 +- .../models/stock_quant.py | 24 +++---- ...test_stock_removal_location_by_priority.py | 63 ++++++++++++++++++- .../views/res_config_settings_views.xml | 27 ++++++++ .../views/stock_location_view.xml | 2 +- 10 files changed, 140 insertions(+), 23 deletions(-) rename stock_removal_location_by_priority/{__openerp__.py => __manifest__.py} (90%) create mode 100644 stock_removal_location_by_priority/models/res_company.py create mode 100644 stock_removal_location_by_priority/models/stock_config_settings.py create mode 100644 stock_removal_location_by_priority/views/res_config_settings_views.xml diff --git a/stock_removal_location_by_priority/README.rst b/stock_removal_location_by_priority/README.rst index 9d50c17bb..c9a8fd763 100644 --- a/stock_removal_location_by_priority/README.rst +++ b/stock_removal_location_by_priority/README.rst @@ -15,13 +15,20 @@ Configuration You can configure the removal priority as follows: +#. Go to "Inventory > Configuration > Settings" +#. In 'Location & Warehouse' section, mark "Use 'Removal Priority' in Locations *" + +Usage +===== + +To use this module, you need to: + #. Go to "Inventory > Configuration > Warehouse Management > Locations" #. In each Location form, put a Removal Priority. - .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/153/9.0 + :target: https://runbot.odoo-community.org/runbot/153/10.0 Bug Tracker diff --git a/stock_removal_location_by_priority/__openerp__.py b/stock_removal_location_by_priority/__manifest__.py similarity index 90% rename from stock_removal_location_by_priority/__openerp__.py rename to stock_removal_location_by_priority/__manifest__.py index 91dd2d686..95870c0a7 100644 --- a/stock_removal_location_by_priority/__openerp__.py +++ b/stock_removal_location_by_priority/__manifest__.py @@ -5,13 +5,14 @@ { "name": "Stock Removal Location by Priority", "summary": "Establish a removal priority on stock locations.", - "version": "9.0.1.0.0", + "version": "10.0.1.0.0", "author": "Eficent, " "Odoo Community Association (OCA)", "website": "https://github.com/OCA/stock-logistics-warehouse", "category": "Warehouse Management", "depends": ["stock"], "data": [ + 'views/res_config_settings_views.xml', 'views/stock_location_view.xml'], "license": "AGPL-3", 'installable': True, diff --git a/stock_removal_location_by_priority/models/__init__.py b/stock_removal_location_by_priority/models/__init__.py index 89a4028f3..76a62a061 100644 --- a/stock_removal_location_by_priority/models/__init__.py +++ b/stock_removal_location_by_priority/models/__init__.py @@ -3,5 +3,7 @@ # (http://www.eficent.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from . import res_company +from . import stock_config_settings from . import stock_location from . import stock_quant diff --git a/stock_removal_location_by_priority/models/res_company.py b/stock_removal_location_by_priority/models/res_company.py new file mode 100644 index 000000000..a920ba57f --- /dev/null +++ b/stock_removal_location_by_priority/models/res_company.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Eficent Business and IT Consulting Services S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResCompany(models.Model): + _inherit = "res.company" + + removal_priority_active = fields.Boolean( + string="Use 'Removal Priority' in Locations", + help="Adds an extra field in Locations named 'Removal Priority'." + "When removing stock from Locations, this priority will apply" + "whenever the incoming dates of the same stock in several " + "locations are the same.") diff --git a/stock_removal_location_by_priority/models/stock_config_settings.py b/stock_removal_location_by_priority/models/stock_config_settings.py new file mode 100644 index 000000000..6b7e3b835 --- /dev/null +++ b/stock_removal_location_by_priority/models/stock_config_settings.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class StockConfigSettings(models.TransientModel): + _inherit = 'stock.config.settings' + + removal_priority_active = fields.Boolean( + related='company_id.removal_priority_active', + string="Use 'Removal Priority' in Locations (*)", + help="This configuration is related to the company you're logged into") diff --git a/stock_removal_location_by_priority/models/stock_location.py b/stock_removal_location_by_priority/models/stock_location.py index 2c0a3c308..08d948fd2 100644 --- a/stock_removal_location_by_priority/models/stock_location.py +++ b/stock_removal_location_by_priority/models/stock_location.py @@ -3,7 +3,7 @@ # (http://www.eficent.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from openerp import fields, models +from odoo import fields, models class StockLocation(models.Model): diff --git a/stock_removal_location_by_priority/models/stock_quant.py b/stock_removal_location_by_priority/models/stock_quant.py index 72c6da995..febc26e1c 100644 --- a/stock_removal_location_by_priority/models/stock_quant.py +++ b/stock_removal_location_by_priority/models/stock_quant.py @@ -3,32 +3,26 @@ # (http://www.eficent.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from openerp import api, fields, models -from openerp.tools.translate import _ -from openerp.exceptions import UserError +from odoo import api, fields, models +from odoo.tools.translate import _ +from odoo.exceptions import UserError -class StockQuant(models.Model): +class Quant(models.Model): _inherit = 'stock.quant' removal_priority = fields.Integer( related='location_id.removal_priority', readonly=True, store=True) @api.model - def apply_removal_strategy(self, quantity, move, ops=False, - domain=None, removal_strategy='fifo'): - if any(move.mapped('location_id.removal_priority')): + def _quants_removal_get_order(self, removal_strategy=None): + if self.env.user.company_id.removal_priority_active: if removal_strategy == 'fifo': - order = 'in_date, removal_priority, id' - return self._quants_get_order( - quantity, move, ops=ops, domain=domain, orderby=order) + return 'in_date, removal_priority, id' elif removal_strategy == 'lifo': - order = 'in_date desc, removal_priority asc, id desc' - return self._quants_get_order( - quantity, move, ops=ops, domain=domain, orderby=order) + return 'in_date desc, removal_priority asc, id desc' raise UserError(_('Removal strategy %s not implemented.') % ( removal_strategy,)) else: - return super(StockQuant, self).apply_removal_strategy( - self, quantity, move, ops=ops, domain=domain, + return super(Quant, self)._quants_removal_get_order( removal_strategy=removal_strategy) diff --git a/stock_removal_location_by_priority/tests/test_stock_removal_location_by_priority.py b/stock_removal_location_by_priority/tests/test_stock_removal_location_by_priority.py index 1c2a4f460..c93bef685 100644 --- a/stock_removal_location_by_priority/tests/test_stock_removal_location_by_priority.py +++ b/stock_removal_location_by_priority/tests/test_stock_removal_location_by_priority.py @@ -2,7 +2,7 @@ # Copyright 2017 Eficent Business and IT Consulting Services S.L. # (http://www.eficent.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from openerp.tests.common import TransactionCase +from odoo.tests.common import TransactionCase class TestStockRemovalLocationByPriority(TransactionCase): @@ -22,7 +22,8 @@ class TestStockRemovalLocationByPriority(TransactionCase): self.location_supplier = self.env.ref('stock.stock_location_suppliers') self.company = self.env.ref('base.main_company') - self.partner = self.env.ref('base.res_partner_1') + self.company.removal_priority_active = True + self.g_stock_user = self.env.ref('stock.group_stock_user') self.user = self._create_user( @@ -89,7 +90,7 @@ class TestStockRemovalLocationByPriority(TransactionCase): }) return picking - def test_stock_removal_location_by_priority(self): + def test_stock_removal_location_by_priority_fifo(self): """Tests removal priority.""" wiz1 = self.stock_change_model.with_context( active_id=self.product_templ_1.id, @@ -138,3 +139,59 @@ class TestStockRemovalLocationByPriority(TransactionCase): for record in records: self.assertEqual(record.qty, 5, 'Removal_priority did\'nt work properly.') + + def test_stock_removal_location_by_priority_lifo(self): + """Tests removal priority.""" + removal_method_id = self.env['product.removal'].search( + [('name', '=', 'lifo')]).id + self.stock.removal_strategy_id = removal_method_id + self.shelf_A.removal_strategy_id = removal_method_id + self.shelf_B.removal_strategy_id = removal_method_id + self.location_supplier.removal_strategy_id = removal_method_id + wiz1 = self.stock_change_model.with_context( + active_id=self.product_templ_1.id, + active_model='product.template' + ).create({'new_quantity': 20, + 'location_id': self.stock.id, + 'product_tmpl_id': self.product_templ_1.id, + }) + wiz1.change_product_qty() + self.product1 = wiz1.product_id + + picking_1 = self._create_picking( + self.picking_internal, self.stock, self.shelf_A, 5) + picking_1.action_confirm() + picking_1.action_assign() + + picking_2 = self._create_picking( + self.picking_internal, self.stock, self.shelf_B, 10) + picking_2.action_confirm() + picking_2.action_assign() + + self.assertEqual(picking_1.pack_operation_ids. + linked_move_operation_ids.reserved_quant_id.in_date, + picking_2.pack_operation_ids. + linked_move_operation_ids.reserved_quant_id.in_date, + 'Testing data not generated properly.') + + wiz_act = picking_1.do_new_transfer() + wiz2 = self.env[wiz_act['res_model']].browse(wiz_act['res_id']) + wiz2.process() + + wiz_act = picking_2.do_new_transfer() + wiz3 = self.env[wiz_act['res_model']].browse(wiz_act['res_id']) + wiz3.process() + + picking_3 = self._create_picking( + self.picking_out, self.stock, self.location_supplier, 5) + picking_3.action_confirm() + picking_3.action_assign() + wiz_act = picking_3.do_new_transfer() + wiz4 = self.env[wiz_act['res_model']].browse(wiz_act['res_id']) + wiz4.process() + + records = self.quant_model.search( + [('product_id', '=', self.product1.id)]) + for record in records: + self.assertEqual(record.qty, 5, + 'Removal_priority did\'nt work properly.') diff --git a/stock_removal_location_by_priority/views/res_config_settings_views.xml b/stock_removal_location_by_priority/views/res_config_settings_views.xml new file mode 100644 index 000000000..28b6e25a4 --- /dev/null +++ b/stock_removal_location_by_priority/views/res_config_settings_views.xml @@ -0,0 +1,27 @@ + + + + + + stock.config.view - removal_priority + stock.config.settings + + + + + +
+ + + +
+
+
+ (*) This configuration is related to the company you're logged into. +
+
+
+
+ +
diff --git a/stock_removal_location_by_priority/views/stock_location_view.xml b/stock_removal_location_by_priority/views/stock_location_view.xml index 5a287231b..db4fd46ac 100644 --- a/stock_removal_location_by_priority/views/stock_location_view.xml +++ b/stock_removal_location_by_priority/views/stock_location_view.xml @@ -10,7 +10,7 @@ - +