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

[ADD] product_pricelist_alternative #1557

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions product_pricelist_alternative/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
=============================
Product Pricelist Alternative
=============================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:86e2eb1f76f677e2d3704362fdf38f1f275251b62d7ac5273c956935e824eade
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |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%2Fproduct--attribute-lightgray.png?logo=github
:target: https://github.com/OCA/product-attribute/tree/16.0/product_pricelist_alternative
:alt: OCA/product-attribute
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/product-attribute-16-0/product-attribute-16-0-product_pricelist_alternative
: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/product-attribute&target_branch=16.0
:alt: Try me on Runboat

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

It allows you to define alternative price lists to a reference price list.
As a general rule, the price of a given product is obtained from the minimum between its reference price list and the alternative price lists.

However, if the product's reference price has been calculated on the basis of a price rule in which the "Alternative Pricelist Policy = Ignore" field is selected, the alternative price lists will not be taken into account.

**Table of contents**

.. contents::
:local:

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/product-attribute/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/product-attribute/issues/new?body=module:%20product_pricelist_alternative%0Aversion:%2016.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
~~~~~~~

* Camptocamp

Contributors
~~~~~~~~~~~~

* Telmo Santos <[email protected]>
* Akim Juillerat <[email protected]>

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/product-attribute <https://github.com/OCA/product-attribute/tree/16.0/product_pricelist_alternative>`_ 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 product_pricelist_alternative/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
22 changes: 22 additions & 0 deletions product_pricelist_alternative/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2024 Camptocamp (<https://www.camptocamp.com>).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

{
"name": "Product Pricelist Alternative",
"version": "16.0.1.0.0",
"development_status": "Beta",
"category": "Product",
"summary": "Calculate product price based on alternative pricelists",
"author": "Camptocamp, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/product-attribute",
"license": "AGPL-3",
"depends": [
"product",
],
"data": [
"views/product_pricelist_item_view.xml",
"views/product_pricelist_view.xml",
],
"installable": True,
"auto_install": False,
}
46 changes: 46 additions & 0 deletions product_pricelist_alternative/i18n/fr.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * product_pricelist_alternative
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-19 09:06+0000\n"
"PO-Revision-Date: 2024-03-19 09:06+0000\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: product_pricelist_alternative
#: model:ir.model.fields,field_description:product_pricelist_alternative.field_product_pricelist_item__alternative_pricelist_policy
msgid "Alternative Pricelist Policy"
msgstr "Politique de prix alternatifs"

#. module: product_pricelist_alternative
#: model_terms:ir.ui.view,arch_db:product_pricelist_alternative.product_pricelist_view
msgid "Alternative Pricelists"
msgstr "Listes de prix alternatives"

#. module: product_pricelist_alternative
#: model:ir.model.fields,field_description:product_pricelist_alternative.field_product_pricelist__alternative_pricelist_ids
msgid "Alternative pricelists"
msgstr "Listes de prix alternatives"

#. module: product_pricelist_alternative
#: model_terms:ir.ui.view,arch_db:product_pricelist_alternative.product_pricelist_view
msgid "Alternative to Pricelist"
msgstr "Alternative à la liste de prix"

#. module: product_pricelist_alternative
#: model:ir.model.fields.selection,name:product_pricelist_alternative.selection__product_pricelist_item__alternative_pricelist_policy__ignore
msgid "Ignore alternatives"
msgstr "Ignorer les alternatives"

#. module: product_pricelist_alternative
#: model:ir.model.fields.selection,name:product_pricelist_alternative.selection__product_pricelist_item__alternative_pricelist_policy__use_lower_price
msgid "Use lower price"
msgstr "Utiliser le prix le plus bas"
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * product_pricelist_alternative
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-19 09:06+0000\n"
"PO-Revision-Date: 2024-03-19 09:06+0000\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: product_pricelist_alternative
#: model:ir.model.fields,field_description:product_pricelist_alternative.field_product_pricelist_item__alternative_pricelist_policy
msgid "Alternative Pricelist Policy"
msgstr ""

#. module: product_pricelist_alternative
#: model_terms:ir.ui.view,arch_db:product_pricelist_alternative.product_pricelist_view
msgid "Alternative Pricelists"
msgstr ""

#. module: product_pricelist_alternative
#: model:ir.model.fields,field_description:product_pricelist_alternative.field_product_pricelist__alternative_pricelist_ids
msgid "Alternative pricelists"
msgstr ""

#. module: product_pricelist_alternative
#: model_terms:ir.ui.view,arch_db:product_pricelist_alternative.product_pricelist_view
msgid "Alternative to Pricelist"
msgstr ""

#. module: product_pricelist_alternative
#: model:ir.model.fields.selection,name:product_pricelist_alternative.selection__product_pricelist_item__alternative_pricelist_policy__ignore
msgid "Ignore alternatives"
msgstr ""

#. module: product_pricelist_alternative
#: model:ir.model.fields,field_description:product_pricelist_alternative.field_product_pricelist__is_alternative_to_pricelist_count
msgid "Is Alternative To Pricelist Count"
msgstr ""

#. module: product_pricelist_alternative
#. odoo-python
#: code:addons/product_pricelist_alternative/models/product_pricelist.py:0
#, python-format
msgid "Is Alternative to Pricelist"
msgstr ""

#. module: product_pricelist_alternative
#: model:ir.model.fields,field_description:product_pricelist_alternative.field_product_pricelist__is_alternative_to_pricelist_ids
msgid "Is alternative to pricelists"
msgstr ""

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

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

#. module: product_pricelist_alternative
#: model:ir.model.fields.selection,name:product_pricelist_alternative.selection__product_pricelist_item__alternative_pricelist_policy__use_lower_price
msgid "Use lower price"
msgstr ""
2 changes: 2 additions & 0 deletions product_pricelist_alternative/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import product_pricelist
from . import product_pricelist_item
76 changes: 76 additions & 0 deletions product_pricelist_alternative/models/product_pricelist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Copyright 2024 Camptocamp (<https://www.camptocamp.com>).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import _, api, fields, models


class Pricelist(models.Model):
_inherit = "product.pricelist"

alternative_pricelist_ids = fields.Many2many(
comodel_name="product.pricelist",
string="Alternative pricelists",
relation="product_pricelist_alternative_rel",
column1="origin_id",
column2="alternative_id",
domain="[('id', '!=', id)]",
)
is_alternative_to_pricelist_ids = fields.Many2many(
comodel_name="product.pricelist",
string="Is alternative to pricelists",
relation="product_pricelist_alternative_rel",
column1="alternative_id",
column2="origin_id",
)
is_alternative_to_pricelist_count = fields.Integer(
compute="_compute_is_alternative_to_pricelist_count"
)

@api.depends("is_alternative_to_pricelist_ids")
def _compute_is_alternative_to_pricelist_count(self):
groups = self.read_group(
[("alternative_pricelist_ids", "in", self.ids)],
["alternative_pricelist_ids"],
"alternative_pricelist_ids",
lazy=False,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why lazy=false?

You don't need to access anything but ID and count.

)
data = {
group["alternative_pricelist_ids"][0]: group["__count"] for group in groups
}
for pricelist in self:
pricelist.is_alternative_to_pricelist_count = data.get(pricelist.id, 0)

def action_view_is_alternative_to_pricelist(self):
santostelmo marked this conversation as resolved.
Show resolved Hide resolved
self.ensure_one()
action = {
"type": "ir.actions.act_window",
"name": _("Is Alternative to Pricelist"),
"res_model": "product.pricelist",
"view_mode": "tree,form",
"domain": [("id", "in", self.is_alternative_to_pricelist_ids.ids)],
"context": dict(self.env.context, create=False),
}
if self.is_alternative_to_pricelist_count == 1:
action.update(
{"view_mode": "form", "res_id": self.is_alternative_to_pricelist_ids.id}
)
return action

def _compute_price_rule(self, products, qty, uom=None, date=False, **kwargs):
res = super()._compute_price_rule(products, qty, uom=uom, date=date, **kwargs)
for product in products:
reference_pricelist_item = self.env["product.pricelist.item"].browse(
res[product.id][1]
)
if (
reference_pricelist_item.alternative_pricelist_policy
== "use_lower_price"
):
for alternative_pricelist in self.alternative_pricelist_ids:
alternative_price_rule = alternative_pricelist._compute_price_rule(
product, qty, uom=uom, date=date, **kwargs
)
# use alternative price if lower
if alternative_price_rule[product.id][0] < res[product.id][0]:
res[product.id] = alternative_price_rule[product.id]
return res
17 changes: 17 additions & 0 deletions product_pricelist_alternative/models/product_pricelist_item.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2024 Camptocamp (<https://www.camptocamp.com>).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import fields, models


class PricelistItem(models.Model):
_inherit = "product.pricelist.item"

alternative_pricelist_policy = fields.Selection(
selection=[
("use_lower_price", "Use lower price"),
("ignore", "Ignore alternatives"),
],
default="use_lower_price",
required=True,
)
2 changes: 2 additions & 0 deletions product_pricelist_alternative/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Telmo Santos <[email protected]>
* Akim Juillerat <[email protected]>
4 changes: 4 additions & 0 deletions product_pricelist_alternative/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
It allows you to define alternative price lists to a reference price list.
As a general rule, the price of a given product is obtained from the minimum between its reference price list and the alternative price lists.

However, if the product's reference price has been calculated on the basis of a price rule in which the "Alternative Pricelist Policy = Ignore" field is selected, the alternative price lists will not be taken into account.
Loading
Loading