diff --git a/purchase_order_line_original_date/README.rst b/purchase_order_line_original_date/README.rst new file mode 100644 index 00000000000..467a9559a63 --- /dev/null +++ b/purchase_order_line_original_date/README.rst @@ -0,0 +1,110 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +================================= +Purchase Order Line Original Date +================================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:76829994f0fe50535aee54cbd34a1543764e31c239b9eea023798a8804634d3e + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-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%2Fpurchase--workflow-lightgray.png?logo=github + :target: https://github.com/OCA/purchase-workflow/tree/19.0/purchase_order_line_original_date + :alt: OCA/purchase-workflow +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/purchase-workflow-19-0/purchase-workflow-19-0-purchase_order_line_original_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/purchase-workflow&target_branch=19.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module adds the *Original Expected Arrival* to Purchase Order +lines. This is useful for past analysis and vendor performance reports. + +In standard Odoo, once a PO is confirmed with expected arrivals on its +lines, this dates can still change to reflect changes in the planning +(e.g. you receive a notification from your supplier that goods will +arrive a couple of days later). In such situation you lost precious +information of the original expected arrivals that can be used to +compute the real delay in the receipt from your supplier. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +1. Create a new PO and assign an expected arrival to its lines. +2. Confirm the PO. +3. Change the expected arrival of some lines. +4. Original expected arrival is kept unchanged. + +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 +------- + +* ForgeFlow + +Contributors +------------ + +- `ForgeFlow `__: + + - Lois Rilo Antelo + +- `SolusiAglis `__: + + - Hudson Amadeus Leonardy + +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-LoisRForgeFlow| image:: https://github.com/LoisRForgeFlow.png?size=40px + :target: https://github.com/LoisRForgeFlow + :alt: LoisRForgeFlow + +Current `maintainer `__: + +|maintainer-LoisRForgeFlow| + +This module is part of the `OCA/purchase-workflow `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/purchase_order_line_original_date/__init__.py b/purchase_order_line_original_date/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/purchase_order_line_original_date/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/purchase_order_line_original_date/__manifest__.py b/purchase_order_line_original_date/__manifest__.py new file mode 100644 index 00000000000..82a9a4035b9 --- /dev/null +++ b/purchase_order_line_original_date/__manifest__.py @@ -0,0 +1,19 @@ +# Copyright 2024 ForgeFlow S.L. (https://www.forgeflow.com) +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). + +{ + "name": "Purchase Order Line Original Date", + "summary": "adds the Original Expected Arrival to PO lines.", + "version": "19.0.1.0.0", + "category": "Purchase Management", + "maintainers": ["LoisRForgeFlow"], + "website": "https://github.com/OCA/purchase-workflow", + "author": "ForgeFlow, Odoo Community Association (OCA)", + "license": "LGPL-3", + "installable": True, + "depends": ["purchase"], + "data": [ + "views/purchase_order_line_views.xml", + "views/purchase_order_views.xml", + ], +} diff --git a/purchase_order_line_original_date/i18n/it.po b/purchase_order_line_original_date/i18n/it.po new file mode 100644 index 00000000000..478d1a134d9 --- /dev/null +++ b/purchase_order_line_original_date/i18n/it.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_order_line_original_date +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2025-08-19 16:27+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\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 5.10.4\n" + +#. module: purchase_order_line_original_date +#: model:ir.model.fields,field_description:purchase_order_line_original_date.field_purchase_order__original_date_planned +#: model:ir.model.fields,field_description:purchase_order_line_original_date.field_purchase_order_line__original_date_planned +msgid "Original Expected Arrival" +msgstr "Arrivo atteso originale" + +#. module: purchase_order_line_original_date +#: model:ir.model.fields,help:purchase_order_line_original_date.field_purchase_order__original_date_planned +msgid "Original Expected Arrival promised by vendor at PO confirmation." +msgstr "Arrivo atteso originale promesso dal fornitore alla conferma OA." + +#. module: purchase_order_line_original_date +#: model:ir.model.fields,help:purchase_order_line_original_date.field_purchase_order_line__original_date_planned +msgid "Original expected arrival at PO confirmation." +msgstr "Arrivo atteso originale alla conferma OA." + +#. module: purchase_order_line_original_date +#: model:ir.model,name:purchase_order_line_original_date.model_purchase_order +msgid "Purchase Order" +msgstr "Ordine di acquisto" + +#. module: purchase_order_line_original_date +#: model:ir.model,name:purchase_order_line_original_date.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "Riga ordine di acquisto" diff --git a/purchase_order_line_original_date/i18n/purchase_order_line_original_date.pot b/purchase_order_line_original_date/i18n/purchase_order_line_original_date.pot new file mode 100644 index 00000000000..8bbabdefb46 --- /dev/null +++ b/purchase_order_line_original_date/i18n/purchase_order_line_original_date.pot @@ -0,0 +1,40 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_order_line_original_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: purchase_order_line_original_date +#: model:ir.model.fields,field_description:purchase_order_line_original_date.field_purchase_order__original_date_planned +#: model:ir.model.fields,field_description:purchase_order_line_original_date.field_purchase_order_line__original_date_planned +msgid "Original Expected Arrival" +msgstr "" + +#. module: purchase_order_line_original_date +#: model:ir.model.fields,help:purchase_order_line_original_date.field_purchase_order__original_date_planned +msgid "Original Expected Arrival promised by vendor at PO confirmation." +msgstr "" + +#. module: purchase_order_line_original_date +#: model:ir.model.fields,help:purchase_order_line_original_date.field_purchase_order_line__original_date_planned +msgid "Original expected arrival at PO confirmation." +msgstr "" + +#. module: purchase_order_line_original_date +#: model:ir.model,name:purchase_order_line_original_date.model_purchase_order +msgid "Purchase Order" +msgstr "" + +#. module: purchase_order_line_original_date +#: model:ir.model,name:purchase_order_line_original_date.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "" diff --git a/purchase_order_line_original_date/models/__init__.py b/purchase_order_line_original_date/models/__init__.py new file mode 100644 index 00000000000..876d2185368 --- /dev/null +++ b/purchase_order_line_original_date/models/__init__.py @@ -0,0 +1,2 @@ +from . import purchase_order_line +from . import purchase_order diff --git a/purchase_order_line_original_date/models/purchase_order.py b/purchase_order_line_original_date/models/purchase_order.py new file mode 100644 index 00000000000..fd011d97064 --- /dev/null +++ b/purchase_order_line_original_date/models/purchase_order.py @@ -0,0 +1,34 @@ +# Copyright 2024 ForgeFlow S.L. (https://www.forgeflow.com) +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). + +from odoo import api, fields, models + + +class PurchaseOrder(models.Model): + _inherit = "purchase.order" + + original_date_planned = fields.Datetime( + string="Original Expected Arrival", + compute="_compute_original_date_planned", + store=True, + readonly=True, + tracking=True, + help="Original Expected Arrival promised by vendor at PO confirmation.", + ) + + @api.depends("order_line.original_date_planned") + def _compute_original_date_planned(self): + for order in self: + dates_list = order.order_line.filtered( + lambda x: not x.display_type and x.original_date_planned + ).mapped("original_date_planned") + if dates_list: + order.original_date_planned = fields.Datetime.to_string(min(dates_list)) + else: + order.original_date_planned = False + + def button_confirm(self): + res = super().button_confirm() + for pol in self.mapped("order_line"): + pol.original_date_planned = pol.date_planned + return res diff --git a/purchase_order_line_original_date/models/purchase_order_line.py b/purchase_order_line_original_date/models/purchase_order_line.py new file mode 100644 index 00000000000..52950e07986 --- /dev/null +++ b/purchase_order_line_original_date/models/purchase_order_line.py @@ -0,0 +1,15 @@ +# Copyright 2024 ForgeFlow S.L. (https://www.forgeflow.com) +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). + +from odoo import fields, models + + +class PurchaseOrderLine(models.Model): + _inherit = "purchase.order.line" + + original_date_planned = fields.Datetime( + string="Original Expected Arrival", + readonly=True, + copy=False, + help="Original expected arrival at PO confirmation.", + ) diff --git a/purchase_order_line_original_date/pyproject.toml b/purchase_order_line_original_date/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/purchase_order_line_original_date/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/purchase_order_line_original_date/readme/CONTRIBUTORS.md b/purchase_order_line_original_date/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..ce3d36de389 --- /dev/null +++ b/purchase_order_line_original_date/readme/CONTRIBUTORS.md @@ -0,0 +1,7 @@ +- [ForgeFlow](https://www.forgeflow.com): + + > - Lois Rilo Antelo + +- [SolusiAglis](https://solusiaglis.co.id): + + > - Hudson Amadeus Leonardy \ No newline at end of file diff --git a/purchase_order_line_original_date/readme/DESCRIPTION.md b/purchase_order_line_original_date/readme/DESCRIPTION.md new file mode 100644 index 00000000000..546f0ca2e38 --- /dev/null +++ b/purchase_order_line_original_date/readme/DESCRIPTION.md @@ -0,0 +1,9 @@ +This module adds the *Original Expected Arrival* to Purchase Order lines. +This is useful for past analysis and vendor performance reports. + +In standard Odoo, once a PO is confirmed with expected arrivals on its +lines, this dates can still change to reflect changes in the planning +(e.g. you receive a notification from your supplier that goods will +arrive a couple of days later). In such situation you lost precious +information of the original expected arrivals that can be used to compute +the real delay in the receipt from your supplier. diff --git a/purchase_order_line_original_date/readme/USAGE.md b/purchase_order_line_original_date/readme/USAGE.md new file mode 100644 index 00000000000..630ecbebde7 --- /dev/null +++ b/purchase_order_line_original_date/readme/USAGE.md @@ -0,0 +1,4 @@ +1. Create a new PO and assign an expected arrival to its lines. +2. Confirm the PO. +3. Change the expected arrival of some lines. +4. Original expected arrival is kept unchanged. diff --git a/purchase_order_line_original_date/static/description/icon.png b/purchase_order_line_original_date/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/purchase_order_line_original_date/static/description/icon.png differ diff --git a/purchase_order_line_original_date/static/description/index.html b/purchase_order_line_original_date/static/description/index.html new file mode 100644 index 00000000000..dad164703cb --- /dev/null +++ b/purchase_order_line_original_date/static/description/index.html @@ -0,0 +1,461 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Purchase Order Line Original Date

