Skip to content

Commit bffb12b

Browse files
committed
[MIG] website_sale_product_brand: Migration to 19.0
1 parent ab63d41 commit bffb12b

File tree

15 files changed

+239
-159
lines changed

15 files changed

+239
-159
lines changed

website_sale_product_brand/README.rst

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ Product Brand Filtering in Website
2121
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
2222
:alt: License: AGPL-3
2323
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fe--commerce-lightgray.png?logo=github
24-
:target: https://github.com/OCA/e-commerce/tree/18.0/website_sale_product_brand
24+
:target: https://github.com/OCA/e-commerce/tree/19.0/website_sale_product_brand
2525
:alt: OCA/e-commerce
2626
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
27-
:target: https://translation.odoo-community.org/projects/e-commerce-18-0/e-commerce-18-0-website_sale_product_brand
27+
:target: https://translation.odoo-community.org/projects/e-commerce-19-0/e-commerce-19-0-website_sale_product_brand
2828
:alt: Translate me on Weblate
2929
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
30-
:target: https://runboat.odoo-community.org/builds?repo=OCA/e-commerce&target_branch=18.0
30+
:target: https://runboat.odoo-community.org/builds?repo=OCA/e-commerce&target_branch=19.0
3131
:alt: Try me on Runboat
3232

3333
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -84,7 +84,7 @@ Bug Tracker
8484
Bugs are tracked on `GitHub Issues <https://github.com/OCA/e-commerce/issues>`_.
8585
In case of trouble, please check there if your issue has already been reported.
8686
If you spotted it first, help us to smash it by providing a detailed and welcomed
87-
`feedback <https://github.com/OCA/e-commerce/issues/new?body=module:%20website_sale_product_brand%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
87+
`feedback <https://github.com/OCA/e-commerce/issues/new?body=module:%20website_sale_product_brand%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
8888

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

@@ -113,6 +113,10 @@ Contributors
113113
- Carlos López
114114
- Pilar Vargas
115115

116+
- `Studio73 <https://www.studio73.es>`__:
117+
118+
- Alex Garcia <[alex@studio73.es]>
119+
116120
Maintainers
117121
-----------
118122

@@ -126,6 +130,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
126130
mission is to support the collaborative development of Odoo features and
127131
promote its widespread use.
128132

129-
This module is part of the `OCA/e-commerce <https://github.com/OCA/e-commerce/tree/18.0/website_sale_product_brand>`_ project on GitHub.
133+
This module is part of the `OCA/e-commerce <https://github.com/OCA/e-commerce/tree/19.0/website_sale_product_brand>`_ project on GitHub.
130134

131135
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

