diff --git a/sale_delivery_split_date/README.rst b/sale_delivery_split_date/README.rst new file mode 100644 index 00000000000..22aba11ff67 --- /dev/null +++ b/sale_delivery_split_date/README.rst @@ -0,0 +1,99 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +======================== +Sale Delivery Split Date +======================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:69652f1972b11818ac88de151e78405313708c3ac7722d9f26939bfa20c21a44 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github + :target: https://github.com/OCA/sale-workflow/tree/19.0/sale_delivery_split_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-19-0/sale-workflow-19-0-sale_delivery_split_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=19.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +When this module is installed, each sale order you confirm will generate +one delivery order per requested date indicated in the sale order lines. + +Furthermore, the delivery orders can be searched by selecting the +scheduled date, which is now displayed in the delivery tree view. + +**Table of contents** + +.. contents:: + :local: + +Known issues / Roadmap +====================== + +- Incompatible with + `sale_procurement_group_by_commitment_date `__ + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Agile Business Group + +Contributors +------------ + +- Alex Comba (https://www.agilebg.com/) +- Carmen Rondon Regalado + (https://odoo.archeti.com/) +- Tatiana Deribina + +Other credits +------------- + +The migration of this module from 18.0 to 19.0 was financially supported +by SprintIT Ltd. + +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. + +This module is part of the `OCA/sale-workflow `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/sale_delivery_split_date/__init__.py b/sale_delivery_split_date/__init__.py new file mode 100644 index 00000000000..31660d6a965 --- /dev/null +++ b/sale_delivery_split_date/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import models diff --git a/sale_delivery_split_date/__manifest__.py b/sale_delivery_split_date/__manifest__.py new file mode 100644 index 00000000000..9c888dcaacd --- /dev/null +++ b/sale_delivery_split_date/__manifest__.py @@ -0,0 +1,20 @@ +# Copyright 2018 Alex Comba - Agile Business Group +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Sale Delivery Split Date", + "version": "19.0.1.0.0", + "summary": "Sale Deliveries split by date", + "category": "Sales Management", + "license": "AGPL-3", + "author": "Agile Business Group, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/sale-workflow", + "depends": [ + "sale_order_line_date", + "sale_stock_reference_by_line", # ex. sale_procurement_group_by_line + ], + "data": [ + "views/stock_picking.xml", + ], + "installable": True, +} diff --git a/sale_delivery_split_date/i18n/ca.po b/sale_delivery_split_date/i18n/ca.po new file mode 100644 index 00000000000..fa70c5c823c --- /dev/null +++ b/sale_delivery_split_date/i18n/ca.po @@ -0,0 +1,36 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_delivery_split_date +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-03-10 10:45+0000\n" +"Last-Translator: Daniel Martinez Vila \n" +"Language-Team: none\n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: sale_delivery_split_date +#: model:ir.model,name:sale_delivery_split_date.model_sale_order_line +msgid "Sales Order Line" +msgstr "Línia de comandes de vendes" + +#. module: sale_delivery_split_date +#: model_terms:ir.ui.view,arch_db:sale_delivery_split_date.view_picking_internal_search +msgid "Scheduled Date" +msgstr "Data prevista" + +#~ msgid "Sale Order" +#~ msgstr "Comanda de venda" + +#~ msgid "Scheduled Date (for filter purpose only)" +#~ msgstr "Data programada (només per al filtre)" + +#~ msgid "Transfer" +#~ msgstr "Transferència" diff --git a/sale_delivery_split_date/i18n/es.po b/sale_delivery_split_date/i18n/es.po new file mode 100644 index 00000000000..818ab4ed1e0 --- /dev/null +++ b/sale_delivery_split_date/i18n/es.po @@ -0,0 +1,36 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_delivery_split_date +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-03-10 10:45+0000\n" +"Last-Translator: Daniel Martinez Vila \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: sale_delivery_split_date +#: model:ir.model,name:sale_delivery_split_date.model_sale_order_line +msgid "Sales Order Line" +msgstr "Línea de pedido de venta" + +#. module: sale_delivery_split_date +#: model_terms:ir.ui.view,arch_db:sale_delivery_split_date.view_picking_internal_search +msgid "Scheduled Date" +msgstr "Fecha prevista" + +#~ msgid "Sale Order" +#~ msgstr "Pedido de venta" + +#~ msgid "Scheduled Date (for filter purpose only)" +#~ msgstr "Fecha programada (solo para fines de filtrado)" + +#~ msgid "Transfer" +#~ msgstr "Transferir" diff --git a/sale_delivery_split_date/i18n/it.po b/sale_delivery_split_date/i18n/it.po new file mode 100644 index 00000000000..17a02d760ae --- /dev/null +++ b/sale_delivery_split_date/i18n/it.po @@ -0,0 +1,37 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_delivery_split_date +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-08-31 14:57+0000\n" +"PO-Revision-Date: 2024-01-25 15:34+0000\n" +"Last-Translator: mymage \n" +"Language-Team: \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: sale_delivery_split_date +#: model:ir.model,name:sale_delivery_split_date.model_sale_order_line +msgid "Sales Order Line" +msgstr "Riga ordine di vendita" + +#. module: sale_delivery_split_date +#: model_terms:ir.ui.view,arch_db:sale_delivery_split_date.view_picking_internal_search +msgid "Scheduled Date" +msgstr "Data schedulata" + +#~ msgid "Sale Order" +#~ msgstr "Ordine di vendita" + +#~ msgid "Scheduled Date (for filter purpose only)" +#~ msgstr "Data pianificata (solo per i filtri)" + +#~ msgid "Transfer" +#~ msgstr "Trasferimento" diff --git a/sale_delivery_split_date/i18n/pt_PT.po b/sale_delivery_split_date/i18n/pt_PT.po new file mode 100644 index 00000000000..76e2cabaf54 --- /dev/null +++ b/sale_delivery_split_date/i18n/pt_PT.po @@ -0,0 +1,36 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_delivery_split_date +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-04-21 20:47+0000\n" +"Last-Translator: educasilva \n" +"Language-Team: none\n" +"Language: pt_PT\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: sale_delivery_split_date +#: model:ir.model,name:sale_delivery_split_date.model_sale_order_line +msgid "Sales Order Line" +msgstr "Linha de encomendas de venda" + +#. module: sale_delivery_split_date +#: model_terms:ir.ui.view,arch_db:sale_delivery_split_date.view_picking_internal_search +msgid "Scheduled Date" +msgstr "Data programada" + +#~ msgid "Sale Order" +#~ msgstr "Ordem de venda" + +#~ msgid "Scheduled Date (for filter purpose only)" +#~ msgstr "Data programada (apenas para fins de filtragem)" + +#~ msgid "Transfer" +#~ msgstr "Transferir" diff --git a/sale_delivery_split_date/i18n/sale_delivery_split_date.pot b/sale_delivery_split_date/i18n/sale_delivery_split_date.pot new file mode 100644 index 00000000000..cd695a0753a --- /dev/null +++ b/sale_delivery_split_date/i18n/sale_delivery_split_date.pot @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_delivery_split_date +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.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_delivery_split_date +#: model:ir.model,name:sale_delivery_split_date.model_sale_order_line +msgid "Sales Order Line" +msgstr "" + +#. module: sale_delivery_split_date +#: model_terms:ir.ui.view,arch_db:sale_delivery_split_date.view_picking_internal_search +msgid "Scheduled Date" +msgstr "" diff --git a/sale_delivery_split_date/models/__init__.py b/sale_delivery_split_date/models/__init__.py new file mode 100644 index 00000000000..15e7252a511 --- /dev/null +++ b/sale_delivery_split_date/models/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import sale_order_line diff --git a/sale_delivery_split_date/models/sale_order_line.py b/sale_delivery_split_date/models/sale_order_line.py new file mode 100644 index 00000000000..93b62fac046 --- /dev/null +++ b/sale_delivery_split_date/models/sale_order_line.py @@ -0,0 +1,52 @@ +# Copyright 2018 Alex Comba - Agile Business Group +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from datetime import timedelta + +from odoo import models +from odoo.tools import format_date + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + def _prepare_reference_vals(self): + vals = super()._prepare_reference_vals() + if self._get_stock_reference_key()[0] == 24: + if self.commitment_date: + comm_date = self._get_security_lead_time_commitment_date() + vals["name"] = ( + f"{vals['name']}/{format_date(self.env, comm_date.date())}" + ) + return vals + + def _get_stock_reference_key(self): + """Return a key with priority to be used to regroup lines in multiple + procurement groups + """ + priority = 24 + key = super()._get_stock_reference_key() + # Check priority + if key[0] < priority: + if self.commitment_date: + # group by date instead of datetime + comm_date = self._get_security_lead_time_commitment_date() + key = (priority, comm_date.date()) + return key + + def _prepare_procurement_values(self): + vals = super()._prepare_procurement_values() + line_com_date = self.commitment_date + if line_com_date: + comm_date = self._get_security_lead_time_commitment_date() + vals.update( + date_planned=comm_date, + date_deadline=line_com_date, + ) + return vals + + def _get_security_lead_time_commitment_date(self): + """Return the commitment date with security lead time""" + return self.commitment_date - timedelta( + days=self.order_id.company_id.security_lead + ) diff --git a/sale_delivery_split_date/pyproject.toml b/sale_delivery_split_date/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/sale_delivery_split_date/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/sale_delivery_split_date/readme/CONTRIBUTORS.md b/sale_delivery_split_date/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..1a7d37f5726 --- /dev/null +++ b/sale_delivery_split_date/readme/CONTRIBUTORS.md @@ -0,0 +1,4 @@ +- Alex Comba \<\> () +- Carmen Rondon Regalado \<\> + () +- Tatiana Deribina \<\> diff --git a/sale_delivery_split_date/readme/CREDITS.md b/sale_delivery_split_date/readme/CREDITS.md new file mode 100644 index 00000000000..47e2d463523 --- /dev/null +++ b/sale_delivery_split_date/readme/CREDITS.md @@ -0,0 +1,2 @@ +The migration of this module from 18.0 to 19.0 was financially supported +by SprintIT Ltd. diff --git a/sale_delivery_split_date/readme/DESCRIPTION.md b/sale_delivery_split_date/readme/DESCRIPTION.md new file mode 100644 index 00000000000..d42a50e915c --- /dev/null +++ b/sale_delivery_split_date/readme/DESCRIPTION.md @@ -0,0 +1,5 @@ +When this module is installed, each sale order you confirm will generate +one delivery order per requested date indicated in the sale order lines. + +Furthermore, the delivery orders can be searched by selecting the +scheduled date, which is now displayed in the delivery tree view. diff --git a/sale_delivery_split_date/readme/ROADMAP.md b/sale_delivery_split_date/readme/ROADMAP.md new file mode 100644 index 00000000000..fd1df7e5cdf --- /dev/null +++ b/sale_delivery_split_date/readme/ROADMAP.md @@ -0,0 +1,2 @@ +- Incompatible with + [sale_procurement_group_by_commitment_date](https://github.com/OCA/sale-workflow/tree/12.0/sale_procurement_group_by_commitment_date) diff --git a/sale_delivery_split_date/static/description/icon.png b/sale_delivery_split_date/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/sale_delivery_split_date/static/description/icon.png differ diff --git a/sale_delivery_split_date/static/description/index.html b/sale_delivery_split_date/static/description/index.html new file mode 100644 index 00000000000..8deae8ff5f2 --- /dev/null +++ b/sale_delivery_split_date/static/description/index.html @@ -0,0 +1,449 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Sale Delivery Split Date

