Skip to content

Commit

Permalink
sale_delivery_date: fix picking report delivery date when late
Browse files Browse the repository at this point in the history
  • Loading branch information
mmequignon committed Jul 7, 2023
1 parent 3fff20d commit a81af5f
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 11 deletions.
46 changes: 38 additions & 8 deletions sale_delivery_date/models/stock_picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,26 @@ class StockPicking(models.Model):
)
expected_delivery_date = fields.Datetime(compute="_compute_expected_delivery_date")

def _get_delays(self):
self.ensure_one()
sale_delays = self.move_lines.product_id.mapped("sale_delay")
if sale_delays:
# Depending on the move_type, customer_lead is either the smallest
# or the biggest one among product's sale_delays.
if self.move_type == "direct":
min_delay = min(sale_delays)
# As we cannot have negative delays
customer_lead = max(min_delay, 0.0)
else:
max_delay = max(sale_delays)
customer_lead = max(max_delay, 0.0)
else:
customer_lead = 0.0
# Otherwise, this is the same than _get_delays() on sale_order_line
security_lead = max(self.company_id.security_lead or 0.0, 0.0)
workload = max(customer_lead - security_lead, 0.0)
return customer_lead, security_lead, workload

def _compute_expected_delivery_date(self):
"""Computes the expected delivery date.
Expand All @@ -41,16 +61,26 @@ def _compute_expected_delivery_date(self):
for record in self:
delivery_date = False
commitment_date = record.sale_id.commitment_date
if commitment_date and commitment_date.date() >= today:
delivery_date = commitment_date
if not delivery_date:
expected_date = record.sale_id.expected_date
if expected_date and expected_date.date() >= today:
delivery_date = expected_date
expected_date = record.sale_id.expected_date
# If we commited to deliver on a given date, we never fall back
# on the expected_date.
# The reason for that is that we might have set and unrealistic
# commitment_date at first.
# In such case, it's normal to be late, and we do not want to postpone.
if commitment_date:
if commitment_date.date() >= today:
delivery_date = commitment_date
elif expected_date and expected_date.date() >= today:
delivery_date = expected_date
if not delivery_date:
date_done = record.date_done or record.scheduled_date
security_lead = record.company_id.security_lead
delivery_date = fields.Datetime.add(date_done, days=security_lead)
sale_line_model = self.env["sale.order.line"]
partner = self.partner_id
warehouse = self.location_id.get_warehouse()
delays = self._get_delays()
delivery_date = sale_line_model._delivery_date_from_expedition_date(
date_done, partner, warehouse.calendar2_id, delays
)
record.expected_delivery_date = delivery_date

@api.depends("location_id")
Expand Down
2 changes: 1 addition & 1 deletion sale_delivery_date/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def _set_partner_time_window(cls, partner, weekday_numbers, date_ranges):
"time_window_end": end,
"time_window_weekday_ids": [(6, 0, weekdays.ids)],
},
)
) for start, end in date_ranges
],
}
)
Expand Down
3 changes: 1 addition & 2 deletions sale_delivery_date/tests/test_delivery_date_in_the_past.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,7 @@ def test_delivery_date_as_late_scheduled_date(self):
# customer delivery preferences applied.
# As customer is set to be delivered anytime, midnight is ok.
td_security_lead = timedelta(days=picking.company_id.security_lead)
expected_datetime = picking.scheduled_date + td_security_lead
self.assertEqual(picking.expected_delivery_date, expected_datetime)
self.assertEqual(str(picking.expected_delivery_date), "2021-10-16 00:00:00")

def test_delivery_date_as_date_done(self):
"""Date done should be used if both commitment_date and
Expand Down
31 changes: 31 additions & 0 deletions sale_delivery_date/tests/test_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

from datetime import datetime

from odoo.tests.common import Form
from odoo.tools import mute_logger

from .common import Common


Expand Down Expand Up @@ -401,3 +404,31 @@ def test_get_latest_work_end_from_date_range_with_calendar(self):
earliest_expedition_date, lastest_expedition_date, **kwargs
)
self.assertEqual(res, earliest_expedition_date)

# picking._get_delays

def _add_product_in_order(self, order, product_qties):
sale_form = Form(order)
with mute_logger("odoo.tests.common.onchange"):
for product, qty in product_qties:
with sale_form.order_line.new() as line:
line.product_id = product
line.product_uom_qty = qty
sale_form.save()

def test_picking_get_delays(self):
order = self.order
product = self.env["product.product"].create(
{"name": "product with delay", "sale_delay": 5, "type": "product"}
)
self._add_product_in_order(order, [(product, 10)])
order.action_confirm()
picking = order.picking_ids
# with move_type = direct, get_delays should return the smallest sale_delay
picking.move_type = "direct"
sale_delay, __, __ = picking._get_delays()
self.assertEqual(sale_delay, 1.0)
# With move_type = one, the biggest one is returned
picking.move_type = "one"
sale_delay, __, __ = picking._get_delays()
self.assertEqual(sale_delay, 5.0)

0 comments on commit a81af5f

Please sign in to comment.