website_sale_product_brand/__manifest__.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"Tecnativa, "
99
"Odoo Community Association (OCA)",
1010
"website": "https://github.com/OCA/e-commerce",
11-
"version": "18.0.1.0.0",
11+
"version": "19.0.1.0.0",
1212
"license": "AGPL-3",
1313
"depends": ["product_brand", "website_sale"],
1414
"data": [
@@ -18,13 +18,14 @@
1818
"views/product_brand_views.xml",
1919
"views/templates.xml",
2020
],
21-
"demo": [
22-
"demo/product_brand_demo.xml",
23-
"demo/product_product_demo.xml",
24-
],
2521
"assets": {
2622
"web.assets_frontend": [
27-
"/website_sale_product_brand/static/src/scss/website_sale_product_brand.scss"
23+
"/website_sale_product_brand/static/src/scss/website_sale_product_brand.scss",
24+
(
25+
"after",
26+
"website_sale/static/src/interactions/website_sale.js",
27+
"/website_sale_product_brand/static/src/interactions/website_sale_brand_filter.esm.js",
28+
),
2829
],
2930
"web.assets_tests": [
3031
"/website_sale_product_brand/static/src/js/tour.esm.js",

website_sale_product_brand/controllers/main.py

Lines changed: 45 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,13 @@
22
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
33

44
from odoo import http
5+
from odoo.fields import Domain
56
from odoo.http import request
6-
from odoo.osv import expression
77

88
from odoo.addons.website_sale.controllers.main import QueryURL, WebsiteSale
99

1010

1111
class WebsiteSale(WebsiteSale):
12-
def _get_shop_domain(
13-
self, search, category, attrib_values, search_in_description=True
14-
):
15-
domain = super()._get_shop_domain(
16-
search=search,
17-
category=category,
18-
attrib_values=attrib_values,
19-
search_in_description=search_in_description,
20-
)
21-
# add selected brands to product search domain
22-
brands_list = self._get_brand_ids(request.httprequest.args)
23-
return self._update_domain(brands_list, domain)
24-
2512
def _update_domain(self, brands_list, domain):
2613
selected_brand_ids = [int(brand) for brand in brands_list]
2714
if brands_list:
@@ -49,20 +36,20 @@ def _build_brands_list(
4936
domain = [("product_ids", "in", search_products.ids)]
5037
return (
5138
request.env["product.brand"]
39+
.sudo()
5240
.search(domain)
5341
.filtered(lambda x: x.products_count > 0)
5442
)
5543

5644
def _get_shop_domain_no_brands(
57-
self, search, category, attrib_values, search_in_description
45+
self, search, category, attribute_value_dict, search_in_description
5846
):
59-
domain = super()._get_shop_domain(
60-
search=search,
61-
category=category,
62-
attrib_values=attrib_values,
47+
return super()._get_shop_domain(
48+
search,
49+
category,
50+
attribute_value_dict,
6351
search_in_description=search_in_description,
6452
)
65-
return domain
6653

6754
def _remove_extra_brands(self, brands, search_products, attrib_values):
6855
if attrib_values:
@@ -74,35 +61,44 @@ def _remove_extra_brands(self, brands, search_products, attrib_values):
7461
def _get_search_options(
7562
self,
7663
category=None,
77-
attrib_values=None,
78-
pricelist=None,
64+
attribute_value_dict=None,
65+
tags=None,
7966
min_price=0.0,
8067
max_price=0.0,
8168
conversion_rate=1,
8269
**post,
8370
):
8471
res = super()._get_search_options(
8572
category=category,
86-
attrib_values=attrib_values,
87-
pricelist=pricelist,
73+
attribute_value_dict=attribute_value_dict,
74+
tags=tags,
8875
min_price=min_price,
8976
max_price=max_price,
9077
conversion_rate=conversion_rate,
9178
**post,
9279
)
93-
res["brand"] = request.context.get("brand_id")
80+
res["brand_ids"] = request.env.context.get("brand_ids")
9481
return res
9582

9683
def _get_shop_domain(
97-
self, search, category, attrib_values, search_in_description=True
84+
self, search, category, attribute_value_dict, search_in_description=True
9885
):
9986
domain = super()._get_shop_domain(
100-
search, category, attrib_values, search_in_description=search_in_description
87+
search,
88+
category,
89+
attribute_value_dict,
90+
search_in_description=search_in_description,
10191
)
102-
if "brand_id" in request.context:
103-
domain = expression.AND(
104-
[domain, [("product_brand_id", "=", request.context["brand_id"])]]
92+
brand_ids = request.env.context.get("brand_ids") or [
93+
int(b)
94+
for b in (
95+
request.httprequest.args.getlist("brand")
96+
or request.httprequest.args.getlist("brand_ids")
10597
)
98+
if b and str(b).isdigit()
99+
]
100+
if brand_ids:
101+
domain = Domain.AND([domain, [("product_brand_id", "in", brand_ids)]])
106102
return domain
107103

108104
@http.route(
@@ -129,9 +125,12 @@ def shop(
129125
brand=None,
130126
**post,
131127
):
132-
if brand:
133-
context = dict(request.context)
134-
context.setdefault("brand_id", int(brand))
128+
brands_list = self._get_brand_ids(request.httprequest.args)
129+
if brands_list:
130+
request.update_context(brand_ids=[int(b) for b in brands_list])
131+
elif brand:
132+
context = dict(request.env.context)
133+
context.setdefault("brand_ids", [int(brand)])
135134
request.update_context(**context)
136135
res = super().shop(
137136
page=page,
@@ -143,19 +142,19 @@ def shop(
143142
brand=brand,
144143
**post,
145144
)
146-
# parse selected attributes
147-
attrib_list = request.httprequest.args.getlist("attribute_value")
148-
attrib_values = res.qcontext["attrib_values"]
149-
if attrib_list:
150-
post["attribute_value"] = attrib_list
151-
# get filtered products
152-
products = res.qcontext["products"]
145+
qcontext = getattr(res, "qcontext", None) or {}
146+
attrib_values = qcontext.get("attrib_values")
147+
products = qcontext.get("products")
148+
if attrib_values is None or products is None:
149+
return res
150+
attribute_values = request.httprequest.args.getlist("attribute_values")
151+
if attribute_values:
152+
post["attribute_values"] = attribute_values
153153
domain = self._get_shop_domain_no_brands(
154154
search, category, attrib_values, search_in_description=False
155155
)
156156
search_products = request.env["product.template"].search(domain)
157157
# build brands list
158-
brands_list = self._get_brand_ids(request.httprequest.args)
159158
selected_brand_ids = [int(brand) for brand in brands_list]
160159
brands = self._build_brands_list(
161160
selected_brand_ids, search, products, search_products, category
@@ -178,22 +177,16 @@ def shop(
178177
)
179178
.ids
180179
)
181-
# keep selected brands in URL
182-
keep = QueryURL(
183-
"/shop",
184-
**self._shop_get_query_url_kwargs(
185-
category and int(category), search, min_price, max_price, **post
186-
),
187-
brand=brands_list,
188-
brand_ids=selected_brand_ids,
189-
)
180+
keep = qcontext.get("keep")
181+
if keep and hasattr(keep, "args"):
182+
keep.args["brand"] = brands_list
183+
keep.args["brand_ids"] = selected_brand_ids
190184
# assign values for usage in qweb
191-
res.qcontext.update(
185+
qcontext.update(
192186
{
193187
"brands": brands,
194188
"selected_brand_ids": selected_brand_ids,
195189
"attr_valid": attrib_valid_ids,
196-
"keep": keep,
197190
}
198191
)
199192
return res

website_sale_product_brand/demo/product_brand_demo.xml

Lines changed: 0 additions & 6 deletions
This file was deleted.

website_sale_product_brand/demo/product_product_demo.xml

Lines changed: 0 additions & 9 deletions
This file was deleted.

website_sale_product_brand/models/product_template.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ class ProductTemplate(models.Model):
1010
def _search_get_detail(self, website, order, options):
1111
res = super()._search_get_detail(website, order, options)
1212
domain = res["base_domain"]
13-
brand_id = options.get("brand")
14-
if brand_id:
15-
domain.append([("product_brand_id", "=", brand_id)])
13+
brand_ids = options.get("brand_ids")
14+
if brand_ids:
15+
domain.append([("product_brand_id", "in", brand_ids)])
1616
res["base_domain"] = domain
1717
return res

website_sale_product_brand/readme/CONTRIBUTORS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@
1111
> - Carlos López
1212
> - Pilar Vargas
1313
14+
- [Studio73](https://www.studio73.es):
15+
> - Alex Garcia <[alex@studio73.es]>
16+

website_sale_product_brand/static/description/index.html

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ <h1>Product Brand Filtering in Website</h1>
374374
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
375375
!! source digest: sha256:2866648306719d101a1a7e53c7797ebb0c3f171e68905bf0f627ed69f5f020f4
376376
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
377-
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/e-commerce/tree/18.0/website_sale_product_brand"><img alt="OCA/e-commerce" src="https://img.shields.io/badge/github-OCA%2Fe--commerce-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/e-commerce-18-0/e-commerce-18-0-website_sale_product_brand"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/e-commerce&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
377+
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/e-commerce/tree/19.0/website_sale_product_brand"><img alt="OCA/e-commerce" src="https://img.shields.io/badge/github-OCA%2Fe--commerce-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/e-commerce-19-0/e-commerce-19-0-website_sale_product_brand"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/e-commerce&amp;target_branch=19.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
378378
<p>This module was written to extend the functionality of product filtering
379379
on website. It will allow you to filter product based on its brand.</p>
380380
<p>While shopping online, we have seen various eShops having a feature to
@@ -431,7 +431,7 @@ <h2><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h2>
431431
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/e-commerce/issues">GitHub Issues</a>.
432432
In case of trouble, please check there if your issue has already been reported.
433433
If you spotted it first, help us to smash it by providing a detailed and welcomed
434-
<a class="reference external" href="https://github.com/OCA/e-commerce/issues/new?body=module:%20website_sale_product_brand%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
434+
<a class="reference external" href="https://github.com/OCA/e-commerce/issues/new?body=module:%20website_sale_product_brand%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
435435
<p>Do not contact contributors directly about support or help with technical issues.</p>
436436
</div>
437437
<div class="section" id="credits">
@@ -462,6 +462,13 @@ <h3><a class="toc-backref" href="#toc-entry-6">Contributors</a></h3>
462462
</ul>
463463
</blockquote>
464464
</li>
465+
<li><p class="first"><a class="reference external" href="https://www.studio73.es">Studio73</a>:</p>
466+
<blockquote>
467+
<ul class="simple">
468+
<li>Alex Garcia &lt;[<a class="reference external" href="mailto:alex&#64;studio73.es]">alex&#64;studio73.es]</a>&gt;</li>
469+
</ul>
470+
</blockquote>
471+
</li>
465472
</ul>
466473
</div>
467474
<div class="section" id="maintainers">
@@ -473,7 +480,7 @@ <h3><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h3>
473480
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
474481
mission is to support the collaborative development of Odoo features and
475482
promote its widespread use.</p>
476-
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/e-commerce/tree/18.0/website_sale_product_brand">OCA/e-commerce</a> project on GitHub.</p>
483+
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/e-commerce/tree/19.0/website_sale_product_brand">OCA/e-commerce</a> project on GitHub.</p>
477484
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
478485
</div>
479486
</div>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import {WebsiteSale} from "@website_sale/interactions/website_sale";
2+
import {patch} from "@web/core/utils/patch";
3+
4+
patch(WebsiteSale.prototype, {
5+
onChangeAttribute(ev) {
6+
const container =
7+
ev.currentTarget.closest(".o_wsale_products_grid_before_rail") ||
8+
ev.currentTarget.closest(".oe_website_sale") ||
9+
document;
10+
const filters = container.querySelectorAll(
11+
"form.js_attributes input:checked, form.js_attributes select"
12+
);
13+
const attributeValues = new Map();
14+
const tags = new Set();
15+
const brands = new Set();
16+
for (const filter of filters) {
17+
if (!filter.value) {
18+
continue;
19+
}
20+
if (filter.name === "attribute_value") {
21+
const [attributeId, attributeValueId] = filter.value.split("-");
22+
const valueIds = attributeValues.get(attributeId) ?? new Set();
23+
valueIds.add(attributeValueId);
24+
attributeValues.set(attributeId, valueIds);
25+
} else if (filter.name === "tags") {
26+
tags.add(filter.value);
27+
} else if (filter.name === "brand") {
28+
brands.add(filter.value);
29+
}
30+
}
31+
const url = new URL(window.location.href);
32+
const searchParams = url.searchParams;
33+
searchParams.delete("attribute_values");
34+
searchParams.delete("tags");
35+
searchParams.delete("brand");
36+
searchParams.delete("brand_ids");
37+
searchParams.delete("page");
38+
39+
for (const entry of attributeValues.entries()) {
40+
searchParams.append(
41+
"attribute_values",
42+
`${entry[0]}-${[...entry[1]].join(",")}`
43+
);
44+
}
45+
if (tags.size) {
46+
searchParams.set("tags", [...tags].join(","));
47+
}
48+
for (const brandId of brands) {
49+
searchParams.append("brand", brandId);
50+
}
51+
52+
window.location.assign(`${url.pathname}?${searchParams.toString()}`);
53+
},
54+
});

website_sale_product_brand/static/src/js/test_website_sale_filter_brand.esm.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ registry.category("web_tour.tours").add("website_sale_filter_product_brand", {
88
content: "Check brand",
99
trigger: 'input[name="brand"]',
1010
run: "click",
11+
expectUnloadPage: true,
12+
},
13+
{
14+
content: "Brand should be checked after reload",
15+
trigger: 'input[name="brand"]:checked',
1116
},
1217
],
1318
});

0 commit comments

Comments
 (0)