Import files from Acsone
parent
0760e9f659
commit
7947f599f0
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright 2020 ACSONE SA/NV
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||||
|
|
||||||
|
<odoo noupdate="1">
|
||||||
|
|
||||||
|
<record model="delivery.week.day" id="delivery_weed_day_monday">
|
||||||
|
<field name="name">0</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="delivery.week.day" id="delivery_weed_day_tuesday">
|
||||||
|
<field name="name">1</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="delivery.week.day" id="delivery_weed_day_wednesday">
|
||||||
|
<field name="name">2</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="delivery.week.day" id="delivery_weed_day_thursday">
|
||||||
|
<field name="name">3</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="delivery.week.day" id="delivery_weed_day_friday">
|
||||||
|
<field name="name">4</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="delivery.week.day" id="delivery_weed_day_saturday">
|
||||||
|
<field name="name">5</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="delivery.week.day" id="delivery_weed_day_sunday">
|
||||||
|
<field name="name">6</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
|
@ -0,0 +1,70 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# 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 DeliveryWeekDay(models.Model):
|
||||||
|
|
||||||
|
_name = "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.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]
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
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]
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
@tools.ormcache("name")
|
||||||
|
def _get_id_by_name(self, name):
|
||||||
|
return self.search([("name", "=", name)], limit=1).id
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, vals):
|
||||||
|
result = super(DeliveryWeekDay, self).create(vals)
|
||||||
|
self._get_id_by_name.clear_cache(self)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def write(self, vals):
|
||||||
|
result = super(DeliveryWeekDay, self).write(vals)
|
||||||
|
self._get_id_by_name.clear_cache(self)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def unlink(self):
|
||||||
|
result = super(DeliveryWeekDay, self).unlink()
|
||||||
|
self._get_id_by_name.clear_cache(self)
|
||||||
|
return result
|
|
@ -0,0 +1,96 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# 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
|
||||||
|
|
||||||
|
|
||||||
|
class DeliveryWindow(models.Model):
|
||||||
|
|
||||||
|
_name = "delivery.window"
|
||||||
|
_description = "Delivery Window"
|
||||||
|
_order = "partner_id, start"
|
||||||
|
|
||||||
|
start = fields.Float("From", required=True)
|
||||||
|
end = fields.Float("To", required=True)
|
||||||
|
week_day_ids = fields.Many2many(
|
||||||
|
comodel_name="alc.delivery.week.day", required=True
|
||||||
|
)
|
||||||
|
partner_id = fields.Many2one(
|
||||||
|
"res.partner", required=True, index=True, ondelete='cascade'
|
||||||
|
)
|
||||||
|
|
||||||
|
@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(
|
||||||
|
_("%s must be > %s")
|
||||||
|
% (
|
||||||
|
self.float_to_time_repr(record.end),
|
||||||
|
self.float_to_time_repr(record.start),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# 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 = """
|
||||||
|
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,
|
||||||
|
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(
|
||||||
|
_("%s overlaps %s")
|
||||||
|
% (record.display_name, other.display_name)
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.depends("start", "end", "week_day_ids")
|
||||||
|
def _compute_display_name(self):
|
||||||
|
for record in self:
|
||||||
|
"{days}: From {start} to {end}".format(
|
||||||
|
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),
|
||||||
|
)
|
||||||
|
|
||||||
|
@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)
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright 2020 ACSONE SA/NV
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||||
|
|
||||||
|
<odoo>
|
||||||
|
<record model="ir.model.access" id="delivery_week_day_access_read">
|
||||||
|
<field name="name">delivery.window.day access read</field>
|
||||||
|
<field name="model_id" ref="model_delivery_week_day"/>
|
||||||
|
<field name="group_id" ref="base.group_user"/>
|
||||||
|
<field name="perm_read" eval="1"/>
|
||||||
|
<field name="perm_create" eval="0"/>
|
||||||
|
<field name="perm_write" eval="0"/>
|
||||||
|
<field name="perm_unlink" eval="0"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.model.access" id="delivery_window_access_read">
|
||||||
|
<field name="name">delivery.window access read</field>
|
||||||
|
<field name="model_id" ref="model_delivery_window"/>
|
||||||
|
<field name="group_id" ref="base.group_user"/>
|
||||||
|
<field name="perm_read" eval="1"/>
|
||||||
|
<field name="perm_create" eval="0"/>
|
||||||
|
<field name="perm_write" eval="0"/>
|
||||||
|
<field name="perm_unlink" eval="0"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.model.access" id="delivery_window_access_manage">
|
||||||
|
<field name="name">delivery.window access read</field>
|
||||||
|
<field name="model_id" ref="model_delivery_window"/>
|
||||||
|
<field name="group_id" ref="sales_team.group_sale_manager"/>
|
||||||
|
<field name="perm_read" eval="1"/>
|
||||||
|
<field name="perm_create" eval="1"/>
|
||||||
|
<field name="perm_write" eval="1"/>
|
||||||
|
<field name="perm_unlink" eval="1"/>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
|
@ -0,0 +1,187 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright 2020 ACSONE SA/NV
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
from odoo.tests import SavepointCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestDeliveryWindow(SavepointCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super(TestDeliveryWindow, cls).setUpClass()
|
||||||
|
cls.partner_1 = cls.env['res.partner'].create({'name': 'partner 1'})
|
||||||
|
cls.partner_2 = cls.env['res.partner'].create({'name': 'patner 2'})
|
||||||
|
cls.DeliveryWindow = cls.env["delivery.window"]
|
||||||
|
cls.monday = cls.env.ref(
|
||||||
|
"partner_delivery_window.delivery_weed_day_monday"
|
||||||
|
)
|
||||||
|
cls.sunday = cls.env.ref(
|
||||||
|
"partner_delivery_window.delivery_weed_day_sunday"
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_00(self):
|
||||||
|
"""
|
||||||
|
Data:
|
||||||
|
A partner without delivery window
|
||||||
|
Test Case:
|
||||||
|
Add a delivery window
|
||||||
|
Expected result:
|
||||||
|
A delivery window is created for the partner
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.assertFalse(self.partner_1.delivery_window_ids)
|
||||||
|
self.DeliveryWindow.create(
|
||||||
|
{
|
||||||
|
"partner_id": self.partner_1.id,
|
||||||
|
"start": 10.0,
|
||||||
|
"end": 12.0,
|
||||||
|
"week_day_ids": [(4, self.monday.id)],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertTrue(self.partner_1.delivery_window_ids)
|
||||||
|
delivery_window = self.partner_1.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)
|
||||||
|
|
||||||
|
def test_01(self):
|
||||||
|
"""
|
||||||
|
Data:
|
||||||
|
A partner without delivery window
|
||||||
|
Test Case:
|
||||||
|
1 Add a delivery window
|
||||||
|
2 unlink the partner
|
||||||
|
Expected result:
|
||||||
|
1 A delivery window is created for the partner
|
||||||
|
2 The delivery window is removed
|
||||||
|
"""
|
||||||
|
partner_id = self.partner_1.id
|
||||||
|
self.assertFalse(self.partner_1.delivery_window_ids)
|
||||||
|
self.DeliveryWindow.create(
|
||||||
|
{
|
||||||
|
"partner_id": self.partner_1.id,
|
||||||
|
"start": 10.0,
|
||||||
|
"end": 12.0,
|
||||||
|
"week_day_ids": [(4, self.monday.id)],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertTrue(self.partner_1.delivery_window_ids)
|
||||||
|
delivery_window = self.DeliveryWindow.search(
|
||||||
|
[("partner_id", "=", partner_id)]
|
||||||
|
)
|
||||||
|
self.assertTrue(delivery_window)
|
||||||
|
self.partner_1.unlink()
|
||||||
|
self.assertFalse(delivery_window.exists())
|
||||||
|
|
||||||
|
def test_02(self):
|
||||||
|
"""
|
||||||
|
Data:
|
||||||
|
A partner without delivery window
|
||||||
|
Test Case:
|
||||||
|
1 Add a delivery window
|
||||||
|
2 Add a second delivery window that overlaps the first one (same day)
|
||||||
|
Expected result:
|
||||||
|
1 A delivery window is created for the partner
|
||||||
|
2 ValidationError is raised
|
||||||
|
"""
|
||||||
|
self.DeliveryWindow.create(
|
||||||
|
{
|
||||||
|
"partner_id": self.partner_1.id,
|
||||||
|
"start": 10.0,
|
||||||
|
"end": 12.0,
|
||||||
|
"week_day_ids": [(4, self.monday.id)],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
self.DeliveryWindow.create(
|
||||||
|
{
|
||||||
|
"partner_id": self.partner_1.id,
|
||||||
|
"start": 11.0,
|
||||||
|
"end": 13.0,
|
||||||
|
"week_day_ids": [(4, self.monday.id), (4, self.sunday.id)],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_03(self):
|
||||||
|
"""
|
||||||
|
Data:
|
||||||
|
A partner without delivery window
|
||||||
|
Test Case:
|
||||||
|
1 Add a delivery window
|
||||||
|
2 Add a second delivery window that overlaps the first one (another day)
|
||||||
|
Expected result:
|
||||||
|
1 A delivery window is created for the partner
|
||||||
|
2 A second delivery window is created for the partner
|
||||||
|
"""
|
||||||
|
self.assertFalse(self.partner_1.delivery_window_ids)
|
||||||
|
self.DeliveryWindow.create(
|
||||||
|
{
|
||||||
|
"partner_id": self.partner_1.id,
|
||||||
|
"start": 10.0,
|
||||||
|
"end": 12.0,
|
||||||
|
"week_day_ids": [(4, self.monday.id)],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertTrue(self.partner_1.delivery_window_ids)
|
||||||
|
self.DeliveryWindow.create(
|
||||||
|
{
|
||||||
|
"partner_id": self.partner_1.id,
|
||||||
|
"start": 11.0,
|
||||||
|
"end": 13.0,
|
||||||
|
"week_day_ids": [(4, self.sunday.id)],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertEquals(len(self.partner_1.delivery_window_ids), 2)
|
||||||
|
|
||||||
|
def test_04(self):
|
||||||
|
"""
|
||||||
|
Data:
|
||||||
|
Partner 1 without delivery window
|
||||||
|
Partner 2 without delivery window
|
||||||
|
Test Case:
|
||||||
|
1 Add a delivery window to partner 1
|
||||||
|
2 Add the same delivery window to partner 2
|
||||||
|
Expected result:
|
||||||
|
1 A delivery window is created for the partner 1
|
||||||
|
1 A delivery window is created for the partner 2
|
||||||
|
"""
|
||||||
|
self.assertFalse(self.partner_1.delivery_window_ids)
|
||||||
|
self.DeliveryWindow.create(
|
||||||
|
{
|
||||||
|
"partner_id": self.partner_1.id,
|
||||||
|
"start": 10.0,
|
||||||
|
"end": 12.0,
|
||||||
|
"week_day_ids": [(4, self.monday.id)],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertTrue(self.partner_1.delivery_window_ids)
|
||||||
|
self.assertFalse(self.partner_2.delivery_window_ids)
|
||||||
|
self.DeliveryWindow.create(
|
||||||
|
{
|
||||||
|
"partner_id": self.partner_2.id,
|
||||||
|
"start": 10.0,
|
||||||
|
"end": 12.0,
|
||||||
|
"week_day_ids": [(4, self.monday.id)],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertTrue(self.partner_2.delivery_window_ids)
|
||||||
|
|
||||||
|
def test_05(self):
|
||||||
|
"""""
|
||||||
|
Data:
|
||||||
|
Partner 1 without delivery window
|
||||||
|
Test Case:
|
||||||
|
Add a delivery window to partner 1 with end > start
|
||||||
|
Expected result:
|
||||||
|
ValidationError is raised
|
||||||
|
"""
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
self.DeliveryWindow.create(
|
||||||
|
{
|
||||||
|
"partner_id": self.partner_1.id,
|
||||||
|
"start": 14.0,
|
||||||
|
"end": 12.0,
|
||||||
|
"week_day_ids": [(4, self.monday.id)],
|
||||||
|
}
|
||||||
|
)
|
Loading…
Reference in New Issue