diff --git a/product_brand_ecommerce/README.md b/product_brand_ecommerce/README.md new file mode 100644 index 000000000..dbc33693a --- /dev/null +++ b/product_brand_ecommerce/README.md @@ -0,0 +1,33 @@ +Product Brand in eCommerce +========================== + +Installation +============ +- www.odoo.com/documentation/16.0/setup/install.html +- Install our custom addon + +License +======= +GNU AFFERO GENERAL PUBLIC LICENSE, Version 3 (AGPLv3) +(http://www.gnu.org/licenses/agpl.html) + +Bug Tracker +=========== +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Credits +======= +* Cybrosys Techno Solutions + + +Developer: Afras Habis - odoo@cybrosys.com, + V15 Midilaj V K - odoo@cybrosys.com + V16 Neenu Merlin Jose - odoo@cybrosys.com + +Maintainer +---------- + +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit https://www.cybrosys.com. + diff --git a/product_brand_ecommerce/__init__.py b/product_brand_ecommerce/__init__.py new file mode 100644 index 000000000..afbd69d17 --- /dev/null +++ b/product_brand_ecommerce/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies() +# Author: Midilaj () +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from . import controllers diff --git a/product_brand_ecommerce/__manifest__.py b/product_brand_ecommerce/__manifest__.py new file mode 100644 index 000000000..a602fa408 --- /dev/null +++ b/product_brand_ecommerce/__manifest__.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2021-TODAY Cybrosys Technologies() +# Author: Midilaj () +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# + +{ + 'name': 'Product Brand in eCommerce', + 'version': '16.0.1.0.0', + 'category': 'eCommerce', + 'summary': 'Product Brand in eCommerce', + 'description': 'Product Brand in eCommerce', + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'images': ['static/description/banner.png'], + 'website': 'https://www.cybrosys.com', + 'depends': ['product_brand_sale', 'website_sale'], + 'data': [ + 'views/template.xml', + 'views/sale_report_views.xml' + ], + 'license': 'AGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, + +} diff --git a/product_brand_ecommerce/controllers/__init__.py b/product_brand_ecommerce/controllers/__init__.py new file mode 100644 index 000000000..5871b7cca --- /dev/null +++ b/product_brand_ecommerce/controllers/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies() +# Author: Midilaj () +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from . import main diff --git a/product_brand_ecommerce/controllers/main.py b/product_brand_ecommerce/controllers/main.py new file mode 100644 index 000000000..78c4adfe3 --- /dev/null +++ b/product_brand_ecommerce/controllers/main.py @@ -0,0 +1,389 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies() +# Author: Midilaj () +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# + +import json +import logging +from collections import defaultdict +from datetime import datetime +from werkzeug.exceptions import Forbidden, NotFound +from itertools import product as cartesian_product + +from odoo import fields, http, tools, _ +from odoo.http import request +from odoo.addons.http_routing.models.ir_http import slug +from odoo.addons.website.controllers.main import QueryURL +from odoo.addons.website_sale.controllers.main import WebsiteSale +from odoo.tools import lazy + +_logger = logging.getLogger(__name__) + + +class TableCompute(object): + + def __init__(self): + self.table = {} + + def _check_place(self, posx, posy, sizex, sizey, ppr): + res = True + for y in range(sizey): + for x in range(sizex): + if posx + x >= ppr: + res = False + break + row = self.table.setdefault(posy + y, {}) + if row.setdefault(posx + x) is not None: + res = False + break + for x in range(ppr): + self.table[posy + y].setdefault(x, None) + return res + + def process(self, products, ppg=20, ppr=4): + # Compute products positions on the grid + minpos = 0 + index = 0 + maxy = 0 + x = 0 + for p in products: + x = min(max(p.website_size_x, 1), ppr) + y = min(max(p.website_size_y, 1), ppr) + if index >= ppg: + x = y = 1 + + pos = minpos + while not self._check_place(pos % ppr, pos // ppr, x, y, ppr): + pos += 1 + # if 21st products (index 20) and the last line is full (ppr products in it), break + # (pos + 1.0) / ppr is the line where the product would be inserted + # maxy is the number of existing lines + # + 1.0 is because pos begins at 0, thus pos 20 is actually the 21st block + # and to force python to not round the division operation + if index >= ppg and ((pos + 1.0) // ppr) > maxy: + break + + if x == 1 and y == 1: # simple heuristic for CPU optimization + minpos = pos // ppr + + for y2 in range(y): + for x2 in range(x): + self.table[(pos // ppr) + y2][(pos % ppr) + x2] = False + self.table[pos // ppr][pos % ppr] = { + 'product': p, 'x': x, 'y': y, + 'ribbon': p.website_ribbon_id, + } + if index <= ppg: + maxy = max(maxy, y + (pos // ppr)) + index += 1 + + # Format table according to HTML needs + rows = sorted(self.table.items()) + rows = [r[1] for r in rows] + for col in range(len(rows)): + cols = sorted(rows[col].items()) + x += len(cols) + rows[col] = [r[1] for r in cols if r[1]] + + return rows + + +class WebsiteSales(WebsiteSale): + @http.route([ + '''/shop''', + '''/shop/page/''', + '''/shop/category/''', + '''/shop/category//page/''', + '''/shop/brand/''', + ], 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, ): + add_qty = int(post.get('add_qty', 1)) + try: + min_price = float(min_price) + except ValueError: + min_price = 0 + try: + max_price = float(max_price) + except ValueError: + max_price = 0 + compute_brand = brand + Category = request.env['product.public.category'] + 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 + + Brand = request.env['product.brand'] + if not brand: + brand = Brand + + 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) + + keep = QueryURL('/shop', category=category and int(category), search=search, attrib=attrib_list, + order=post.get('order')) + now = datetime.timestamp(datetime.now()) + pricelist = request.website.get_current_pricelist() + if not pricelist or request.session.get('website_sale_pricelist_time', + 0) < now - 60 * 60: # test: 1 hour in session + pricelist = request.website.get_current_pricelist() + request.session['website_sale_pricelist_time'] = now + request.session['website_sale_current_pl'] = pricelist.id + + request.update_context(pricelist=pricelist.id, partner=request.env.user.partner_id) + + filter_by_price_enabled = request.website.is_view_active('website_sale.filter_products_price') + if filter_by_price_enabled: + company_currency = request.website.company_id.currency_id + conversion_rate = request.env['res.currency']._get_conversion_rate( + company_currency, pricelist.currency_id, request.website.company_id, fields.Date.today()) + else: + conversion_rate = 1 + + url = "/shop" + if search: + post["search"] = search + if attrib_list: + post['attrib'] = attrib_list + options = self._get_search_options( + category=category, + attrib_values=attrib_values, + pricelist=pricelist, + min_price=min_price, + max_price=max_price, + conversion_rate=conversion_rate, + **post + ) + product_count, details, fuzzy_search_term = request.website._search_with_fuzzy("products_only", search, + limit=None, + order=self._get_search_order( + post), + options=options) + search_product = details[0].get('results', request.env['product.template']).with_context(bin_size=True) + if attrib_set: + # Attributes value per attribute + attribute_values = request.env['product.attribute.value'].browse(attrib_set) + values_per_attribute = defaultdict(lambda: request.env['product.attribute.value']) + # In case we have only one value per attribute we can check for a combination using those attributes directly + + multi_value_attribute = False + for value in attribute_values: + values_per_attribute[value.attribute_id] |= value + if len(values_per_attribute[value.attribute_id]) > 1: + multi_value_attribute = True + + def filter_template(template, attribute_values_list): + # Transform product.attribute.value to product.template.attribute.value + attribute_value_to_ptav = dict() + for ptav in template.attribute_line_ids.product_template_value_ids: + attribute_value_to_ptav[ptav.product_attribute_value_id] = ptav.id + possible_combinations = False + for attribute_values in attribute_values_list: + ptavs = request.env['product.template.attribute.value'].browse( + [attribute_value_to_ptav[val] for val in attribute_values if val in attribute_value_to_ptav] + ) + if len(ptavs) < len(attribute_values): + # In this case the template is not compatible with this specific combination + continue + if len(ptavs) == len(template.attribute_line_ids): + if template._is_combination_possible(ptavs): + return True + elif len(ptavs) < len(template.attribute_line_ids): + if len(attribute_values_list) == 1: + if any(template._get_possible_combinations(necessary_values=ptavs)): + return True + if not possible_combinations: + possible_combinations = template._get_possible_combinations() + if any(len(ptavs & combination) == len(ptavs) for combination in possible_combinations): + return True + return False + + if not multi_value_attribute: + possible_attrib_values_list = [attribute_values] + else: + # Cartesian product from dict keys and values + possible_attrib_values_list = [request.env['product.attribute.value'].browse([v.id for v in values]) + for + values in cartesian_product(*values_per_attribute.values())] + + search_product = search_product.filtered( + lambda tmpl: filter_template(tmpl, possible_attrib_values_list)) + + filter_by_price_enabled = request.website.is_view_active('website_sale.filter_products_price') + if filter_by_price_enabled: + # TODO Find an alternative way to obtain the domain through the search metadata. + Product = request.env['product.template'].with_context(bin_size=True) + domain = self._get_search_domain(search, category, attrib_values) + + # This is ~4 times more efficient than a search for the cheapest and most expensive products + from_clause, where_clause, where_params = Product._where_calc(domain).get_sql() + query = f""" + SELECT COALESCE(MIN(list_price), 0) * {conversion_rate}, COALESCE(MAX(list_price), 0) * {conversion_rate} + FROM {from_clause} + WHERE {where_clause} + """ + request.env.cr.execute(query, where_params) + available_min_price, available_max_price = request.env.cr.fetchone() + + if min_price or max_price: + if min_price: + min_price = min_price if min_price <= available_max_price else available_min_price + post['min_price'] = min_price + if max_price: + max_price = max_price if max_price >= available_min_price else available_max_price + post['max_price'] = max_price + + + website_domain = request.website.website_domain() + categs_domain = [('parent_id', '=', False)] + 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 = Category + categs = Category.search(categs_domain) + + 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)) + + 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' + products_prices = products._get_sales_prices(pricelist) + + Brand = request.env['product.brand'].search([]) + if compute_brand: + products_brand = request.env['product.template'].search( + ['&', ('brand_id', '=', brand.id), ('sale_ok', '=', True)]) + product_brand_count = len(products_brand) + pager_brand = request.website.pager(url=url, total=product_brand_count, page=page, step=ppg, scope=7, + url_args=post) + values = { + 'search': search, + 'original_search':fuzzy_search_term and search, + 'category': category, + 'brand': brand, + 'attrib_values': attrib_values, + 'attrib_set': attrib_set, + 'pager': pager_brand, + 'pricelist': pricelist, + # 'website_sale_pricelists': pricelist, + 'add_qty': add_qty, + 'products': products_brand, + 'search_count': product_brand_count, # common for all searchbox + 'bins': TableCompute().process(products_brand, ppg, ppr), + 'ppg': ppg, + 'ppr': ppr, + 'categories': categs, + 'attributes': attributes, + 'keep': keep, + 'search_categories_ids': search_categories.ids, + 'layout_mode': layout_mode, + 'brands': Brand, + 'products_prices': products_prices, + 'get_product_prices': lambda product: lazy(lambda: products_prices[product.id]), + 'float_round': tools.float_round, + + } + website = request.env['website'].get_current_website() + filter_by_price_enabled = website.is_view_active('website_sale.filter_products_price') + if filter_by_price_enabled: + values['min_price'] = min_price or available_min_price + values['max_price'] = max_price or available_max_price + values['available_min_price'] = tools.float_round(available_min_price, 2) + values['available_max_price'] = tools.float_round(available_max_price, 2) + if category: + values['main_object'] = category + values.update(self._get_additional_shop_values(values)) + print(values,'if values') + return request.render("website_sale.products", values) + else: + values = { + 'brand': brand, + 'search': search, + 'category': category, + 'original_search': fuzzy_search_term and search, + 'order': post.get('order', ''), + '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': categs, + 'attributes': attributes, + 'keep': keep, + 'search_categories_ids': search_categories.ids, + 'layout_mode': layout_mode, + 'brands': Brand, + 'products_prices': products_prices, + 'get_product_prices': lambda product: lazy(lambda: products_prices[product.id]), + 'float_round': tools.float_round, + + } + website = request.env['website'].get_current_website() + filter_by_price_enabled = website.is_view_active('website_sale.filter_products_price') + if filter_by_price_enabled: + values['min_price'] = min_price or available_min_price + values['max_price'] = max_price or available_max_price + values['available_min_price'] = tools.float_round(available_min_price, 2) + values['available_max_price'] = tools.float_round(available_max_price, 2) + if category: + values['main_object'] = category + values.update(self._get_additional_shop_values(values)) + print(values,'else values') + return request.render("website_sale.products", values) diff --git a/product_brand_ecommerce/doc/RELEASE_NOTES.md b/product_brand_ecommerce/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..a1e3c4ef0 --- /dev/null +++ b/product_brand_ecommerce/doc/RELEASE_NOTES.md @@ -0,0 +1,4 @@ +## Module + +#### 26.09.2022 +#### Version 16.0.1.0.0 \ No newline at end of file diff --git a/product_brand_ecommerce/static/description/assets/icons/check.png b/product_brand_ecommerce/static/description/assets/icons/check.png new file mode 100644 index 000000000..c8e85f51d Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/check.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/chevron.png b/product_brand_ecommerce/static/description/assets/icons/chevron.png new file mode 100644 index 000000000..2089293d6 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/chevron.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/cogs.png b/product_brand_ecommerce/static/description/assets/icons/cogs.png new file mode 100644 index 000000000..95d0bad62 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/cogs.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/consultation.png b/product_brand_ecommerce/static/description/assets/icons/consultation.png new file mode 100644 index 000000000..8319d4baa Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/consultation.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/ecom-black.png b/product_brand_ecommerce/static/description/assets/icons/ecom-black.png new file mode 100644 index 000000000..a9385ff13 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/ecom-black.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/education-black.png b/product_brand_ecommerce/static/description/assets/icons/education-black.png new file mode 100644 index 000000000..3eb09b27b Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/education-black.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/hotel-black.png b/product_brand_ecommerce/static/description/assets/icons/hotel-black.png new file mode 100644 index 000000000..130f613be Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/hotel-black.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/license.png b/product_brand_ecommerce/static/description/assets/icons/license.png new file mode 100644 index 000000000..a5869797e Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/license.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/lifebuoy.png b/product_brand_ecommerce/static/description/assets/icons/lifebuoy.png new file mode 100644 index 000000000..658d56ccc Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/lifebuoy.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/manufacturing-black.png b/product_brand_ecommerce/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 000000000..697eb0e9f Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/manufacturing-black.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/pos-black.png b/product_brand_ecommerce/static/description/assets/icons/pos-black.png new file mode 100644 index 000000000..97c0f90c1 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/pos-black.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/puzzle.png b/product_brand_ecommerce/static/description/assets/icons/puzzle.png new file mode 100644 index 000000000..65cf854e7 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/puzzle.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/restaurant-black.png b/product_brand_ecommerce/static/description/assets/icons/restaurant-black.png new file mode 100644 index 000000000..4a35eb939 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/restaurant-black.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/service-black.png b/product_brand_ecommerce/static/description/assets/icons/service-black.png new file mode 100644 index 000000000..301ab51cb Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/service-black.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/trading-black.png b/product_brand_ecommerce/static/description/assets/icons/trading-black.png new file mode 100644 index 000000000..9398ba2f1 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/trading-black.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/training.png b/product_brand_ecommerce/static/description/assets/icons/training.png new file mode 100644 index 000000000..884ca024d Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/training.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/update.png b/product_brand_ecommerce/static/description/assets/icons/update.png new file mode 100644 index 000000000..ecbc5a01a Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/update.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/user.png b/product_brand_ecommerce/static/description/assets/icons/user.png new file mode 100644 index 000000000..6ffb23d9f Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/user.png differ diff --git a/product_brand_ecommerce/static/description/assets/icons/wrench.png b/product_brand_ecommerce/static/description/assets/icons/wrench.png new file mode 100644 index 000000000..6c04dea0f Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/icons/wrench.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/categories.png b/product_brand_ecommerce/static/description/assets/misc/categories.png new file mode 100644 index 000000000..bedf1e0b1 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/categories.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/check-box.png b/product_brand_ecommerce/static/description/assets/misc/check-box.png new file mode 100644 index 000000000..42caf24b9 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/check-box.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/compass.png b/product_brand_ecommerce/static/description/assets/misc/compass.png new file mode 100644 index 000000000..d5fed8faa Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/compass.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/corporate.png b/product_brand_ecommerce/static/description/assets/misc/corporate.png new file mode 100644 index 000000000..2eb13edbf Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/corporate.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/customer-support.png b/product_brand_ecommerce/static/description/assets/misc/customer-support.png new file mode 100644 index 000000000..79efc72ed Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/customer-support.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/cybrosys-logo.png b/product_brand_ecommerce/static/description/assets/misc/cybrosys-logo.png new file mode 100644 index 000000000..cc3cc0ccf Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/cybrosys-logo.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/features.png b/product_brand_ecommerce/static/description/assets/misc/features.png new file mode 100644 index 000000000..b41769f77 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/features.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/logo.png b/product_brand_ecommerce/static/description/assets/misc/logo.png new file mode 100644 index 000000000..478462d3e Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/logo.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/pictures.png b/product_brand_ecommerce/static/description/assets/misc/pictures.png new file mode 100644 index 000000000..56d255fe9 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/pictures.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/pie-chart.png b/product_brand_ecommerce/static/description/assets/misc/pie-chart.png new file mode 100644 index 000000000..426e05244 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/pie-chart.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/right-arrow.png b/product_brand_ecommerce/static/description/assets/misc/right-arrow.png new file mode 100644 index 000000000..730984a06 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/right-arrow.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/star.png b/product_brand_ecommerce/static/description/assets/misc/star.png new file mode 100644 index 000000000..2eb9ab29f Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/star.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/support.png b/product_brand_ecommerce/static/description/assets/misc/support.png new file mode 100644 index 000000000..4f18b8b82 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/support.png differ diff --git a/product_brand_ecommerce/static/description/assets/misc/whatsapp.png b/product_brand_ecommerce/static/description/assets/misc/whatsapp.png new file mode 100644 index 000000000..d513a5356 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/misc/whatsapp.png differ diff --git a/product_brand_ecommerce/static/description/assets/modules/1.png b/product_brand_ecommerce/static/description/assets/modules/1.png new file mode 100644 index 000000000..5238bdeab Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/modules/1.png differ diff --git a/product_brand_ecommerce/static/description/assets/modules/2.png b/product_brand_ecommerce/static/description/assets/modules/2.png new file mode 100644 index 000000000..1ae7cfe3b Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/modules/2.png differ diff --git a/product_brand_ecommerce/static/description/assets/modules/3.png b/product_brand_ecommerce/static/description/assets/modules/3.png new file mode 100644 index 000000000..3c3ff1afb Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/modules/3.png differ diff --git a/product_brand_ecommerce/static/description/assets/modules/4.png b/product_brand_ecommerce/static/description/assets/modules/4.png new file mode 100644 index 000000000..3fae4631e Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/modules/4.png differ diff --git a/product_brand_ecommerce/static/description/assets/modules/5.gif b/product_brand_ecommerce/static/description/assets/modules/5.gif new file mode 100644 index 000000000..2a5f8e659 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/modules/5.gif differ diff --git a/product_brand_ecommerce/static/description/assets/modules/6.png b/product_brand_ecommerce/static/description/assets/modules/6.png new file mode 100644 index 000000000..7f2815273 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/modules/6.png differ diff --git a/product_brand_ecommerce/static/description/assets/screenshots/1.png b/product_brand_ecommerce/static/description/assets/screenshots/1.png new file mode 100644 index 000000000..b7457167e Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/screenshots/1.png differ diff --git a/product_brand_ecommerce/static/description/assets/screenshots/2.png b/product_brand_ecommerce/static/description/assets/screenshots/2.png new file mode 100644 index 000000000..1e9d5b214 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/screenshots/2.png differ diff --git a/product_brand_ecommerce/static/description/assets/screenshots/3.png b/product_brand_ecommerce/static/description/assets/screenshots/3.png new file mode 100644 index 000000000..fcf5a31d3 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/screenshots/3.png differ diff --git a/product_brand_ecommerce/static/description/assets/screenshots/4.png b/product_brand_ecommerce/static/description/assets/screenshots/4.png new file mode 100644 index 000000000..ce8af3075 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/screenshots/4.png differ diff --git a/product_brand_ecommerce/static/description/assets/screenshots/hero.gif b/product_brand_ecommerce/static/description/assets/screenshots/hero.gif new file mode 100644 index 000000000..fcf6ec2e4 Binary files /dev/null and b/product_brand_ecommerce/static/description/assets/screenshots/hero.gif differ diff --git a/product_brand_ecommerce/static/description/banner.png b/product_brand_ecommerce/static/description/banner.png new file mode 100644 index 000000000..1d2238b80 Binary files /dev/null and b/product_brand_ecommerce/static/description/banner.png differ diff --git a/product_brand_ecommerce/static/description/icon.png b/product_brand_ecommerce/static/description/icon.png new file mode 100644 index 000000000..f86fc394d Binary files /dev/null and b/product_brand_ecommerce/static/description/icon.png differ diff --git a/product_brand_ecommerce/static/description/index.html b/product_brand_ecommerce/static/description/index.html new file mode 100644 index 000000000..cf9ed7771 --- /dev/null +++ b/product_brand_ecommerce/static/description/index.html @@ -0,0 +1,555 @@ +
+ +
+ +
+
+ Community +
+
+ Enterprise +
+
+ Odoo.sh +
+
+
+ + + +

Product Brand in eCommerce

+

Easily Manage Product Brands

+ + + +
+ + +
+
+ +
+

Explore This + Module

+
+ + + + +
+
+ +
+

Overview +

+
+
+
+ This module allows the odoo users to manage their product brands easily.

+ +
+
+ + + +
+
+ +
+

Features +

+
+
+
+
+ + Community & Enterprise Support +
+
+ + Available 23 language transliteration. +
+

+ Available in Odoo 15.0 Community and Enterprise.

+
+
+
+ + Activate Product Brand Filter. +
+
+ + Product Brand Filter in eCommerce. +
+
+ + Product Brand in Pivot View. +
+
+
+ + + +
+
+ +
+

Screenshots +

+
+
+
+ + + +
+

Product Brand Filter in eCommerce

+

Product Brand Filter will be shows in the eCommerce website.

+ +
+
+

Products in the selected brand

+

view products available in the each brand.

+ +
+ +
+

Product Brand in Pivot View

+

Brand filter available in pivot view.

+ +
+
+

Filtered by Product Brand

+

User can Filtered by product brand in pivot view.

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

Related + Products +

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

Our Services +

+
+ +
+
+
+
+ +
+
+ Odoo + Customization
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Support
+
+ + +
+
+ +
+
+ Hire + Odoo + Developer
+
+ +
+
+ +
+
+ Odoo + Integration
+
+ +
+
+ +
+
+ Odoo + Migration
+
+ + +
+
+ +
+
+ Odoo + Consultancy
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Licensing Consultancy
+
+
+ +
+ + + + + +
+
+ +
+

Our + Industries +

+
+ +
+
+
+
+ +
+ Trading +
+

+ Easily procure + and + sell your products

+
+
+ +
+
+ +
+ POS +
+

+ Easy + configuration + and convivial experience

+
+
+ +
+
+ +
+ Education +
+

+ A platform for + educational management

+
+
+ +
+
+ +
+ Manufacturing +
+

+ Plan, track and + schedule your operations

+
+
+ +
+
+ +
+ E-commerce & Website +
+

+ Mobile + friendly, + awe-inspiring product pages

+
+
+ +
+
+ +
+ Service Management +
+

+ Keep track of + services and invoice

+
+
+ +
+
+ +
+ Restaurant +
+

+ Run your bar or + restaurant methodically

+
+
+ +
+
+ +
+ Hotel Management +
+

+ An + all-inclusive + hotel management application

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

Support +

+
+
+
+
+
+
+ +
+
+

Need Help?

+

Got questions or need help? Get in touch.

+ +

+ odoo@cybrosys.com

+
+
+
+
+
+
+
+ +
+
+

WhatsApp

+

Say hi to us on WhatsApp!

+ +

+91 86068 + 27707

+
+
+
+
+
+
+
+ +
+
+
+ \ No newline at end of file diff --git a/product_brand_ecommerce/views/sale_report_views.xml b/product_brand_ecommerce/views/sale_report_views.xml new file mode 100644 index 000000000..522d1fd82 --- /dev/null +++ b/product_brand_ecommerce/views/sale_report_views.xml @@ -0,0 +1,16 @@ + + + + + + sale.report.search.inherit + sale.report + + + + + + + + + \ No newline at end of file diff --git a/product_brand_ecommerce/views/template.xml b/product_brand_ecommerce/views/template.xml new file mode 100644 index 000000000..848979679 --- /dev/null +++ b/product_brand_ecommerce/views/template.xml @@ -0,0 +1,29 @@ + + + + + + + +