Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[17.0][MIG] sale_pricelist_global_rule: Migration to version 17.0 #3526

Open
wants to merge 8 commits into
base: 17.0
Choose a base branch
from
Open
4 changes: 3 additions & 1 deletion sale_fixed_discount/models/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ def _compute_discount(self):
lines_with_discount_fixed = self.filtered(lambda sol: sol.discount_fixed)
for line in lines_with_discount_fixed:
line.discount = line._get_discount_from_fixed_discount()
return super(SaleOrderLine, self - lines_with_discount_fixed)
return super(
SaleOrderLine, self - lines_with_discount_fixed
)._compute_discount()

def _get_discount_from_fixed_discount(self):
"""Calculate the discount percentage from the fixed discount amount."""
Expand Down
7 changes: 7 additions & 0 deletions sale_order_general_discount/models/sale_order_line.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright 2018 Tecnativa - Sergio Teruel
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.tools import config


class SaleOrderLine(models.Model):
Expand All @@ -15,6 +16,12 @@ class SaleOrderLine(models.Model):
@api.depends("order_id", "order_id.general_discount")
def _compute_discount(self):
res = super()._compute_discount()
test_condition = not config["test_enable"] or (
config["test_enable"]
and self.env.context.get("test_sale_order_general_discount")
)
if not test_condition:
return res
for line in self:
# We check the value of general_discount on origin too to cover
# the case where a discount was set to a value != 0 and then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ class TestSaleOrderLineInput(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(
context=dict(cls.env.context, test_sale_order_general_discount=True)
)
cls.partner = cls.env["res.partner"].create(
{"name": "Test", "sale_discount": 10.0}
)
Expand Down
127 changes: 127 additions & 0 deletions sale_pricelist_global_rule/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
==========================
Sale pricelist global rule
==========================

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

.. |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/17.0/sale_pricelist_global_rule
: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-17-0/sale-workflow-17-0-sale_pricelist_global_rule
: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=17.0
:alt: Try me on Runboat

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

This module allows configured pricelists to be applied to a sales order
by considering cumulative quantities across all lines.

**Global by Product Template**

If a pricelist rule has a min_quantity = 15, and a sales order contains:

- Line 1: Variant 1, quantity = 8
- Line 2: Variant 2, quantity = 8

**Global by Product Category**

Similarly, if a pricelist rule has a min_quantity = 20 for products
within a category, and a sales order includes:

- Line 1: Product 1, quantity = 10
- Line 2: Product 2, quantity = 10

In standard Odoo, pricelist rules would not apply since no single line
meets the minimum quantity. With this module, however, cumulative
quantities across lines allow the pricelist rule to apply, as they meet
the minimum threshold (16 in the product template example and 20 in the
product category example).

**Table of contents**

.. contents::
:local:

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

- Go to Sales -> Products -> Pricelist.
- Create a new Pricelist and add at least one line with the Apply On
option set to Global - Product template or Global - Product category
- Choose the specific product template or category for the rule.
- Set the computation mode and save

Usage
=====

- Go to Sales -> Orders -> Quotations.
- Create a new record and fill the required fields.
- Choose a Pricelist that has a global rule configured (either by
Category or Product).
- Click the **Recompute pricelist global** button to update prices
according to the specified pricelist rules.

Known issues / Roadmap
======================

- Implement automatic application of the pricelist whenever changes are
made to order lines (such as prices, quantities, etc.) or to the
pricelist itself, eliminating the need for manual button clicks.

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_pricelist_global_rule%0Aversion:%2017.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
-------

* Tecnativa

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

- `Tecnativa <https://www.tecnativa.com>`__

- Pedro M. Baeza
- Carlos López

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 <https://github.com/OCA/sale-workflow/tree/17.0/sale_pricelist_global_rule>`_ 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_pricelist_global_rule/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
14 changes: 14 additions & 0 deletions sale_pricelist_global_rule/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "Sale pricelist global rule",
"version": "17.0.1.0.0",
"summary": "Apply a global rule to all sale order",
"author": "Tecnativa, Odoo Community Association (OCA)",
"category": "Sales Management",
"website": "https://github.com/OCA/sale-workflow",
"depends": [
"sale",
],
"data": ["views/product_pricelist_item_views.xml", "views/sale_order_views.xml"],
"installable": True,
"license": "AGPL-3",
}
100 changes: 100 additions & 0 deletions sale_pricelist_global_rule/i18n/sale_pricelist_global_rule.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_pricelist_global_rule
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.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_global_rule
#: model:ir.model.fields,field_description:sale_pricelist_global_rule.field_product_pricelist_item__applied_on
msgid "Apply On"
msgstr ""

