Skip to content

Commit fd68cc5

Browse files
[16.0][IMP] - Handling case of discount category defined on a Parent Category
[IMP]Add Ancestor Product Category Global discount rule Fix pre-commit Fix pre-commit Fix pre-commit [MIG] sale_pricelist_global_rule: Migration to 16.0 Update READ and Contribution Update applying price by update _is_applicable_for function in product_pricelist Remove redundant file Update _is_applicable_for function Adding Unit tests and README Fix pre-commit
1 parent b6e0733 commit fd68cc5

File tree

23 files changed

+2537
-0
lines changed

23 files changed

+2537
-0
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
==========================
2+
Sale pricelist global rule
3+
==========================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:b93829a100ce8864f9f399ba2bf2c998544d9a7b00d3555405045eaebe3f4cd4
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Beta
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
17+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18+
:alt: License: AGPL-3
19+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github
20+
:target: https://github.com/OCA/sale-workflow/tree/16.0/sale_pricelist_global_rule
21+
:alt: OCA/sale-workflow
22+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23+
:target: https://translation.odoo-community.org/projects/sale-workflow-16-0/sale-workflow-16-0-sale_pricelist_global_rule
24+
:alt: Translate me on Weblate
25+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26+
:target: https://runboat.odoo-community.org/builds?repo=OCA/sale-workflow&target_branch=16.0
27+
:alt: Try me on Runboat
28+
29+
|badge1| |badge2| |badge3| |badge4| |badge5|
30+
31+
This module allows configured pricelists to be applied to a sales order
32+
by considering cumulative quantities across all lines.
33+
34+
**Global by Product Template**
35+
36+
If a pricelist rule has a min_quantity = 15, and a sales order contains:
37+
38+
- Line 1: Variant 1, quantity = 8
39+
- Line 2: Variant 2, quantity = 8
40+
41+
**Global by Product Category**
42+
43+
Similarly, if a pricelist rule has a min_quantity = 20 for products
44+
within a category, and a sales order includes:
45+
46+
- Line 1: Product 1, quantity = 10
47+
- Line 2: Product 2, quantity = 10
48+
49+
In standard Odoo, pricelist rules would not apply since no single line
50+
meets the minimum quantity. With this module, however, cumulative
51+
quantities across lines allow the pricelist rule to apply, as they meet
52+
the minimum threshold (16 in the product template example and 20 in the
53+
product category example).
54+
55+
**Global by Ancestor Product Category**
56+
57+
This option allows defining a rule on an *ancestor category*, and it will
58+
apply to all products that belong to this category or any of its descendants.
59+
The minimum quantity check is performed on the **total ordered quantity**
60+
across all descendant categories.
61+
62+
For example, suppose we have the following category tree:
63+
64+
- Cat A
65+
- Cat B
66+
- Cat C
67+
- Cat D
68+
69+
And a pricelist rule is configured on *Cat C* with a minimum quantity = 5
70+
and a 20% discount.
71+
If a sales order contains:
72+
73+
- Line 1: Product in Cat C, quantity = 4
74+
- Line 2: Product in Cat D, quantity = 2
75+
76+
Then the total for Cat C’s branch = 6 (4 + 2), which meets the minimum
77+
threshold of 5. As a result, the 20% discount rule applies to both lines.
78+
79+
**Table of contents**
80+
81+
.. contents::
82+
:local:
83+
84+
Configuration
85+
=============
86+
87+
- Go to Sales -> Products -> Pricelist.
88+
- Create a new Pricelist and add at least one line with the Apply On
89+
option set to Global - Product template or Global - Product category
90+
or Global - Ancestor Product Category
91+
- Choose the specific product template or category for the rule.
92+
- Set the computation mode and save
93+
94+
Usage
95+
=====
96+
97+
- Go to Sales -> Orders -> Quotations.
98+
- Create a new record and fill the required fields.
99+
- Choose a Pricelist that has a global rule configured (either by
100+
Category or Product).
101+
- Click the **Recompute pricelist global** button to update prices
102+
according to the specified pricelist rules.
103+
104+
When using **Ancestor Product Category**, the system will sum the ordered
105+
quantities of all products belonging to the selected ancestor category
106+
and all its descendants.
107+
If the accumulated quantity meets the rule’s minimum quantity, the
108+
discount will be applied to each matching order line.
109+
110+
Known issues / Roadmap
111+
======================
112+
113+
- Implement automatic application of the pricelist whenever changes are
114+
made to order lines (such as prices, quantities, etc.) or to the
115+
pricelist itself, eliminating the need for manual button clicks.
116+
117+
Bug Tracker
118+
===========
119+
120+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/sale-workflow/issues>`_.
121+
In case of trouble, please check there if your issue has already been reported.
122+
If you spotted it first, help us to smash it by providing a detailed and welcomed
123+
`feedback <https://github.com/OCA/sale-workflow/issues/new?body=module:%20sale_pricelist_global_rule%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
124+
125+
Do not contact contributors directly about support or help with technical issues.
126+
127+
Credits
128+
=======
129+
130+
Authors
131+
-------
132+
133+
* Tecnativa
134+
135+
Contributors
136+
------------
137+
138+
- `Tecnativa <https://www.tecnativa.com>`__
139+
140+
- Pedro M. Baeza
141+
- Carlos López
142+
143+
- `Komit-consulting <https://komit-consulting.com/>`__
144+
145+
- Truong Duc
146+
147+
Maintainers
148+
-----------
149+
150+
This module is maintained by the OCA.
151+
152+
.. image:: https://odoo-community.org/logo.png
153+
:alt: Odoo Community Association
154+
:target: https://odoo-community.org
155+
156+
OCA, or the Odoo Community Association, is a nonprofit organization whose
157+
mission is to support the collaborative development of Odoo features and
158+
promote its widespread use.
159+
160+
This module is part of the `OCA/sale-workflow <https://github.com/OCA/sale-workflow/tree/16.0/sale_pricelist_global_rule>`_ project on GitHub.
161+
162+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "Sale pricelist global rule",
3+
"version": "16.0.1.0.0",
4+
"summary": "Apply a global rule to all sale order",
5+
"author": "Tecnativa, Odoo Community Association (OCA),"
6+
"Truong Duc (Komit-consulting)",
7+
"category": "Sales Management",
8+
"website": "https://github.com/OCA/sale-workflow",
9+
"depends": [
10+
"sale",
11+
],
12+
"data": ["views/product_pricelist_item_views.xml", "views/sale_order_views.xml"],
13+
"installable": True,
14+
"license": "AGPL-3",
15+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Translation of Odoo Server.
2+
# This file contains the translation of the following modules:
3+
# * sale_pricelist_global_rule
4+
#
5+
msgid ""
6+
msgstr ""
7+
"Project-Id-Version: Odoo Server 15.0\n"
8+
"Report-Msgid-Bugs-To: \n"
9+
"Last-Translator: \n"
10+
"Language-Team: \n"
11+
"MIME-Version: 1.0\n"
12+
"Content-Type: text/plain; charset=UTF-8\n"
13+
"Content-Transfer-Encoding: \n"
14+
"Plural-Forms: \n"
15+
16+
#. module: sale_pricelist_global_rule
17+
#: model:ir.model.fields,field_description:sale_pricelist_global_rule.field_product_pricelist_item__applied_on
18+
msgid "Apply On"
19+
msgstr ""
20+
21+
#. module: sale_pricelist_global_rule
22+
#: model:ir.model.fields.selection,name:sale_pricelist_global_rule.selection__product_pricelist_item__applied_on__5_global_product_category
23+
msgid "Global - Product category"
24+
msgstr ""
25+
26+
#. module: sale_pricelist_global_rule
27+
#: model:ir.model.fields.selection,name:sale_pricelist_global_rule.selection__product_pricelist_item__applied_on__4_global_product_template
28+
msgid "Global - Product template"
29+
msgstr ""
30+
31+
#. module: sale_pricelist_global_rule
32+
#: code:addons/sale_pricelist_global_rule/models/product_pricelist.py:0
33+
#, python-format
34+
msgid "Global category: %s"
35+
msgstr ""
36+
37+
#. module: sale_pricelist_global_rule
38+
#: code:addons/sale_pricelist_global_rule/models/product_pricelist.py:0
39+
#, python-format
40+
msgid "Global product: %s"
41+
msgstr ""
42+
43+
#. module: sale_pricelist_global_rule
44+
#: model:ir.model.fields,field_description:sale_pricelist_global_rule.field_sale_order__has_pricelist_global
45+
msgid "Has Pricelist Global"
46+
msgstr ""
47+
48+
#. module: sale_pricelist_global_rule
49+
#: model:ir.model.fields,field_description:sale_pricelist_global_rule.field_sale_order__need_recompute_pricelist_global
50+
msgid "Need Recompute Pricelist Global"
51+
msgstr ""
52+
53+
#. module: sale_pricelist_global_rule
54+
#: code:addons/sale_pricelist_global_rule/models/product_pricelist.py:0
55+
#, python-format
56+
msgid ""
57+
"Please specify the category for which this global rule should be applied"
58+
msgstr ""
59+
60+
#. module: sale_pricelist_global_rule
61+
#: code:addons/sale_pricelist_global_rule/models/product_pricelist.py:0
62+
#, python-format
63+
msgid ""
64+
"Please specify the product for which this global rule should be applied"
65+
msgstr ""
66+
67+
#. module: sale_pricelist_global_rule
68+
#: model:ir.model,name:sale_pricelist_global_rule.model_product_pricelist
69+
msgid "Pricelist"
70+
msgstr ""
71+
72+
#. module: sale_pricelist_global_rule
73+
#: model:ir.model.fields,help:sale_pricelist_global_rule.field_product_pricelist_item__applied_on
74+
msgid "Pricelist Item applicable on selected option"
75+
msgstr ""
76+
77+
#. module: sale_pricelist_global_rule
78+
#: model:ir.model,name:sale_pricelist_global_rule.model_product_pricelist_item
79+
msgid "Pricelist Rule"
80+
msgstr ""
81+
82+
#. module: sale_pricelist_global_rule
83+
#: model:ir.model.fields,field_description:sale_pricelist_global_rule.field_product_pricelist_item__global_product_tmpl_id
84+
msgid "Product"
85+
msgstr ""
86+
87+
#. module: sale_pricelist_global_rule
88+
#: model:ir.model.fields,field_description:sale_pricelist_global_rule.field_product_pricelist_item__global_categ_id
89+
msgid "Product Category"
90+
msgstr ""
91+
92+
#. module: sale_pricelist_global_rule
93+
#: model_terms:ir.ui.view,arch_db:sale_pricelist_global_rule.view_sale_order_form
94+
msgid "Recompute pricelist global"
95+
msgstr ""
96+
97+
#. module: sale_pricelist_global_rule
98+
#: model:ir.model,name:sale_pricelist_global_rule.model_sale_order
99+
msgid "Sales Order"
100+
msgstr ""
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright 2025 Tecnativa - Carlos Lopez
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
3+
4+
from openupgradelib import openupgrade
5+
6+
7+
@openupgrade.migrate()
8+
def migrate(env, version):
9+
openupgrade.logged_query(
10+
env.cr,
11+
"""UPDATE product_pricelist_item
12+
SET applied_on='3_1_global_product_template'
13+
WHERE applied_on = '4_global_product_template'
14+
""",
15+
)
16+
openupgrade.logged_query(
17+
env.cr,
18+
"""UPDATE product_pricelist_item
19+
SET applied_on='3_2_global_product_category'
20+
WHERE applied_on = '5_global_product_category'
21+
""",
22+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from . import sale_order
2+
from . import product_pricelist
3+
from . import sale_order_line

0 commit comments

Comments
 (0)