diff --git a/shipment_advice_planner_toursolver/__manifest__.py b/shipment_advice_planner_toursolver/__manifest__.py
index 7a40fef5..226da9f9 100644
--- a/shipment_advice_planner_toursolver/__manifest__.py
+++ b/shipment_advice_planner_toursolver/__manifest__.py
@@ -8,10 +8,9 @@
"license": "AGPL-3",
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/stock-logistics-transport",
- "depends": ["shipment_advice_planner"],
+ "depends": ["shipment_advice_planner", "base_time_window"],
"data": [
# data
- "data/toursolver_delivery_week_day.xml",
"data/toursolver_backend.xml",
"data/ir_ui_menu.xml",
"data/ir_sequence.xml",
@@ -20,7 +19,6 @@
"security/toursolver_backend.xml",
"security/toursolver_resource.xml",
"security/toursolver_task.xml",
- "security/toursolver_delivery_week_day.xml",
"security/toursolver_delivery_window.xml",
# views
"views/toursolver_backend.xml",
diff --git a/shipment_advice_planner_toursolver/data/toursolver_delivery_week_day.xml b/shipment_advice_planner_toursolver/data/toursolver_delivery_week_day.xml
deleted file mode 100644
index aa08bb4d..00000000
--- a/shipment_advice_planner_toursolver/data/toursolver_delivery_week_day.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
- 0
-
-
- 1
-
-
- 2
-
-
- 3
-
-
- 4
-
-
- 5
-
-
- 6
-
-
diff --git a/shipment_advice_planner_toursolver/models/__init__.py b/shipment_advice_planner_toursolver/models/__init__.py
index e507edb5..8585920e 100644
--- a/shipment_advice_planner_toursolver/models/__init__.py
+++ b/shipment_advice_planner_toursolver/models/__init__.py
@@ -5,6 +5,5 @@
from . import toursolver_task
from . import stock_picking
from . import toursolver_delivery_window
-from . import toursolver_delivery_week_day
from . import res_partner
from . import shipment_advice
diff --git a/shipment_advice_planner_toursolver/models/res_partner.py b/shipment_advice_planner_toursolver/models/res_partner.py
index 9dea407b..215be39a 100644
--- a/shipment_advice_planner_toursolver/models/res_partner.py
+++ b/shipment_advice_planner_toursolver/models/res_partner.py
@@ -22,37 +22,14 @@ def _get_delivery_windows(self, day_name):
"""
Return the list of delivery windows by partner id for the given day.
- :param day: The day name (see toursolver.delivery.week.day)
+ :param day: The day name (see time.weekday)
:return: dict partner_id:[delivery_window, ]
"""
self.ensure_one()
- week_day_id = self.env["toursolver.delivery.week.day"]._get_id_by_name(day_name)
+ week_day_id = self.env["time.weekday"]._get_id_by_name(day_name)
return self.env["toursolver.delivery.window"].search(
- [("partner_id", "=", self.id), ("week_day_ids", "in", week_day_id)]
+ [
+ ("partner_id", "=", self.id),
+ ("time_window_weekday_ids", "in", week_day_id),
+ ]
)
-
- def _get_delivery_sequence(self, day_name):
- """
- Return a sequence position by partner id for the given day.
-
- The sequence is computed from the delivery_widow start
-
- :param day: The day name (see toursolver.delivery.week.day)
- :return: dict partner_id:sequence
- """
- week_day_id = self.env["toursolver.delivery.week.day"]._get_id_by_name(day_name)
- res = {}
- windows = self.env["toursolver.delivery.window"].search(
- [("partner_id", "in", self.ids), ("week_day_ids", "in", week_day_id)],
- order="start ASC",
- )
- i = 1
- for window in windows.sorted("start"):
- if window.partner_id.id not in res:
- res[window.partner_id.id] = i
- i += 1
- for partner in self.sorted("name"):
- if partner.id not in res:
- res[partner.id] = i
- i += 1
- return res
diff --git a/shipment_advice_planner_toursolver/models/toursolver_delivery_week_day.py b/shipment_advice_planner_toursolver/models/toursolver_delivery_week_day.py
deleted file mode 100644
index c9c85971..00000000
--- a/shipment_advice_planner_toursolver/models/toursolver_delivery_week_day.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2020 ACSONE SA/NV
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-
-from odoo import _, api, fields, models, tools
-
-
-class TourSolverDeliveryWeekDay(models.Model):
-
- _name = "toursolver.delivery.week.day"
- _description = "Delivery Week Day"
-
- name = fields.Selection(
- selection=[
- ("0", "Monday"),
- ("1", "Tuesday"),
- ("2", "Wednesday"),
- ("3", "Thursday"),
- ("4", "Friday"),
- ("5", "Saturday"),
- ("6", "Sunday"),
- ],
- required=True,
- )
- _sql_constraints = [("name_uniq", "UNIQUE(name)", _("Name must be unique"))]
-
- @api.model
- @tools.ormcache("name")
- def _get_id_by_name(self, name):
- return self.search([("name", "=", name)], limit=1).id
-
- @api.depends("name")
- def _compute_display_name(self):
- """
- WORKAROUND since Odoo doesn't handle properly records where name is.
-
- a selection
- """
- translated_values = dict(self._fields["name"]._description_selection(self.env))
- for record in self:
- record.display_name = translated_values[record.name]
-
- def name_get(self):
- """
- WORKAROUND since Odoo doesn't handle properly records where name is.
-
- a selection
- """
- return [(r.id, r.display_name) for r in self]
diff --git a/shipment_advice_planner_toursolver/models/toursolver_delivery_window.py b/shipment_advice_planner_toursolver/models/toursolver_delivery_window.py
index fcf7f940..9b8e3edf 100644
--- a/shipment_advice_planner_toursolver/models/toursolver_delivery_window.py
+++ b/shipment_advice_planner_toursolver/models/toursolver_delivery_window.py
@@ -1,25 +1,18 @@
# Copyright 2020 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-import math
-from psycopg2.extensions import AsIs
-
-from odoo import _, api, fields, models
-from odoo.exceptions import ValidationError
+from odoo import fields, models
class ToursolverDeliveryWindow(models.Model):
_name = "toursolver.delivery.window"
+ _inherit = "time.window.mixin"
_description = "TourSolver Delivery Window"
- _order = "partner_id, start"
+ _order = "partner_id, time_window_start"
+ _time_window_overlap_check_field = "partner_id"
- start = fields.Float("From", required=True)
- end = fields.Float("To", required=True)
- week_day_ids = fields.Many2many(
- comodel_name="toursolver.delivery.week.day", required=True
- )
partner_id = fields.Many2one(
comodel_name="res.partner", required=True, index=True, ondelete="cascade"
)
@@ -28,69 +21,3 @@ class ToursolverDeliveryWindow(models.Model):
required=True,
default="preferable",
)
-
- @api.constrains("start", "end", "week_day_ids")
- def _check_window_no_onverlaps(self):
- week_days_field = self._fields["week_day_ids"]
- for record in self:
- if record.start > record.end:
- raise ValidationError(_("End time must be higher than start time."))
- # here we use a plain SQL query to benefit of the numrange
- # function available in PostgresSQL
- # (http://www.postgresql.org/docs/current/static/rangetypes.html)
- sql_query = """
- SELECT
- id
- FROM
- %(table)s w
- join %(relation)s as d
- on d.%(relation_window_fkey)s = w.id
- WHERE
- NUMRANGE(w.start::numeric, w.end::numeric) &&
- NUMRANGE(%(start)s::numeric, %(end)s::numeric)
- AND w.id != %(window_id)s
- AND d.%(relation_week_day_fkey)s in %(week_day_ids)s
- AND w.partner_id = %(partner_id)s"""
- self.env.cr.execute(
- sql_query,
- dict(
- table=AsIs(self._table),
- relation=AsIs(week_days_field.relation),
- relation_window_fkey=AsIs(week_days_field.column1),
- relation_week_day_fkey=AsIs(week_days_field.column2),
- start=record.start,
- end=record.end,
- window_id=record.id,
- week_day_ids=tuple(record.week_day_ids.ids),
- partner_id=record.partner_id.id,
- ),
- )
- res = self.env.cr.fetchall()
- if res:
- other = self.browse(res[0][0])
- raise ValidationError(
- _("%(rec_display_name)s overlaps %(other_display_name)s")
- % dict(
- rec_display_name=record.display_name,
- other_display_name=other.display_name,
- )
- )
-
- @api.depends("start", "end", "week_day_ids")
- def _compute_display_name(self):
- for record in self:
- days = ", ".join(record.week_day_ids.mapped("display_name"))
- start = self.float_to_time_repr(record.start)
- end = self.float_to_time_repr(record.end)
- record.display_name = f"{days}: From {start} to {end}"
-
- @api.model
- def float_to_time_repr(self, value):
- pattern = "%02d:%02d"
- hour = math.floor(value)
- min_ = round((value % 1) * 60)
- if min_ == 60:
- min_ = 0
- hour += 1
-
- return pattern % (hour, min_)
diff --git a/shipment_advice_planner_toursolver/models/toursolver_resource.py b/shipment_advice_planner_toursolver/models/toursolver_resource.py
index ffd5e50d..7fc6fea3 100644
--- a/shipment_advice_planner_toursolver/models/toursolver_resource.py
+++ b/shipment_advice_planner_toursolver/models/toursolver_resource.py
@@ -24,7 +24,7 @@ class ToursolverResource(models.Model):
)
use_delivery_person_coordinates_as_end = fields.Boolean(
help="If true the computed delivery will end at the delivery person's "
- "address. Otherwise it will end at the Alcyon warehouse"
+ "address. Otherwise it will end at the warehouse address"
)
partner_id = fields.Many2one(comodel_name="res.partner", string="Contact")
diff --git a/shipment_advice_planner_toursolver/models/toursolver_task.py b/shipment_advice_planner_toursolver/models/toursolver_task.py
index e9f2b1c4..9b244a65 100644
--- a/shipment_advice_planner_toursolver/models/toursolver_task.py
+++ b/shipment_advice_planner_toursolver/models/toursolver_task.py
@@ -291,8 +291,10 @@ def _toursolver_json_request_order_time_window(self, partner):
for window in delivery_windows:
time_windows.append(
{
- "beginTime": window.float_to_time_repr(window.start),
- "endTime": window.float_to_time_repr(window.end),
+ "beginTime": window.float_to_time_repr(
+ window.time_window_start
+ ),
+ "endTime": window.float_to_time_repr(window.time_window_end),
}
)
else:
diff --git a/shipment_advice_planner_toursolver/security/toursolver_delivery_week_day.xml b/shipment_advice_planner_toursolver/security/toursolver_delivery_week_day.xml
deleted file mode 100644
index 35f3a29a..00000000
--- a/shipment_advice_planner_toursolver/security/toursolver_delivery_week_day.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
- toursolver.delivery.window.day access read
-
-
-
-
-
-
-
-
diff --git a/shipment_advice_planner_toursolver/tests/test_toursolver_delivery_window.py b/shipment_advice_planner_toursolver/tests/test_toursolver_delivery_window.py
index 0134a3aa..62aba4d0 100644
--- a/shipment_advice_planner_toursolver/tests/test_toursolver_delivery_window.py
+++ b/shipment_advice_planner_toursolver/tests/test_toursolver_delivery_window.py
@@ -13,12 +13,8 @@ def setUpClass(cls):
cls.partner_model = cls.env["res.partner"]
cls.partner_1 = cls.partner_model.create({"name": "partner 1"})
cls.partner_2 = cls.partner_model.create({"name": "patner 2"})
- cls.monday = cls.env.ref(
- "shipment_advice_planner_toursolver.toursolver_delivery_weed_day_monday"
- )
- cls.sunday = cls.env.ref(
- "shipment_advice_planner_toursolver.toursolver_delivery_weed_day_sunday"
- )
+ cls.monday = cls.env.ref("base_time_window.time_weekday_monday")
+ cls.sunday = cls.env.ref("base_time_window.time_weekday_sunday")
def test_00(self):
"""
@@ -35,16 +31,16 @@ def test_00(self):
self.delivery_window_model.create(
{
"partner_id": self.partner_1.id,
- "start": 10.0,
- "end": 12.0,
- "week_day_ids": [(4, self.monday.id)],
+ "time_window_start": 10.0,
+ "time_window_end": 12.0,
+ "time_window_weekday_ids": [(4, self.monday.id)],
}
)
self.assertTrue(self.partner_1.toursolver_delivery_window_ids)
delivery_window = self.partner_1.toursolver_delivery_window_ids
- self.assertEqual(delivery_window.start, 10.0)
- self.assertEqual(delivery_window.end, 12.0)
- self.assertEqual(delivery_window.week_day_ids, self.monday)
+ self.assertEqual(delivery_window.time_window_start, 10.0)
+ self.assertEqual(delivery_window.time_window_end, 12.0)
+ self.assertEqual(delivery_window.time_window_weekday_ids, self.monday)
def test_01(self):
"""
@@ -63,9 +59,9 @@ def test_01(self):
self.delivery_window_model.create(
{
"partner_id": self.partner_1.id,
- "start": 10.0,
- "end": 12.0,
- "week_day_ids": [(4, self.monday.id)],
+ "time_window_start": 10.0,
+ "time_window_end": 12.0,
+ "time_window_weekday_ids": [(4, self.monday.id)],
}
)
self.assertTrue(self.partner_1.toursolver_delivery_window_ids)
@@ -91,18 +87,21 @@ def test_02(self):
self.delivery_window_model.create(
{
"partner_id": self.partner_1.id,
- "start": 10.0,
- "end": 12.0,
- "week_day_ids": [(4, self.monday.id)],
+ "time_window_start": 10.0,
+ "time_window_end": 12.0,
+ "time_window_weekday_ids": [(4, self.monday.id)],
}
)
with self.assertRaises(ValidationError):
self.delivery_window_model.create(
{
"partner_id": self.partner_1.id,
- "start": 11.0,
- "end": 13.0,
- "week_day_ids": [(4, self.monday.id), (4, self.sunday.id)],
+ "time_window_start": 11.0,
+ "time_window_end": 13.0,
+ "time_window_weekday_ids": [
+ (4, self.monday.id),
+ (4, self.sunday.id),
+ ],
}
)
@@ -122,18 +121,18 @@ def test_03(self):
self.delivery_window_model.create(
{
"partner_id": self.partner_1.id,
- "start": 10.0,
- "end": 12.0,
- "week_day_ids": [(4, self.monday.id)],
+ "time_window_start": 10.0,
+ "time_window_end": 12.0,
+ "time_window_weekday_ids": [(4, self.monday.id)],
}
)
self.assertTrue(self.partner_1.toursolver_delivery_window_ids)
self.delivery_window_model.create(
{
"partner_id": self.partner_1.id,
- "start": 11.0,
- "end": 13.0,
- "week_day_ids": [(4, self.sunday.id)],
+ "time_window_start": 11.0,
+ "time_window_end": 13.0,
+ "time_window_weekday_ids": [(4, self.sunday.id)],
}
)
self.assertEqual(len(self.partner_1.toursolver_delivery_window_ids), 2)
@@ -155,9 +154,9 @@ def test_04(self):
self.delivery_window_model.create(
{
"partner_id": self.partner_1.id,
- "start": 10.0,
- "end": 12.0,
- "week_day_ids": [(4, self.monday.id)],
+ "time_window_start": 10.0,
+ "time_window_end": 12.0,
+ "time_window_weekday_ids": [(4, self.monday.id)],
}
)
self.assertTrue(self.partner_1.toursolver_delivery_window_ids)
@@ -165,9 +164,9 @@ def test_04(self):
self.delivery_window_model.create(
{
"partner_id": self.partner_2.id,
- "start": 10.0,
- "end": 12.0,
- "week_day_ids": [(4, self.monday.id)],
+ "time_window_start": 10.0,
+ "time_window_end": 12.0,
+ "time_window_weekday_ids": [(4, self.monday.id)],
}
)
self.assertTrue(self.partner_2.toursolver_delivery_window_ids)
@@ -178,7 +177,7 @@ def test_05(self):
Partner 1 without delivery window
Test Case:
- Add a delivery window to partner 1 with end > start
+ Add a delivery window to partner 1 with time_window_end > time_window_start
Expected result:
ValidationError is raised
"""
@@ -186,8 +185,8 @@ def test_05(self):
self.delivery_window_model.create(
{
"partner_id": self.partner_1.id,
- "start": 14.0,
- "end": 12.0,
- "week_day_ids": [(4, self.monday.id)],
+ "time_window_start": 14.0,
+ "time_window_end": 12.0,
+ "time_window_weekday_ids": [(4, self.monday.id)],
}
)
diff --git a/shipment_advice_planner_toursolver/views/res_partner.xml b/shipment_advice_planner_toursolver/views/res_partner.xml
index a54d04cd..89e51418 100644
--- a/shipment_advice_planner_toursolver/views/res_partner.xml
+++ b/shipment_advice_planner_toursolver/views/res_partner.xml
@@ -9,10 +9,10 @@
-
-
+
+
-
+
diff --git a/shipment_advice_planner_toursolver/views/toursolver_delivery_window.xml b/shipment_advice_planner_toursolver/views/toursolver_delivery_window.xml
index e88cceb7..fd875e1a 100644
--- a/shipment_advice_planner_toursolver/views/toursolver_delivery_window.xml
+++ b/shipment_advice_planner_toursolver/views/toursolver_delivery_window.xml
@@ -7,7 +7,7 @@
-
+
-
-
+
+
-
+