#. module: sale_pricelist_global_rule
#: model:ir.model.fields.selection,name:sale_pricelist_global_rule.selection__product_pricelist_item__applied_on__5_global_product_category
msgid "Global - Product category"
msgstr ""

#. module: sale_pricelist_global_rule
#: model:ir.model.fields.selection,name:sale_pricelist_global_rule.selection__product_pricelist_item__applied_on__4_global_product_template
msgid "Global - Product template"
msgstr ""

#. module: sale_pricelist_global_rule
#: code:addons/sale_pricelist_global_rule/models/product_pricelist.py:0
#, python-format
msgid "Global category: %s"
msgstr ""

#. module: sale_pricelist_global_rule
#: code:addons/sale_pricelist_global_rule/models/product_pricelist.py:0
#, python-format
msgid "Global product: %s"
msgstr ""

#. module: sale_pricelist_global_rule
#: model:ir.model.fields,field_description:sale_pricelist_global_rule.field_sale_order__has_pricelist_global
msgid "Has Pricelist Global"
msgstr ""

#. module: sale_pricelist_global_rule
#: model:ir.model.fields,field_description:sale_pricelist_global_rule.field_sale_order__need_recompute_pricelist_global
msgid "Need Recompute Pricelist Global"
msgstr ""

#. module: sale_pricelist_global_rule
#: code:addons/sale_pricelist_global_rule/models/product_pricelist.py:0
#, python-format
msgid ""
"Please specify the category for which this global rule should be applied"
msgstr ""

#. module: sale_pricelist_global_rule
#: code:addons/sale_pricelist_global_rule/models/product_pricelist.py:0
#, python-format
msgid ""
"Please specify the product for which this global rule should be applied"
msgstr ""

#. module: sale_pricelist_global_rule
#: model:ir.model,name:sale_pricelist_global_rule.model_product_pricelist
msgid "Pricelist"
msgstr ""

#. module: sale_pricelist_global_rule
#: model:ir.model.fields,help:sale_pricelist_global_rule.field_product_pricelist_item__applied_on
msgid "Pricelist Item applicable on selected option"
msgstr ""

#. module: sale_pricelist_global_rule
#: model:ir.model,name:sale_pricelist_global_rule.model_product_pricelist_item
msgid "Pricelist Rule"
msgstr ""

#. module: sale_pricelist_global_rule
#: model:ir.model.fields,field_description:sale_pricelist_global_rule.field_product_pricelist_item__global_product_tmpl_id
msgid "Product"
msgstr ""

#. module: sale_pricelist_global_rule
#: model:ir.model.fields,field_description:sale_pricelist_global_rule.field_product_pricelist_item__global_categ_id
msgid "Product Category"
msgstr ""

#. module: sale_pricelist_global_rule
#: model_terms:ir.ui.view,arch_db:sale_pricelist_global_rule.view_sale_order_form
msgid "Recompute pricelist global"
msgstr ""

#. module: sale_pricelist_global_rule
#: model:ir.model,name:sale_pricelist_global_rule.model_sale_order
msgid "Sales Order"
msgstr ""
22 changes: 22 additions & 0 deletions sale_pricelist_global_rule/migrations/17.0.1.0.0/pre-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2025 Tecnativa - Carlos Lopez
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from openupgradelib import openupgrade


@openupgrade.migrate()
def migrate(env, version):
openupgrade.logged_query(
env.cr,
"""UPDATE product_pricelist_item
SET applied_on='3_1_global_product_template'
WHERE applied_on = '4_global_product_template'
""",
)
openupgrade.logged_query(
env.cr,
"""UPDATE product_pricelist_item
SET applied_on='3_2_global_product_category'
WHERE applied_on = '5_global_product_category'
""",
)
3 changes: 3 additions & 0 deletions sale_pricelist_global_rule/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import sale_order
from . import product_pricelist
from . import sale_order_line
Loading
Loading