From 8b1594ae4f659b90838519714a782c9249ffd9cc Mon Sep 17 00:00:00 2001 From: jcoux Date: Fri, 12 Mar 2021 15:42:48 +0100 Subject: [PATCH 01/11] [14.0][ADD] sale_pricelist_from_commitment_date When the sale order commitment date is set, this date is used by pricelist to compute price unit instead of using order date. --- .../README.rst | 0 .../__init__.py | 3 + .../__manifest__.py | 13 +++ .../models/__init__.py | 6 ++ .../models/product_pricelist.py | 43 +++++++++ .../models/product_product.py | 22 +++++ .../models/sale_order.py | 50 ++++++++++ .../models/sale_order_line.py | 32 +++++++ .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 2 + .../tests/__init__.py | 3 + .../test_pricelist_from_commitment_date.py | 92 +++++++++++++++++++ 12 files changed, 267 insertions(+) create mode 100644 sale_pricelist_from_commitment_date/README.rst create mode 100644 sale_pricelist_from_commitment_date/__init__.py create mode 100644 sale_pricelist_from_commitment_date/__manifest__.py create mode 100644 sale_pricelist_from_commitment_date/models/__init__.py create mode 100644 sale_pricelist_from_commitment_date/models/product_pricelist.py create mode 100644 sale_pricelist_from_commitment_date/models/product_product.py create mode 100644 sale_pricelist_from_commitment_date/models/sale_order.py create mode 100644 sale_pricelist_from_commitment_date/models/sale_order_line.py create mode 100644 sale_pricelist_from_commitment_date/readme/CONTRIBUTORS.rst create mode 100644 sale_pricelist_from_commitment_date/readme/DESCRIPTION.rst create mode 100644 sale_pricelist_from_commitment_date/tests/__init__.py create mode 100644 sale_pricelist_from_commitment_date/tests/test_pricelist_from_commitment_date.py diff --git a/sale_pricelist_from_commitment_date/README.rst b/sale_pricelist_from_commitment_date/README.rst new file mode 100644 index 00000000000..e69de29bb2d diff --git a/sale_pricelist_from_commitment_date/__init__.py b/sale_pricelist_from_commitment_date/__init__.py new file mode 100644 index 00000000000..31660d6a965 --- /dev/null +++ b/sale_pricelist_from_commitment_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_pricelist_from_commitment_date/__manifest__.py b/sale_pricelist_from_commitment_date/__manifest__.py new file mode 100644 index 00000000000..307709bf2d7 --- /dev/null +++ b/sale_pricelist_from_commitment_date/__manifest__.py @@ -0,0 +1,13 @@ +# Copyright 2021 Camptocamp +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Sale Pricelist From Commitment Date", + "summary": "Use sale order commitment date to compute line price from pricelist", + "version": "14.0.1.0.0", + "category": "Sale", + "website": "https://github.com/OCA/sale-workflow", + "author": "Camptocamp, Odoo Community Association (OCA)", + "license": "AGPL-3", + "depends": ["sale"], + "installable": True, +} diff --git a/sale_pricelist_from_commitment_date/models/__init__.py b/sale_pricelist_from_commitment_date/models/__init__.py new file mode 100644 index 00000000000..94476542da7 --- /dev/null +++ b/sale_pricelist_from_commitment_date/models/__init__.py @@ -0,0 +1,6 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import product_pricelist +from . import product_product +from . import sale_order +from . import sale_order_line diff --git a/sale_pricelist_from_commitment_date/models/product_pricelist.py b/sale_pricelist_from_commitment_date/models/product_pricelist.py new file mode 100644 index 00000000000..c1dc3419905 --- /dev/null +++ b/sale_pricelist_from_commitment_date/models/product_pricelist.py @@ -0,0 +1,43 @@ +# Copyright 2021 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class ProductPricelist(models.Model): + + _inherit = "product.pricelist" + + def _compute_price_rule_multi(self, products_qty_partner, date=False, uom_id=False): + force_pricelist_date = self.env.context.get("force_pricelist_date") + if force_pricelist_date: + date = force_pricelist_date + return super()._compute_price_rule_multi(products_qty_partner, date, uom_id) + + def _compute_price_rule(self, products_qty_partner, date=False, uom_id=False): + force_pricelist_date = self.env.context.get("force_pricelist_date") + if force_pricelist_date: + date = force_pricelist_date + return super()._compute_price_rule(products_qty_partner, date, uom_id) + + def get_products_price( + self, products, quantities, partners, date=False, uom_id=False + ): + force_pricelist_date = self.env.context.get("force_pricelist_date") + if force_pricelist_date: + date = force_pricelist_date + return super().get_products_price(products, quantities, partners, date, uom_id) + + def get_product_price(self, product, quantity, partner, date=False, uom_id=False): + force_pricelist_date = self.env.context.get("force_pricelist_date") + if force_pricelist_date: + date = force_pricelist_date + return super().get_product_price(product, quantity, partner, date, uom_id) + + def get_product_price_rule( + self, product, quantity, partner, date=False, uom_id=False + ): + force_pricelist_date = self.env.context.get("force_pricelist_date") + if force_pricelist_date: + date = force_pricelist_date + return super().get_product_price_rule(product, quantity, partner, date, uom_id) diff --git a/sale_pricelist_from_commitment_date/models/product_product.py b/sale_pricelist_from_commitment_date/models/product_product.py new file mode 100644 index 00000000000..eaed1c08db5 --- /dev/null +++ b/sale_pricelist_from_commitment_date/models/product_product.py @@ -0,0 +1,22 @@ +# Copyright 2021 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, models + + +class ProductProduct(models.Model): + + _inherit = "product.product" + + @api.depends_context( + "pricelist", + "partner", + "quantity", + "uom", + "date", + "no_variant_attributes_price_extra", + "force_pricelist_date", + ) + def _compute_product_price(self): + # Just add force_pricelist_date in list of depends context + return super()._compute_product_price() diff --git a/sale_pricelist_from_commitment_date/models/sale_order.py b/sale_pricelist_from_commitment_date/models/sale_order.py new file mode 100644 index 00000000000..d481d674b82 --- /dev/null +++ b/sale_pricelist_from_commitment_date/models/sale_order.py @@ -0,0 +1,50 @@ +# Copyright 2021 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, models + + +class SaleOrder(models.Model): + + _inherit = "sale.order" + + def _apply_pricelist_from_commitment_date(self): + self.ensure_one() + for line in self.order_line: + # Price unit is still modifiable if not quantity invoiced + if not line.qty_invoiced: + # Call product_uom_change as it only updates price_unit using pricelist + line.with_context( + force_pricelist_date=self.commitment_date + ).product_uom_change() + + @api.onchange("commitment_date", "pricelist_id") + def onchange_price_with_commitment_date(self): + self._apply_pricelist_from_commitment_date() + + def create(self, vals): + sale = super().create(vals) + if sale.commitment_date: + sale._apply_pricelist_from_commitment_date() + return sale + + def write(self, vals): + if "commitment_date" not in vals and "pricelist_id" not in vals: + return super().write(vals) + for sale in self: + old_commitment_date = sale.commitment_date + old_pricelist = sale.pricelist_id + super(SaleOrder, sale).write(vals) + if ( + old_commitment_date != sale.commitment_date + or old_pricelist != sale.pricelist_id + ): + sale._apply_pricelist_from_commitment_date() + return True + + def update_prices(self): + self.ensure_one() + return super( + SaleOrder, + self.with_context(force_pricelist_date=self.commitment_date), + ).update_prices() diff --git a/sale_pricelist_from_commitment_date/models/sale_order_line.py b/sale_pricelist_from_commitment_date/models/sale_order_line.py new file mode 100644 index 00000000000..5437355cfe3 --- /dev/null +++ b/sale_pricelist_from_commitment_date/models/sale_order_line.py @@ -0,0 +1,32 @@ +# Copyright 2021 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, models + + +class SaleOrderLine(models.Model): + + _inherit = "sale.order.line" + + @api.onchange("product_id") + def product_id_change(self): + return super( + SaleOrderLine, + self.with_context(force_pricelist_date=self.order_id.commitment_date), + ).product_id_change() + + @api.onchange("product_uom", "product_uom_qty") + def product_uom_change(self): + return super( + SaleOrderLine, + self.with_context(force_pricelist_date=self.order_id.commitment_date), + ).product_uom_change() + + @api.onchange( + "product_id", "price_unit", "product_uom", "product_uom_qty", "tax_id" + ) + def _onchange_discount(self): + return super( + SaleOrderLine, + self.with_context(force_pricelist_date=self.order_id.commitment_date), + )._onchange_discount() diff --git a/sale_pricelist_from_commitment_date/readme/CONTRIBUTORS.rst b/sale_pricelist_from_commitment_date/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..17464bd6e0b --- /dev/null +++ b/sale_pricelist_from_commitment_date/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Julien Coux diff --git a/sale_pricelist_from_commitment_date/readme/DESCRIPTION.rst b/sale_pricelist_from_commitment_date/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..394371ade9d --- /dev/null +++ b/sale_pricelist_from_commitment_date/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +When the sale order commitment date is set, +this date is used by pricelist to compute price unit instead of using order date. diff --git a/sale_pricelist_from_commitment_date/tests/__init__.py b/sale_pricelist_from_commitment_date/tests/__init__.py new file mode 100644 index 00000000000..9060048d491 --- /dev/null +++ b/sale_pricelist_from_commitment_date/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import test_pricelist_from_commitment_date diff --git a/sale_pricelist_from_commitment_date/tests/test_pricelist_from_commitment_date.py b/sale_pricelist_from_commitment_date/tests/test_pricelist_from_commitment_date.py new file mode 100644 index 00000000000..238f4e30cc8 --- /dev/null +++ b/sale_pricelist_from_commitment_date/tests/test_pricelist_from_commitment_date.py @@ -0,0 +1,92 @@ +# Copyright 2021 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests.common import SavepointCase + + +class PricelistFromCommitmentDate(SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + + # Pricelists. + cls.pricelist_default = cls.env.ref("product.list0") + cls.pricelist_parent = cls._create_price_list("Parent Pricelist") + cls.pricelist = cls._create_price_list("Simple Pricelist") + cls.env["product.pricelist.item"].create( + { + "pricelist_id": cls.pricelist.id, + "applied_on": "3_global", + "compute_price": "formula", + "base": "pricelist", + "base_pricelist_id": cls.pricelist_parent.id, + } + ) + # Test in the past to avoid to have date order in the interval + cls._create_price_list_item(cls.pricelist, 10, "2020-03-05", "2020-03-09") + cls._create_price_list_item(cls.pricelist, 20, "2020-03-10", "2020-03-14") + # Parent item + cls._create_price_list_item( + cls.pricelist_parent, 30, "2020-03-15", "2020-03-20" + ) + + # Create the SO with 1 order line + cls.sale = cls.env.ref("sale.sale_order_1") + + @classmethod + def _create_price_list(cls, name): + return cls.env["product.pricelist"].create( + { + "name": name, + "active": True, + "currency_id": cls.env.ref("base.USD").id, + "company_id": cls.env.user.company_id.id, + } + ) + + @classmethod + def _create_price_list_item(cls, pricelist, price, date_start=None, date_end=None): + values = { + "pricelist_id": pricelist.id, + "applied_on": "3_global", + "base": "list_price", + "compute_price": "fixed", + "fixed_price": price, + } + if date_start: + values["date_start"] = date_start + if date_end: + values["date_end"] = date_end + return cls.env["product.pricelist.item"].create(values) + + def test_pricelist(self): + sale = self.sale + order_line = sale.order_line[0] + product = order_line.product_id + self.assertEqual(order_line.price_unit, product.list_price) + # Change pricelist have no effect as no item match + sale.pricelist_id = self.pricelist + self.assertEqual(order_line.price_unit, product.list_price) + # Test with commitment date + sale.commitment_date = "2020-03-08" + self.assertEqual(order_line.price_unit, 10) + sale.commitment_date = "2020-03-12" + self.assertEqual(order_line.price_unit, 20) + # Parent price list must match + sale.commitment_date = "2020-03-17" + self.assertEqual(order_line.price_unit, 30) + sale.date_order = "2020-03-08" + # No change with changing order date + self.assertEqual(order_line.price_unit, 30) + # Call the recompute function to be sure we have no changes + sale._apply_pricelist_from_commitment_date() + self.assertEqual(order_line.price_unit, 30) + # Remove commitment date, will match on date_order + sale.commitment_date = False + self.assertEqual(order_line.price_unit, 10) + # Remove the order date, will match on default price + sale.date_order = False + # Simulate change of product as the date order must no change normally + order_line.product_id_change() + self.assertEqual(order_line.price_unit, product.list_price) From 22e892dbc81a061723452b71574a95c850211269 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Thu, 6 May 2021 08:10:06 +0000 Subject: [PATCH 02/11] [UPD] Update sale_pricelist_from_commitment_date.pot --- .../sale_pricelist_from_commitment_date.pot | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 sale_pricelist_from_commitment_date/i18n/sale_pricelist_from_commitment_date.pot diff --git a/sale_pricelist_from_commitment_date/i18n/sale_pricelist_from_commitment_date.pot b/sale_pricelist_from_commitment_date/i18n/sale_pricelist_from_commitment_date.pot new file mode 100644 index 00000000000..eb84d5bc8b2 --- /dev/null +++ b/sale_pricelist_from_commitment_date/i18n/sale_pricelist_from_commitment_date.pot @@ -0,0 +1,58 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_pricelist_from_commitment_date +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.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_pricelist_from_commitment_date +#: model:ir.model.fields,field_description:sale_pricelist_from_commitment_date.field_product_pricelist__display_name +#: model:ir.model.fields,field_description:sale_pricelist_from_commitment_date.field_product_product__display_name +#: model:ir.model.fields,field_description:sale_pricelist_from_commitment_date.field_sale_order__display_name +#: model:ir.model.fields,field_description:sale_pricelist_from_commitment_date.field_sale_order_line__display_name +msgid "Display Name" +msgstr "" + +#. module: sale_pricelist_from_commitment_date +#: model:ir.model.fields,field_description:sale_pricelist_from_commitment_date.field_product_pricelist__id +#: model:ir.model.fields,field_description:sale_pricelist_from_commitment_date.field_product_product__id +#: model:ir.model.fields,field_description:sale_pricelist_from_commitment_date.field_sale_order__id +#: model:ir.model.fields,field_description:sale_pricelist_from_commitment_date.field_sale_order_line__id +msgid "ID" +msgstr "" + +#. module: sale_pricelist_from_commitment_date +#: model:ir.model.fields,field_description:sale_pricelist_from_commitment_date.field_product_pricelist____last_update +#: model:ir.model.fields,field_description:sale_pricelist_from_commitment_date.field_product_product____last_update +#: model:ir.model.fields,field_description:sale_pricelist_from_commitment_date.field_sale_order____last_update +#: model:ir.model.fields,field_description:sale_pricelist_from_commitment_date.field_sale_order_line____last_update +msgid "Last Modified on" +msgstr "" + +#. module: sale_pricelist_from_commitment_date +#: model:ir.model,name:sale_pricelist_from_commitment_date.model_product_pricelist +msgid "Pricelist" +msgstr "" + +#. module: sale_pricelist_from_commitment_date +#: model:ir.model,name:sale_pricelist_from_commitment_date.model_product_product +msgid "Product" +msgstr "" + +#. module: sale_pricelist_from_commitment_date +#: model:ir.model,name:sale_pricelist_from_commitment_date.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: sale_pricelist_from_commitment_date +#: model:ir.model,name:sale_pricelist_from_commitment_date.model_sale_order_line +msgid "Sales Order Line" +msgstr "" From ede955d715a9fef97931783fbc6569f194259b8b Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 6 May 2021 08:21:38 +0000 Subject: [PATCH 03/11] [UPD] README.rst --- .../README.rst | 74 +++ .../static/description/index.html | 420 ++++++++++++++++++ 2 files changed, 494 insertions(+) create mode 100644 sale_pricelist_from_commitment_date/static/description/index.html diff --git a/sale_pricelist_from_commitment_date/README.rst b/sale_pricelist_from_commitment_date/README.rst index e69de29bb2d..6a87701c9fd 100644 --- a/sale_pricelist_from_commitment_date/README.rst +++ b/sale_pricelist_from_commitment_date/README.rst @@ -0,0 +1,74 @@ +=================================== +Sale Pricelist From Commitment Date +=================================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/licence-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/14.0/sale_pricelist_from_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-14-0/sale-workflow-14-0-sale_pricelist_from_commitment_date + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/167/14.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +When the sale order commitment date is set, +this date is used by pricelist to compute price unit instead of using order date. + +**Table of contents** + +.. contents:: + :local: + +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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Camptocamp + +Contributors +~~~~~~~~~~~~ + +* Julien Coux + +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_pricelist_from_commitment_date/static/description/index.html b/sale_pricelist_from_commitment_date/static/description/index.html new file mode 100644 index 00000000000..90dd9e7b792 --- /dev/null +++ b/sale_pricelist_from_commitment_date/static/description/index.html @@ -0,0 +1,420 @@ + + + + + + +Sale Pricelist From Commitment Date + + + +
+

