[FIX] mrp_multi_level: Consider timezone of the warehouse to generate mrp inventory records.

This commit is contained in:
Lois Rilo
2021-04-22 15:52:32 +02:00
parent 3e1561f351
commit bb088bd8ed
4 changed files with 70 additions and 7 deletions

View File

@@ -1,5 +1,5 @@
# © 2016 Ucamco - Wim Audenaert <wim.audenaert@ucamco.com>
# © 2016-19 ForgeFlow S.L. (https://www.forgeflow.com)
# © 2016-21 ForgeFlow S.L. (https://www.forgeflow.com)
# - Jordi Ballester Alomar <jordi.ballester@eficent.com>
# - Lois Rilo Antelo <lois.rilo@eficent.com>
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
@@ -32,6 +32,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,
)
@api.multi
def _get_locations(self):
self.ensure_one()

View File

@@ -165,6 +165,19 @@ class TestMrpMultiLevelCommon(SavepointCase):
'mrp_nbr_days': 7,
'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())

View File

@@ -1,10 +1,12 @@
# Copyright 2018-19 ForgeFlow S.L. (https://www.forgeflow.com)
# Copyright 2018-21 ForgeFlow S.L. (https://www.forgeflow.com)
# (http://www.eficent.com)
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from odoo.addons.mrp_multi_level.tests.common import TestMrpMultiLevelCommon
from odoo import fields
from datetime import date, datetime
class TestMrpMultiLevel(TestMrpMultiLevelCommon):
@@ -289,3 +291,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())

View File

@@ -20,8 +20,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
@@ -42,6 +40,7 @@ class MultiLevelMrp(models.TransientModel):
@api.model
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
@@ -70,9 +69,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,