+ +

Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

+

When this module is installed, each sale order you confirm will generate +one delivery order per requested date indicated in the sale order lines.

+

Furthermore, the delivery orders can be searched by selecting the +scheduled date, which is now displayed in the delivery tree view.

+

Table of contents

+ + +
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Agile Business Group
  • +
+
+ +
+

Other credits

+

The migration of this module from 18.0 to 19.0 was financially supported +by SprintIT Ltd.

+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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.

+

This module is part of the OCA/sale-workflow project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+
+ + diff --git a/sale_delivery_split_date/tests/__init__.py b/sale_delivery_split_date/tests/__init__.py new file mode 100644 index 00000000000..d4fe79507a5 --- /dev/null +++ b/sale_delivery_split_date/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import test_sale_delivery diff --git a/sale_delivery_split_date/tests/test_sale_delivery.py b/sale_delivery_split_date/tests/test_sale_delivery.py new file mode 100644 index 00000000000..8c0e84839b4 --- /dev/null +++ b/sale_delivery_split_date/tests/test_sale_delivery.py @@ -0,0 +1,251 @@ +# Copyright 2018 Alex Comba - Agile Business Group +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import datetime + +from odoo.tools import format_date + +from odoo.addons.sale_stock.tests.common import TestSaleStockCommon + + +class TestSaleDelivery(TestSaleStockCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + customer = cls.partner_a + p1 = cls._create_product( + name="test_product1", + is_storable=True, + ) + p2 = cls._create_product( + name="test_product2", + is_storable=True, + ) + today = datetime.datetime(2020, 1, 1) + cls.dt1 = today + datetime.timedelta(days=9) + cls.dt2 = today + datetime.timedelta(days=10) + cls.date_sooner = cls.dt1 + cls.date_later = cls.dt2 + cls.so = cls._create_sale_order(customer) + cls.so_line1 = cls._create_sale_order_line(cls.so, p1, 10, 100.0, cls.dt1) + cls.so_line2 = cls._create_sale_order_line(cls.so, p2, 10, 200.0, cls.dt1) + + @classmethod + def _create_sale_order(cls, customer): + return cls.env["sale.order"].create({"partner_id": customer.id}) + + @classmethod + def _create_sale_order_line(cls, sale, product, qty, price, date): + return cls.env["sale.order.line"].create( + { + "product_id": product.id, + "name": "cool product", + "order_id": sale.id, + "price_unit": price, + "product_uom_qty": qty, + "commitment_date": date, + } + ) + + def test_check_single_date(self): + self.assertEqual( + len(self.so.picking_ids), + 0, + "There must not be pickings for the SO when draft", + ) + self.so.action_confirm() + self.assertEqual( + len(self.so.picking_ids), + 1, + "There must be 1 picking for the SO when confirmed", + ) + self.assertEqual( + self.so.picking_ids[0].scheduled_date, + self.date_sooner, + "The picking must be planned at the expected date", + ) + self.assertEqual( + self.so_line1.stock_reference_id, + self.so_line2.stock_reference_id, + "The procurement group must be the same", + ) + self.assertIn( + format_date(self.env, self.date_sooner.date()), + self.so_line1.stock_reference_id.name, + ) + + def test_check_multiple_dates(self): + # Change the date of the second line + self.so_line2.commitment_date = self.dt2 + self.assertEqual( + len(self.so.picking_ids), + 0, + "There must not be pickings for the SO when draft", + ) + self.so.action_confirm() + self.assertEqual( + len(self.so.picking_ids), + 2, + "There must be 2 pickings for the SO when confirmed", + ) + sorted_pickings = self.so.picking_ids.sorted(lambda x: x.scheduled_date) + self.assertEqual( + sorted_pickings[0].scheduled_date, + self.date_sooner, + "The first picking must be planned at the soonest date", + ) + self.assertEqual( + sorted_pickings[1].scheduled_date, + self.date_later, + "The second picking must be planned at the latest date", + ) + self.assertNotEqual( + self.so_line1.stock_reference_id, + self.so_line2.stock_reference_id, + "The procurement group must be different", + ) + self.assertIn( + format_date(self.env, self.date_sooner.date()), + self.so_line1.stock_reference_id.name, + ) + self.assertIn( + format_date(self.env, self.date_later.date()), + self.so_line2.stock_reference_id.name, + ) + + def test_check_same_dates(self): + # Change the date of the second line by just adding 1 hour + same_date = self.dt1 + datetime.timedelta(hours=1) + self.so_line2.commitment_date = same_date + self.assertEqual( + len(self.so.picking_ids), + 0, + "There must not be pickings for the SO when draft", + ) + self.so.action_confirm() + self.assertEqual( + len(self.so.picking_ids), + 1, + "There must be only one picking for the SO when confirmed", + ) + self.assertEqual( + self.so.picking_ids.scheduled_date, + self.date_sooner, + "The picking must be planned at the expected date", + ) + self.assertEqual( + self.so_line1.move_ids.date_deadline, + self.so_line1.commitment_date, + "First SO Line move deadline must be equal to commitment date", + ) + self.assertEqual( + self.so_line2.move_ids.date_deadline, + self.so_line2.commitment_date, + "Second SO Line move deadline must be equal to commitment date", + ) + + self.assertEqual( + self.so_line1.stock_reference_id, + self.so_line2.stock_reference_id, + "The procurement group must be the same", + ) + self.assertIn( + format_date(self.env, self.date_sooner.date()), + self.so_line1.stock_reference_id.name, + ) + + def test_security_lead_time_same_dates(self): + same_date = self.dt1 + datetime.timedelta(hours=1) + self.so_line2.commitment_date = same_date + self.so.company_id.security_lead = 2 + security_date = self.date_sooner - datetime.timedelta(days=2) + self.assertEqual( + len(self.so.picking_ids), + 0, + "There must not be pickings for the SO when draft", + ) + self.so.action_confirm() + self.assertEqual( + len(self.so.picking_ids), + 1, + "There must be only one picking for the SO when confirmed", + ) + self.assertEqual( + self.so.picking_ids.scheduled_date, + security_date, + "The picking must be planned at the expected date " + "(with security lead time)", + ) + self.assertEqual( + self.so_line1.move_ids.date_deadline, + self.so_line1.commitment_date, + "First SO Line move deadline must be equal to commitment date", + ) + self.assertEqual( + self.so_line2.move_ids.date_deadline, + self.so_line2.commitment_date, + "Second SO Line move deadline must be equal to commitment date", + ) + self.assertEqual( + self.so_line1.stock_reference_id, + self.so_line2.stock_reference_id, + "The procurement group must be the same", + ) + self.assertIn( + format_date(self.env, security_date.date()), + self.so_line1.stock_reference_id.name, + ) + + def test_security_lead_time_multiple_dates(self): + self.so_line2.commitment_date = self.dt2 + self.so.company_id.security_lead = 3 + security_date_sooner = self.date_sooner - datetime.timedelta(days=3) + security_date_later = self.date_later - datetime.timedelta(days=3) + self.assertEqual( + len(self.so.picking_ids), + 0, + "There must not be pickings for the SO when draft", + ) + self.so.action_confirm() + self.assertEqual( + len(self.so.picking_ids), + 2, + "There must be 2 pickings for the SO when confirmed", + ) + sorted_pickings = self.so.picking_ids.sorted(lambda x: x.scheduled_date) + self.assertEqual( + sorted_pickings[0].scheduled_date, + security_date_sooner, + "The first picking must be planned at the soonest date " + "(with security lead time)", + ) + self.assertEqual( + sorted_pickings[0].date_deadline, + self.so_line1.commitment_date, + "The picking deadline must be equal to commitment date", + ) + self.assertEqual( + sorted_pickings[1].scheduled_date, + security_date_later, + "The second picking must be planned at the latest date " + "(with security lead time)", + ) + self.assertEqual( + sorted_pickings[1].date_deadline, + self.so_line2.commitment_date, + "The picking deadline must be equal to commitment date", + ) + self.assertNotEqual( + self.so_line1.stock_reference_id, + self.so_line2.stock_reference_id, + "The procurement group must be different", + ) + self.assertIn( + format_date(self.env, security_date_sooner.date()), + self.so_line1.stock_reference_id.name, + ) + self.assertIn( + format_date(self.env, security_date_later.date()), + self.so_line2.stock_reference_id.name, + ) diff --git a/sale_delivery_split_date/views/stock_picking.xml b/sale_delivery_split_date/views/stock_picking.xml new file mode 100644 index 00000000000..4a45a5bc907 --- /dev/null +++ b/sale_delivery_split_date/views/stock_picking.xml @@ -0,0 +1,26 @@ + + + + + stock.picking.tree + stock.picking + + + + 0 + + + + + + stock.picking.internal.search + stock.picking + + + + + + + + diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 00000000000..02346340860 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,2 @@ +odoo-addon-sale_stock_reference_by_line @ git+https://github.com/OCA/sale-workflow.git@refs/pull/3947/head#subdirectory=sale_stock_reference_by_line +odoo-addon-sale_order_line_date @ git+https://github.com/OCA/sale-workflow.git@refs/pull/3946/head#subdirectory=sale_order_line_date