diff --git a/mrp_multi_level/models/mrp_area.py b/mrp_multi_level/models/mrp_area.py index ad0368e40..561b4ba8d 100644 --- a/mrp_multi_level/models/mrp_area.py +++ b/mrp_multi_level/models/mrp_area.py @@ -1,10 +1,10 @@ # © 2016 Ucamco - Wim Audenaert -# Copyright 2016-19 ForgeFlow S.L. (https://www.forgeflow.com) +# Copyright 2016-21 ForgeFlow S.L. (https://www.forgeflow.com) # - Jordi Ballester Alomar # - Lois Rilo Antelo # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). -from odoo import fields, models +from odoo import api, fields, models class MrpArea(models.Model): @@ -28,6 +28,14 @@ class MrpArea(models.Model): related="warehouse_id.calendar_id", ) + @api.model + def _datetime_to_date_tz(self, dt_to_convert=None): + """Coverts a datetime to date considering the timezone of MRP Area. + If no datetime is provided, it returns today's date in the timezone.""" + return fields.Date.context_today( + self.with_context(tz=self.calendar_id.tz), timestamp=dt_to_convert, + ) + def _get_locations(self): self.ensure_one() return self.env["stock.location"].search( diff --git a/mrp_multi_level/tests/common.py b/mrp_multi_level/tests/common.py index 20482b437..7108645e4 100644 --- a/mrp_multi_level/tests/common.py +++ b/mrp_multi_level/tests/common.py @@ -186,6 +186,19 @@ class TestMrpMultiLevelCommon(SavepointCase): "mrp_qty_multiple": 5.0, } ) + # Another product: + cls.product_tz = cls.product_obj.create( + { + "name": "Product Timezone", + "type": "product", + "list_price": 100.0, + "route_ids": [(6, 0, [route_buy])], + "seller_ids": [(0, 0, {"name": vendor1.id, "price": 20.0})], + } + ) + cls.product_mrp_area_obj.create( + {"product_id": cls.product_tz.id, "mrp_area_id": cls.cases_area.id} + ) # Create pickings for Scenario 1: dt_base = cls.calendar.plan_days(3 + 1, datetime.today()) diff --git a/mrp_multi_level/tests/test_mrp_multi_level.py b/mrp_multi_level/tests/test_mrp_multi_level.py index 9282ad9a7..a0ab39d9b 100644 --- a/mrp_multi_level/tests/test_mrp_multi_level.py +++ b/mrp_multi_level/tests/test_mrp_multi_level.py @@ -1,6 +1,8 @@ # Copyright 2018-19 ForgeFlow S.L. (https://www.forgeflow.com) # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). +from datetime import date, datetime + from odoo import fields from .common import TestMrpMultiLevelCommon @@ -336,3 +338,40 @@ class TestMrpMultiLevel(TestMrpMultiLevelCommon): [("product_mrp_area_id.product_id", "=", self.av_22.id)] ) self.assertTrue(av_22_supply) + + def test_13_timezone_handling(self): + self.calendar.tz = "Australia/Sydney" # Oct-Apr/Apr-Oct: UTC+11/UTC+10 + date_move = datetime(2090, 4, 19, 20, 00) # Apr 20 6/7 am in Sidney + sidney_date = date(2090, 4, 20) + self._create_picking_in( + self.product_tz, 10.0, date_move, location=self.cases_loc + ) + self.mrp_multi_level_wiz.create( + {"mrp_area_ids": [(6, 0, self.cases_area.ids)]} + ).run_mrp_multi_level() + inventory = self.mrp_inventory_obj.search( + [ + ("mrp_area_id", "=", self.cases_area.id), + ("product_id", "=", self.product_tz.id), + ] + ) + self.assertEqual(len(inventory), 1) + self.assertEqual(inventory.date, sidney_date) + + def test_14_timezone_not_set(self): + self.wh.calendar_id = False + date_move = datetime(2090, 4, 19, 20, 00) + self._create_picking_in( + self.product_tz, 10.0, date_move, location=self.cases_loc + ) + self.mrp_multi_level_wiz.create( + {"mrp_area_ids": [(6, 0, self.cases_area.ids)]} + ).run_mrp_multi_level() + inventory = self.mrp_inventory_obj.search( + [ + ("mrp_area_id", "=", self.cases_area.id), + ("product_id", "=", self.product_tz.id), + ] + ) + self.assertEqual(len(inventory), 1) + self.assertEqual(inventory.date, date_move.date()) diff --git a/mrp_multi_level/wizards/mrp_multi_level.py b/mrp_multi_level/wizards/mrp_multi_level.py index bb7557185..ee2d370d0 100644 --- a/mrp_multi_level/wizards/mrp_multi_level.py +++ b/mrp_multi_level/wizards/mrp_multi_level.py @@ -22,8 +22,6 @@ class MultiLevelMrp(models.TransientModel): help="If empty, all areas will be computed.", ) - # TODO: dates are not being correctly computed for supply... - @api.model def _prepare_product_mrp_area_data(self, product_mrp_area): qty_available = 0.0 @@ -45,6 +43,7 @@ class MultiLevelMrp(models.TransientModel): def _prepare_mrp_move_data_from_stock_move( self, product_mrp_area, move, direction="in" ): + area = product_mrp_area.mrp_area_id if direction == "out": mrp_type = "d" product_qty = -move.product_qty @@ -74,9 +73,13 @@ class MultiLevelMrp(models.TransientModel): else: order_number = (move.picking_id or move).name origin = "mv" - mrp_date = date.today() - if move.date_expected.date() > date.today(): - mrp_date = move.date_expected.date() + # The date to display is based on the timezone of the warehouse. + today_tz = area._datetime_to_date_tz() + move_date_tz = area._datetime_to_date_tz(move.date_expected) + if move_date_tz > today_tz: + mrp_date = move_date_tz + else: + mrp_date = today_tz return { "product_id": move.product_id.id, "product_mrp_area_id": product_mrp_area.id,