Sale Pricelist From Commitment Date

+ + +

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

+

When the sale order commitment date is set, +this date is used by pricelist to compute price unit instead of using order date.

+

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 smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Camptocamp
  • +
+
+ +
+

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.

+
+
+
+ + From 5ae2d6bcf99249447a3570820979c765c68077a5 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 6 May 2021 08:21:38 +0000 Subject: [PATCH 04/11] [ADD] icon.png --- .../static/description/icon.png | Bin 0 -> 9455 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 sale_pricelist_from_commitment_date/static/description/icon.png diff --git a/sale_pricelist_from_commitment_date/static/description/icon.png b/sale_pricelist_from_commitment_date/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 From a45c40c2b4129030ccc947e1b657115958d5750f Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 6 May 2021 08:21:39 +0000 Subject: [PATCH 05/11] sale_pricelist_from_commitment_date 14.0.1.0.1 --- sale_pricelist_from_commitment_date/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sale_pricelist_from_commitment_date/__manifest__.py b/sale_pricelist_from_commitment_date/__manifest__.py index 307709bf2d7..9fcc038b5b8 100644 --- a/sale_pricelist_from_commitment_date/__manifest__.py +++ b/sale_pricelist_from_commitment_date/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Sale Pricelist From Commitment Date", "summary": "Use sale order commitment date to compute line price from pricelist", - "version": "14.0.1.0.0", + "version": "14.0.1.0.1", "category": "Sale", "website": "https://github.com/OCA/sale-workflow", "author": "Camptocamp, Odoo Community Association (OCA)", From 480782c8a4d9ecb05873a783d88de4e3846544ff Mon Sep 17 00:00:00 2001 From: SilvioC2C Date: Tue, 15 Mar 2022 12:57:21 +0100 Subject: [PATCH 06/11] [FIX] sale_pricelist_from_commitment_date Avoid overriding unit price when importing data via the Odoo base importer --- .../models/sale_order.py | 4 ++ .../test_pricelist_from_commitment_date.py | 67 ++++++++++++++++++- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/sale_pricelist_from_commitment_date/models/sale_order.py b/sale_pricelist_from_commitment_date/models/sale_order.py index d481d674b82..dcf387bb455 100644 --- a/sale_pricelist_from_commitment_date/models/sale_order.py +++ b/sale_pricelist_from_commitment_date/models/sale_order.py @@ -23,12 +23,16 @@ def onchange_price_with_commitment_date(self): self._apply_pricelist_from_commitment_date() def create(self, vals): + if self._context.get("import_file"): + return super().create(vals) sale = super().create(vals) if sale.commitment_date: sale._apply_pricelist_from_commitment_date() return sale def write(self, vals): + if self._context.get("import_file"): + return super().write(vals) if "commitment_date" not in vals and "pricelist_id" not in vals: return super().write(vals) for sale in self: diff --git a/sale_pricelist_from_commitment_date/tests/test_pricelist_from_commitment_date.py b/sale_pricelist_from_commitment_date/tests/test_pricelist_from_commitment_date.py index 238f4e30cc8..ed93f88c135 100644 --- a/sale_pricelist_from_commitment_date/tests/test_pricelist_from_commitment_date.py +++ b/sale_pricelist_from_commitment_date/tests/test_pricelist_from_commitment_date.py @@ -60,7 +60,40 @@ def _create_price_list_item(cls, pricelist, price, date_start=None, date_end=Non values["date_end"] = date_end return cls.env["product.pricelist.item"].create(values) - def test_pricelist(self): + def _import_file_and_check_price_unit(self, file_vals): + file = "{}\r\n{}".format( + ",".join(file_vals.keys()), ",".join(file_vals.values()) + ) + # Create the importer and run it + res = ( + self.env["base_import.import"] + .create( + { + "res_model": "sale.order", + "file": file.encode("utf-8"), + "file_type": "text/csv", + "file_name": "data.csv", + } + ) + .do( + fields=list(file_vals.keys()), + columns=list(file_vals.keys()), + options={ + "quoting": '"', + "separator": ",", + "headers": True, + "encoding": "utf-8", + "datetime_format": "%Y-%m-%d %H:%M:%S", + }, + ) + ) + # Check if the order line's price unit is the expected one + order = self.env["sale.order"].browse(res["ids"]) + real_pu = order.order_line[-1].price_unit + expected_pu = float(file_vals["order_line/price_unit"]) + self.assertEqual(real_pu, expected_pu) + + def test_00_pricelist(self): sale = self.sale order_line = sale.order_line[0] product = order_line.product_id @@ -90,3 +123,35 @@ def test_pricelist(self): # Simulate change of product as the date order must no change normally order_line.product_id_change() self.assertEqual(order_line.price_unit, product.list_price) + + def test_01_import_create(self): + """Tests whether prices are correctly set when creating a new SO""" + # These are the values we'll use to create the file to import + partner = self.env.ref("base.res_partner_2") + product = self.env.ref("product.product_product_8") + user = self.env.ref("base.user_demo") + self._import_file_and_check_price_unit( + { + "id": "__import__.sale_order_test_pricelist_from_commitment_date", + "name": "Test Pricelist From Commitment Date", + "partner_id": partner.name, + "user_id": user.name, + "order_line/product_id": product.name, + "order_line/product_uom_qty": "1", + "order_line/price_unit": "300.00", + "commitment_date": "2021-10-22 6:30:00", + } + ) + + def test_02_import_write(self): + """Tests whether prices are correctly set when updating a SO""" + # These are the values we'll use to create the file to import + product = self.env.ref("product.product_product_8") + self._import_file_and_check_price_unit( + { + "id": self.sale.get_xml_id()[self.sale.id], + "order_line/product_id": product.name, + "order_line/product_uom_qty": "1", + "order_line/price_unit": "300.00", + } + ) From 77ed0201bbe9c4817b2d6aefa7736979b8cc8f0e Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 28 Mar 2022 11:34:31 +0000 Subject: [PATCH 07/11] sale_pricelist_from_commitment_date 14.0.1.0.2 --- sale_pricelist_from_commitment_date/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sale_pricelist_from_commitment_date/__manifest__.py b/sale_pricelist_from_commitment_date/__manifest__.py index 9fcc038b5b8..c46f0171743 100644 --- a/sale_pricelist_from_commitment_date/__manifest__.py +++ b/sale_pricelist_from_commitment_date/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Sale Pricelist From Commitment Date", "summary": "Use sale order commitment date to compute line price from pricelist", - "version": "14.0.1.0.1", + "version": "14.0.1.0.2", "category": "Sale", "website": "https://github.com/OCA/sale-workflow", "author": "Camptocamp, Odoo Community Association (OCA)", From 1591124c49b3f0614ed33920eb34151e8daee9d9 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 2 Jun 2022 04:27:07 +0000 Subject: [PATCH 08/11] [UPD] README.rst --- sale_pricelist_from_commitment_date/README.rst | 5 +---- .../static/description/index.html | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/sale_pricelist_from_commitment_date/README.rst b/sale_pricelist_from_commitment_date/README.rst index 6a87701c9fd..257674854d2 100644 --- a/sale_pricelist_from_commitment_date/README.rst +++ b/sale_pricelist_from_commitment_date/README.rst @@ -19,11 +19,8 @@ Sale Pricelist From Commitment Date .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/sale-workflow-14-0/sale-workflow-14-0-sale_pricelist_from_commitment_date :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/167/14.0 - :alt: Try me on Runbot -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| When the sale order commitment date is set, this date is used by pricelist to compute price unit instead of using order date. diff --git a/sale_pricelist_from_commitment_date/static/description/index.html b/sale_pricelist_from_commitment_date/static/description/index.html index 90dd9e7b792..198a9808a4b 100644 --- a/sale_pricelist_from_commitment_date/static/description/index.html +++ b/sale_pricelist_from_commitment_date/static/description/index.html @@ -367,7 +367,7 @@

