99
1010
1111class 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+
25+ def _update_domain (self , brands_list , domain ):
26+ selected_brand_ids = [int (brand ) for brand in brands_list ]
27+ if brands_list :
28+ for leaf in domain :
29+ if leaf [0 ] == "product_brand_id" :
30+ domain .remove (leaf )
31+ domain += [("product_brand_id" , "in" , selected_brand_ids )]
32+ return domain
33+
34+ def _get_brand_ids (self , req ):
35+ return req .getlist ("brand" ) or req .getlist ("brand_ids" ) or []
36+
37+ def _build_brands_list (
38+ self ,
39+ selected_brand_ids ,
40+ search = None ,
41+ products = None ,
42+ search_products = None ,
43+ category = None ,
44+ ):
45+ domain = []
46+ if not products :
47+ domain = [("id" , "in" , selected_brand_ids )]
48+ elif search or category :
49+ domain = [("product_ids" , "in" , search_products .ids )]
50+ return (
51+ request .env ["product.brand" ]
52+ .search (domain )
53+ .filtered (lambda x : x .products_count > 0 )
54+ )
55+
56+ def _get_shop_domain_no_brands (
57+ self , search , category , attrib_values , search_in_description
58+ ):
59+ domain = super ()._get_shop_domain (
60+ search = search ,
61+ category = category ,
62+ attrib_values = attrib_values ,
63+ search_in_description = search_in_description ,
64+ )
65+ return domain
66+
67+ def _remove_extra_brands (self , brands , search_products , attrib_values ):
68+ if attrib_values :
69+ search_product_brands = search_products .mapped ("product_brand_id" )
70+ brands = brands .filtered (lambda b : b .id in search_product_brands .ids )
71+ # sort brands by name
72+ return brands .sorted (key = lambda brand : brand .name )
73+
1274 def _get_search_options (
1375 self ,
1476 category = None ,
@@ -31,10 +93,10 @@ def _get_search_options(
3193 res ["brand" ] = request .context .get ("brand_id" )
3294 return res
3395
34- def _get_search_domain (
96+ def _get_shop_domain (
3597 self , search , category , attrib_values , search_in_description = True
3698 ):
37- domain = super ()._get_search_domain (
99+ domain = super ()._get_shop_domain (
38100 search , category , attrib_values , search_in_description = search_in_description
39101 )
40102 if "brand_id" in request .context :
@@ -71,7 +133,7 @@ def shop(
71133 context = dict (request .context )
72134 context .setdefault ("brand_id" , int (brand ))
73135 request .update_context (** context )
74- return super ().shop (
136+ res = super ().shop (
75137 page = page ,
76138 category = category ,
77139 search = search ,
@@ -81,6 +143,60 @@ def shop(
81143 brand = brand ,
82144 ** post ,
83145 )
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" ]
153+ domain = self ._get_shop_domain_no_brands (
154+ search , category , attrib_values , search_in_description = False
155+ )
156+ search_products = request .env ["product.template" ].search (domain )
157+ # build brands list
158+ brands_list = self ._get_brand_ids (request .httprequest .args )
159+ selected_brand_ids = [int (brand ) for brand in brands_list ]
160+ brands = self ._build_brands_list (
161+ selected_brand_ids , search , products , search_products , category
162+ )
163+ brands = self ._remove_extra_brands (brands , search_products , attrib_values )
164+ # use search() domain instead of mapped() for better performance:
165+ # will basically search for product's related attribute values
166+ attrib_valid_ids = (
167+ request .env ["product.attribute.value" ]
168+ .search (
169+ [
170+ "&" ,
171+ (
172+ "pav_attribute_line_ids.product_tmpl_id" ,
173+ "in" ,
174+ search_products ._ids ,
175+ ),
176+ ("pav_attribute_line_ids.value_ids" , "!=" , False ),
177+ ]
178+ )
179+ .ids
180+ )
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+ )
190+ # assign values for usage in qweb
191+ res .qcontext .update (
192+ {
193+ "brands" : brands ,
194+ "selected_brand_ids" : selected_brand_ids ,
195+ "attr_valid" : attrib_valid_ids ,
196+ "keep" : keep ,
197+ }
198+ )
199+ return res
84200
85201 # Method to get the brands.
86202 @http .route (["/page/product_brands" ], type = "http" , auth = "public" , website = True )
0 commit comments