Skip to content

Commit

Permalink
[FIX] website_sale_product_minimal_price: Take into account all price…
Browse files Browse the repository at this point in the history
…list items

Previous approach only considered pricelist items in the same pricelist as the current
one, but you can have some items that point to another pricelists, so we are changing
the approach to get all possible items, no matter the pricelist, get the minimal quantity
which they apply to, and then get the price for that quantity to see if with the price
computation, they return a different value, marking them in the scale table. With this,
we get a compromise between performance and accuracy.

NOTE: There are still left intentionally items for "All products" that can have other
scaled prices, but as this can have a lot of impact in performance and it's improbable
that someone configures pricelists this way, it's better to not include them.

TT29708
  • Loading branch information
CarlosRoca13 committed Jun 11, 2021
1 parent 4e92f80 commit b547a6f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 46 deletions.
72 changes: 29 additions & 43 deletions website_sale_product_minimal_price/controllers/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright 2020 Tecnativa - Carlos Roca
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo.addons.website_sale.controllers.main import WebsiteSale
from odoo import http, fields
from odoo import http
from odoo.http import request


Expand All @@ -16,48 +16,34 @@ def get_combination_info_pricelist_atributes(
"""Special route to use website logic in get_combination_info override.
This route is called in JS by appending _website to the base route.
"""
actual_qty = int(actual_qty)
product = request.env["product.product"].browse(product_id)
current_website = request.env["website"].get_current_website()
today = fields.Date.today()
pricelist = request.env["website"].get_current_website().get_current_pricelist()
# Getting all min_quantity of the current product to compute the posible
# price scale.
qty_list = request.env["product.pricelist.item"].search([
"|",
("product_id", "=", product.id),
"|",
("product_tmpl_id", "=", product.product_tmpl_id.id),
("categ_id", "in", list(map(
int, product.categ_id.parent_path.split('/')[0:-1]))),
("min_quantity", ">", 0),
]).mapped("min_quantity")
qty_list = sorted(set(qty_list))
res = []
pricelist = current_website.get_current_pricelist()
pricelist_items = pricelist.item_ids.filtered(
lambda i: i.product_id == product
and (not i.date_start or i.date_start <= today)
and (not i.date_end or today <= i.date_end)
and i.min_quantity > 0)
pricelist_items = pricelist_items + pricelist.item_ids.filtered(
lambda i: i.product_tmpl_id == product.product_tmpl_id
and (not i.date_start or i.date_start <= today)
and (not i.date_end or today <= i.date_end)
and i.min_quantity > 0
and (i.min_quantity < min(
pricelist_items.mapped('min_quantity')) if pricelist_items else True))
pricelist_items = pricelist_items + pricelist.item_ids.filtered(
lambda i: i.categ_id.id in list(
map(int, product.categ_id.parent_path.split('/')[0:-1]))
and (not i.date_start or i.date_start <= today)
and (not i.date_end or today <= i.date_end)
and i.min_quantity > 0
and (i.min_quantity < min(
pricelist_items.mapped('min_quantity')) if pricelist_items else True))
res = self._prepare_dictionary(pricelist_items, product, pricelist)
res.sort(key=lambda i: i.get('min_qty', 0))
return res

def _prepare_dictionary(self, pricelist_items, product, pricelist):
res = []
for item in pricelist_items:
ctx = dict(
request.env.context, pricelist=pricelist.id, quantity=item.min_quantity)
final_price = product.with_context(ctx).price
res.append({
"min_qty": item.min_quantity,
"price": final_price,
"currency": {
"position": product.currency_id.position,
"symbol": product.currency_id.symbol,
},
})
ctx = dict(request.env.context, pricelist=pricelist.id, quantity=0)
last_price = product.with_context(ctx).price
for min_qty in qty_list:
ctx["quantity"] = min_qty
new_price = product.with_context(ctx).price
if new_price != last_price:
res.append({
"min_qty": min_qty,
"price": new_price,
"currency": {
"position": product.currency_id.position,
"symbol": product.currency_id.symbol,
},
})
last_price = new_price
return res
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,18 @@ odoo.define("website_sale_product_minimal_price.load", function (require) {
);
// We define a limit of displayed columns as 4
var limit_col = 4;
var $div = undefined;
var $div;
for (var i in unit_prices) {
if (unit_prices[i].price === 0) {
continue;
}
if (i % limit_col === 0) {
var id = i/limit_col;
var first = '<div id="row_';
var end = '" class="row temporal"></div>';
$form.append(
'<div id="row_'+ id +'" class="row temporal"></div>');
$div = $('#row_' + id); // eslint-disable-line no-undef-init
first + id + end);
$div = $('#row_' + id);
}
var monetary_u = field_utils.format.monetary(
unit_prices[i].price,
Expand Down

0 comments on commit b547a6f

Please sign in to comment.