-
-
Notifications
You must be signed in to change notification settings - Fork 556
[19.0][MIG]: website_sale_product_brand #1181
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
Open
Alexgars73
wants to merge
34
commits into
OCA:19.0
Choose a base branch
from
Studio73:19.0-mig-website_sale_product_brand
base: 19.0
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
157cbfc
[IMP]Changed name of module.
495cf78
[MIG]Migrated shop_by_brand module in v9.
6174b0e
[ADD][website_sale_wishlist] Wishlist for your online shop. (#122)
yajo 74f8f0c
[FIX] website_sale_product_brand: Page not found in category pagination
carlosdauden f968a80
[MIG] website_sale_product_brand: Migration to 11.0
ernestotejeda bc612c6
[MIG] website_sale_product_brand: Migration to v12.0
sergio-teruel cc59bd2
[IMP] website_sale_product_brand: Better website view
sergio-teruel 49e5b55
[IMP] website_sale_product_brand: black, isort
Tardo 641ea04
[MIG] website_sale_product_brand: Migration to 13.0
Tardo bdda6ec
[FIX] website_sale_product_brand: Fix _get_search_domain parameters
sergio-teruel b4548bf
Translated using Weblate (Portuguese (Brazil))
458ee3c
Added translation using Weblate (Dutch)
bosd 601b58a
Translated using Weblate (Dutch)
bosd 9c471c4
Translated using Weblate (Catalan)
claudiagn 6779197
[IMP] website_sale_product_brand: black, isort, prettier
victoralmau 39e0aca
[MIG] website_sale_product_brand: Migration to 14.0
victoralmau 8da6603
Translated using Weblate (Spanish (Argentina))
ibuioli 44a8d50
[MIG] website_sale_product_brand: Migration to 15.0
CarlosRoca13 013dcca
[FIX] website_sale_product_brand: image proportions
chienandalu 9975a86
[IMP] website_sale_product_brand: add website.published.mixin
chienandalu 8ef9866
[IMP] website_sale_product_brand: Use options to define the brand
CarlosRoca13 c272fb0
[MIG] website_sale_product_brand: Migration to 16.0
miguel-S73 828f5b6
Translated using Weblate (Spanish)
Ivorra78 ac6a7d3
Translated using Weblate (Spanish (Argentina))
ibuioli a7649ff
[IMP] website_sale_product_brand: test performance improvement
josep-tecnativa 03a93ea
Translated using Weblate (Italian)
mymage d4dc824
Translated using Weblate (Portuguese (Brazil))
4d97d11
Translated using Weblate (Swedish)
jakobkrabbe 85cc175
[IMP] website_sale_product_brand: pre-commit auto fixes
carlos-lopez-tecnativa 19e6eb3
[MIG] website_sale_product_brand: Migration to version 17.0
carlos-lopez-tecnativa 8f25fbc
[IMP] website_sale_product_brand: pre-commit auto fixes
pilarvargas-tecnativa 5f137ee
[MIG] website_sale_product_brand: Migration to version 18.0
pilarvargas-tecnativa b4073a9
[IMP] website_sale_product_brand: merged website_sale_filter_product_…
eduezerouali-tecnativa f35a7aa
[MIG] website_sale_product_brand: Migration to 19.0
Alexgars73 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| .. image:: https://odoo-community.org/readme-banner-image | ||
| :target: https://odoo-community.org/get-involved?utm_source=readme | ||
| :alt: Odoo Community Association | ||
|
|
||
| ================================== | ||
| Product Brand Filtering in Website | ||
| ================================== | ||
|
|
||
| .. | ||
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| !! This file is generated by oca-gen-addon-readme !! | ||
| !! changes will be overwritten. !! | ||
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| !! source digest: sha256:2866648306719d101a1a7e53c7797ebb0c3f171e68905bf0f627ed69f5f020f4 | ||
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
|
|
||
| .. |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/license-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%2Fe--commerce-lightgray.png?logo=github | ||
| :target: https://github.com/OCA/e-commerce/tree/19.0/website_sale_product_brand | ||
| :alt: OCA/e-commerce | ||
| .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png | ||
| :target: https://translation.odoo-community.org/projects/e-commerce-19-0/e-commerce-19-0-website_sale_product_brand | ||
| :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/e-commerce&target_branch=19.0 | ||
| :alt: Try me on Runboat | ||
|
|
||
| |badge1| |badge2| |badge3| |badge4| |badge5| | ||
|
|
||
| This module was written to extend the functionality of product filtering | ||
| on website. It will allow you to filter product based on its brand. | ||
|
|
||
| While shopping online, we have seen various eShops having a feature to | ||
| shop by brands which ODOO does not yet provide officially. Website Sale | ||
| Product Brand fills the gap at certain extent and by providing basic | ||
| search by brands, thus reducing end-user’s efforts in searching the | ||
| products he/she wants to purchase. | ||
|
|
||
| **Table of contents** | ||
|
|
||
| .. contents:: | ||
| :local: | ||
|
|
||
| Configuration | ||
| ============= | ||
|
|
||
| In order to hide brands from the e-commerce: | ||
|
|
||
| 1. Go to *Website > eCommerce > Product brands* | ||
| 2. Click on the brand you want to unpublish. | ||
| 3. Click on the *Website published* smart button. | ||
|
|
||
| Usage | ||
| ===== | ||
|
|
||
| Shop by brand feature is available on various famous e-commerce websites | ||
| like amazon, flipkart and many. Shop by brand feature enables you to | ||
| display product relevant to that particular brand. | ||
|
|
||
| To use this module, you need to: | ||
|
|
||
| Once you install this module, user will be able to create a new brand | ||
| and define the brand to a product. | ||
|
|
||
| To create product brand go to *Website > Settings > Products > Product | ||
| brands*: | ||
|
|
||
| - User can assign a nice logo with brand description. | ||
| - After configuring the brand, user can assign a particular brand to | ||
| a particular products. | ||
|
|
||
| Based on this configuration, you will see the menuitem shop by brand | ||
| next to shop menu. It will show all the brands and once you select that | ||
| brand it will show product's which is related to this brand. | ||
|
|
||
| Bug Tracker | ||
| =========== | ||
|
|
||
| Bugs are tracked on `GitHub Issues <https://github.com/OCA/e-commerce/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/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**>`_. | ||
|
|
||
| Do not contact contributors directly about support or help with technical issues. | ||
|
|
||
| Credits | ||
| ======= | ||
|
|
||
| Authors | ||
| ------- | ||
|
|
||
| * Serpent Consulting Services Pvt. Ltd. | ||
| * Tecnativa | ||
|
|
||
| Contributors | ||
| ------------ | ||
|
|
||
| - Jay Vora <jay.vora@serpentcs.com> | ||
|
|
||
| - Meet Dholakia <m.dholakia.serpentcs@gmail.com> | ||
|
|
||
| - `Tecnativa <https://www.tecnativa.com>`__: | ||
|
|
||
| - Ernesto Tejeda <ernesto.tejeda@tecnativa.com> | ||
| - Sergio Teruel <sergio.teruel@tecnativa.com> | ||
| - Alexandre Díaz | ||
| - David Vidal | ||
| - Carlos López | ||
| - Pilar Vargas | ||
|
|
||
| - `Studio73 <https://www.studio73.es>`__: | ||
|
|
||
| - Alex Garcia <[alex@studio73.es]> | ||
|
|
||
| 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/e-commerce <https://github.com/OCA/e-commerce/tree/19.0/website_sale_product_brand>`_ project on GitHub. | ||
|
|
||
| You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # © 2016 Serpent Consulting Services Pvt. Ltd. (http://www.serpentcs.com) | ||
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
|
||
| from . import models | ||
| from . import controllers |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| # © 2016 Serpent Consulting Services Pvt. Ltd. (http://www.serpentcs.com) | ||
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
|
||
| { | ||
| "name": "Product Brand Filtering in Website", | ||
| "category": "e-commerce", | ||
| "author": "Serpent Consulting Services Pvt. Ltd., " | ||
| "Tecnativa, " | ||
| "Odoo Community Association (OCA)", | ||
| "website": "https://github.com/OCA/e-commerce", | ||
| "version": "19.0.1.0.0", | ||
| "license": "AGPL-3", | ||
| "depends": ["product_brand", "website_sale"], | ||
| "data": [ | ||
| "security/ir.model.access.csv", | ||
| "data/website_menu.xml", | ||
| "views/product_brand.xml", | ||
| "views/product_brand_views.xml", | ||
| "views/templates.xml", | ||
| ], | ||
| "assets": { | ||
| "web.assets_frontend": [ | ||
| "/website_sale_product_brand/static/src/scss/website_sale_product_brand.scss", | ||
| ( | ||
| "after", | ||
| "website_sale/static/src/interactions/website_sale.js", | ||
| "/website_sale_product_brand/static/src/interactions/website_sale_brand_filter.esm.js", | ||
| ), | ||
| ], | ||
| "web.assets_tests": [ | ||
| "/website_sale_product_brand/static/src/js/tour.esm.js", | ||
| "/website_sale_product_brand/static/src/js/test_website_sale_filter_brand.esm.js", | ||
| ], | ||
| }, | ||
| "installable": True, | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # © 2016 Serpent Consulting Services Pvt. Ltd. (http://www.serpentcs.com) | ||
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
|
||
| from . import main |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,211 @@ | ||
| # © 2016 Serpent Consulting Services Pvt. Ltd. (http://www.serpentcs.com) | ||
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
|
||
| from odoo import http | ||
| from odoo.fields import Domain | ||
| from odoo.http import request | ||
|
|
||
| from odoo.addons.website_sale.controllers.main import QueryURL, WebsiteSale | ||
|
|
||
|
|
||
| class WebsiteSale(WebsiteSale): | ||
| def _update_domain(self, brands_list, domain): | ||
| selected_brand_ids = [int(brand) for brand in brands_list] | ||
| if brands_list: | ||
| for leaf in domain: | ||
| if leaf[0] == "product_brand_id": | ||
| domain.remove(leaf) | ||
| domain += [("product_brand_id", "in", selected_brand_ids)] | ||
| return domain | ||
|
|
||
| def _get_brand_ids(self, req): | ||
| return req.getlist("brand") or req.getlist("brand_ids") or [] | ||
|
|
||
| def _build_brands_list( | ||
| self, | ||
| selected_brand_ids, | ||
| search=None, | ||
| products=None, | ||
| search_products=None, | ||
| category=None, | ||
| ): | ||
| domain = [] | ||
| if not products: | ||
| domain = [("id", "in", selected_brand_ids)] | ||
| elif search or category: | ||
| domain = [("product_ids", "in", search_products.ids)] | ||
| return ( | ||
| request.env["product.brand"] | ||
| .sudo() | ||
| .search(domain) | ||
| .filtered(lambda x: x.is_published and x.published_products_count > 0) | ||
| ) | ||
|
|
||
| def _get_shop_domain_no_brands( | ||
| self, search, category, attribute_value_dict, search_in_description | ||
| ): | ||
| return super()._get_shop_domain( | ||
| search, | ||
| category, | ||
| attribute_value_dict, | ||
| search_in_description=search_in_description, | ||
| ) | ||
|
|
||
| def _remove_extra_brands(self, brands, search_products, attrib_values): | ||
| if attrib_values: | ||
| search_product_brands = search_products.mapped("product_brand_id") | ||
| brands = brands.filtered(lambda b: b.id in search_product_brands.ids) | ||
| # sort brands by name | ||
| return brands.sorted(key=lambda brand: brand.name) | ||
|
|
||
| def _get_search_options( | ||
| self, | ||
| category=None, | ||
| attribute_value_dict=None, | ||
| tags=None, | ||
| min_price=0.0, | ||
| max_price=0.0, | ||
| conversion_rate=1, | ||
| **post, | ||
| ): | ||
| res = super()._get_search_options( | ||
| category=category, | ||
| attribute_value_dict=attribute_value_dict, | ||
| tags=tags, | ||
| min_price=min_price, | ||
| max_price=max_price, | ||
| conversion_rate=conversion_rate, | ||
| **post, | ||
| ) | ||
| res["brand_ids"] = request.env.context.get("brand_ids") | ||
| return res | ||
|
|
||
| def _get_shop_domain( | ||
| self, search, category, attribute_value_dict, search_in_description=True | ||
| ): | ||
| domain = super()._get_shop_domain( | ||
| search, | ||
| category, | ||
| attribute_value_dict, | ||
| search_in_description=search_in_description, | ||
| ) | ||
| brand_ids = request.env.context.get("brand_ids") or [ | ||
| int(b) | ||
| for b in ( | ||
| request.httprequest.args.getlist("brand") | ||
| or request.httprequest.args.getlist("brand_ids") | ||
| ) | ||
| if b and str(b).isdigit() | ||
| ] | ||
| if brand_ids: | ||
| domain = Domain.AND([domain, [("product_brand_id", "in", brand_ids)]]) | ||
| return domain | ||
|
|
||
| @http.route( | ||
| [ | ||
| "/shop", | ||
| "/shop/page/<int:page>", | ||
| '/shop/category/<model("product.public.category"):category>', | ||
| '/shop/category/<model("product.public.category"):category' | ||
| ">/page/<int:page>", # Continue previous line | ||
| "/shop/brands", | ||
| ], | ||
| type="http", | ||
| auth="public", | ||
| website=True, | ||
| ) | ||
| def shop( | ||
| self, | ||
| page=0, | ||
| category=None, | ||
| search="", | ||
| min_price=0.0, | ||
| max_price=0.0, | ||
| ppg=False, | ||
| brand=None, | ||
| **post, | ||
| ): | ||
| brands_list = self._get_brand_ids(request.httprequest.args) | ||
| if brands_list: | ||
| request.update_context(brand_ids=[int(b) for b in brands_list]) | ||
| elif brand: | ||
| context = dict(request.env.context) | ||
| context.setdefault("brand_ids", [int(brand)]) | ||
| request.update_context(**context) | ||
| res = super().shop( | ||
| page=page, | ||
| category=category, | ||
| search=search, | ||
| min_price=min_price, | ||
| max_price=max_price, | ||
| ppg=ppg, | ||
| brand=brand, | ||
| **post, | ||
| ) | ||
| qcontext = getattr(res, "qcontext", None) or {} | ||
| attrib_values = qcontext.get("attrib_values") | ||
| products = qcontext.get("products") | ||
| if attrib_values is None or products is None: | ||
| return res | ||
| attribute_values = request.httprequest.args.getlist("attribute_values") | ||
| if attribute_values: | ||
| post["attribute_values"] = attribute_values | ||
| domain = self._get_shop_domain_no_brands( | ||
| search, category, attrib_values, search_in_description=False | ||
| ) | ||
| search_products = request.env["product.template"].search(domain) | ||
| # build brands list | ||
| selected_brand_ids = [int(brand) for brand in brands_list] | ||
| brands = self._build_brands_list( | ||
| selected_brand_ids, search, products, search_products, category | ||
| ) | ||
| brands = self._remove_extra_brands(brands, search_products, attrib_values) | ||
| # use search() domain instead of mapped() for better performance: | ||
| # will basically search for product's related attribute values | ||
| attrib_valid_ids = ( | ||
| request.env["product.attribute.value"] | ||
| .search( | ||
| [ | ||
| "&", | ||
| ( | ||
| "pav_attribute_line_ids.product_tmpl_id", | ||
| "in", | ||
| search_products._ids, | ||
| ), | ||
| ("pav_attribute_line_ids.value_ids", "!=", False), | ||
| ] | ||
| ) | ||
| .ids | ||
| ) | ||
| keep = qcontext.get("keep") | ||
| if keep and hasattr(keep, "args"): | ||
| keep.args["brand"] = brands_list | ||
| keep.args["brand_ids"] = selected_brand_ids | ||
| # assign values for usage in qweb | ||
| qcontext.update( | ||
| { | ||
| "brands": brands, | ||
| "selected_brand_ids": selected_brand_ids, | ||
| "attr_valid": attrib_valid_ids, | ||
| } | ||
| ) | ||
| return res | ||
|
|
||
| # Method to get the brands. | ||
| @http.route(["/page/product_brands"], type="http", auth="public", website=True) | ||
| def product_brands(self, **post): | ||
| b_obj = request.env["product.brand"] | ||
| domain = [("website_published", "=", True)] | ||
| if post.get("search"): | ||
| domain += [("name", "ilike", post.get("search"))] | ||
| brand_rec = ( | ||
| b_obj.sudo() | ||
| .search(domain) | ||
| .filtered(lambda x: x.published_products_count > 0) | ||
| ) | ||
|
|
||
| keep = QueryURL("/page/product_brands", brand_id=[]) | ||
| values = {"brand_rec": brand_rec, "keep": keep} | ||
| if post.get("search"): | ||
| values.update({"search": post.get("search")}) | ||
| return request.render("website_sale_product_brand.product_brands", values) | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
published_products_count > 0can be added to the domainThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Ricardoalso i think not it's a compute
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, it's a computed and stored field. Not searchable as-is 👍
This leads me to question the utility of filtering on
published_products_count > 0🤔It wasn't the case in previous versions, and doing so will exclude brands from the website even if we want to display a landing (for example) page for brands we have but have not yet configured any product.template for. I am currently working on such improvements (product brand landing page), and with this business case it makes more sense to display all brands even if no product.template is associated. What do you think? Did you have any specific technical or business need or issue that led you to implement this filter on
published_products_count > 0?Thanks in advance for your input 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened a PR #1204 with the feature "brand landing page"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Ricardoalso We were looking into it and saw the need to make that improvement because I think it makes perfect sense; why publish a brand if there isn't an active product yet?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can make sense in the current state indeed. I will add a configuration in my PR where I add the brand "landing pages" feature
Thanks for you feedback