diff --git a/product_visibility_website/__init__.py b/product_visibility_website/__init__.py new file mode 100644 index 000000000..ec25d99be --- /dev/null +++ b/product_visibility_website/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies (). +# Author: Shijin V () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from . import controllers +from . import models diff --git a/product_visibility_website/__manifest__.py b/product_visibility_website/__manifest__.py new file mode 100644 index 000000000..4f512178d --- /dev/null +++ b/product_visibility_website/__manifest__.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies (). +# Author: Shijin V () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +{ + 'name': 'Website Product Visibility', + 'summary': 'Website Product visibility for Users', + 'version': '13.0.1.0.0', + 'description': """Website Product visibility for Users""", + 'author': 'Cybrosys Techno Solution', + 'maintainer': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': 'https://www.cybrosys.com', + 'category': 'Website', + 'depends': ['contacts', 'website_sale'], + 'data': [ + 'views/website_product_visibility.xml', + ], + 'images': ['static/description/banner.png'], + 'license': 'AGPL-3', + 'installable': True, + 'application': False, + 'auto_install': False, +} diff --git a/product_visibility_website/controllers/__init__.py b/product_visibility_website/controllers/__init__.py new file mode 100644 index 000000000..6b634292c --- /dev/null +++ b/product_visibility_website/controllers/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies (). +# Author: Shijin V () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from . import main diff --git a/product_visibility_website/controllers/main.py b/product_visibility_website/controllers/main.py new file mode 100644 index 000000000..37f455ff7 --- /dev/null +++ b/product_visibility_website/controllers/main.py @@ -0,0 +1,331 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies (). +# Author: Shijin V () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from werkzeug.exceptions import NotFound + +from addons.http_routing.models.ir_http import slug +from addons.website.controllers.main import QueryURL +from addons.website_sale.controllers.main import TableCompute +from odoo import http +from ast import literal_eval +from odoo.http import request +from odoo.addons.website.models.ir_http import sitemap_qs2dom +from odoo.addons.website_sale.controllers.main import WebsiteSale + +from odoo.osv import expression + + + +class ProductVisibilityCon(WebsiteSale): + + def sitemap_shop(env, rule, qs): + if not qs or qs.lower() in '/shop': + yield {'loc': '/shop'} + category = env['product.public.category'] + dom = sitemap_qs2dom(qs, '/shop/category', category._rec_name) + dom += env['website'].get_current_website().website_domain() + for cat in category.search(dom): + loc = '/shop/category/%s' % slug(cat) + if not qs or qs.lower() in loc: + yield {'loc': loc} + + def reset_domain(self, search, categories, available_products, attrib_values, search_in_description=True): + ''' + Function returns a domain consist of filter conditions + :param search: search variable + :param categories: list of category available + :param available_products: list of available product ids from product.template + :param attrib_values:product attiribute values + :param search_in_description: boolean filed showing there is search variable exist or not''' + + domains = [request.website.sale_product_domain()] + if search: + for srch in search.split(" "): + subdomains = [ + [('name', 'ilike', srch)], + [('product_variant_ids.default_code', 'ilike', srch)] + ] + if search_in_description: + subdomains.append([('description', 'ilike', srch)]) + subdomains.append([('description_sale', 'ilike', srch)]) + domains.append(expression.OR(subdomains)) + if available_products: + domains.append([('id', 'in', available_products.ids)]) + if categories: + domains.append([('public_categ_ids', 'child_of', categories.ids)]) + if attrib_values: + attrib = None + ids = [] + for value in attrib_values: + if not attrib: + attrib = value[0] + ids.append(value[1]) + elif value[0] == attrib: + ids.append(value[1]) + else: + domains.append([('attribute_line_ids.value_ids', 'in', ids)]) + attrib = value[0] + ids = [value[1]] + if attrib: + domains.append([('attribute_line_ids.value_ids', 'in', ids)]) + + return expression.AND(domains) + + @http.route([ + '''/shop''', + '''/shop/page/''', + '''/shop/category/''', + '''/shop/category//page/''' + ], type='http', auth="public", website=True, sitemap=sitemap_shop) + def shop(self, page=0, category=None, search='', ppg=False, **post): + ''''Override shop function.''' + available_categ = available_products = '' + user = request.env['res.users'].sudo().search([('id', '=', request.env.user.id)]) + if not user: + mode = request.env['ir.config_parameter'].sudo().get_param('filter_mode') + products = literal_eval(request.env['ir.config_parameter'].sudo().get_param('product_visibility_website.available_product_ids', 'False')) + if mode == 'product_only': + available_products = request.env['product.template'].search([('id', 'in', products)]) + cat = literal_eval(request.env['ir.config_parameter'].sudo().get_param('product_visibility_website.available_cat_ids', 'False')) + available_categ = request.env['product.public.category'].search([('id', 'in', cat)]) + else: + partner = request.env['res.partner'].sudo().search([('id', '=', user.partner_id.id)]) + mode = partner.filter_mode + if mode == 'product_only': + available_products = self.availavle_products() + available_categ = partner.website_available_cat_ids + + Category_avail = [] + Category = request.env['product.public.category'] + + for ids in available_categ: + if not ids.parent_id.id in available_categ.ids: + Category_avail.append(ids.id) + categ = request.env['product.public.category'].search([('id', 'in', Category_avail)]) + if mode == 'product_only': + categ = Category.search([('parent_id', '=', False), ('product_tmpl_ids', 'in', available_products.ids)]) + + # supering shop*** + + if not available_categ and not available_products: + return super(ProductVisibilityCon, self).shop(page, category, search, ppg, **post) + add_qty = int(post.get('add_qty', 1)) + + if category: + category = Category.search([('id', '=', int(category))], limit=1) + if not category or not category.can_access_from_current_website(): + raise NotFound() + else: + category = Category + + if ppg: + try: + ppg = int(ppg) + post['ppg'] = ppg + except ValueError: + ppg = False + if not ppg: + ppg = request.env['website'].get_current_website().shop_ppg or 20 + ppr = request.env['website'].get_current_website().shop_ppr or 4 + attrib_list = request.httprequest.args.getlist('attrib') + attrib_values = [[int(x) for x in v.split("-")] for v in attrib_list if v] + attributes_ids = {v[0] for v in attrib_values} + attrib_set = {v[1] for v in attrib_values} + domain = self._get_search_domain(search, category, attrib_values) + Product = request.env['product.template'].with_context(bin_size=True) + if available_products: + domain_pro = self.reset_domain(search, category, available_products, attrib_values) + Product = Product.search(domain_pro) + keep = QueryURL('/shop', category=category and int(category), search=search, attrib=attrib_list, + order=post.get('order')) + pricelist_context, pricelist = self._get_pricelist_context() + request.context = dict(request.context, pricelist=pricelist.id, partner=request.env.user.partner_id) + url = "/shop" + if search: + post["search"] = search + if attrib_list: + post['attrib'] = attrib_list + if not category: + domain = self.reset_domain(search, available_categ, available_products, attrib_values) + search_product = Product.search(domain) + website_domain = request.website.website_domain() + categs_domain = [('parent_id', '=', False), ('product_tmpl_ids', 'in', search_product.ids)] + website_domain + if search: + search_categories = Category.search( + [('product_tmpl_ids', 'in', search_product.ids)] + website_domain).parents_and_self + categs_domain.append(('id', 'in', search_categories.ids)) + else: + search_categories = available_categ + if category: + url = "/shop/category/%s" % slug(category) + product_count = len(search_product) + pager = request.website.pager(url=url, total=product_count, page=page, step=ppg, scope=7, url_args=post) + products = Product.search(domain, limit=ppg, offset=pager['offset'], order=self._get_search_order(post)) + if not category: + if available_products: + products = Product.search(domain_pro, limit=ppg, offset=pager['offset'], + order=self._get_search_order(post)) + else: + products = Product.search(domain, limit=ppg, offset=pager['offset'], + order=self._get_search_order(post)) + else: + if available_products: + products = Product.search(domain_pro, limit=ppg, offset=pager['offset'], + order=self._get_search_order(post)) + else: + products = Product.search(domain, limit=ppg, offset=pager['offset'], + order=self._get_search_order(post)) + ProductAttribute = request.env['product.attribute'] + if products: + # get all products without limit + attributes = ProductAttribute.search([('product_tmpl_ids', 'in', search_product.ids)]) + else: + attributes = ProductAttribute.browse(attributes_ids) + + layout_mode = request.session.get('website_sale_shop_layout_mode') + if not layout_mode: + if request.website.viewref('website_sale.products_list_view').active: + layout_mode = 'list' + else: + layout_mode = 'grid' + values = { + 'search': search, + 'category': category, + 'attrib_values': attrib_values, + 'attrib_set': attrib_set, + 'pager': pager, + 'pricelist': pricelist, + 'add_qty': add_qty, + 'products': products, + 'search_count': product_count, # common for all searchbox + 'bins': TableCompute().process(products, ppg, ppr), + 'ppg': ppg, + 'ppr': ppr, + 'categories': categ, + 'attributes': attributes, + 'keep': keep, + 'search_categories_ids': categ.ids, + 'layout_mode': layout_mode, + } + + if category: + values['main_object'] = category + return request.render("website_sale.products", values) + + def availavle_products(self): + ''''Returns the available product (product.template) ids''' + user = request.env['res.users'].sudo().search([('id', '=', request.env.user.id)]) + partner = request.env['res.partner'].sudo().search([('id', '=', user.partner_id.id)]) + return partner.website_available_product_ids + + # -------------------------------------------------------------------------- + # Products Search Bar + # -------------------------------------------------------------------------- + + @http.route('/shop/products/autocomplete', type='json', auth='public', website=True) + def products_autocomplete(self, term, options={}, **kwargs): + """ + Returns list of products according to the term and product options + + Params: + term (str): search term written by the user + options (dict) + - 'limit' (int), default to 5: number of products to consider + - 'display_description' (bool), default to True + - 'display_price' (bool), default to True + - 'order' (str) + - 'max_nb_chars' (int): max number of characters for the + description if returned + + Returns: + dict (or False if no result) + - 'products' (list): products (only their needed field values) + note: the prices will be strings properly formatted and + already containing the currency + - 'products_count' (int): the number of products in the database + that matched the search query + """ + + user = request.env['res.users'].sudo().search([('id', '=', request.env.user.id)]) + available_categ = available_products = '' + if not user: + mode = request.env['ir.config_parameter'].sudo().get_param('filter_mode') + products = literal_eval( + request.env['ir.config_parameter'].sudo().get_param('product_visibility_website.available_product_ids', + 'False')) + if mode == 'product_only': + available_products = request.env['product.template'].search([('id', 'in', products)]) + cat = literal_eval( + request.env['ir.config_parameter'].sudo().get_param('product_visibility_website.available_cat_ids', + 'False')) + available_categ = request.env['product.public.category'].search([('id', 'in', cat)]) + else: + partner = request.env['res.partner'].sudo().search([('id', '=', user.partner_id.id)]) + mode = partner.filter_mode + if mode != 'categ_only': + available_products = self.availavle_products() + available_categ = partner.website_available_cat_ids + ProductTemplate = request.env['product.template'] + display_description = options.get('display_description', True) + display_price = options.get('display_price', True) + order = self._get_search_order(options) + max_nb_chars = options.get('max_nb_chars', 999) + category = options.get('category') + attrib_values = options.get('attrib_values') + + if not available_products and not available_categ: + domain = self._get_search_domain(term, category, attrib_values, display_description) + else: + domain = self.reset_domain(term,available_categ, available_products, attrib_values,display_description) + products = ProductTemplate.search( + domain, + limit=min(20, options.get('limit', 5)), + order=order + ) + fields = ['id', 'name', 'website_url'] + if display_description: + fields.append('description_sale') + + res = { + 'products': products.read(fields), + 'products_count': ProductTemplate.search_count(domain), + } + + if display_description: + for res_product in res['products']: + desc = res_product['description_sale'] + if desc and len(desc) > max_nb_chars: + res_product['description_sale'] = "%s..." % desc[:(max_nb_chars - 3)] + + if display_price: + FieldMonetary = request.env['ir.qweb.field.monetary'] + monetary_options = { + 'display_currency': request.website.get_current_pricelist().currency_id, + } + for res_product, product in zip(res['products'], products): + combination_info = product._get_combination_info(only_template=True) + res_product.update(combination_info) + res_product['list_price'] = FieldMonetary.value_to_html(res_product['list_price'], monetary_options) + res_product['price'] = FieldMonetary.value_to_html(res_product['price'], monetary_options) + + return res diff --git a/product_visibility_website/doc/RELEASE_NOTES.md b/product_visibility_website/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..047c5c722 --- /dev/null +++ b/product_visibility_website/doc/RELEASE_NOTES.md @@ -0,0 +1,9 @@ +## Module + +#### 31.03.2020 +#### Version 13.0.1.0.0 +##### ADD + + + + diff --git a/product_visibility_website/models/__init__.py b/product_visibility_website/models/__init__.py new file mode 100644 index 000000000..ad66c1036 --- /dev/null +++ b/product_visibility_website/models/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies (). +# Author: Shijin V () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from . import website_product_visibility diff --git a/product_visibility_website/models/website_product_visibility.py b/product_visibility_website/models/website_product_visibility.py new file mode 100644 index 000000000..8d628f982 --- /dev/null +++ b/product_visibility_website/models/website_product_visibility.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies (). +# Author: Shijin V () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from odoo import fields, models, api +from ast import literal_eval + + +class ProductVisibility(models.Model): + _inherit = 'res.partner' + + filter_mode = fields.Selection([('null', 'No Filter'), ('product_only', 'Product Wise'), + ('categ_only', 'Category Wise')], string='Filter Mode', default='null') + website_available_product_ids = fields.Many2many('product.template', string='Available Product', + domain="[('is_published', '=', True)]", + help='The website will only display products which are within one ' + 'of the selected category trees. If no category is specified,' + ' all available products will be shown') + website_available_cat_ids = fields.Many2many('product.public.category', string='Available Product Categories', + help='The website will only display products which are selected.' + ' If no product is specified,' + ' all available products will be shown') + + +class WebsiteGuestVisibility(models.TransientModel): + _inherit = 'res.config.settings' + + product_visibility_guest_user = fields.Boolean(string="Product visibility Guest User") + filter_mode = fields.Selection([('product_only', 'Product Wise'), + ('categ_only', 'Category Wise')], string='Filter Mode',default='product_only') + + available_product_ids = fields.Many2many('product.template', string='Available Product', + domain="[('is_published', '=', True)]", + help='The website will only display products which are within one ' + 'of the selected category trees. If no category is specified,' + ' all available products will be shown') + available_cat_ids = fields.Many2many('product.public.category', string='Available Product Categories', + help='The website will only display products which are selected.' + ' If no product is specified,' + ' all available products will be shown') + + + @api.model + def set_values(self): + res = super(WebsiteGuestVisibility, self).set_values() + self.env['ir.config_parameter'].sudo().set_param('product_visibility_guest_user', + self.product_visibility_guest_user) + self.env['ir.config_parameter'].sudo().set_param('filter_mode', + self.filter_mode) + if not self.product_visibility_guest_user: + self.available_cat_ids = None + self.available_product_ids = None + if self.filter_mode == 'product_only': + self.available_cat_ids = None + elif self.filter_mode == 'categ_only': + self.available_product_ids = None + + self.env['ir.config_parameter'].sudo().set_param('product_visibility_website.available_product_ids', + self.available_product_ids.ids) + self.env['ir.config_parameter'].sudo().set_param('product_visibility_website.available_cat_ids', + self.available_cat_ids.ids) + return res + + @api.model + def get_values(self): + res = super(WebsiteGuestVisibility, self).get_values() + product_ids = literal_eval(self.env['ir.config_parameter'].sudo().get_param('product_visibility_website.available_product_ids', 'False')) + cat_ids = literal_eval(self.env['ir.config_parameter'].sudo().get_param('product_visibility_website.available_cat_ids', 'False')) + + res.update( + product_visibility_guest_user=self.env['ir.config_parameter'].sudo().get_param( + 'product_visibility_guest_user'), + filter_mode=self.env['ir.config_parameter'].sudo().get_param( + 'filter_mode'), + available_product_ids=[(6, 0, product_ids)], + available_cat_ids=[(6, 0, cat_ids)], + ) + return res diff --git a/product_visibility_website/static/description/banner.png b/product_visibility_website/static/description/banner.png new file mode 100644 index 000000000..20ddb92cc Binary files /dev/null and b/product_visibility_website/static/description/banner.png differ diff --git a/product_visibility_website/static/description/icon.png b/product_visibility_website/static/description/icon.png new file mode 100644 index 000000000..79c992d1a Binary files /dev/null and b/product_visibility_website/static/description/icon.png differ diff --git a/product_visibility_website/static/description/images/checked.png b/product_visibility_website/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/product_visibility_website/static/description/images/checked.png differ diff --git a/product_visibility_website/static/description/images/cybrosys.png b/product_visibility_website/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/product_visibility_website/static/description/images/cybrosys.png differ diff --git a/product_visibility_website/static/description/images/odoo-powr-countdown-timer-12.0.1.0.zip b/product_visibility_website/static/description/images/odoo-powr-countdown-timer-12.0.1.0.zip new file mode 100644 index 000000000..54b4beb1f Binary files /dev/null and b/product_visibility_website/static/description/images/odoo-powr-countdown-timer-12.0.1.0.zip differ diff --git a/product_visibility_website/static/description/images/paytm_payment_gateway.gif b/product_visibility_website/static/description/images/paytm_payment_gateway.gif new file mode 100644 index 000000000..d18f662d3 Binary files /dev/null and b/product_visibility_website/static/description/images/paytm_payment_gateway.gif differ diff --git a/product_visibility_website/static/description/images/product_brand_ecommerce.png b/product_visibility_website/static/description/images/product_brand_ecommerce.png new file mode 100644 index 000000000..4a3246e78 Binary files /dev/null and b/product_visibility_website/static/description/images/product_brand_ecommerce.png differ diff --git a/product_visibility_website/static/description/images/scrn1.png b/product_visibility_website/static/description/images/scrn1.png new file mode 100644 index 000000000..7e5c77b10 Binary files /dev/null and b/product_visibility_website/static/description/images/scrn1.png differ diff --git a/product_visibility_website/static/description/images/scrn2.png b/product_visibility_website/static/description/images/scrn2.png new file mode 100644 index 000000000..f18a5bfe5 Binary files /dev/null and b/product_visibility_website/static/description/images/scrn2.png differ diff --git a/product_visibility_website/static/description/images/scrn3.png b/product_visibility_website/static/description/images/scrn3.png new file mode 100644 index 000000000..cb86d7d81 Binary files /dev/null and b/product_visibility_website/static/description/images/scrn3.png differ diff --git a/product_visibility_website/static/description/images/scrn4.png b/product_visibility_website/static/description/images/scrn4.png new file mode 100644 index 000000000..af28b80db Binary files /dev/null and b/product_visibility_website/static/description/images/scrn4.png differ diff --git a/product_visibility_website/static/description/images/scrn5.png b/product_visibility_website/static/description/images/scrn5.png new file mode 100644 index 000000000..9c0019f97 Binary files /dev/null and b/product_visibility_website/static/description/images/scrn5.png differ diff --git a/product_visibility_website/static/description/images/scrn6.png b/product_visibility_website/static/description/images/scrn6.png new file mode 100644 index 000000000..f0cdec232 Binary files /dev/null and b/product_visibility_website/static/description/images/scrn6.png differ diff --git a/product_visibility_website/static/description/images/website_featured_products.jpeg b/product_visibility_website/static/description/images/website_featured_products.jpeg new file mode 100644 index 000000000..9542b3f7a Binary files /dev/null and b/product_visibility_website/static/description/images/website_featured_products.jpeg differ diff --git a/product_visibility_website/static/description/images/website_repeat_sale.jpeg b/product_visibility_website/static/description/images/website_repeat_sale.jpeg new file mode 100644 index 000000000..dc8e987fb Binary files /dev/null and b/product_visibility_website/static/description/images/website_repeat_sale.jpeg differ diff --git a/product_visibility_website/static/description/images/website_sale_advanced_search.png b/product_visibility_website/static/description/images/website_sale_advanced_search.png new file mode 100644 index 000000000..691f06847 Binary files /dev/null and b/product_visibility_website/static/description/images/website_sale_advanced_search.png differ diff --git a/product_visibility_website/static/description/images/website_sale_product_quick_view.jpeg b/product_visibility_website/static/description/images/website_sale_product_quick_view.jpeg new file mode 100644 index 000000000..6fa520659 Binary files /dev/null and b/product_visibility_website/static/description/images/website_sale_product_quick_view.jpeg differ diff --git a/product_visibility_website/static/description/index.html b/product_visibility_website/static/description/index.html new file mode 100644 index 000000000..d1866fdc4 --- /dev/null +++ b/product_visibility_website/static/description/index.html @@ -0,0 +1,321 @@ +
cybrosys-logo
+
+
+
+