+ +

Beta License: LGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

+

This module adds the Original Expected Arrival to Purchase Order +lines. This is useful for past analysis and vendor performance reports.

+

In standard Odoo, once a PO is confirmed with expected arrivals on its +lines, this dates can still change to reflect changes in the planning +(e.g. you receive a notification from your supplier that goods will +arrive a couple of days later). In such situation you lost precious +information of the original expected arrivals that can be used to +compute the real delay in the receipt from your supplier.

+

Table of contents

+ +
+

Usage

+
    +
  1. Create a new PO and assign an expected arrival to its lines.
  2. +
  3. Confirm the PO.
  4. +
  5. Change the expected arrival of some lines.
  6. +
  7. Original expected arrival is kept unchanged.
  8. +
+
+
+

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

+
    +
  • ForgeFlow
  • +
+
+
+

Contributors

+ +
+
+

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.

+

Current maintainer:

+

LoisRForgeFlow

+

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

+

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

+
+
+
+
+ + diff --git a/purchase_order_line_original_date/tests/__init__.py b/purchase_order_line_original_date/tests/__init__.py new file mode 100644 index 00000000000..3f384033d08 --- /dev/null +++ b/purchase_order_line_original_date/tests/__init__.py @@ -0,0 +1 @@ +from . import test_purchase_order_line_original_date diff --git a/purchase_order_line_original_date/tests/test_purchase_order_line_original_date.py b/purchase_order_line_original_date/tests/test_purchase_order_line_original_date.py new file mode 100644 index 00000000000..3aec475cb69 --- /dev/null +++ b/purchase_order_line_original_date/tests/test_purchase_order_line_original_date.py @@ -0,0 +1,69 @@ +# Copyright 2024 ForgeFlow S.L. (https://www.forgeflow.com) +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). + +from datetime import datetime +from datetime import timedelta as td + +from odoo.tests import common + + +class TestPoLineOriginalDate(common.TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.po_model = cls.env["purchase.order"] + + cls.vendor_1 = cls.env["res.partner"].create( + { + "name": "Vendor 1", + } + ) + cls.product_1 = cls.env["product.product"].create({"name": "test"}) + cls.comparison_delta = td(seconds=1) + cls.today = datetime.today() + cls.tomorrow = cls.today + td(1) + cls.day_2 = cls.today + td(2) + + @classmethod + def create_purchase_order(cls, product, date_planned, qty=10.0): + return cls.env["purchase.order"].create( + { + "partner_id": cls.vendor_1.id, + "order_line": [ + ( + 0, + 0, + { + "product_id": product.id, + "product_uom_id": product.uom_id.id, + "name": product.name, + "price_unit": 100.0, + "date_planned": date_planned, + "product_qty": qty, + }, + ) + ], + } + ) + + def test_01_original_date_planned_stored(self): + po = self.create_purchase_order(self.product_1, self.tomorrow) + self.assertTrue(po.date_planned) + self.assertFalse(po.original_date_planned) + line = po.order_line + self.assertTrue(line.date_planned) + self.assertFalse(line.original_date_planned) + po.button_confirm() + self.assertTrue(po.original_date_planned) + self.assertEqual( + po.date_planned.replace(microsecond=0), po.original_date_planned + ) + self.assertTrue(line.original_date_planned) + self.assertEqual(line.date_planned, line.original_date_planned) + line.date_planned = self.day_2 + self.assertAlmostEqual( + po.original_date_planned, self.tomorrow, delta=self.comparison_delta + ) + self.assertAlmostEqual(po.date_planned, self.day_2, delta=self.comparison_delta) + self.assertEqual(line.original_date_planned, self.tomorrow) + self.assertEqual(line.date_planned, self.day_2) diff --git a/purchase_order_line_original_date/views/purchase_order_line_views.xml b/purchase_order_line_original_date/views/purchase_order_line_views.xml new file mode 100644 index 00000000000..9cf9c2df046 --- /dev/null +++ b/purchase_order_line_original_date/views/purchase_order_line_views.xml @@ -0,0 +1,28 @@ + + + + + purchase.order.line.tree- purchase_order_line_original_date + purchase.order.line + + + + + + + + + + stock.move.form - purchase_order_line_original_date + purchase.order.line + + + + + + + + diff --git a/purchase_order_line_original_date/views/purchase_order_views.xml b/purchase_order_line_original_date/views/purchase_order_views.xml new file mode 100644 index 00000000000..43151bebb30 --- /dev/null +++ b/purchase_order_line_original_date/views/purchase_order_views.xml @@ -0,0 +1,21 @@ + + + + + purchase.order.form - stock_move_original_date + purchase.order + + + + + + + + + + +