Skip to content

Commit 01c9036

Browse files
committed
[ADD] sale_order_compute_commitment_date: New module sale_order_compute_commitment_date
1 parent fb4b57d commit 01c9036

17 files changed

Lines changed: 1191 additions & 0 deletions
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
==================================
2+
Sale Order Compute Commitment Date
3+
==================================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:f77cbe11285d1aff1796eee9fac951f13819b1741c0660524121c96d6fb1f610
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Beta
16+
.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png
17+
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
18+
:alt: License: LGPL-3
19+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github
20+
:target: https://github.com/OCA/sale-workflow/tree/18.0/sale_order_compute_commitment_date
21+
:alt: OCA/sale-workflow
22+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23+
:target: https://translation.odoo-community.org/projects/sale-workflow-18-0/sale-workflow-18-0-sale_order_compute_commitment_date
24+
:alt: Translate me on Weblate
25+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26+
:target: https://runboat.odoo-community.org/builds?repo=OCA/sale-workflow&target_branch=18.0
27+
:alt: Try me on Runboat
28+
29+
|badge1| |badge2| |badge3| |badge4| |badge5|
30+
31+
This module automatically computes sale orders commitment date based on
32+
the product template sale_delay and product attribute variant lead time
33+
fields.
34+
35+
**Table of contents**
36+
37+
.. contents::
38+
:local:
39+
40+
Configuration
41+
=============
42+
43+
To configure this module, you need to:
44+
45+
- Create a product.
46+
- Set its delay time on the "Inventory" tab.
47+
- If you want product variants to increase the commitment date, check
48+
the Extend Lead Time boolean.
49+
- Now configure a variant for the product and set its lead time.
50+
- Create a sales order and add the product.
51+
- On the "Other Information" tab you will see the commitment date its
52+
automatically computed.
53+
- This module relies on the resource calendar to calculate dates,
54+
including both working days and any configured leave days.
55+
- Once the sale order is confirmed, it computes again the commitment
56+
date.
57+
58+
Bug Tracker
59+
===========
60+
61+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/sale-workflow/issues>`_.
62+
In case of trouble, please check there if your issue has already been reported.
63+
If you spotted it first, help us to smash it by providing a detailed and welcomed
64+
`feedback <https://github.com/OCA/sale-workflow/issues/new?body=module:%20sale_order_compute_commitment_date%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
65+
66+
Do not contact contributors directly about support or help with technical issues.
67+
68+
Credits
69+
=======
70+
71+
Authors
72+
-------
73+
74+
* APSL - Nagarro
75+
76+
Contributors
77+
------------
78+
79+
- ``APSL-Nagarro <https://apsl.tech>``\ \_:
80+
81+
- Miquel Pascual miquel.pascual@nagarro.com
82+
83+
Maintainers
84+
-----------
85+
86+
This module is maintained by the OCA.
87+
88+
.. image:: https://odoo-community.org/logo.png
89+
:alt: Odoo Community Association
90+
:target: https://odoo-community.org
91+
92+
OCA, or the Odoo Community Association, is a nonprofit organization whose
93+
mission is to support the collaborative development of Odoo features and
94+
promote its widespread use.
95+
96+
.. |maintainer-mpascuall| image:: https://github.com/mpascuall.png?size=40px
97+
:target: https://github.com/mpascuall
98+
:alt: mpascuall
99+
100+
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
101+
102+
|maintainer-mpascuall|
103+
104+
This module is part of the `OCA/sale-workflow <https://github.com/OCA/sale-workflow/tree/18.0/sale_order_compute_commitment_date>`_ project on GitHub.
105+
106+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright 2025 APSL Nagarro
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from . import models
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2025 APSL Nagarro
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
{
5+
"name": "Sale Order Compute Commitment Date",
6+
"version": "18.0.1.0.0",
7+
"category": "Sales Management",
8+
"summary": "Automatically computes the commitment date based on product"
9+
"lead times and attributes",
10+
"author": "APSL - Nagarro, Odoo Community Association (OCA)",
11+
"maintainers": ["mpascuall"],
12+
"website": "https://github.com/OCA/sale-workflow",
13+
"license": "LGPL-3",
14+
"depends": ["base", "sale_management", "stock"],
15+
"data": [
16+
"views/product_attribute_value.xml",
17+
"views/product_template.xml",
18+
],
19+
"installable": True,
20+
"application": False,
21+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Translation of Odoo Server.
2+
# This file contains the translation of the following modules:
3+
# * sale_order_compute_commitment_date
4+
#
5+
msgid ""
6+
msgstr ""
7+
"Project-Id-Version: Odoo Server 18.0+e\n"
8+
"Report-Msgid-Bugs-To: \n"
9+
"POT-Creation-Date: 2025-06-26 07:21+0000\n"
10+
"PO-Revision-Date: 2025-06-26 07:21+0000\n"
11+
"Last-Translator: \n"
12+
"Language-Team: \n"
13+
"MIME-Version: 1.0\n"
14+
"Content-Type: text/plain; charset=UTF-8\n"
15+
"Content-Transfer-Encoding: \n"
16+
"Plural-Forms: \n"
17+
18+
#. module: sale_order_compute_commitment_date
19+
#: model:ir.model,name:sale_order_compute_commitment_date.model_product_attribute_value
20+
msgid "Attribute Value"
21+
msgstr "Valor del Atributo"
22+
23+
#. module: sale_order_compute_commitment_date
24+
#: model:ir.model.fields,field_description:sale_order_compute_commitment_date.field_sale_order__commitment_date
25+
msgid "Delivery Date"
26+
msgstr "Fecha de entrega"
27+
28+
#. module: sale_order_compute_commitment_date
29+
#: model:ir.model.fields,field_description:sale_order_compute_commitment_date.field_product_product__extend_lead_time
30+
#: model:ir.model.fields,field_description:sale_order_compute_commitment_date.field_product_template__extend_lead_time
31+
msgid "Extend Lead Time"
32+
msgstr "Tiempo de Entrega Extendido"
33+
34+
#. module: sale_order_compute_commitment_date
35+
#: model:ir.model.fields,help:sale_order_compute_commitment_date.field_product_product__extend_lead_time
36+
#: model:ir.model.fields,help:sale_order_compute_commitment_date.field_product_template__extend_lead_time
37+
msgid ""
38+
"If checked, the attribute lead time will be taken into account to calculate "
39+
"the final lead time."
40+
msgstr "Si está marcado, el tiempo de entrega del atributo se tendrá "
41+
"en cuenta para calcular el tiempo de entrega final."
42+
43+
#. module: sale_order_compute_commitment_date
44+
#: model:ir.model.fields,field_description:sale_order_compute_commitment_date.field_product_attribute_value__lead_time
45+
msgid "Lead Time"
46+
msgstr "Tiempo de Entrega"
47+
48+
#. module: sale_order_compute_commitment_date
49+
#: model:ir.model,name:sale_order_compute_commitment_date.model_product_template
50+
msgid "Product"
51+
msgstr "Producto"
52+
53+
#. module: sale_order_compute_commitment_date
54+
#: model:ir.model,name:sale_order_compute_commitment_date.model_sale_order
55+
msgid "Sales Order"
56+
msgstr "Pedido de venta"
57+
58+
#. module: sale_order_compute_commitment_date
59+
#: model:ir.model.fields,help:sale_order_compute_commitment_date.field_product_attribute_value__lead_time
60+
msgid "The number of days this attribute adds to the product's lead time."
61+
msgstr "El número de días que este atributo añade al tiempo de entrega del producto."
62+
63+
#. module: sale_order_compute_commitment_date
64+
#: model:ir.model.fields,help:sale_order_compute_commitment_date.field_sale_order__commitment_date
65+
msgid ""
66+
"This is the delivery date promised to the customer. If set, the delivery "
67+
"order will be scheduled based on this date rather than product lead times."
68+
msgstr ""
69+
"Ésta es la fecha de entrega prometida al cliente. Si se establece, la orden "
70+
"de entrega se programará en función de esta fecha en lugar de los plazos de "
71+
"entrega del producto."
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright 2025 APSL Nagarro
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from . import product_template
5+
from . import product_attribute_value
6+
from . import sale_order
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright 2025 APSL Nagarro
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from odoo import fields, models
5+
6+
7+
class ProductAttributeValue(models.Model):
8+
_inherit = "product.attribute.value"
9+
10+
lead_time = fields.Integer(
11+
help="The number of days this attribute adds to the product's lead time.",
12+
)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright 2025 APSL Nagarro
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from odoo import fields, models
5+
6+
7+
class ProductTemplate(models.Model):
8+
_inherit = "product.template"
9+
10+
extend_lead_time = fields.Boolean(
11+
help="If checked, the attribute lead time will be "
12+
"taken into account to calculate the final lead time.",
13+
)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Copyright 2025 APSL Nagarro
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from datetime import timedelta
5+
6+
from pytz import timezone, utc
7+
8+
from odoo import api, fields, models
9+
10+
11+
class SaleOrder(models.Model):
12+
_inherit = "sale.order"
13+
14+
commitment_date = fields.Datetime(
15+
"Delivery Date",
16+
compute="_compute_commitment_date",
17+
store=True,
18+
readonly=False,
19+
help="This is the delivery date promised to the customer. "
20+
"If set, the delivery order will be "
21+
"scheduled based on this date rather than product lead times.",
22+
)
23+
24+
@api.depends(
25+
"order_line.product_id",
26+
"order_line.product_id.sale_delay",
27+
"order_line.product_id.product_tmpl_id.extend_lead_time",
28+
"order_line.product_id.product_template_attribute_value_ids.product_attribute_value_id.lead_time",
29+
"date_order",
30+
"state",
31+
"company_id.resource_calendar_id.attendance_ids.dayofweek",
32+
"company_id.resource_calendar_id.leave_ids",
33+
)
34+
def _compute_commitment_date(self):
35+
for order in self:
36+
max_total_lead_time = 0
37+
38+
for line in order.order_line:
39+
product_template = line.product_id.product_tmpl_id
40+
41+
current_line_lead_time = (
42+
product_template.sale_delay
43+
if product_template.sale_delay is not None
44+
else 0
45+
)
46+
47+
if product_template.extend_lead_time:
48+
for ptav in line.product_id.product_template_attribute_value_ids:
49+
if ptav.product_attribute_value_id.lead_time:
50+
current_line_lead_time += (
51+
ptav.product_attribute_value_id.lead_time
52+
)
53+
54+
if current_line_lead_time > max_total_lead_time:
55+
max_total_lead_time = current_line_lead_time
56+
57+
base_date_for_calculation = order.date_order
58+
59+
if base_date_for_calculation:
60+
order.commitment_date = order._get_date_with_lead_time_from_calendar(
61+
base_date_for_calculation, max_total_lead_time
62+
)
63+
else:
64+
order.commitment_date = False
65+
66+
def _get_date_with_lead_time_from_calendar(self, base_datetime, lead_time_days):
67+
self.ensure_one()
68+
69+
calendar = self.company_id.resource_calendar_id
70+
71+
if not calendar:
72+
return base_datetime + timedelta(days=lead_time_days)
73+
74+
hours_per_day = calendar.hours_per_day if calendar.hours_per_day else 8.0
75+
hours_to_add = lead_time_days * hours_per_day
76+
77+
calendar_tz = timezone(calendar.tz) if calendar.tz else timezone("UTC")
78+
79+
if not base_datetime.tzinfo:
80+
base_datetime_aware = utc.localize(base_datetime)
81+
else:
82+
base_datetime_aware = base_datetime
83+
84+
base_dt_in_calendar_tz = base_datetime_aware.astimezone(calendar_tz)
85+
naive_base_dt = base_dt_in_calendar_tz.replace(tzinfo=None)
86+
87+
final_datetime_aware = calendar.plan_hours(
88+
hours_to_add, naive_base_dt, compute_leaves=True
89+
)
90+
91+
return final_datetime_aware.astimezone(timezone("UTC")).replace(tzinfo=None)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[build-system]
2+
requires = ["whool"]
3+
build-backend = "whool.buildapi"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
To configure this module, you need to:
2+
3+
- Create a product.
4+
- Set its delay time on the "Inventory" tab.
5+
- If you want product variants to increase the commitment date, check the Extend Lead Time boolean.
6+
- Now configure a variant for the product and set its lead time.
7+
- Create a sales order and add the product.
8+
- On the "Other Information" tab you will see the commitment date its automatically computed.
9+
- This module relies on the resource calendar to calculate dates, including both working days and any configured leave days.
10+
- Once the sale order is confirmed, it computes again the commitment date.

0 commit comments

Comments
 (0)