Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[13.0] Add module sale_cutoff_time_weekday_delivery #1107

2 changes: 2 additions & 0 deletions sale_partner_cutoff_delivery_window/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
16 changes: 16 additions & 0 deletions sale_partner_cutoff_delivery_window/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
{
"name": "Sale Partner Cutoff Delivery Window",
"summary": "Schedule delivery orders according to cutoff and window preferences",
"version": "13.0.1.0.0",
"development_status": "Alpha",
"category": "Warehouse Management",
"website": "https://github.com/OCA/sale-workflow",
"author": "Camptocamp, Odoo Community Association (OCA)",
"license": "AGPL-3",
"application": False,
"installable": True,
"depends": ["sale_cutoff_time_delivery", "sale_partner_delivery_window"],
"auto-install": True,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Akim Juillerat <akim.juillerat@camptocamp.com>
3 changes: 3 additions & 0 deletions sale_partner_cutoff_delivery_window/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
This module adds some unittests to ensure Method Resolution Order of
`sale.order.line._prepare_procurement_values` for modules
`sale_cutoff_time_delivery` and `sale_partner_delivery_window` is correct.
1 change: 1 addition & 0 deletions sale_partner_cutoff_delivery_window/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_cutoff_delivery_window
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
from freezegun import freeze_time

from odoo import fields
from odoo.tests import SavepointCase


class TestSaleCutoffDeliveryWindow(SavepointCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.customer_partner = cls.env["res.partner"].create(
{
"name": "Partner cutoff",
"order_delivery_cutoff_preference": "partner_cutoff",
"cutoff_time": 9.0,
"delivery_time_preference": "time_windows",
"delivery_time_window_ids": [
(
0,
0,
{
"time_window_start": 8.0,
"time_window_end": 18.00,
"time_window_weekday_ids": [
(
6,
0,
[
cls.env.ref(
"base_time_window.time_weekday_monday"
).id,
cls.env.ref(
"base_time_window.time_weekday_friday"
).id,
],
)
],
},
)
],
}
)
cls.customer_warehouse = cls.env["res.partner"].create(
{
"name": "Partner warehouse cutoff",
"order_delivery_cutoff_preference": "warehouse_cutoff",
"cutoff_time": 9.0,
"delivery_time_preference": "time_windows",
"delivery_time_window_ids": [
(
0,
0,
{
"time_window_start": 8.0,
"time_window_end": 18.00,
"time_window_weekday_ids": [
(
6,
0,
[
cls.env.ref(
"base_time_window.time_weekday_monday"
).id,
cls.env.ref(
"base_time_window.time_weekday_friday"
).id,
],
)
],
},
)
],
}
)
cls.warehouse = cls.env.ref("stock.warehouse0")
cls.warehouse.write(
{"apply_cutoff": True, "cutoff_time": 10.0,}
)
cls.product = cls.env.ref("product.product_product_9")

def _create_order(self, partner=None):
order = self.env["sale.order"].create(
{
"partner_id": partner.id,
"partner_shipping_id": partner.id,
"order_line": [
(
0,
0,
{
"name": self.product.name,
"product_id": self.product.id,
"product_uom_qty": 1,
"product_uom": self.product.uom_id.id,
"price_unit": self.product.list_price,
},
)
],
}
)
# Play onchange manually to ensure customer_lead is set on the line
order.order_line._onchange_product_id_set_customer_lead()
return order

@freeze_time("2020-03-26 18:00:00") # thursday evening
def test_after_cutoff_preferred_weekday(self):
# After partner cutoff
order = self._create_order(partner=self.customer_partner)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-27 09:00:00")
)
# Before warehouse cutoff
order = self._create_order(partner=self.customer_warehouse)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-27 10:00:00")
)

@freeze_time("2020-03-27 08:00:00") # friday morning
def test_before_cutoff_preferred_weekday(self):
# Before partner cutoff
order = self._create_order(partner=self.customer_partner)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-27 09:00:00")
)
# Before warehouse cutoff
order = self._create_order(partner=self.customer_warehouse)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-27 10:00:00")
)

@freeze_time("2020-03-27 18:00:00") # friday evening
def test_after_cutoff_other_weekday(self):
# After partner cutoff
order = self._create_order(partner=self.customer_partner)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-30 08:00:00")
)
# After warehouse cutoff
order = self._create_order(partner=self.customer_warehouse)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-30 08:00:00")
)

@freeze_time("2020-03-28 08:00:00") # saturday morning
def test_before_cutoff_other_weekday(self):
# Before partner cutoff
order = self._create_order(partner=self.customer_partner)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-30 08:00:00")
)
# Before warehouse cutoff
order = self._create_order(partner=self.customer_warehouse)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-30 08:00:00")
)

@freeze_time("2020-03-23 08:00:00") # monday morning
def test_before_cutoff_lead_time_preferred_weekday(self):
self.product.sale_delay = 4
# Before partner cutoff
order = self._create_order(partner=self.customer_partner)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-27 09:00:00")
)
# Before partner cutoff
order = self._create_order(partner=self.customer_warehouse)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-27 10:00:00")
)

@freeze_time("2020-03-23 18:00:00") # monday evening
def test_after_cutoff_lead_time_preferred_weekday(self):
# THIS IS PROBABLY THE MOST IMPORTANT TEST HERE:
# This test ensures that cutoff is applied before delivery window
# because both sale_cutoff_time_delivery and sale_weekday_delivery
# override _get_procurement_values.
# Also, at the beginning both modules had the same dependency and it
# did seem to work because sale_cutoff_time_delivery is alphabetically
# before sale_partner_delivery_window /!\
# Anyway, here we want the computation to happen as follows:
# confirmation time: 2020-03-23 18:00:00
# application of lead time: 2020-03-27 18:00:00
# application of cutoff: 2020-03-28 09:00:00
# application of weekday: 2020-03-30 08:00:00
# what matches both cutoff and delivery window preference

# If somehow the MRO of _prepare_procurement_values is WRONG we'd have:
# confirmation time: 2020-03-23 18:00:00
# application of lead time: 2020-03-27 18:00:00
# application of weekday: 2020-03-27 18:00:00
# application of cutoff: 2020-03-28 09:00:00
# what doesn't match the delivery window preference!
self.product.sale_delay = 4
# Before partner cutoff
order = self._create_order(partner=self.customer_partner)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-30 08:00:00")
)
# Before partner cutoff
order = self._create_order(partner=self.customer_warehouse)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-30 08:00:00")
)

@freeze_time("2020-03-24 08:00:00") # tuesday morning
def test_before_cutoff_lead_time_other_weekday(self):
self.product.sale_delay = 4
# Before partner cutoff
order = self._create_order(partner=self.customer_partner)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-30 08:00:00")
)
# Before partner cutoff
order = self._create_order(partner=self.customer_warehouse)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-30 08:00:00")
)

@freeze_time("2020-03-24 18:00:00") # tuesday evening
def test_after_cutoff_lead_time_other_weekday(self):
self.product.sale_delay = 4
# Before partner cutoff
order = self._create_order(partner=self.customer_partner)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-30 08:00:00")
)
# Before partner cutoff
order = self._create_order(partner=self.customer_warehouse)
order.action_confirm()
picking = order.picking_ids
self.assertEqual(
picking.scheduled_date, fields.Datetime.to_datetime("2020-03-30 08:00:00")
)
6 changes: 6 additions & 0 deletions setup/sale_partner_cutoff_delivery_window/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)