Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ addon | version | maintainers | summary
[website_sale_hide_price](website_sale_hide_price/) | 18.0.1.0.0 | | Hide product prices on the shop
[website_sale_order_shipping_modification](website_sale_order_shipping_modification/) | 18.0.1.0.0 | | Change the delivery address in quotes from the portal
[website_sale_order_type](website_sale_order_type/) | 18.0.1.0.0 | <a href='https://github.com/pilarvargas-tecnativa'><img src='https://github.com/pilarvargas-tecnativa.png' width='32' height='32' style='border-radius:50%;' alt='pilarvargas-tecnativa'/></a> | This module allows sale_order_type to work with website_sale.
[website_sale_product_assortment](website_sale_product_assortment/) | 18.0.1.1.0 | <a href='https://github.com/CarlosRoca13'><img src='https://github.com/CarlosRoca13.png' width='32' height='32' style='border-radius:50%;' alt='CarlosRoca13'/></a> | Use product assortments to display products available on e-commerce.
[website_sale_product_attribute_filter_category](website_sale_product_attribute_filter_category/) | 18.0.1.0.1 | | Allow group attributes in shop by categories
[website_sale_product_attribute_value_filter_existing](website_sale_product_attribute_value_filter_existing/) | 18.0.1.1.2 | | Allow hide attributes values not used in variants
[website_sale_product_brand](website_sale_product_brand/) | 18.0.1.0.0 | | Product Brand Filtering in Website
Expand Down
3 changes: 2 additions & 1 deletion setup/_metapackage/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "odoo-addons-oca-e-commerce"
version = "18.0.20260521.0"
version = "18.0.20260601.0"
dependencies = [
"odoo-addon-product_template_multi_link==18.0.*",
"odoo-addon-product_template_multi_link_date_span==18.0.*",
Expand All @@ -18,6 +18,7 @@ dependencies = [
"odoo-addon-website_sale_hide_price==18.0.*",
"odoo-addon-website_sale_order_shipping_modification==18.0.*",
"odoo-addon-website_sale_order_type==18.0.*",
"odoo-addon-website_sale_product_assortment==18.0.*",
"odoo-addon-website_sale_product_attribute_filter_category==18.0.*",
"odoo-addon-website_sale_product_attribute_value_filter_existing==18.0.*",
"odoo-addon-website_sale_product_brand==18.0.*",
Expand Down
119 changes: 119 additions & 0 deletions website_sale_product_assortment/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

============================
eCommerce product assortment
============================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:4cbb6bfa52522bc9a4568e76a389c20b6c5f138d4a3371faf58e1c87a8bd2bd0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |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/18.0/website_sale_product_assortment
: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-18-0/e-commerce-18-0-website_sale_product_assortment
: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=18.0
:alt: Try me on Runboat

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

This module allows to set e-commerce restrictions on product
assortments.

**Table of contents**

.. contents::
:local:

Configuration
=============

To see this module working, you have to define a product assortment and
select an option on the website availability field.

- **Don't apply restriction**: This option will not set any kind of
restriction on product items.
- **Avoid to show non available products**: This option will hide on the
e-commerce, the products that are not added to the products domain. If
a product template has at least one allowed variant to show, the
product will appear on the product items view but only that variants
will be able to be bought.
- **Avoid selling not available products**: This option will restrict to
buy the products that are added to the assortment on the e-commerce.
To inform the clients, two more fields were added: "Message when
unavailable" and "Assortment information". The first one will add a
short description to the product item and the other one will set a
detailed description on the product sheet. This second one is editable
from the website editor.

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_assortment%0Aversion:%2018.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
-------

* Tecnativa

Contributors
------------

- `Tecnativa <https://www.tecnativa.com>`__:

- Carlos Roca
- Pedro M. Baeza
- Stefan Ungureanu
- Pilar Vargas

- `Ooops <https://www.ooops404.com>`__:

- Ashish Hirpara (https://ashish-hirpara.com)

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.

.. |maintainer-CarlosRoca13| image:: https://github.com/CarlosRoca13.png?size=40px
:target: https://github.com/CarlosRoca13
:alt: CarlosRoca13

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-CarlosRoca13|

This module is part of the `OCA/e-commerce <https://github.com/OCA/e-commerce/tree/18.0/website_sale_product_assortment>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions website_sale_product_assortment/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import controllers
from . import models
28 changes: 28 additions & 0 deletions website_sale_product_assortment/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2021 Tecnativa - Carlos Roca
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "eCommerce product assortment",
"summary": "Use product assortments to display products available on e-commerce.",
"version": "18.0.1.1.0",
"development_status": "Beta",
"license": "AGPL-3",
"category": "Website",
"website": "https://github.com/OCA/e-commerce",
"author": "Tecnativa, Odoo Community Association (OCA)",
"maintainers": ["CarlosRoca13"],
"installable": True,
"depends": ["product_assortment", "website_sale"],
"data": ["views/ir_filters_views.xml"],
"assets": {
"web.assets_frontend": [
"website_sale_product_assortment/static/src/xml/*.xml",
"website_sale_product_assortment/static/src/js/variant_mixin.esm.js",
"website_sale_product_assortment/static/src/js/assortment_list_preview.esm.js",
],
"web.assets_tests": [
"website_sale_product_assortment/static/src/js/no_purchase_tour.esm.js",
"website_sale_product_assortment/static/src/js/no_restriction_tour.esm.js",
"website_sale_product_assortment/static/src/js/no_show_tour.esm.js",
],
},
}
2 changes: 2 additions & 0 deletions website_sale_product_assortment/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import variant
from . import website_sale
44 changes: 44 additions & 0 deletions website_sale_product_assortment/controllers/variant.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Copyright 2020 Tecnativa - Carlos Roca
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import _, http
from odoo.http import request

from odoo.addons.sale.controllers.product_configurator import (
SaleProductConfiguratorController,
)


class WebsiteSaleVariantController(SaleProductConfiguratorController):
@http.route(
["/sale/get_info_assortment_preview"],
type="json",
auth="public",
methods=["POST"],
website=True,
)
def get_info_assortment_preview(self, product_template_ids, **kw):
"""Special route to use website logic in get_combination_info override.
This route is called in JS by appending _website to the base route.
"""
res = []
templates = request.env["product.template"].sudo().browse(product_template_ids)
not_allowed_product_dict = templates.get_product_assortment_restriction_info(
templates.mapped("product_variant_ids.id")
)
for template in templates:
variant_ids = set(template.product_variant_ids.ids)
if (
variant_ids
and variant_ids & set(not_allowed_product_dict.keys()) == variant_ids
):
res.append(
{
"id": template.id,
"message_unavailable": not_allowed_product_dict[
variant_ids.pop()
][0].message_unavailable
or _("Not available"),
}
)
return res
78 changes: 78 additions & 0 deletions website_sale_product_assortment/controllers/website_sale.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Copyright 2021 Tecnativa - Carlos Roca
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from werkzeug.exceptions import NotFound

from odoo.http import request, route

from odoo.addons.website_sale.controllers.main import WebsiteSale


class WebsiteSale(WebsiteSale):
def _get_products_allowed(self):
partner = request.env.user.partner_id
website_id = request.website.id
assortments = (
request.env["ir.filters"]
.sudo()
.search(
[
("is_assortment", "=", True),
("website_availability", "=", "no_show"),
"|",
("website_ids", "=", False),
("website_ids", "=", website_id),
]
)
)
assortment_restriction = False
allowed_product_ids = set()
for assortment in assortments:
if (
# Set active_test to False to allow filtering by partners
# that are not active, (for example Public User)
partner & assortment.with_context(active_test=False).all_partner_ids
):
assortment_restriction = True
allowed_product_ids = allowed_product_ids.union(
set(assortment.all_product_ids.ids)
)
return allowed_product_ids, assortment_restriction

@route()
def product(self, product, category="", search="", **kwargs):
"""Overriding product method to avoid accessing to product sheet when the
product assortments prevent to show them.
"""
allowed_product_ids, assortment_restriction = self._get_products_allowed()
if assortment_restriction:
if len(set(product.product_variant_ids.ids) & allowed_product_ids) == 0:
raise NotFound()
return super().product(product, category=category, search=search, **kwargs)

def _get_search_options(
self,
category=None,
attrib_values=None,
pricelist=None,
min_price=0.0,
max_price=0.0,
conversion_rate=1,
**post,
):
"""Overriding _get_search_options method to avoid show product templates that
has all their variants not allowed to be shown."""
res = super()._get_search_options(
category=category,
attrib_values=attrib_values,
pricelist=pricelist,
min_price=min_price,
max_price=max_price,
conversion_rate=conversion_rate,
**post,
)
allowed_product_ids, assortment_restriction = self._get_products_allowed()
if assortment_restriction:
res["allowed_product_domain"] = [
("product_variant_ids", "in", list(allowed_product_ids))
]
return res
Loading
Loading