Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions sale_order_safe_commitment_date/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
===============================
Sale order safe commitment date
===============================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:c47b35103c45553d6342b739f08528e0bb434daabc9e9e1794bb3d518c250424
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
:target: https://odoo-community.org/page/development-status
:alt: Alpha
.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github
:target: https://github.com/OCA/sale-workflow/tree/18.0/sale_order_safe_commitment_date
:alt: OCA/sale-workflow
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/sale-workflow-18-0/sale-workflow-18-0-sale_order_safe_commitment_date
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/sale-workflow&target_branch=18.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module allows to avoid that the salesmen set a delivery date before
the minimum expected date.

.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
Only for development or testing purpose, do not use in production.
`More details on development status <https://odoo-community.org/page/development-status>`_

**Table of contents**

.. contents::
:local:

Use Cases / Context
===================

When salesmen set a delivery date there's nothing disallowing them to
set it before the expected date computed according to the order lead
times. That can cause great issues with deliveries schedules, as those
lead times are set to ensure that the orders are delivered on time.

Configuration
=============

To set the sales cut-off hours:

1. Go to *Sales > Configuration > Settings* and then to the *Shipping*
section.
2. Set the *Sales cut-off schedule*: you can create a new one or select
an existing one.
3. In that calendar, set the cut-off hours for the given days.

Usage
=====

To test the module:

- Go to *Sales > Orders* and create a new quotation.
- Set whatever customer and order lines.
- Go to the *Other info* tab, section *Delivery* and set a *Delivery
date* previous to the expected date.
- A popup will raise warning about setting a delivery before the minimum
date possible to promise the delivery.
- Additionally, a warning alert will be shown on the top side of the
order advising the salesman to fix that issue.
- If the salesman ignores it, the delivery date will be set to the
minimum expected date when the order gets confirmed.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/sale-workflow/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/sale-workflow/issues/new?body=module:%20sale_order_safe_commitment_date%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Moduon

Contributors
------------

- David Vidal (`Moduon <https://www.moduon.team/>`__)

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-chienandalu| image:: https://github.com/chienandalu.png?size=40px
:target: https://github.com/chienandalu
:alt: chienandalu
.. |maintainer-rafaelbn| image:: https://github.com/rafaelbn.png?size=40px
:target: https://github.com/rafaelbn
:alt: rafaelbn

Current `maintainers <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-chienandalu| |maintainer-rafaelbn|

This module is part of the `OCA/sale-workflow <https://github.com/OCA/sale-workflow/tree/18.0/sale_order_safe_commitment_date>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions sale_order_safe_commitment_date/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
18 changes: 18 additions & 0 deletions sale_order_safe_commitment_date/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2025 Moduon Team S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0)
{
"name": "Sale order safe commitment date",
"summary": "Avoid confirming a commitment date previous to the expected date",
"version": "18.0.1.0.0",
"development_status": "Alpha",
"category": "Sales Management",
"website": "https://github.com/OCA/sale-workflow",
"author": "Moduon, Odoo Community Association (OCA)",
"maintainers": ["chienandalu", "rafaelbn"],
"license": "LGPL-3",
"depends": ["sale"],
"data": [
"views/sale_order_views.xml",
"views/res_config_settings_views.xml",
],
}
71 changes: 71 additions & 0 deletions sale_order_safe_commitment_date/i18n/es.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_safe_commitment_date
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-05-22 07:27+0000\n"
"PO-Revision-Date: 2025-08-13 17:25+0000\n"
"Last-Translator: David Vidal <[email protected]>\n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.10.4\n"

#. module: sale_order_safe_commitment_date
#: model_terms:ir.ui.view,arch_db:sale_order_safe_commitment_date.view_order_form
msgid ""
", but it's not possible based on current lead times. Odoo will adjust the "
"date automatically. Contact your sales manager if it’s urgent."
msgstr ""
", pero no es posible según los plazos actuales. Odoo ajustará la fecha "
"automáticamente. Contacta con tu responsable si es urgente."

#. module: sale_order_safe_commitment_date
#: model_terms:ir.ui.view,arch_db:sale_order_safe_commitment_date.view_order_form
msgid "<i class=\"fa fa-warning\"/> You requested delivery on"
msgstr "<i class=\"fa fa-warning\"/> Has solicitado entregar el pedido el"

#. module: sale_order_safe_commitment_date
#: model:ir.model.fields,field_description:sale_order_safe_commitment_date.field_sale_order__date_for_commitment
msgid "Delivery date"
msgstr "Fecha de entrega"

#. module: sale_order_safe_commitment_date
#: model:ir.model.fields,field_description:sale_order_safe_commitment_date.field_sale_order__is_commitment_date_unsafe
msgid "Is Commitment Date Unsafe"
msgstr "La fecha de entrega es insegura"