Sale Pricelist From Commitment Date

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

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

+

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

When the sale order commitment date is set, this date is used by pricelist to compute price unit instead of using order date.

Table of contents

From cf516989d66c713fe9b8d927f5fde9919f565538 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 2 Jun 2022 05:13:57 +0000 Subject: [PATCH 09/11] [UPD] README.rst --- sale_pricelist_from_commitment_date/README.rst | 5 ++++- .../static/description/index.html | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sale_pricelist_from_commitment_date/README.rst b/sale_pricelist_from_commitment_date/README.rst index 257674854d2..6a87701c9fd 100644 --- a/sale_pricelist_from_commitment_date/README.rst +++ b/sale_pricelist_from_commitment_date/README.rst @@ -19,8 +19,11 @@ Sale Pricelist From Commitment Date .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/sale-workflow-14-0/sale-workflow-14-0-sale_pricelist_from_commitment_date :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/167/14.0 + :alt: Try me on Runbot -|badge1| |badge2| |badge3| |badge4| +|badge1| |badge2| |badge3| |badge4| |badge5| When the sale order commitment date is set, this date is used by pricelist to compute price unit instead of using order date. diff --git a/sale_pricelist_from_commitment_date/static/description/index.html b/sale_pricelist_from_commitment_date/static/description/index.html index 198a9808a4b..90dd9e7b792 100644 --- a/sale_pricelist_from_commitment_date/static/description/index.html +++ b/sale_pricelist_from_commitment_date/static/description/index.html @@ -367,7 +367,7 @@