Website Product Visibility

+

Website Product visibility for Users.

+
+

Key Highlights

+
    +
  • checkFilter product and product categories according to the logged user.
  • +
  • check Filter product and product categories according to the public users/visitors.
  • +
  • checkUser can only search product and category among from the available product/category.
  • +
+
+ +
+
+
+
+
+ +
+
+ +

Overview

+
+

+ This module helps you to make visible only the filtered products and product categories for a logged in and logged out users/visitors.Also, it enables the user to search products and product categories only from those available products and categories. +

+
+
+ +

Website Product Visibility

+
+
    +
  • + checkFilter product and product categories according to the logged user. +
  • +
  • + checkFilter product and product categories according to the public users/visitors. +
  • +
  • + checkUser can only search product and category among from the available product/category. +
  • +
+
+ +
+
+

Screenshots

+
+
+
+ +
+
+
+
+ + + + + + + + +
+
+
+
+
+

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+ +
+
+

Trading

+

Easily procure and sell your products.

+
+
+
+
+ +
+
+

Manufacturing

+

Plan, track and schedule your operations.

+
+
+
+
+ +
+
+

Restaurant

+

Run your bar or restaurant methodical.

+
+
+
+
+ +
+
+

POS

+

Easy configuring and convivial selling.

+
+
+
+
+ +
+
+

E-commerce & Website

+

Mobile friendly, awe-inspiring product pages.

+
+
+
+
+ +
+
+

Hotel Management

+

An all-inclusive hotel management application.

+
+
+
+
+ +
+
+

Education

+

A Collaborative platform for educational management.

+
+
+
+
+ +
+
+

Service Management

+

Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/product_visibility_website/views/website_product_visibility.xml b/product_visibility_website/views/website_product_visibility.xml new file mode 100644 index 000000000..e12b3235d --- /dev/null +++ b/product_visibility_website/views/website_product_visibility.xml @@ -0,0 +1,66 @@ + + + + + base.view.partner.form.inherit + res.partner + + + + + + + + + + + + + + + + + + + + + website.config.view.inherit + res.config.settings + + + +
+

Product Visibility

+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file