#. module: sale_order_safe_commitment_date
#: model:ir.model,name:sale_order_safe_commitment_date.model_sale_order
msgid "Sales Order"
msgstr "Pedido de venta"

#. module: sale_order_safe_commitment_date
#: model:ir.model.fields,help:sale_order_safe_commitment_date.field_sale_order__date_for_commitment
msgid ""
"This is the delivery date promised to the customer. If set, the delivery "
"order will be scheduled based on this date rather than product lead times."
msgstr ""
"Es la fecha de entrega prometida al cliente. Si se establece, la orden de "
"entrega se programará en función de esta fecha en lugar de los plazos de "
"entrega del producto."

#~ msgid ""
#~ "<i class=\"fa fa-warning text-warning\" attrs=\"{'invisible': "
#~ "[('is_commitment_date_unsafe', '=', False)]}\" alt=\"The delivery date is "
#~ "sooner than the expected date. You may be unable to honor the delivery "
#~ "date.\"/> Expected:"
#~ msgstr ""
#~ "<i class=\"fa fa-warning text-warning\" attrs=\"{'invisible': "
#~ "[('is_commitment_date_unsafe', '=', False)]}\" alt=\"La fecha de entrega "
#~ "es anterior a la fecha esperada. Es posible que no pueda respetar la "
#~ "fecha de entrega.\"/> Previsto:"

#~ msgid "Delivery Date"
#~ msgstr "Fecha de entrega"
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_safe_commitment_date
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: sale_order_safe_commitment_date
#: model_terms:ir.ui.view,arch_db:sale_order_safe_commitment_date.view_order_form
msgid ""
", but it's not possible based on current lead times. Odoo will adjust the "
"date automatically. Contact your sales manager if it’s urgent."
msgstr ""

#. module: sale_order_safe_commitment_date
#: model_terms:ir.ui.view,arch_db:sale_order_safe_commitment_date.view_order_form
msgid "<i class=\"fa fa-warning\"/> You requested delivery on"
msgstr ""

#. module: sale_order_safe_commitment_date
#: model:ir.model.fields,field_description:sale_order_safe_commitment_date.field_sale_order__date_for_commitment
msgid "Delivery date"
msgstr ""

#. module: sale_order_safe_commitment_date
#: model:ir.model.fields,field_description:sale_order_safe_commitment_date.field_sale_order__is_commitment_date_unsafe
msgid "Is Commitment Date Unsafe"
msgstr ""

#. module: sale_order_safe_commitment_date
#: model:ir.model,name:sale_order_safe_commitment_date.model_sale_order
msgid "Sales Order"
msgstr ""

#. module: sale_order_safe_commitment_date
#: model:ir.model.fields,help:sale_order_safe_commitment_date.field_sale_order__date_for_commitment
msgid ""
"This is the delivery date promised to the customer. If set, the delivery "
"order will be scheduled based on this date rather than product lead times."
msgstr ""
3 changes: 3 additions & 0 deletions sale_order_safe_commitment_date/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import sale_order
from . import res_config_settings
from . import res_company
39 changes: 39 additions & 0 deletions sale_order_safe_commitment_date/models/res_company.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2025 Moduon Team S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0)
import pytz
from dateutil.relativedelta import relativedelta

from odoo import fields, models


class ResCompany(models.Model):
_inherit = "res.company"

sales_cutoff_calendar = fields.Many2one(
comodel_name="resource.calendar",
string="Sales cut-off schedule",
)
in_sale_cutoff_hour = fields.Boolean(
compute="_compute_in_sale_cutoff_hour",
help="Sales can't be delivered according to their lead times and will be"
"postponed for a day",
)

def _compute_in_sale_cutoff_hour(self):
# TODO: Maybe we should seek for the next period that isn't cutoff
self.in_sale_cutoff_hour = False
now = self.env.context.get("sale_cutoff_datetime")
for company in self.filtered("sales_cutoff_calendar"):
resource = self.env["resource.resource"]
if not now:
now = fields.Datetime.now().replace(tzinfo=pytz.utc)
now = now.astimezone(pytz.timezone(self.env.user.tz or "UTC"))
range_end = now + relativedelta(days=1, hour=0, minute=0, second=0)
interval = sorted(
company.sales_cutoff_calendar._work_intervals_batch(
now, range_end, resource
)[resource.id],
key=lambda i, now=now: abs(i[0] - now),
)
if interval:
company.in_sale_cutoff_hour = interval[0][0] <= now
11 changes: 11 additions & 0 deletions sale_order_safe_commitment_date/models/res_config_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright 2025 Moduon Team S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0)
from odoo import fields, models


class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"

sales_cutoff_calendar = fields.Many2one(
related="company_id.sales_cutoff_calendar", readonly=False
)
Loading
Loading