Sale Pricelist From Commitment Date

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

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

+

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

When the sale order commitment date is set, this date is used by pricelist to compute price unit instead of using order date.

Table of contents

From 6431206753295475e26c2cfbe4dbed35ad75880a Mon Sep 17 00:00:00 2001 From: Telmo Santos Date: Mon, 28 Aug 2023 12:01:34 +0200 Subject: [PATCH 10/11] [IMP] sale_pricelist_from_commitment_date: pre-commit run --- sale_pricelist_from_commitment_date/__manifest__.py | 2 +- .../odoo/addons/sale_pricelist_from_commitment_date | 1 + setup/sale_pricelist_from_commitment_date/setup.py | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 120000 setup/sale_pricelist_from_commitment_date/odoo/addons/sale_pricelist_from_commitment_date create mode 100644 setup/sale_pricelist_from_commitment_date/setup.py diff --git a/sale_pricelist_from_commitment_date/__manifest__.py b/sale_pricelist_from_commitment_date/__manifest__.py index c46f0171743..6b7d5d50aa2 100644 --- a/sale_pricelist_from_commitment_date/__manifest__.py +++ b/sale_pricelist_from_commitment_date/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Sale Pricelist From Commitment Date", "summary": "Use sale order commitment date to compute line price from pricelist", - "version": "14.0.1.0.2", + "version": "16.0.1.0.2", "category": "Sale", "website": "https://github.com/OCA/sale-workflow", "author": "Camptocamp, Odoo Community Association (OCA)", diff --git a/setup/sale_pricelist_from_commitment_date/odoo/addons/sale_pricelist_from_commitment_date b/setup/sale_pricelist_from_commitment_date/odoo/addons/sale_pricelist_from_commitment_date new file mode 120000 index 00000000000..85df3e07f04 --- /dev/null +++ b/setup/sale_pricelist_from_commitment_date/odoo/addons/sale_pricelist_from_commitment_date @@ -0,0 +1 @@ +../../../../sale_pricelist_from_commitment_date \ No newline at end of file diff --git a/setup/sale_pricelist_from_commitment_date/setup.py b/setup/sale_pricelist_from_commitment_date/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/sale_pricelist_from_commitment_date/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 96b31e4c8db3e7e2843b9c8e249280a656169fff Mon Sep 17 00:00:00 2001 From: Telmo Santos Date: Mon, 28 Aug 2023 14:03:21 +0200 Subject: [PATCH 11/11] [MIG] sale_pricelist_from_commitment_date: Migration to 16.0 --- .../__manifest__.py | 2 +- .../models/__init__.py | 3 +- .../models/product_pricelist.py | 32 +---------- .../models/product_pricelist_item.py | 15 ++++++ .../models/product_product.py | 22 -------- .../models/sale_order.py | 54 ------------------- .../models/sale_order_line.py | 41 +++++++------- .../test_pricelist_from_commitment_date.py | 51 ++++++++---------- 8 files changed, 61 insertions(+), 159 deletions(-) create mode 100644 sale_pricelist_from_commitment_date/models/product_pricelist_item.py delete mode 100644 sale_pricelist_from_commitment_date/models/product_product.py delete mode 100644 sale_pricelist_from_commitment_date/models/sale_order.py diff --git a/sale_pricelist_from_commitment_date/__manifest__.py b/sale_pricelist_from_commitment_date/__manifest__.py index 6b7d5d50aa2..dc89df303ea 100644 --- a/sale_pricelist_from_commitment_date/__manifest__.py +++ b/sale_pricelist_from_commitment_date/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Sale Pricelist From Commitment Date", "summary": "Use sale order commitment date to compute line price from pricelist", - "version": "16.0.1.0.2", + "version": "16.0.1.0.0", "category": "Sale", "website": "https://github.com/OCA/sale-workflow", "author": "Camptocamp, Odoo Community Association (OCA)", diff --git a/sale_pricelist_from_commitment_date/models/__init__.py b/sale_pricelist_from_commitment_date/models/__init__.py index 94476542da7..00e1dc3c31f 100644 --- a/sale_pricelist_from_commitment_date/models/__init__.py +++ b/sale_pricelist_from_commitment_date/models/__init__.py @@ -1,6 +1,5 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from . import product_pricelist -from . import product_product -from . import sale_order +from . import product_pricelist_item from . import sale_order_line diff --git a/sale_pricelist_from_commitment_date/models/product_pricelist.py b/sale_pricelist_from_commitment_date/models/product_pricelist.py index c1dc3419905..6d3745df2d0 100644 --- a/sale_pricelist_from_commitment_date/models/product_pricelist.py +++ b/sale_pricelist_from_commitment_date/models/product_pricelist.py @@ -8,36 +8,8 @@ class ProductPricelist(models.Model): _inherit = "product.pricelist" - def _compute_price_rule_multi(self, products_qty_partner, date=False, uom_id=False): + def _get_product_rule(self, product, quantity, uom=None, date=False, **kwargs): force_pricelist_date = self.env.context.get("force_pricelist_date") if force_pricelist_date: date = force_pricelist_date - return super()._compute_price_rule_multi(products_qty_partner, date, uom_id) - - def _compute_price_rule(self, products_qty_partner, date=False, uom_id=False): - force_pricelist_date = self.env.context.get("force_pricelist_date") - if force_pricelist_date: - date = force_pricelist_date - return super()._compute_price_rule(products_qty_partner, date, uom_id) - - def get_products_price( - self, products, quantities, partners, date=False, uom_id=False - ): - force_pricelist_date = self.env.context.get("force_pricelist_date") - if force_pricelist_date: - date = force_pricelist_date - return super().get_products_price(products, quantities, partners, date, uom_id) - - def get_product_price(self, product, quantity, partner, date=False, uom_id=False): - force_pricelist_date = self.env.context.get("force_pricelist_date") - if force_pricelist_date: - date = force_pricelist_date - return super().get_product_price(product, quantity, partner, date, uom_id) - - def get_product_price_rule( - self, product, quantity, partner, date=False, uom_id=False - ): - force_pricelist_date = self.env.context.get("force_pricelist_date") - if force_pricelist_date: - date = force_pricelist_date - return super().get_product_price_rule(product, quantity, partner, date, uom_id) + return super()._get_product_rule(product, quantity, uom, date, **kwargs) diff --git a/sale_pricelist_from_commitment_date/models/product_pricelist_item.py b/sale_pricelist_from_commitment_date/models/product_pricelist_item.py new file mode 100644 index 00000000000..ab4b2c894da --- /dev/null +++ b/sale_pricelist_from_commitment_date/models/product_pricelist_item.py @@ -0,0 +1,15 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class ProductPricelistItem(models.Model): + + _inherit = "product.pricelist.item" + + def _compute_price(self, product, quantity, uom, date, currency=None): + force_pricelist_date = self.env.context.get("force_pricelist_date") + if force_pricelist_date: + date = force_pricelist_date + return super()._compute_price(product, quantity, uom, date, currency) diff --git a/sale_pricelist_from_commitment_date/models/product_product.py b/sale_pricelist_from_commitment_date/models/product_product.py deleted file mode 100644 index eaed1c08db5..00000000000 --- a/sale_pricelist_from_commitment_date/models/product_product.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2021 Camptocamp SA -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import api, models - - -class ProductProduct(models.Model): - - _inherit = "product.product" - - @api.depends_context( - "pricelist", - "partner", - "quantity", - "uom", - "date", - "no_variant_attributes_price_extra", - "force_pricelist_date", - ) - def _compute_product_price(self): - # Just add force_pricelist_date in list of depends context - return super()._compute_product_price() diff --git a/sale_pricelist_from_commitment_date/models/sale_order.py b/sale_pricelist_from_commitment_date/models/sale_order.py deleted file mode 100644 index dcf387bb455..00000000000 --- a/sale_pricelist_from_commitment_date/models/sale_order.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2021 Camptocamp SA -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import api, models - - -class SaleOrder(models.Model): - - _inherit = "sale.order" - - def _apply_pricelist_from_commitment_date(self): - self.ensure_one() - for line in self.order_line: - # Price unit is still modifiable if not quantity invoiced - if not line.qty_invoiced: - # Call product_uom_change as it only updates price_unit using pricelist - line.with_context( - force_pricelist_date=self.commitment_date - ).product_uom_change() - - @api.onchange("commitment_date", "pricelist_id") - def onchange_price_with_commitment_date(self): - self._apply_pricelist_from_commitment_date() - - def create(self, vals): - if self._context.get("import_file"): - return super().create(vals) - sale = super().create(vals) - if sale.commitment_date: - sale._apply_pricelist_from_commitment_date() - return sale - - def write(self, vals): - if self._context.get("import_file"): - return super().write(vals) - if "commitment_date" not in vals and "pricelist_id" not in vals: - return super().write(vals) - for sale in self: - old_commitment_date = sale.commitment_date - old_pricelist = sale.pricelist_id - super(SaleOrder, sale).write(vals) - if ( - old_commitment_date != sale.commitment_date - or old_pricelist != sale.pricelist_id - ): - sale._apply_pricelist_from_commitment_date() - return True - - def update_prices(self): - self.ensure_one() - return super( - SaleOrder, - self.with_context(force_pricelist_date=self.commitment_date), - ).update_prices() diff --git a/sale_pricelist_from_commitment_date/models/sale_order_line.py b/sale_pricelist_from_commitment_date/models/sale_order_line.py index 5437355cfe3..5128f97d252 100644 --- a/sale_pricelist_from_commitment_date/models/sale_order_line.py +++ b/sale_pricelist_from_commitment_date/models/sale_order_line.py @@ -8,25 +8,26 @@ class SaleOrderLine(models.Model): _inherit = "sale.order.line" - @api.onchange("product_id") - def product_id_change(self): - return super( - SaleOrderLine, - self.with_context(force_pricelist_date=self.order_id.commitment_date), - ).product_id_change() - - @api.onchange("product_uom", "product_uom_qty") - def product_uom_change(self): - return super( - SaleOrderLine, - self.with_context(force_pricelist_date=self.order_id.commitment_date), - ).product_uom_change() + @api.depends( + "product_id", "product_uom", "product_uom_qty", "order_id.commitment_date" + ) + def _compute_price_unit(self): + for line in self: + date = self.env.context.get( + "force_pricelist_date", line.order_id.commitment_date + ) + line = line.with_context(force_pricelist_date=date) + super(SaleOrderLine, line)._compute_price_unit() + return True - @api.onchange( - "product_id", "price_unit", "product_uom", "product_uom_qty", "tax_id" + @api.depends( + "product_id", "product_uom", "product_uom_qty", "order_id.commitment_date" ) - def _onchange_discount(self): - return super( - SaleOrderLine, - self.with_context(force_pricelist_date=self.order_id.commitment_date), - )._onchange_discount() + def _compute_pricelist_item_id(self): + for line in self: + date = self.env.context.get( + "force_pricelist_date", line.order_id.commitment_date + ) + line = line.with_context(force_pricelist_date=date) + super(SaleOrderLine, line)._compute_pricelist_item_id() + return True diff --git a/sale_pricelist_from_commitment_date/tests/test_pricelist_from_commitment_date.py b/sale_pricelist_from_commitment_date/tests/test_pricelist_from_commitment_date.py index ed93f88c135..6564786aa9b 100644 --- a/sale_pricelist_from_commitment_date/tests/test_pricelist_from_commitment_date.py +++ b/sale_pricelist_from_commitment_date/tests/test_pricelist_from_commitment_date.py @@ -1,10 +1,10 @@ # Copyright 2021 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo.tests.common import SavepointCase +from odoo.tests import TransactionCase -class PricelistFromCommitmentDate(SavepointCase): +class PricelistFromCommitmentDate(TransactionCase): @classmethod def setUpClass(cls): super().setUpClass() @@ -65,27 +65,24 @@ def _import_file_and_check_price_unit(self, file_vals): ",".join(file_vals.keys()), ",".join(file_vals.values()) ) # Create the importer and run it - res = ( - self.env["base_import.import"] - .create( - { - "res_model": "sale.order", - "file": file.encode("utf-8"), - "file_type": "text/csv", - "file_name": "data.csv", - } - ) - .do( - fields=list(file_vals.keys()), - columns=list(file_vals.keys()), - options={ - "quoting": '"', - "separator": ",", - "headers": True, - "encoding": "utf-8", - "datetime_format": "%Y-%m-%d %H:%M:%S", - }, - ) + import_wizard = self.env["base_import.import"].create( + { + "res_model": "sale.order", + "file": file.encode("utf-8"), + "file_type": "text/csv", + "file_name": "data.csv", + } + ) + res = import_wizard.execute_import( + list(file_vals.keys()), + list(file_vals.keys()), + { + "quoting": '"', + "separator": ",", + "has_headers": True, + "datetime_format": "%Y-%m-%d %H:%M:%S", + }, + True, ) # Check if the order line's price unit is the expected one order = self.env["sale.order"].browse(res["ids"]) @@ -112,17 +109,11 @@ def test_00_pricelist(self): sale.date_order = "2020-03-08" # No change with changing order date self.assertEqual(order_line.price_unit, 30) - # Call the recompute function to be sure we have no changes - sale._apply_pricelist_from_commitment_date() - self.assertEqual(order_line.price_unit, 30) # Remove commitment date, will match on date_order sale.commitment_date = False self.assertEqual(order_line.price_unit, 10) # Remove the order date, will match on default price sale.date_order = False - # Simulate change of product as the date order must no change normally - order_line.product_id_change() - self.assertEqual(order_line.price_unit, product.list_price) def test_01_import_create(self): """Tests whether prices are correctly set when creating a new SO""" @@ -149,7 +140,7 @@ def test_02_import_write(self): product = self.env.ref("product.product_product_8") self._import_file_and_check_price_unit( { - "id": self.sale.get_xml_id()[self.sale.id], + "id": self.sale.get_external_id()[self.sale.id], "order_line/product_id": product.name, "order_line/product_uom_qty": "1", "order_line/price_unit": "300.00",