[ADD] theme_prime, droggol_theme_common: v14

This commit is contained in:
Abdurrahman Saber 2025-04-29 09:22:39 +03:00
parent 6607a679d1
commit ba94f7f8b8
884 changed files with 26908 additions and 34212 deletions

View File

@ -1,7 +1,7 @@
Most of the files are
Copyright (c) 2019 - present Droggol Infotech Private Limited.
Copyright (c) 2019 - present Droggol.
Some javascript files might be from from third
parties libraries. In that case the original

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from . import controllers
from . import models
from . import deprecated

View File

@ -1,66 +1,51 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
{
'name': 'Droggol Theme Common',
'description': 'Droggol Theme Common',
'category': 'eCommerce',
'version': '16.0.0.0.8',
'version': '14.0.0.3.8',
'depends': [
'sale_product_configurator',
'website_sale_comparison',
'website_sale_wishlist',
'website_sale_stock',
'website_sale_stock_wishlist',
],
'license': 'OPL-1',
'author': 'Droggol Infotech Private Limited',
'company': 'Droggol Infotech Private Limited',
'maintainer': 'Droggol Infotech Private Limited',
'author': 'Droggol',
'company': 'Droggol',
'maintainer': 'Droggol',
'website': 'https://www.droggol.com/',
'price': 10.00,
'price': 15.00,
'currency': 'USD',
'live_test_url': '',
'data': [
'security/ir.model.access.csv',
'deprecated/ir.model.access.csv',
'views/templates.xml',
'data/groups.xml',
'views/assets.xml',
'views/backend_templates.xml',
'views/dr_config_template.xml',
# Backend
'views/backend/menu_label.xml',
'views/backend/website_menu.xml',
'views/backend/product_brand.xml',
'views/backend/product_label.xml',
'views/backend/product_tags.xml',
'views/backend/product_template.xml',
'views/backend/product_attribute.xml',
'views/backend/product_brand.xml',
'views/backend/dr_website_content.xml',
'views/backend/product_pricelist.xml',
'views/backend/pwa_shortcuts.xml',
'views/backend/res_config_settings.xml',
'views/backend/dr_theme_config.xml',
'views/backend/dr_config.xml',
'views/backend/category_label.xml',
'views/backend/product_category.xml',
'views/backend/website.xml',
# Snippets
'views/snippets/s_mega_menu.xml',
],
'assets': {
'web.assets_frontend': [
'droggol_theme_common/static/src/scss/variants.scss',
],
'web.assets_backend': [
'droggol_theme_common/static/src/scss/variants.scss',
'droggol_theme_common/static/src/js/components/*.xml',
'droggol_theme_common/static/src/js/hooks.js',
],
'website.assets_editor': [
'droggol_theme_common/static/src/js/components/*.js',
'droggol_theme_common/static/src/js/components/*.scss',
'droggol_theme_common/static/src/js/navbar/*.js',
]
},
'qweb': [
'static/src/xml/backend/list_view_brand.xml',
],
}

View File

@ -1,4 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
from . import main

View File

@ -1,12 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
from odoo import http
from odoo.http import request
class DroggolThemeCommon(http.Controller):
@http.route(['/droggol_theme_common/design_content/<model("dr.website.content"):content>'], type='http', website=True, auth='user')
def design_content(self, content, **post):
return request.render('droggol_theme_common.design_content', {'content': content, 'no_header': True, 'no_footer': True})

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="base.group_user" model="res.groups">
<field name="implied_ids" eval="[(4, ref('product.group_product_variant'))]"/>
</record>
</odoo>

View File

@ -1,8 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# [Files will be removed in a future version]
# Contains deprecated fields and models
from . import deprecated_v16
from . import deprecated_v15

View File

@ -1,66 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
from odoo import fields, models
from odoo.tools.translate import html_translate
class DrProductBrand(models.Model):
_name = 'dr.product.brand'
_inherit = ['website.multi.mixin']
_description = 'Product Brand'
_order = 'sequence,id'
name = fields.Char(required=True, translate=True)
description = fields.Char(translate=True)
image = fields.Binary()
sequence = fields.Integer(string='Sequence')
active = fields.Boolean(default=True)
class DrProductOffer(models.Model):
_name = 'dr.product.offer'
_description = 'Product Offers'
_order = 'sequence,id'
name = fields.Char(string='Title', required=True, translate=True)
description = fields.Char(string='Description', required=True, translate=True)
icon = fields.Char(default='list')
sequence = fields.Integer(string='Sequence')
dialog_content = fields.Html(sanitize_attributes=False, translate=html_translate, sanitize_form=False)
product_id = fields.Many2one('product.template')
tag_id = fields.Many2one('dr.product.tags')
class DrProductTabs(models.Model):
_name = 'dr.product.tabs'
_description = 'Product Tabs'
_order = 'sequence,id'
name = fields.Char(string='Title', required=True, translate=True)
icon = fields.Char(default='list')
content = fields.Html(sanitize_attributes=False, translate=html_translate, sanitize_form=False)
sequence = fields.Integer(string='Sequence')
product_id = fields.Many2one('product.template')
tag_id = fields.Many2one('dr.product.tags')
class DrProductTagsExt(models.Model):
_inherit = 'dr.product.tags'
dr_tab_ids = fields.One2many('dr.product.tabs', 'tag_id', string='Tabs', help='Display in product detail page on website.')
dr_offer_ids = fields.One2many('dr.product.offer', 'tag_id', string='Offers', help='Display in product detail page on website.')
class ProductTemplate(models.Model):
_inherit = 'product.template'
dr_brand_id = fields.Many2one('dr.product.brand')
dr_offer_ids = fields.One2many('dr.product.offer', 'product_id', help='Display in product detail page on website.')
dr_tab_ids = fields.One2many('dr.product.tabs', 'product_id', help='Display in product detail page on website.')
class WebsiteMenu(models.Model):
_inherit = 'website.menu'
dr_is_special_menu = fields.Boolean()

View File

@ -1,21 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
from odoo import fields, models
class DrProductTags(models.Model):
_name = 'dr.product.tags'
_inherit = ['website.multi.mixin']
_description = 'Product Tags'
name = fields.Char(required=True, translate=True)
product_ids = fields.Many2many('product.template', 'dr_product_tags_rel', 'tag_id', 'product_id', string='Products')
product_count = fields.Integer(compute='_compute_product_count')
active = fields.Boolean(default=True)
class ProductTemplate(models.Model):
_inherit = 'product.template'
dr_tag_ids = fields.Many2many('dr.product.tags', 'dr_product_tags_rel', 'product_id', 'tag_id', string='Tags')

View File

@ -1,8 +0,0 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_dr_product_brand_manager,dr.product.brand.manager,model_dr_product_brand,sales_team.group_sale_manager,1,1,1,1
access_dr_product_tabs_manager,dr.product.tabs.manager,model_dr_product_tabs,sales_team.group_sale_manager,1,1,1,1
access_dr_product_tabs_public,dr.product.tabs.public,model_dr_product_tabs,,1,0,0,0
access_dr_product_offer_manager,dr.product.offer.manager,model_dr_product_offer,sales_team.group_sale_manager,1,1,1,1
access_dr_product_offer_public,dr.product.offer.public,model_dr_product_offer,,1,0,0,0
access_dr_product_tags_manager,dr.product.tags.manager,model_dr_product_tags,sales_team.group_sale_manager,1,1,1,1
access_dr_product_tags_public,dr.product.tags.public,model_dr_product_tags,,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_dr_product_brand_manager dr.product.brand.manager model_dr_product_brand sales_team.group_sale_manager 1 1 1 1
3 access_dr_product_tabs_manager dr.product.tabs.manager model_dr_product_tabs sales_team.group_sale_manager 1 1 1 1
4 access_dr_product_tabs_public dr.product.tabs.public model_dr_product_tabs 1 0 0 0
5 access_dr_product_offer_manager dr.product.offer.manager model_dr_product_offer sales_team.group_sale_manager 1 1 1 1
6 access_dr_product_offer_public dr.product.offer.public model_dr_product_offer 1 0 0 0
7 access_dr_product_tags_manager dr.product.tags.manager model_dr_product_tags sales_team.group_sale_manager 1 1 1 1
8 access_dr_product_tags_public dr.product.tags.public model_dr_product_tags 1 0 0 0

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,16 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from . import dr_cache_mixin
from . import dr_category_label
from . import dr_product_label
from . import dr_pwa_shortcuts
from . import dr_theme_config
from . import dr_website_content
from . import dr_product_brand
from . import dr_product_tags
from . import dr_product_tabs
from . import product_template
from . import dr_website_menu_label
from . import product_attribute
from . import product_pricelist_item
from . import product_public_category
from . import product_template
from . import res_config_settings
from . import sale_order
from . import website
from . import website_menu
from . import product_pricelist_item
from . import dr_pwa_shortcuts
from . import res_config_settings
from . import dr_config
from . import dr_category_lable

View File

@ -1,24 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
from odoo import api, models
class DrCacheMixin(models.AbstractModel):
_name = 'dr.cache.mixin'
_description = 'Cache Mixin'
_fields_to_watch = []
@api.model_create_multi
def create(self, vals_list):
self.clear_caches()
return super().create(vals_list)
def write(self, vals):
self.clear_caches()
return super().write(vals)
def unlink(self):
self.clear_caches()
return super().unlink()

View File

@ -1,13 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
from odoo import fields, models
class DrProductPublicCategoryLabel(models.Model):
_name = 'dr.product.public.category.label'
_description = 'Category Label'
name = fields.Char(required=True, translate=True)
background_color = fields.Char('Background Color', default='#000000')
text_color = fields.Char('Text Color', default='#FFFFFF')

View File

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from odoo import fields, models
class DrWebsiteCategoryLabel(models.Model):
_name = 'dr.product.public.category.label'
_description = 'Category Label'
name = fields.Char(required=True, translate=True)
color = fields.Selection([('green', 'Green'), ('blue', 'Blue'), ('red', 'Red'), ('orange', 'Orange'), ('gray', 'Gray'), ('black', 'Black')])
category_ids = fields.One2many('product.public.category', 'dr_category_label_id')
category_count = fields.Integer(compute='_compute_category_count')
def _compute_category_count(self):
for label in self:
label.category_count = len(label.category_ids)
def action_open_category(self):
self.ensure_one()
action = self.env.ref('website_sale.product_public_category_action').read()[0]
action['domain'] = [('dr_category_label_id', '=', self.id)]
action['context'] = {}
return action
class DrProductPublicCategory(models.Model):
_inherit = 'product.public.category'
dr_category_label_id = fields.Many2one('dr.product.public.category.label', string='Label')
dr_category_cover_image = fields.Binary(string='Cover Image')

View File

@ -1,23 +1,38 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
import json
import logging
import json
from odoo import _, api, fields, models, tools
from odoo.http import request
_logger = logging.getLogger(__name__)
class DrThemeConfig(models.Model):
_name = 'dr.theme.config'
_inherit = 'dr.cache.mixin'
_description = 'Droggol Theme Config'
_rec_name = 'key'
_rec_name = "key"
key = fields.Char(required=True)
value = fields.Char()
website_id = fields.Many2one('website')
@api.model_create_multi
def create(self, vals_list):
self.clear_caches()
return super(DrThemeConfig, self).create(vals_list)
def write(self, vals):
self.clear_caches()
res = super(DrThemeConfig, self).write(vals)
return res
@api.model
@tools.ormcache('website_id')
def _get_all_config(self, website_id):
@ -29,7 +44,7 @@ class DrThemeConfig(models.Model):
result_configs[config.key] = config.value == 'True'
elif config.key.startswith('json_'):
config_value = json.loads(config.value)
if isinstance(config_value, dict) and result_configs.get(config.key):
if isinstance(config_value, dict):
result_configs[config.key].update(config_value)
else:
result_configs[config.key] = config_value
@ -47,29 +62,64 @@ class DrThemeConfig(models.Model):
def _get_default_theme_config(self, website_id):
website = self.env['website'].sudo().browse(website_id)
# TODO: Clear cache on website write (when theme is installed)
return {
'json_sidebar_config': {'category_sidebar_style': '2', 'category_sidebar_show_count': True, 'menu_sidebar_show_category': True},
'json_shop_layout': {'layout': 'prime', 'show_view_switcher': True, 'default_view_mode': 'grid', 'load_more_products': 'button'},
'json_shop_product_item': {'style': '1', 'image_size': 'default', 'image_fill': 'cover', 'show_add_to_cart': True, 'show_wishlist': True, 'show_compare': True, 'show_quick_view': True, 'show_similar_products': True, 'show_product_preview_swatches': True, 'show_rating': True, 'show_stock_label': False},
'json_shop_category_pills': {'active': True, 'style': '1', 'show_child_categories': True, 'hide_in_desktop': False},
'json_shop_filters': {'lazy_method': True, 'filter_style': '1', 'filter_position': 'left', 'show_in_sidebar': False, 'collapsible_category': True, 'collapsible_attribute': True, 'show_category_count': True, 'show_attribute_count': False, 'hide_extra_attrib_value': False, 'show_rating_filter': True, 'show_availability_filter': False},
'json_zoom': {'zoom_enabled': True, 'zoom_factor': 2},
'bool_enable_ajax_load_on_click': False,
'bool_enable_ajax_load': False,
'json_bottom_bar': {'show_bottom_bar': True, 'show_bottom_bar_on_scroll': False, 'filters': True, 'actions': ['tp_home', 'tp_search', 'tp_wishlist', 'tp_offer', 'tp_brands', 'tp_category', 'tp_orders']},
'bool_show_bottom_bar_onscroll': False,
'bool_display_bottom_bar': True,
'bool_mobile_filters': True,
'json_zoom': {
'zoom_enabled': True,
'zoom_factor': 2,
'disable_small': False
},
'json_category_pills': {
'enable': True,
'enable_child': True,
'hide_desktop': True,
'show_title': True,
'style': 1,
},
'json_grid_product': {
'show_color_preview': True,
'show_quick_view': True,
'show_similar_products': True,
'show_rating': True,
},
'json_shop_filters': {
'in_sidebar': False,
'collapsible': True,
'show_category_count': True,
'show_attrib_count': False,
'hide_attrib_value': False,
'show_price_range_filter': True,
'price_range_display_type': 'sales_price',
'show_rating_filter': True,
'show_brand_search': True,
'show_labels_search': True,
'show_tags_search': True,
'brands_style': 1,
'tags_style': 1,
},
'bool_sticky_add_to_cart': True,
'json_general_language_pricelist_selector': {'hide_country_flag': False},
'json_b2b_shop_config': {'dr_enable_b2b': False, 'dr_only_assigned_pricelist': False},
'json_mobile': {},
'json_product_search': {'advance_search': True, 'search_category': True, 'search_attribute': True, 'search_suggestion': True, 'search_limit': 10, 'search_max_product': 3, 'search_fuzzy': True},
'json_brands_page': {'disable_brands_grouping': False},
'bool_general_show_category_search': True,
'json_general_language_pricelist_selector': {
'hide_country_flag': False,
},
'json_brands_page': {
'disable_brands_grouping': False,
},
'cart_flow': 'default',
'json_bottom_bar_config': ['tp_home', 'tp_search', 'tp_wishlist', 'tp_offer', 'tp_brands', 'tp_category', 'tp_orders'],
'theme_installed': website.theme_id and website.theme_id.name.startswith('theme_prime') or False,
'pwa_active': website.dr_pwa_activated,
'bool_product_offers': True,
'bool_show_products_nav': True,
}
def save_config(self, website_id, configs):
def _save_config(self, website_id, configs):
all_config = self.search([('website_id', '=', website_id)])
for key, value in configs.items():
key, value = self._prepare_value_for_write(key, value)
@ -86,3 +136,14 @@ class DrThemeConfig(models.Model):
elif key.startswith('int_'):
value = value
return key.strip(), value
class Http(models.AbstractModel):
_inherit = 'ir.http'
@api.model
def get_dr_theme_config(self):
result = {}
if request.website:
result = request.website._get_dr_theme_config()
return result

View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from odoo import api, fields, models
class DrProductBrand(models.Model):
_name = 'dr.product.brand'
_inherit = ['website.multi.mixin']
_description = 'Product Brand'
_order = 'sequence,id'
name = fields.Char(required=True, translate=True)
description = fields.Char(translate=True)
image = fields.Binary()
product_ids = fields.One2many('product.template', 'dr_brand_id')
product_count = fields.Integer(compute='_compute_product_count')
sequence = fields.Integer(string='Sequence')
active = fields.Boolean(default=True)
def _compute_product_count(self):
for brand in self:
brand.product_count = len(brand.product_ids)
def action_open_products(self):
self.ensure_one()
action = self.env.ref('website_sale.product_template_action_website').read()[0]
action['domain'] = [('dr_brand_id', '=', self.id)]
return action
@api.model
def reorder_sequence(self):
sequence = 1
for brand in self.search([], order='name'):
brand.sequence = sequence
sequence += 1

View File

@ -1,38 +1,37 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from PIL import ImageColor
from odoo import api, fields, models
class DrProductLabel(models.Model):
_name = 'dr.product.label'
_description = 'Product Label'
_inherit = 'dr.cache.mixin'
name = fields.Char(required=True, translate=True)
background_color = fields.Char('Background Color', default='#000000')
background_color_rgb = fields.Char(compute='_compute_background_color_rgb', store=True, string='Background Color RGB')
text_color = fields.Char('Text Color', default='#FFFFFF')
style = fields.Selection([('1', 'Tag'), ('2', 'Badge'), ('3', 'Circle'), ('4', 'Square')], default='1', required=True)
color = fields.Selection([
('green', 'Green'),
('blue', 'Blue'),
('orange', 'Orange'),
('red', 'Red'),
('gray', 'Gray'),
('black', 'Black'),
])
style = fields.Selection([
('1', 'Tag'),
('2', 'Badge'),
('3', 'Circle'),
], default='1', required=True)
product_ids = fields.One2many('product.template', 'dr_label_id')
product_count = fields.Integer(compute='_compute_product_count')
active = fields.Boolean(default=True)
def _compute_product_count(self):
label_data = self.env['product.template'].read_group([('dr_label_id', 'in', self.ids)], ['dr_label_id'], ['dr_label_id'])
mapped_data = dict([(x['dr_label_id'][0], x['dr_label_id_count']) for x in label_data])
for label in self:
label.product_count = mapped_data.get(label.id, 0)
@api.depends('background_color')
def _compute_background_color_rgb(self):
for label in self:
colors = ImageColor.getcolor(label.background_color, 'RGB')
label.background_color_rgb = '%s, %s, %s' % (colors[0], colors[1], colors[2])
label.product_count = len(label.product_ids)
def action_open_products(self):
self.ensure_one()
action = self.env.ref('website_sale.product_template_action_website').read()[0]
action['domain'] = [('dr_label_id', '=', self.id)]
action['context'] = {}
return action

View File

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from odoo import api, fields, models
class DrProductTabs(models.Model):
_name = 'dr.product.tabs'
_description = 'Product Tabs'
_order = 'sequence,id'
name = fields.Char(string='Title', required=True, translate=True)
icon = fields.Char(default='list')
content = fields.Html(sanitize_attributes=False, translate=True, sanitize_form=False)
sequence = fields.Integer(string='Sequence')
product_id = fields.Many2one('product.template')
tag_id = fields.Many2one('dr.product.tags')
class DrProductOffer(models.Model):
_name = 'dr.product.offer'
_description = 'Product Offers'
_order = 'sequence,id'
name = fields.Char(string='Title', required=True, translate=True)
description = fields.Char(string='Description', required=True, translate=True)
icon = fields.Char(default='list')
sequence = fields.Integer(string='Sequence')
dialog_content = fields.Html(sanitize_attributes=False, translate=True, sanitize_form=False)
product_id = fields.Many2one('product.template')
tag_id = fields.Many2one('dr.product.tags')

View File

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from odoo import api, fields, models
class DrProductTags(models.Model):
_name = 'dr.product.tags'
_inherit = ['website.multi.mixin']
_description = 'Product Tags'
name = fields.Char(required=True, translate=True)
product_ids = fields.Many2many('product.template', 'dr_product_tags_rel', 'tag_id', 'product_id')
product_count = fields.Integer(compute='_compute_product_count')
active = fields.Boolean(default=True)
dr_tab_ids = fields.One2many('dr.product.tabs', 'tag_id', string='Tabs', help='Display in product detail page on website.')
dr_offer_ids = fields.One2many('dr.product.offer', 'tag_id', string='Offers', help='Display in product detail page on website.')
def _compute_product_count(self):
for tag in self:
tag.product_count = len(tag.product_ids)
def action_open_products(self):
self.ensure_one()
action = self.env.ref('website_sale.product_template_action_website').read()[0]
action['domain'] = [('dr_tag_ids', 'in', self.id)]
return action

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from odoo import fields, models
from odoo import fields, models, tools
class PWAShortcuts(models.Model):
@ -11,7 +11,7 @@ class PWAShortcuts(models.Model):
website_id = fields.Many2one('website')
sequence = fields.Integer()
name = fields.Char(required=True, translate=True, help='The human-readable label for the app shortcut when displayed to the user.')
short_name = fields.Char('Short Name', translate=True, help='The human-readable label used where space is limited.')
short_name = fields.Char(translate=True, help='The human-readable label used where space is limited.')
description = fields.Text(help='The human-readable purpose for the app shortcut.')
url = fields.Char('URL', required=True, help='The URL opened when a user activates the app shortcut.')
icon = fields.Binary()

View File

@ -1,40 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
from odoo import fields, models
from odoo.tools.translate import html_translate
class DrWebsiteContent(models.Model):
_name = 'dr.website.content'
_description = 'Website Content'
_inherit = 'dr.cache.mixin'
_order = 'sequence,id'
sequence = fields.Integer()
name = fields.Char(required=True, translate=True)
identifier = fields.Char('Extra Label', help="It is just displayed in backend dropdown and breadcrumb")
description = fields.Char(translate=True)
icon = fields.Char(default='list')
content = fields.Html(sanitize_attributes=False, translate=html_translate, sanitize_form=False)
content_type = fields.Selection([('tab', 'Product Tab'), ('offer_popup', 'Offer Popup'), ('attribute_popup', 'Attribute Popup')], default='tab', required=True, string='Type')
dr_tab_products_ids = fields.Many2many('product.template', 'product_template_tab_rel', 'tab_id', 'product_template_id', string='Tab Products')
dr_offer_products_ids = fields.Many2many('product.template', 'product_template_offer_rel', 'offer_id', 'product_template_id', string='Offer Products')
def name_get(self):
result = []
for content in self:
name = content.name
if content.identifier:
name = f'[{content.identifier}] {name}'
result.append((content.id, name))
return result
def open_design_page(self):
self.ensure_one()
return {
'type': 'ir.actions.act_url',
'target': 'new',
'url': '/droggol_theme_common/design_content/%s?enable_editor=1' % (self.id),
}

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from odoo import fields, models
from odoo import api, fields, models
class DrWebsiteMenuLabel(models.Model):
@ -9,5 +9,38 @@ class DrWebsiteMenuLabel(models.Model):
_description = 'Website Menu Label'
name = fields.Char(required=True, translate=True)
background_color = fields.Char('Background Color', default='#000000')
text_color = fields.Char('Text Color', default='#FFFFFF')
color = fields.Selection([
('green', 'Green'),
('blue', 'Blue'),
('red', 'Red'),
('orange', 'Orange'),
('gray', 'Gray'),
('black', 'Black'),
])
menu_ids = fields.One2many('website.menu', 'dr_menu_label_id')
menu_count = fields.Integer(compute='_compute_menu_count')
def _compute_menu_count(self):
for label in self:
label.menu_count = len(label.menu_ids)
def action_open_menus(self):
self.ensure_one()
action = self.env.ref('website.action_website_menu').read()[0]
action['domain'] = [('dr_menu_label_id', '=', self.id)]
action['context'] = {}
return action
class WebsiteMenu(models.Model):
_inherit = 'website.menu'
dr_menu_label_id = fields.Many2one('dr.website.menu.label', string='Label')
dr_is_special_menu = fields.Boolean()
@api.model
def get_tree(self, website_id, menu_id=None):
result = super(WebsiteMenu, self).get_tree(website_id, menu_id)
for menu in result['children']:
menu['fields']['dr_is_special_menu'] = self.browse(menu['fields']['id']).dr_is_special_menu
return result

View File

@ -1,14 +1,11 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from odoo import api, fields, models, _
from odoo.exceptions import UserError
from odoo import api, fields, models
class ProductAttribute(models.Model):
_name = 'product.attribute'
_inherit = ['product.attribute', 'dr.cache.mixin']
_fields_to_watch = ['name', 'display_type', 'dr_attribute_popup_id', 'dr_radio_image_style', 'dr_is_brand']
_inherit = 'product.attribute'
display_type = fields.Selection(
selection_add=[
@ -16,66 +13,17 @@ class ProductAttribute(models.Model):
('radio_square', 'Radio Square'),
('radio_image', 'Radio Image'),
], ondelete={'radio_circle': 'cascade', 'radio_square': 'cascade', 'radio_image': 'cascade'})
dr_is_hide_shop_filter = fields.Boolean('Hide in Shop Filter', default=False)
dr_is_show_shop_search = fields.Boolean('Show Searchbar in Shop Filter', default=False)
dr_attribute_popup_id = fields.Many2one('dr.website.content', string='Popup', domain='[("content_type", "=", "attribute_popup")]')
dr_radio_image_style = fields.Selection([
('default', 'Default'),
('image', 'Image'),
('image_text', 'Image + Text'),
], default='default', string='Style')
dr_search_suggestion = fields.Selection([('auto', 'Autocomplete'), ('auto_suggestion', 'Autocomplete & Suggestion')], string='Search suggestion type')
dr_is_brand = fields.Boolean('Is Brand?')
@api.onchange('dr_is_brand')
def _onchange_dr_is_brand(self):
self.display_type = 'radio_image'
@api.constrains('dr_is_brand', 'display_type')
def _constrains_dr_is_brand(self):
for attribute in self:
if attribute.dr_is_brand and not attribute.display_type == 'radio_image':
raise UserError(_('Brand attribute must have display type "Radio Image".'))
def open_create_brand_value(self):
return {
'type': 'ir.actions.act_window',
'name': _('Brand'),
'res_model': 'product.attribute.value',
'view_mode': 'form',
'target': 'new',
'views': [[False, 'form']],
'context': {'default_attribute_id': self.id}
}
class ProductAttributeValue(models.Model):
_name = 'product.attribute.value'
_inherit = ['product.attribute.value', 'dr.cache.mixin']
_fields_to_watch = ['name', 'html_color', 'dr_image', 'dr_brand_description']
_inherit = 'product.attribute.value'
dr_image = fields.Binary('Image')
dr_brand_description = fields.Text('Description', translate=True)
ds_name = fields.Char('Search DS Name', compute="_compute_ds_name", search="_search_ds_name")
def _compute_ds_name(self):
for attr in self:
attr.ds_name = attr.name
@api.model
def _search_ds_name(self, operator, value):
return [('name', operator, value)]
dr_image = fields.Binary(string='Image')
class ProductTemplateAttributeValue(models.Model):
_name = 'product.template.attribute.value'
_inherit = ['product.template.attribute.value', 'dr.cache.mixin']
_fields_to_watch = ['dr_thumb_image']
_inherit = 'product.template.attribute.value'
dr_image = fields.Binary('Image', related='product_attribute_value_id.dr_image')
dr_thumb_image = fields.Image('Swatch Image', max_width=128, max_height=128)
class ProductTemplateAttributeLine(models.Model):
_inherit = 'product.template.attribute.line'
dr_attribute_popup_id = fields.Many2one('dr.website.content', string='Website Popup', domain='[("content_type", "=", "attribute_popup")]')

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from odoo import fields, models
from odoo import api, fields, models
class PricelistItem(models.Model):

View File

@ -1,51 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
import re
from odoo import fields, models, api
class ProductPublicCategory(models.Model):
_inherit = 'product.public.category'
dr_category_label_id = fields.Many2one('dr.product.public.category.label', string='Label')
dr_category_cover_image = fields.Binary('Cover Image')
dr_category_icon = fields.Binary('Icon Image')
dr_category_sidebar_cover = fields.Binary('Sidebar Cover')
dr_search_formulate = fields.Boolean('Formulated Search', help="Use to search multi level categories \
e.g. Men Shirt (Here men and shirt are diffrent category but will be displayed as one in smart search)")
ds_name = fields.Char('Search DS Name', compute="_compute_ds_name", search="_search_ds_name")
def _compute_ds_name(self):
for category in self:
if self.env.context.get('dr_formulate'):
category.ds_name = ' '.join([categ.name for categ in category.parents_and_self if (category.id == categ.id or categ.dr_search_formulate)])
else:
category.ds_name = category.name
@api.model
def _search_ds_name(self, operator, value):
if not self.env.context.get('dr_formulate'):
return [('name', operator, value)]
# Assumes operator is 'ilike'
domain, website_id = [('dr_search_formulate', '=', False)], self.env.context.get('website_id')
if website_id:
domain += self.env['website'].website_domain(website_id=website_id)
categ_ids = [categ.id for categ in self.search(domain) if re.search(re.escape(value), categ.ds_name, re.IGNORECASE)]
return [('id', 'in', categ_ids)]
@api.model
def _search_get_detail(self, website, order, options):
"Fix the issue of Odoo's search in html fields"
with_image = options['displayImage']
options = options.copy()
options['displayDescription'] = False
result = super()._search_get_detail(website, order, options)
if with_image:
result['mapping']['image_url'] = {'name': 'image_url', 'type': 'html'}
# to fix Odoo's issue Odoo catagory is not multi website compatible
result['base_domain'] = [website.website_domain()]
return result

View File

@ -1,182 +1,44 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from odoo import api, fields, models, Command
from odoo.addons.website.models import ir_http
from odoo import api, fields, models
from odoo.http import request
class ProductTemplate(models.Model):
_inherit = 'product.template'
dr_label_id = fields.Many2one('dr.product.label', string='Label')
dr_brand_id = fields.Many2one('dr.product.brand', string='Brand')
dr_tag_ids = fields.Many2many('dr.product.tags', 'dr_product_tags_rel', 'product_id', 'tag_id', string='Tags')
dr_tab_ids = fields.One2many('dr.product.tabs', 'product_id', string='Tabs', help='Display in product detail page on website.')
dr_offer_ids = fields.One2many('dr.product.offer', 'product_id', string='Offers', help='Display in product detail page on website.')
dr_product_tab_ids = fields.Many2many('dr.website.content', 'product_template_tab_rel', 'product_template_id', 'tab_id', string='Tabs')
dr_product_offer_ids = fields.Many2many('dr.website.content', 'product_template_offer_rel', 'product_template_id', 'offer_id', string='Offers')
dr_document_ids = fields.Many2many('ir.attachment', 'product_template_document_attachment_rel', 'product_template_id', 'attachment_id', string='Documents', help='Documents publicly downloadable from eCommerce product page.')
dr_brand_value_id = fields.Many2one('product.attribute.value', compute='_compute_dr_brand_value_id', inverse='_inverse_dr_brand_value_id', search='_search_dr_brand_value_id', string='Brand')
dr_brand_attribute_ids = fields.Many2many('product.attribute', compute='_compute_dr_brand_attribute_ids')
dr_free_qty = fields.Float('Free To Use Quantity', compute='_compute_dr_free_qty', search='_search_dr_free_qty', compute_sudo=False, digits='Product Unit of Measure')
dr_show_out_of_stock = fields.Char(compute='_compute_dr_show_out_of_stock', compute_sudo=True)
dr_ptav_ids = fields.One2many('product.template.attribute.value', 'product_tmpl_id')
@api.model_create_multi
def create(self, vals):
res = super().create(vals)
res.dr_document_ids.public = True
return res
def write(self, vals):
res = super().write(vals)
if 'dr_document_ids' in vals:
self.dr_document_ids.public = True
return res
def _search_dr_brand_value_id(self, operator, value):
if operator in ['in', 'not in']:
return [('attribute_line_ids.value_ids', operator, value)]
elif operator in ['ilike', 'not ilike', '=', '!=']:
brand_attribute_id = self._get_brand_attribute()
values = self.env['product.attribute.value'].search([('name', operator, value), ('attribute_id', 'in', brand_attribute_id.ids)])
return [('attribute_line_ids.value_ids', 'in', values.ids)]
# Does not support other cases
return []
def _compute_dr_brand_value_id(self):
for product in self:
brand_lines = product.attribute_line_ids.filtered(lambda x: x.attribute_id.dr_is_brand)
product.dr_brand_value_id = self.env['product.attribute.value']
if brand_lines:
product.dr_brand_value_id = brand_lines[0].value_ids[0]
def _inverse_dr_brand_value_id(self):
brand_value_id = self.dr_brand_value_id
for product in self:
brand_lines = product.attribute_line_ids.filtered(lambda x: x.attribute_id.dr_is_brand)
brand_line = brand_lines and brand_lines[0]
if brand_line and brand_value_id:
brand_line.value_ids = brand_value_id
elif brand_line and not brand_value_id:
brand_line.unlink()
elif brand_value_id:
product.attribute_line_ids = [Command.create({
'attribute_id': brand_value_id.attribute_id.id,
'value_ids': [Command.set(brand_value_id.ids)],
})]
def _compute_dr_brand_attribute_ids(self):
attributes = self._get_brand_attribute()
for product in self:
product.dr_brand_attribute_ids = attributes
def _get_brand_attribute(self):
return self.env['product.attribute'].search([('dr_is_brand', '=', True)])
@api.depends('product_variant_ids.free_qty')
def _compute_dr_free_qty(self):
res = self._compute_dr_free_qty_quantities_dict()
for template in self:
template.dr_free_qty = res[template.id]['free_qty']
def _compute_dr_free_qty_quantities_dict(self):
variants_available = {
p['id']: p for p in self.product_variant_ids.read(['free_qty'])
}
prod_available = {}
for template in self:
free_qty = 0
for p in template.product_variant_ids:
free_qty += variants_available[p.id]['free_qty']
prod_available[template.id] = {
'free_qty': free_qty,
}
return prod_available
def _search_dr_free_qty(self, operator, value):
domain = [('free_qty', operator, value)]
product_variant_query = self.env['product.product'].sudo()._search(domain)
return [('product_variant_ids', 'in', product_variant_query)]
def _compute_dr_show_out_of_stock(self):
website = ir_http.get_request_website()
for product in self:
product.dr_show_out_of_stock = ''
if website and website._get_dr_theme_config('json_shop_product_item').get('show_stock_label') and not product.allow_out_of_stock_order and product.detailed_type == 'product':
free_qty = product.dr_free_qty
if product.show_availability and free_qty <= product.available_threshold:
product.dr_show_out_of_stock = int(free_qty)
if free_qty <= 0:
product.dr_show_out_of_stock = 'OUT_OF_STOCK'
@api.onchange('website_id')
def _onchange_website_id(self):
self.dr_label_id = False
self.dr_brand_id = False
self.dr_tag_ids = False
@api.model
def _search_get_detail(self, website, order, options):
res = super()._search_get_detail(website, order, options)
# Hide out of stock
if options.get('hide_out_of_stock'):
res['base_domain'].append(['|', '|', ('detailed_type', '!=', 'product'), ('allow_out_of_stock_order', '=', True), '&', ('dr_free_qty', '>', 0), ('allow_out_of_stock_order', '=', False)])
# Tag
tag = options.get('tag')
if tag:
res['base_domain'].append([('product_tag_ids', 'in', [int(x) for x in tag])])
# Rating
ratings = options.get('rating')
if ratings:
result = self.env['rating.rating'].sudo().read_group([('res_model', '=', 'product.template')], ['rating:avg'], groupby=['res_id'], lazy=False)
rating_product_ids = []
for rating in ratings:
rating_product_ids.extend([item['res_id'] for item in result if item['rating'] >= int(rating)])
if rating_product_ids:
res['base_domain'].append([('id', 'in', rating_product_ids)])
else:
res['base_domain'].append([('id', 'in', [])])
return res
def _get_image_size_based_grid(self, columns, view_mode):
if view_mode == 'list':
return 'image_1024'
if columns <= 2:
return 'image_1024'
return 'image_512'
def _get_product_preview_swatches(self, limit=3):
swatches = []
for ptav in self.dr_ptav_ids:
if ptav.ptav_active and ptav.ptav_product_variant_ids:
vals = {'id': ptav.id, 'name': ptav.name, 'preview_image': '/web/image/product.product/%s' % ptav.ptav_product_variant_ids.ids[0]}
if ptav.dr_thumb_image:
vals.update({'type': 'image', 'value': '/web/image/product.template.attribute.value/%s/dr_thumb_image' % ptav.id})
swatches.append(vals)
elif ptav.html_color:
vals.update({'type': 'color', 'value': ptav.html_color})
swatches.append(vals)
return {'swatches': swatches[:limit], 'more': len(swatches) - limit}
def _get_product_colors(self):
color_variants = self.attribute_line_ids.filtered(lambda x: x.attribute_id.display_type == 'color')
if len(color_variants) == 1:
if len(color_variants.value_ids) == 1:
return []
return color_variants.value_ids.mapped('html_color')
return []
@api.model
def _get_product_pricelist_offer(self):
website_id = self.env['website'].get_current_website()
if not website_id._dr_has_b2b_access():
return False
pricelist_id = website_id.get_current_pricelist()
price_rule = pricelist_id._compute_price_rule(self, 1)
partner = self._context.get('partner')
pricelist_id = self._context.get('pricelist')
pricelist = self.env['product.pricelist'].browse(pricelist_id)
price_rule = pricelist._compute_price_rule([(self, 1, partner)])
price_rule_id = price_rule.get(self.id)[1]
if price_rule_id:
rule = self.env['product.pricelist.item'].browse(price_rule_id)
rule = self.env['product.pricelist.item'].browse([price_rule_id])
if rule and rule.date_end:
return {'rule': rule, 'date_end': rule.date_end.strftime('%Y-%m-%d %H:%M:%S')}
return False
def _get_combination_info(self, combination=False, product_id=False, add_qty=1, pricelist=False, parent_combination=False, only_template=False):
combination_info = super()._get_combination_info(combination=combination, product_id=product_id, add_qty=add_qty, pricelist=pricelist, parent_combination=parent_combination, only_template=only_template)
if combination_info['product_id']:
website = self.env['website'].get_current_website()
theme_id = website.sudo().theme_id
product_variant_id = self.env['product.product'].browse(combination_info['product_id'])
if website and theme_id and theme_id.name.startswith('theme_prime'):
# Render extra fields on product detail page
IrUiView = self.env['ir.ui.view']
combination_info['tp_extra_fields'] = IrUiView._render_template('theme_prime.product_extra_fields', values={'website': website, 'product_variant': product_variant_id, 'product': product_variant_id.product_tmpl_id})
# Hide price per UoM feature for B2B mode
if not website._dr_has_b2b_access():
combination_info['base_unit_price'] = 0
return combination_info

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from odoo import api, fields, models, _
@ -7,51 +7,38 @@ from odoo import api, fields, models, _
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
dr_pwa_activated = fields.Boolean(related='website_id.dr_pwa_activated', readonly=False)
dr_pwa_name = fields.Char(related='website_id.dr_pwa_name', readonly=False)
dr_pwa_short_name = fields.Char(related='website_id.dr_pwa_short_name', readonly=False)
dr_pwa_background_color = fields.Char(related='website_id.dr_pwa_background_color', readonly=False)
dr_pwa_theme_color = fields.Char(related='website_id.dr_pwa_theme_color', readonly=False)
dr_pwa_icon_192 = fields.Binary(related='website_id.dr_pwa_icon_192', readonly=False)
dr_pwa_icon_512 = fields.Binary(related='website_id.dr_pwa_icon_512', readonly=False)
dr_pwa_start_url = fields.Char(related='website_id.dr_pwa_start_url', readonly=False)
dr_pwa_shortcuts = fields.One2many(related='website_id.dr_pwa_shortcuts', readonly=False)
dr_pwa_offline_page = fields.Boolean(related='website_id.dr_pwa_offline_page', readonly=False)
# This has been done in order to fix Odoo's broken behavior for theme customization.
# If database already have theme installed, it is impossible to have custom module later.
dr_has_custom_module = fields.Boolean(compute='_compute_dr_has_custom_module')
@api.depends('website_id')
def _compute_dr_has_custom_module(self):
IrModuleModule = self.env['ir.module.module']
themes = self._get_droggol_theme_list()
theme_list = self._get_droggol_theme_list()
for setting in self:
setting.dr_has_custom_module = False
if setting.website_id and setting.website_id.theme_id and setting.website_id.theme_id.name in themes:
if setting.website_id and setting.website_id.theme_id and setting.website_id.theme_id.name in theme_list:
search_term = '%s_%%' % setting.website_id.theme_id.name
has_custom_apps = IrModuleModule.sudo().search([('name', '=ilike', search_term)])
setting.dr_has_custom_module = bool(has_custom_apps)
def dr_open_pwa_shortcuts(self):
self.website_id._force()
action = self.env.ref('droggol_theme_common.dr_pwa_shortcuts_action').read()[0]
action['domain'] = [('website_id', '=', self.website_id.id)]
action['context'] = {'default_website_id': self.website_id.id}
return action
has_custom_apps = self.env['ir.module.module'].sudo().search([('name', '=ilike', search_term)])
if has_custom_apps:
setting.dr_has_custom_module = True
else:
setting.dr_has_custom_module = False
else:
setting.dr_has_custom_module = False
def dr_open_theme_custom_modules(self):
self.ensure_one()
themes = self._get_droggol_theme_list()
if self.website_id and self.website_id.theme_id and self.website_id.theme_id.name in themes:
theme_list = self._get_droggol_theme_list()
if self.website_id and self.website_id.theme_id and self.website_id.theme_id.name in theme_list:
search_term = '%s_%%' % self.website_id.theme_id.name
return {
action = {
'name': _('Theme Customizations'),
'view_mode': 'kanban,tree,form',
'res_model': 'ir.module.module',
'type': 'ir.actions.act_window',
'domain': [('name', '=ilike', search_term)]
}
return action
return True
def _get_droggol_theme_list(self):

View File

@ -1,16 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
from odoo import models
class SaleOrder(models.Model):
_inherit = 'sale.order'
def _cart_update(self, product_id=None, line_id=None, add_qty=0, set_qty=0, **kwargs):
values = super()._cart_update(product_id=product_id, line_id=line_id, add_qty=add_qty, set_qty=set_qty, **kwargs)
if self.website_id and not self.website_id._dr_has_b2b_access():
for line in self.order_line:
new_val = super()._cart_update(product_id=line.product_id.id, line_id=line.id, add_qty=-1, set_qty=0, **kwargs)
values.update(new_val)
return values

View File

@ -1,79 +1,70 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from odoo import _, api, fields, models
import base64
from odoo import _, fields, models, tools, api
from odoo.osv import expression
from odoo.tools.translate import html_translate
from odoo.modules.module import get_resource_path
class Website(models.Model):
_inherit = 'website'
dr_sale_special_offer = fields.Html('Sale Special Offer', sanitize_attributes=False, translate=html_translate, sanitize_form=False)
def _default_footer_logo(self):
image_path = get_resource_path('website', 'static/src/img', 'website_logo.png')
with tools.file_open(image_path, 'rb') as f:
return base64.b64encode(f.read())
dr_pwa_activated = fields.Boolean('PWA Activated')
dr_pwa_name = fields.Char('PWA Name')
dr_pwa_short_name = fields.Char('PWA Short Name')
dr_pwa_background_color = fields.Char('PWA Background Color', default='#000000')
dr_pwa_theme_color = fields.Char('PWA Theme Color', default='#FFFFFF')
dr_pwa_icon_192 = fields.Binary('PWA Icon 192x192')
dr_pwa_icon_512 = fields.Binary('PWA Icon 512x512')
dr_pwa_start_url = fields.Char('PWA Start URL', default='/shop')
dr_pwa_offline_page = fields.Boolean('PWA Offline Page')
dr_pwa_version = fields.Integer('PWA Version')
dr_pwa_shortcuts = fields.One2many('dr.pwa.shortcuts', 'website_id', string='Shortcuts')
dr_sale_special_offer = fields.Html(sanitize_attributes=False, translate=True)
def _get_brands(self, domain=[], limit=None, order=None):
brand_attributes = self._get_brand_attributes().ids
domain = expression.AND([domain, [('attribute_id', 'in', brand_attributes)]])
return self.env['product.attribute.value'].search(domain, limit=limit, order=order)
def _dr_has_b2b_access(self, record=None):
if self._get_dr_theme_config('json_b2b_shop_config')['dr_enable_b2b']:
return not self.env.user.has_group('base.group_public')
return True
def _get_brand_attributes(self):
""" This will preserver the sequence """
current_website_products = self.env['product.template'].search(self.sale_product_domain())
all_brand_attributes = self.env['product.template']._get_brand_attribute()
return self.env['product.template.attribute.line'].search([('product_tmpl_id', 'in', current_website_products.ids), ('attribute_id', 'in', all_brand_attributes.ids)]).mapped('attribute_id')
def get_dr_theme_config(self):
return self._get_dr_theme_config()
# PWA
dr_pwa_activated = fields.Boolean()
dr_pwa_name = fields.Char()
dr_pwa_short_name = fields.Char()
dr_pwa_background_color = fields.Char(default='#000000')
dr_pwa_theme_color = fields.Char(default='#FFFFFF')
dr_pwa_icon_192 = fields.Binary()
dr_pwa_icon_512 = fields.Binary()
dr_pwa_start_url = fields.Char(default='/shop')
dr_pwa_offline_page = fields.Boolean()
dr_pwa_version = fields.Integer(default=1)
dr_pwa_shortcuts = fields.One2many('dr.pwa.shortcuts', 'website_id')
def _get_dr_theme_config(self, key=False):
""" See dr.theme.config for more info"""
self.ensure_one()
website_config = self.env['dr.theme.config']._get_all_config(self.id)
website_config['is_public_user'] = not self.env.user.has_group('website.group_website_restricted_editor')
website_config['has_sign_up'] = False
if website_config.get('json_b2b_shop_config')['dr_enable_b2b']:
website_config['has_sign_up'] = self.env['res.users']._get_signup_invitation_scope() == 'b2c'
website_config['is_public_user'] = not self.env.user.has_group('website.group_website_publisher')
if key:
return website_config.get(key)
return website_config
def _get_pricelist_available(self, req, show_visible=False):
if self._get_dr_theme_config('json_b2b_shop_config')['dr_only_assigned_pricelist'] and not self.env.user.has_group('base.group_website_designer'):
return self.env.user.partner_id.property_product_pricelist
return super()._get_pricelist_available(req, show_visible=show_visible)
@api.model
def get_theme_prime_shop_config(self):
def _get_theme_prime_shop_config(self):
Website = self.get_current_website()
return {
'is_rating_active': Website.sudo().viewref('website_sale.product_comment').active,
'is_buy_now_active': Website.sudo().viewref('website_sale.product_buy_now').active,
'is_multiplier_active': Website.sudo().viewref('website_sale.product_quantity').active,
'is_wishlist_active': Website.sudo().viewref('website_sale_wishlist.product_add_to_wishlist').active,
'is_comparison_active': Website.sudo().viewref('website_sale_comparison.add_to_compare').active}
result = {
'is_rating_active': Website.viewref('website_sale.product_comment').active,
'is_buy_now_active': Website.viewref('website_sale.product_buy_now').active,
'is_multiplier_active': Website.viewref('website_sale.product_quantity').active,
'is_wishlist_active': Website.viewref('website_sale_wishlist.add_to_wishlist').active,
'is_comparison_active': Website.viewref('website_sale_comparison.add_to_compare').active,
'is_wishlist_installed': False,
'is_compare_installed': False,
}
modules = self.env['ir.module.module'].sudo().search(expression.OR([[('name', '=', 'website_sale_wishlist')], [('name', '=', 'website_sale_comparison')]]))
for module in modules:
if module.state == 'installed':
if module.name == 'website_sale_comparison':
result['is_compare_installed'] = True
if module.name == 'website_sale_wishlist':
result['is_wishlist_installed'] = True
return result
def _get_website_category(self):
return self.env['product.public.category'].search([('website_id', 'in', [False, self.id]), ('parent_id', '=', False)])
def _get_theme_prime_rating_template(self, rating_avg, rating_count=False):
return self.env['ir.ui.view']._render_template('theme_prime.d_rating_widget_stars_static', values={
return self.env["ir.ui.view"]._render_template('theme_prime.d_rating_widget_stars_static', values={
'rating_avg': rating_avg,
'rating_count': rating_count,
})
@ -81,17 +72,54 @@ class Website(models.Model):
@api.model
def get_theme_prime_bottom_bar_action_buttons(self):
# Add to cart, blog, checkout, pricelist, language,
return {'tp_home': {'name': _("Home"), 'url': '/', 'icon': 'fa fa-home'}, 'tp_search': {'name': _("Search"), 'icon': 'dri dri-search', 'action_class': 'tp-search-sidebar-action'}, 'tp_wishlist': {'name': _("Wishlist"), 'icon': 'dri dri-wishlist', 'url': '/shop/wishlist'}, 'tp_offer': {'name': _("Offers"), 'url': '/offers', 'icon': 'dri dri-bolt'}, 'tp_brands': {'name': _("Brands"), 'icon': 'dri dri-tag-l ', 'url': '/shop/all-brands'}, 'tp_category': {'name': _("Category"), 'icon': 'dri dri-category', 'action_class': 'tp-category-action'}, 'tp_orders': {'name': _("Orders"), 'icon': 'fa fa-file-text-o', 'url': '/my/orders'}, 'tp_cart': {'name': _("Cart"), 'icon': 'dri dri-cart', 'url': '/shop/cart'}, 'tp_lang_selector': {'name': _("Language and Pricelist selector")}}
return {
'tp_home': {'name': _("Home"), 'url': '/', 'icon': 'fa fa-home'},
'tp_search': {'name': _("Search"), 'icon': 'dri dri-search', 'action_class': 'tp-search-sidebar-action'},
'tp_wishlist': {'name': _("Wishlist"), 'icon': 'dri dri-wishlist', 'url': '/shop/wishlist'},
'tp_offer': {'name': _("Offers"), 'url': '/offers', 'icon': 'dri dri-bolt'},
'tp_brands': {'name': _("Brands"), 'icon': 'dri dri-tag-l ', 'url': '/shop/all_brands'},
'tp_category': {'name': _("Category"), 'icon': 'dri dri-category', 'action_class': 'tp-category-action'},
'tp_orders': {'name': _("Orders"), 'icon': 'fa fa-file-text-o', 'url': '/my/orders'},
'tp_cart': {'name': _("Cart"), 'icon': 'dri dri-cart', 'url': '/shop/cart'},
'tp_lang_selector': {'name': _("Language and Pricelist selector")},
}
def _is_snippet_used(self, snippet_module, snippet_id, asset_version, asset_type, html_fields):
""" There is no versioning for all theme snippets (for the test case)"""
if snippet_module and snippet_module.startswith('theme_prime'):
return True
return super()._is_snippet_used(snippet_module, snippet_id, asset_version, asset_type, html_fields)
def _convert_currency_price(self, amount, from_base_currency=True, rounding_method=None):
""" This function converts amount based website pricelist and company company currency
:param amount: float or int,
:param from_base_currency: If True then coverts amount from company currency to pricelist currency
else it converts pricelist currency to company currency
:param rounding_method: funcation reference to round the final amount
"""
base_currency = self.company_id.currency_id
pricelist_currency = self.get_current_pricelist().currency_id
if base_currency != pricelist_currency:
if from_base_currency:
amount = base_currency._convert(amount, pricelist_currency, self.company_id, fields.Date.today())
else:
amount = pricelist_currency._convert(amount, base_currency, self.company_id, fields.Date.today())
return rounding_method(amount) if rounding_method else amount
class WebsiteSaleExtraField(models.Model):
_inherit = 'website.sale.extra.field'
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
dr_label = fields.Char('Display Label', translate=True)
field_id = fields.Many2one('ir.model.fields', domain=[('model_id.model', '=', 'product.template'), '|', ('ttype', 'in', ['char', 'binary']), ('name', 'in', ['public_categ_ids'])])
# PWA
dr_pwa_activated = fields.Boolean(related='website_id.dr_pwa_activated', readonly=False)
dr_pwa_name = fields.Char(related='website_id.dr_pwa_name', readonly=False)
dr_pwa_short_name = fields.Char(related='website_id.dr_pwa_short_name', readonly=False)
dr_pwa_background_color = fields.Char(related='website_id.dr_pwa_background_color', readonly=False)
dr_pwa_theme_color = fields.Char(related='website_id.dr_pwa_theme_color', readonly=False)
dr_pwa_icon_192 = fields.Binary(related='website_id.dr_pwa_icon_192', readonly=False)
dr_pwa_icon_512 = fields.Binary(related='website_id.dr_pwa_icon_512', readonly=False)
dr_pwa_start_url = fields.Char(related='website_id.dr_pwa_start_url', readonly=False)
dr_pwa_shortcuts = fields.One2many(related='website_id.dr_pwa_shortcuts', readonly=False)
dr_pwa_offline_page = fields.Boolean(related='website_id.dr_pwa_offline_page', readonly=False)
def dr_open_pwa_shortcuts(self):
self.website_id._force()
action = self.env.ref('droggol_theme_common.dr_pwa_shortcuts_action').read()[0]
action['domain'] = [('website_id', '=', self.website_id.id)]
action['context'] = {'default_website_id': self.website_id.id}
return action

View File

@ -1,18 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
from odoo import api, fields, models
class WebsiteMenu(models.Model):
_inherit = 'website.menu'
dr_menu_label_id = fields.Many2one('dr.website.menu.label', string='Label')
dr_highlight_menu = fields.Selection([('solid', 'Solid'), ('soft', 'Soft')], string='Highlight Menu')
@api.model
def get_tree(self, website_id, menu_id=None):
result = super().get_tree(website_id, menu_id=menu_id)
for menu in result['children']:
menu['fields']['dr_highlight_menu'] = self.browse(menu['fields']['id']).dr_highlight_menu
return result

View File

@ -3,8 +3,14 @@ access_dr_product_label_manager,dr.product.label.manager,model_dr_product_label,
access_dr_product_label_public,dr.product.label.public,model_dr_product_label,,1,0,0,0
access_dr_product_public_category_label_manager,dr.product.public.category.label.manager,model_dr_product_public_category_label,sales_team.group_sale_manager,1,1,1,1
access_dr_product_public_category_label_public,dr.product.public.category.label.public,model_dr_product_public_category_label,,1,0,0,0
access_dr_website_content_manager,dr.website.content.manager,model_dr_website_content,sales_team.group_sale_manager,1,1,1,1
access_dr_website_content_public,dr.website.content.public,model_dr_website_content,,1,0,0,0
access_dr_product_brand_manager,dr.product.brand.manager,model_dr_product_brand,sales_team.group_sale_manager,1,1,1,1
access_dr_product_brand_public,dr.product.brand.public,model_dr_product_brand,,1,0,0,0
access_dr_product_tags_manager,dr.product.tags.manager,model_dr_product_tags,sales_team.group_sale_manager,1,1,1,1
access_dr_product_tags_public,dr.product.tags.public,model_dr_product_tags,,1,0,0,0
access_dr_product_tabs_manager,dr.product.tabs.manager,model_dr_product_tabs,sales_team.group_sale_manager,1,1,1,1
access_dr_product_tabs_public,dr.product.tabs.public,model_dr_product_tabs,,1,0,0,0
access_dr_product_offer_manager,dr.product.offer.manager,model_dr_product_offer,sales_team.group_sale_manager,1,1,1,1
access_dr_product_offer_public,dr.product.offer.public,model_dr_product_offer,,1,0,0,0
access_dr_website_menu_label_designer,dr.website.menu.label.designer,model_dr_website_menu_label,website.group_website_designer,1,1,1,1
access_dr_website_menu_label,dr.website.menu.label.public,model_dr_website_menu_label,,1,0,0,0
access_dr_pwa_shortcuts_designer,dr.pwa.shortcuts.designer,model_dr_pwa_shortcuts,website.group_website_designer,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
3 access_dr_product_label_public dr.product.label.public model_dr_product_label 1 0 0 0
4 access_dr_product_public_category_label_manager dr.product.public.category.label.manager model_dr_product_public_category_label sales_team.group_sale_manager 1 1 1 1
5 access_dr_product_public_category_label_public dr.product.public.category.label.public model_dr_product_public_category_label 1 0 0 0
6 access_dr_website_content_manager access_dr_product_brand_manager dr.website.content.manager dr.product.brand.manager model_dr_website_content model_dr_product_brand sales_team.group_sale_manager 1 1 1 1
7 access_dr_website_content_public access_dr_product_brand_public dr.website.content.public dr.product.brand.public model_dr_website_content model_dr_product_brand 1 0 0 0
8 access_dr_product_tags_manager dr.product.tags.manager model_dr_product_tags sales_team.group_sale_manager 1 1 1 1
9 access_dr_product_tags_public dr.product.tags.public model_dr_product_tags 1 0 0 0
10 access_dr_product_tabs_manager dr.product.tabs.manager model_dr_product_tabs sales_team.group_sale_manager 1 1 1 1
11 access_dr_product_tabs_public dr.product.tabs.public model_dr_product_tabs 1 0 0 0
12 access_dr_product_offer_manager dr.product.offer.manager model_dr_product_offer sales_team.group_sale_manager 1 1 1 1
13 access_dr_product_offer_public dr.product.offer.public model_dr_product_offer 1 0 0 0
14 access_dr_website_menu_label_designer dr.website.menu.label.designer model_dr_website_menu_label website.group_website_designer 1 1 1 1
15 access_dr_website_menu_label dr.website.menu.label.public model_dr_website_menu_label 1 0 0 0
16 access_dr_pwa_shortcuts_designer dr.pwa.shortcuts.designer model_dr_pwa_shortcuts website.group_website_designer 1 1 1 1

View File

@ -4,7 +4,7 @@
<!-- Help START-->
<div class="row pb16 pt16" style="padding: 10px;background-image: url(images/dots_bg.svg);">
<a href="https://www.droggol.com/" target="_blank" style="width: 100%; display: block; text-align: center;">
<img src="images/logo.svg" style="background-color: #3c4858; padding: 15px; max-width: 150px; text-align: center; margin: auto; border-radius: 8px;"/>
<img src="https://www.droggol.com/images/14.0/droggol_theme_common_icon.png" style="background-color: #3c4858; padding: 15px; max-width: 150px; text-align: center; margin: auto; border-radius: 8px;"/>
</a>
<div class="alert alert-warning text-center mt32 mb32"
style="padding: 21px 51px;background-color: #ffffff;border: 0px;border-top: 3px solid #0080FF;box-shadow: 0px 1px 7px 0px #35353521;color: #414d5c;margin: auto;display: block;border-radius: 1px;min-width: 80%;">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

View File

@ -0,0 +1,38 @@
odoo.define('droggol_theme_common.list_view_brand', function (require) {
"use strict";
const core = require('web.core');
const Dialog = require('web.Dialog');
const ListController = require('web.ListController');
const ListView = require('web.ListView');
const viewRegistry = require('web.view_registry');
const _t = core._t;
const BrandListController = ListController.extend({
buttons_template: 'BrandListView.buttons',
events: _.extend({}, ListController.prototype.events, {
'click .o_button_reorder': '_onClickReorder',
}),
_onClickReorder: function () {
const self = this;
Dialog.confirm(this, _t('This will reorder sequence of all brands based on alphabetical order (from A to Z).'), {
confirm_callback: function () {
self._rpc({
model: self.modelName,
method: 'reorder_sequence',
}).then(() => self.reload());
}
});
},
});
const BrandListView = ListView.extend({
config: _.extend({}, ListView.prototype.config, {
Controller: BrandListController,
}),
});
viewRegistry.add('dr_list_view_brand', BrandListView);
});

View File

@ -0,0 +1,16 @@
odoo.define('droggol_theme_common.settings', function (require) {
const BaseSettingController = require('base.settings').Controller;
const FormController = require('web.FormController');
BaseSettingController.include({
_onButtonClicked: function (ev) {
if (ev.data.attrs.name === 'dr_open_pwa_shortcuts' || ev.data.attrs.name === 'dr_open_theme_custom_modules') {
FormController.prototype._onButtonClicked.apply(this, arguments);
} else {
this._super.apply(this, arguments);
}
},
});
});

View File

@ -1,273 +0,0 @@
/** @odoo-module **/
import { WebsiteDialog } from '@website/components/dialog/dialog';
import { evaluateExpr } from "@web/core/py_js/py";
const { Component, useState, onWillStart, onWillUpdateProps, toRaw } = owl;
import { useService } from '@web/core/utils/hooks';
import { useCore } from '@droggol_theme_common/js/hooks';
import { _t } from 'web.core';
export class AbstractThemeOption extends Component {
setup() {
this.key = this.props.key;
onWillUpdateProps(nextProps => {
this.updateVal(nextProps);
});
}
updateVal (props) {
if (props.visibilityExpr) {
props['visibility'] = evaluateExpr(props.visibilityExpr, props.source)
}
this.env.updateConfigValue(this.key, props.value)
}
updateSource (value) {
this.env.updateSource(this.key, value)
}
}
export class ThemeOptionTitle extends AbstractThemeOption {}
ThemeOptionTitle.template = 'theme_config.ThemeOptionTitle';
export class ThemeOptionRadio extends AbstractThemeOption {}
ThemeOptionRadio.template = 'theme_config.ThemeOptionRadio';
export class ThemeOptionSelection extends AbstractThemeOption {}
ThemeOptionSelection.template = 'theme_config.Selection';
export class ThemeOptionCheckbox extends AbstractThemeOption {}
ThemeOptionCheckbox.template = 'theme_config.Checkbox';
export class ThemeOptionCardBtnCheckbox extends AbstractThemeOption {}
ThemeOptionCardBtnCheckbox.template = 'theme_config.BtnCheckbox';
export class ThemeOptionNumber extends AbstractThemeOption {}
ThemeOptionNumber.template = 'theme_config.Number';
export class ThemeOptionChar extends AbstractThemeOption {}
ThemeOptionChar.template = 'theme_config.Char';
export class ThemeOptionJson extends AbstractThemeOption {
setup() {
super.setup();
this.updatedValue = this.props.value;
this._coreProps = {
updateConfigValue: this.updateConfigValue.bind(this),
updateSource: this.updateSource.bind(this),
};
useCore({subMode: true});
}
prepareProps (self_props, sub_props) {
var props = sub_props || {};
props['visibility'] = true;
props['source'] = self_props.source[self_props.key];
if (props.visibilityExpr) {
props['visibility'] = evaluateExpr(props.visibilityExpr, props['source'])
}
props['value'] = props['source'][sub_props.key] || false;
return props;
}
updateConfigValue (key, value) {
var rawValue = toRaw(this.updatedValue);
rawValue[key] = value;
this.env.updateConfigValue(this.key, rawValue);
}
updateSource (key, value) {
this.props.source[this.key][key] = value;
this.env.updateSource(this.key, this.props.source[this.key]);
}
}
ThemeOptionJson.template = 'theme_config.JSON';
export class ThemeOptionBottomBar extends AbstractThemeOption {
setup() {
super.setup();
this.orm = useService("orm");
this.state = useState({
'actions': this.props.value
});
onWillStart(async () => {
this.allButtons = await this.orm.call('website', 'get_theme_prime_bottom_bar_action_buttons');
});
}
removeAction (action) {
const index = this.state.actions.indexOf(action);
this.state.actions.splice(index, 1);
this.updateSource(this.state.actions);
}
addAction (action) {
this.state.actions.push(action);
this.updateSource(this.state.actions);
}
}
ThemeOptionBottomBar.template = 'theme_config.BottomBar';
export class ThemeConfigDialog extends Component {
setup() {
this.orm = useService('orm');
this.website = useService('website');
this.title = this.env._t("Theme Configuration");
this.primaryTitle = this.env._t("Save");
this.size = 'md';
this.updatedValue = {};
this.source = useState({});
this._coreProps = {
updateConfigValue: this.updateConfigValue.bind(this),
updateSource: this.updateSource.bind(this)
};
onWillStart(async () => {
var source = await this.orm.call("website", "get_dr_theme_config", [this.website.currentWebsite.id]);
for (var key in source) {
this.source[key] = source[key];
}
});
useCore({});
}
async saveConfig() {
await this.orm.call("dr.theme.config", "save_config", [[], this.website.currentWebsite.id, this.updatedValue]);
window.location.reload();
}
get _tabInfo() {
return [{
name: 'general',
icon: 'fa fa-sliders',
label: _t('General'),
components: [
{ props: { title: _t('Search'), subtitle: _t('Tweak search behavior for your website.'), _classes: 'mt-0'}, componentRef: ThemeOptionTitle },
{ props: { key: 'json_product_search', components: [
{ props: { key: 'advance_search', label: _t('Enable advance search')}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'search_category', label: _t('Categories'), visibilityExpr: 'advance_search'}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'search_attribute', label: _t('Smart Autocomplete'), visibilityExpr: 'advance_search'}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'search_suggestion', label: _t('Smart Suggestion'), visibilityExpr: 'advance_search'}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'search_fuzzy', label: _t('Fuzzy search'), visibilityExpr: 'advance_search'}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'search_max_product', label: _t('Products limit'), tooltip: _("Max 5"), visibilityExpr: 'advance_search'}, componentRef: ThemeOptionNumber },
{ props: { key: 'search_limit', label: _t('Result Limit'), tooltip: _("Min 5 and Max 10"), visibilityExpr: 'advance_search'}, componentRef: ThemeOptionNumber },
]}, componentRef: ThemeOptionJson},
{ props: { key: 'cart_flow_title', title: _t('Cart Flow'), subtitle: _t('You can change how products are being added in cart.')}, key: 'cart_flow_title', componentRef: ThemeOptionTitle},
{ props: { key: 'cart_flow', selection: [['default', 'Default'], ['notification', 'Notification'], ['dialog', 'Dialog'], ['side_cart', 'Open Cart Sidebar']]}, componentRef: ThemeOptionRadio},
{ props: { key: 'brand_title', title: _t('Brand Page')}, componentRef: ThemeOptionTitle},
{ props: { key: 'json_brands_page', components: [
{ props: { key: 'disable_brands_grouping', label: _t('Disable grouping of brands')}, componentRef: ThemeOptionCheckbox }
]}, componentRef: ThemeOptionJson},
{ props: { key: 'lang_title', title: _t('Language/Pricelist Selector')}, componentRef: ThemeOptionTitle},
{ props: { key: 'json_general_language_pricelist_selector', components: [
{ props: { key: 'hide_country_flag', label: _t('Hide country flag')}, componentRef: ThemeOptionCheckbox }
]}, componentRef: ThemeOptionJson},
{ props: { title: _t('B2b Configuration'), subtitle: _t('Tweak your shop behavior.')}, componentRef: ThemeOptionTitle },
{ props: { key: 'json_b2b_shop_config', components: [{ props: { key: 'dr_enable_b2b', label: _t('B2B Mode'), tooltip: _("This option will hide product price for public users and don't allow them to place an order") }, componentRef: ThemeOptionCheckbox }, { props: { key: 'dr_only_assigned_pricelist', label: _t('Pricelist per customer'), tooltip: _("After enabling this option user will only see assigned pricelist to their contact record.") }, componentRef: ThemeOptionCheckbox }]}, componentRef: ThemeOptionJson},
]
}, {
name: 'shop',
icon: 'fa fa-shopping-cart',
label: _t('Shop'),
components: [
{ props: { title: _t('Shop'), subtitle: _t('Shop page main layout.'), _classes: 'mt-0' }, componentRef: ThemeOptionTitle },
{ props: { key: 'json_shop_layout', components: [
{ props: { key: 'layout', label: _t('Layout'), selection: [['prime', 'Prime'], ['default', 'Default']]}, componentRef: ThemeOptionSelection },
{ props: { key: 'show_view_switcher', label: _t('Show view switcher'), visibilityExpr: "layout == 'prime'"}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'default_view_mode', label: _t('Default view mode'), selection: [['grid', 'Grid'], ['list', 'List']], visibilityExpr: "layout == 'prime'"}, componentRef: ThemeOptionSelection },
{ props: { key: 'load_more_products', label: _t('Behavior of load more products'), selection: [['pager', 'Pager'], ['button', 'Load More Button'], ['scroll', 'Infinite Scroll']], visibilityExpr: "layout == 'prime'"}, componentRef: ThemeOptionSelection },
], visibilityKey: 'enable'}, componentRef: ThemeOptionJson},
{ props: { title: _t('Category Pills'), subtitle: _t('Show product category pills on top of the shop page.'), visibilityExpr: "json_shop_layout.layout == 'prime'"}, componentRef: ThemeOptionTitle },
{ props: { key: 'json_shop_category_pills', components: [
{ props: { key: 'active', label: _t('Enable category pills')}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'style', label: _t('Style'), selection: [['1', 'Card'], ['2', 'Text'], ['3', 'Image + Text'], ['4', 'Image + Text (Rounded)'], ['5', 'Image Only']], visibilityExpr: 'active'}, componentRef: ThemeOptionSelection },
{ props: { key: 'show_child_categories', label: _t('Show child categories pills of active category'), visibilityExpr: 'active'}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'hide_in_desktop', label: _t('Hide in desktop device'), visibilityExpr: 'active'}, componentRef: ThemeOptionCheckbox },
], visibilityExpr: "json_shop_layout.layout == 'prime'"}, componentRef: ThemeOptionJson},
{ props: { title: _t('Shop Filter'), subtitle: _t('Tweak filters behavior on shop.'), visibilityExpr: "json_shop_layout.layout == 'prime'"}, componentRef: ThemeOptionTitle },
{ props: { key: 'json_shop_filters', components: [
{ props: { key: 'lazy_method', label: _t('Apply filters with lazy method') }, componentRef: ThemeOptionCheckbox },
{ props: { key: 'filter_style', label: _t('Filter Style'), selection: [['1', 'Clean'], ['2', 'Underline'], ['3', 'Card'], ['4', 'Bordered'], ['5', 'Boxed']]}, componentRef: ThemeOptionSelection },
{ props: { key: 'show_in_sidebar', label: _t('Show filters in sidebar')}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'filter_position', label: _t('Filter Position'), selection: [['left', 'Left'], ['right', 'Right']], visibilityExpr: "show_in_sidebar == false"}, componentRef: ThemeOptionSelection },
{ props: { key: 'collapsible_category', label: _t('Collapsible category')}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'collapsible_attribute', label: _t('Collapsible attributes')}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'show_category_count', label: _t('Show category count')}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'show_attribute_count', label: _t('Show attribute count') }, componentRef: ThemeOptionCheckbox },
{ props: { key: 'hide_extra_attrib_value', label: _t('Hide extra attributes'), tooltip: _("Hide attribute value if it is not matched with any product") }, componentRef: ThemeOptionCheckbox },
{ props: { key: 'show_rating_filter', label: _t('Show rating filter'), tooltip: _("To show rating filter, First you have to activate customers 'Rating' option in product detail page.")}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'show_availability_filter', label: _t('Show availability filter'), tooltip: _("If you have large number of products this option may affect performance.")}, componentRef: ThemeOptionCheckbox },
], visibilityExpr: "json_shop_layout.layout == 'prime'"}, componentRef: ThemeOptionJson},
{ props: { title: _t('Product Card'), subtitle: _t('Configure actions and style of product card.'), visibilityExpr: "json_shop_layout.layout == 'prime'"}, componentRef: ThemeOptionTitle },
{ props: { key: 'json_shop_product_item', components: [
{ props: { key: 'style', label: _t('Style'), selection: [['1', 'Square'], ['2', 'Rounded']]}, componentRef: ThemeOptionSelection },
{ props: { key: 'image_size', label: _t('Image Size'), selection: [['default', 'Default (1/1)'], ['landscape', 'Landscape (4/3)'], ['portrait', 'Portrait (4/5)'], ['vertical', 'Vertical (2/3)']]}, componentRef: ThemeOptionSelection },
{ props: { key: 'image_fill', label: _t('Image Fill'), selection: [['contain', 'Contain'], ['cover', 'Cover'], ['fill', 'Fill']]}, componentRef: ThemeOptionSelection },
{ props: { title: _t('Product Card Actions'), subtitle: _t('Configure action buttons of product card in shop page.')}, componentRef: ThemeOptionTitle },
{ props: { key: 'show_add_to_cart', icon: 'fa fa-shopping-cart', label: _t('Show add to cart')}, componentRef: ThemeOptionCardBtnCheckbox },
{ props: { key: 'show_wishlist', icon: 'fa fa-heart', label: _t('Show wishlist')}, componentRef: ThemeOptionCardBtnCheckbox },
{ props: { key: 'show_compare', icon: 'fa fa-retweet', label: _t('Show compare')}, componentRef: ThemeOptionCardBtnCheckbox },
{ props: { key: 'show_quick_view', icon: 'fa fa-eye', label: _t('Show quick view')}, componentRef: ThemeOptionCardBtnCheckbox },
{ props: { key: 'show_similar_products', icon: 'fa fa-clone', label: _t('Show similar products')}, componentRef: ThemeOptionCardBtnCheckbox },
{ props: { key: 'show_product_preview_swatches', icon: 'fa fa-adjust', label: _t('Show product preview swatches')}, componentRef: ThemeOptionCardBtnCheckbox },
{ props: { key: 'show_rating', icon: 'fa fa-star', label: _t('Show rating'), tooltip: _("To show rating, First you have to activate customers 'Rating' option in product detail page.")}, componentRef: ThemeOptionCardBtnCheckbox },
{ props: { key: 'show_stock_label', icon: 'fa fa-tag', label: _t('Show stock label')}, componentRef: ThemeOptionCardBtnCheckbox },
], visibilityExpr: "json_shop_layout.layout == 'prime'"}, componentRef: ThemeOptionJson},
]
}, {
name: 'product_detail',
icon: 'fa fa-cube',
label: _t('Product Detail'),
components: [
{ props: { title: _t('Zoom Product Images'), subtitle: _t('Zoom product images in product detail page and quick view.'), _classes: 'mt-0' }, componentRef: ThemeOptionTitle },
{ props: { key: 'json_zoom', components: [
{ props: { key: 'zoom_enabled', label: _t('Enable zoom')}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'zoom_factor', label: _t('Zoom factor'), visibilityExpr: 'zoom_enabled'}, componentRef: ThemeOptionNumber },
], visibilityKey: 'zoom_enabled'}, componentRef: ThemeOptionJson},
{ props: { title: _t('Sticky Add to Cart'), subtitle: _t("Allows users to follow up product's Add to Cart button until bottom scroll reached."), }, componentRef: ThemeOptionTitle },
{ props: { key: 'bool_sticky_add_to_cart', 'label': _t('Enable sticky add to cart') }, componentRef: ThemeOptionCheckbox},
{ props: { title: _t('Product Offers'), subtitle: _t("You will be able to add offers on product and show details in dialog.")}, componentRef: ThemeOptionTitle },
{ props: { key: 'bool_product_offers', 'label': _t('Enable product offers') }, componentRef: ThemeOptionCheckbox},
{ props: { title: _t('General')}, componentRef: ThemeOptionTitle },
{ props: { key: 'bool_show_products_nav', 'label': _t('Product Navigation'), tooltip: _t("Shows button to see next, previous products based on product sequence.") }, componentRef: ThemeOptionCheckbox},
]
}, {
name: 'mobile',
icon: 'fa fa-mobile',
label: _t('Mobile'),
components: [
{ props: { title: _t('Sidebar'), subtitle: _t('You can change behaviour of sidebars.'), _classes: 'mt-0' }, componentRef: ThemeOptionTitle },
{ props: { key: 'json_sidebar_config', components: [
{ props: { key: 'category_sidebar_style', label: _t('Category sidebar style'), selection: [['1', 'Text'], ['2', 'Image + Text'], ['3', 'Cover']]}, componentRef: ThemeOptionSelection },
{ props: { key: 'category_sidebar_show_count', label: _t('Show product count in category sidebar') }, componentRef: ThemeOptionCheckbox },
{ props: { key: 'menu_sidebar_show_category', label: _t('Show category link in menu sidebar') }, componentRef: ThemeOptionCheckbox },
]}, componentRef: ThemeOptionJson},
{ props: { title: _t('Bottombar'), subtitle: _t("Bottom bar allow movement between primary destinations on the website.")}, componentRef: ThemeOptionTitle },
{ props: { key: 'json_bottom_bar', components: [
{ props: { key: 'show_bottom_bar', label: _t('Show Bottombar')}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'show_bottom_bar_on_scroll', label: _t('Show Bottombar On Scroll'), visibilityExpr: 'show_bottom_bar'}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'filters', label: _t('Show sort and filter button on shop'), visibilityExpr: 'show_bottom_bar'}, componentRef: ThemeOptionCheckbox },
{ props: { key: 'actions', label: _t('Buttombar Buttons'), visibilityExpr: 'show_bottom_bar'}, componentRef: ThemeOptionBottomBar },
], visibilityKey: 'show_bottom_bar'}, componentRef: ThemeOptionJson},
]
}
];}
prepareProps (props) {
props = props || {};
props['source'] = this.source;
props['visibility'] = true;
if (props.key) {
props['value'] = this.source[props.key] || false;
}
if (props.visibilityExpr) {
props['visibility'] = evaluateExpr(props.visibilityExpr, this.source)
}
return props;
}
updateConfigValue (key, value) {
this.updatedValue[key] = value;
}
updateSource (key, value) {
this.source[key] = value;
}
}
ThemeConfigDialog.template = 'droggol_theme_common.ThemeConfigDialog';
ThemeConfigDialog.components = { WebsiteDialog };

View File

@ -1,75 +0,0 @@
$tp-setting-color: #0080ff;
.tp_config_dialog {
border-radius: 16px;
.text-primary {
color: $tp-setting-color !important;
}
.bg-tpc-primary {
background-color: $tp-setting-color;
color: #fff;
}
.bg-tpc-primary-dark {
background-color: darken($tp-setting-color, 10%);
color: #fff;
}
.tp-cp {
cursor: pointer;
}
.pe-24 {
padding-right: 24px !important;
}
header {
h4, .btn-close{
display: none;
}
}
.tp-setting-tab{
font-weight: bold;
border-radius: 6px;
letter-spacing: 1px;
color: #000;
&.active {
background-color: rgba($tp-setting-color, 0.15);
color: $tp-setting-color;
}
}
.o_switch {
input + span {
padding-left: 4px;
padding-right: 2px;
width: 37px;
height: 21px;
background: #c1ccdd !important;
&:after {
margin-top: 1px;
display: inline-block;
}
}
input:checked + span {
background: #06bb72 !important;
// background: $tp-setting-color !important;
}
}
.tp-setting-bg {
background-color: #e7f1ff;
border-radius: 10px;
}
.form-check-input:checked {
background-color: $tp-setting-color;
border-color: $tp-setting-color;
}
.btn-outline-primary {
border-color: $tp-setting-color;
color: $tp-setting-color;
&:hover {
background-color: #c1ccdd;
}
}
.btn-check:checked + .btn-outline-primary {
background-color: $tp-setting-color;
border-color: $tp-setting-color;
}
}

View File

@ -1,181 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="droggol_theme_common.ThemeConfigDialog" owl="1">
<WebsiteDialog title="title" size="size" header="true" primaryTitle="primaryTitle" primaryClick="() => this.saveConfig()" close="props.close" contentClass="'tp_config_dialog'">
<t t-portal="'.tp_config_dialog header'">
<div class="row g-0">
<div class="col-3">
<img src="/droggol_theme_common/static/src/images/settings.png" class="img-fluid"/>
</div>
<div class="col-9">
<ul class="nav nav-pills mb-3 float-end mt-3" id="tp-settings-pills-tab" role="tablist">
<t t-foreach="_tabInfo" t-as="tabData" t-key="tabData.name">
<li class="nav-item" role="presentation">
<button t-attf-class="nav-link tp-setting-tab #{tabData_index == 0 ? 'active': ''}" id="pills-home-tab" data-bs-toggle="pill" t-attf-data-bs-target="#pills-#{tabData.name}" type="button" role="tab">
<i t-att-class="tabData.icon" /> <t t-esc="tabData.label"/>
</button>
</li>
</t>
</ul>
</div>
</div>
</t>
<t t-portal="'.tp_config_dialog footer'">
<a class="btn btn-link position-absolute end-0 me-2" href="https://prime-docs-v16-25092021.droggol.com/" target="_blank">
<i class="fa fa-book me-1"/> User Guide
</a>
</t>
<div class="row">
<div class="col-12">
<div class="tab-content" id="tp-settings-pills-tabContent">
<t t-foreach="_tabInfo" t-as="tabData" t-key="tabData.name">
<div t-attf-class="tab-pane #{tabData_index == 0 ? 'fade show active': ''} p-2" t-attf-id="pills-#{tabData.name}" role="tabpanel">
<t t-foreach="tabData.components" t-as="component_data" t-key="component_data_index">
<t t-component="component_data.componentRef" t-props="prepareProps(component_data.props)"/>
</t>
</div>
</t>
</div>
</div>
<!-- <div class="col-6">
<div class="p-2 h-100 tp-setting-bg">
asd
</div>
</div> -->
</div>
</WebsiteDialog>
</t>
<t t-name="theme_config.ThemeOptionTitle" owl="1">
<t t-if="props.visibility">
<h5 t-attf-class="mb-0 text-primary tp-config-title #{props._classes or 'mt-5'}">
<t t-esc="props.title"/>
</h5>
<p t-if="props.subtitle" class="text-muted mt-1 mb-2">
<t t-esc="props.subtitle"/>
</p>
</t>
</t>
<t t-name="theme_config.ThemeOptionRadio" owl="1">
<div t-att-invisible="!props.visibility">
<div class="form-check">
<input class="form-check-input" name="key" type="radio" id="default" value="default" t-model="props.source[key]"/>
<label class="form-check-label" t-attf-for="default">
Default
</label>
</div>
<div class="form-check">
<input class="form-check-input" name="key" type="radio" id="notification" value="notification" t-model="props.source[key]"/>
<label class="form-check-label" t-attf-for="notification">
Notification
</label>
</div>
<div class="form-check">
<input class="form-check-input" name="key" type="radio" id="dialog" value="dialog" t-model="props.source[key]"/>
<label class="form-check-label" t-attf-for="dialog">
Dialog
</label>
</div>
<div class="form-check">
<input class="form-check-input" name="key" type="radio" id="side_cart" value="side_cart" t-model="props.source[key]"/>
<label class="form-check-label" t-attf-for="side_cart">
Open Cart Sidebar
</label>
</div>
</div>
<!-- <t t-foreach="props.selection" t-as="opt" t-key="opt[0]">
<t t-esc="props.source[key]" />
<div class="form-check">
<input class="form-check-input" t-att-name="key" type="radio" t-att-id="opt[0]" t-att-value="opt[0]" t-model="props.source[key]"/>
<label class="form-check-label" t-attf-for="opt[0]">
<t t-esc="opt[1]"/>
</label>
</div>
</t> -->
</t>
<t t-name="theme_config.Selection" owl="1">
<div t-attf-class="row mb-2 #{props._classes or ''}" t-att-expr="props.visibilityExpr" t-if="props.visibility">
<div class="col-6 col-lg-5">
<strong t-esc="props.label"/>
<i t-if="props.tooltip" class="fa fa-info-circle ms-2" t-att-title="props.tooltip"/>
</div>
<div class="col-6 col-lg-7">
<label class="mb-0 d-inline-block" t-att-for="key">
<select t-model="props.source[key]" class="form-select form-select-sm">
<t t-foreach="props.selection" t-as="item" t-key="item_index">
<option t-att-value="item[0]">
<t t-esc="item[1]"/>
</option>
</t>
</select>
</label>
<small t-if="note" class="d-block"><t t-esc="props.note"/></small>
</div>
</div>
</t>
<t t-name="theme_config.Checkbox" t-inherit="theme_config.Selection" t-inherit-mode="primary" owl="1">
<xpath expr="//label" position="replace">
<label class="o_switch mb-0 o_switch_danger_success w-25">
<input type="checkbox" t-model="props.source[key]"/>
<span> </span>
</label>
</xpath>
</t>
<t t-name="theme_config.Number" t-inherit="theme_config.Selection" t-inherit-mode="primary" owl="1">
<xpath expr="//div[hasclass('col-lg-7')]" position="replace">
<div class="col-6 col-lg-3">
<input type="number" class="form-control form-control-sm" t-att-id="props.key" t-model.number="props.source[key]"/>
<small t-if="note" class="d-block"> <t t-esc="props.note"/></small>
</div>
</xpath>
</t>
<t t-name="theme_config.Char" t-inherit="theme_config.Selection" t-inherit-mode="primary" owl="1">
<xpath expr="//div[hasclass('col-lg-7')]" position="replace">
<div class="col-6 col-lg-3">
<input type="text" class="form-control form-control-sm" t-att-id="props.key" t-model="props.source[key]"/>
<small t-if="note" class="d-block"> <t t-esc="props.note"/></small>
</div>
</xpath>
</t>
<t t-name="theme_config.JSON" owl="1">
<t t-if="props.visibility">
<t t-foreach="props.components" t-as="sub_component_data" t-key="sub_component_data_index">
<t t-component="sub_component_data.componentRef" t-props="prepareProps(props, sub_component_data.props)"/>
</t>
</t>
</t>
<t t-name="theme_config.BottomBar" t-inherit="theme_config.Selection" t-inherit-mode="primary" owl="1">
<xpath expr="//label" position="replace">
<div class="border border-1 p-2 pb-0 rounded">
<t t-foreach="state.actions" t-as="action" t-key="action">
<span class="badge bg-tpc-primary d-inline-block p-2 pe-24 mx-1 position-relative overflow-hidden">
<t t-out="allButtons[action].name"/>
<i class="fa fa-times position-absolute top-0 end-0 bg-tpc-primary-dark h-100 px-2 py-2 tp-cp" t-on-click="() => this.removeAction(action)"/>
</span>
</t>
</div>
<div>
<t t-foreach="allButtons" t-as="button" t-key="button">
<span t-if="!state.actions.includes(button)" class="badge bg-300 d-inline-block p-2 px-3 mx-1 mt-1 tp-cp position-relative" t-on-click="() => this.addAction(button)">
<i class="fa fa-plus" /> <t t-out="allButtons[button].name"/>
</span>
</t>
</div>
</xpath>
</t>
<t t-name="theme_config.BtnCheckbox" owl="1">
<input type="checkbox" class="btn-check" t-att-id="key" autocomplete="off" t-model="props.source[key]"/>
<label class="btn btn-outline-primary me-2" t-att-for="key" t-att-title="props.tooltip || props.label"><i t-att-class="props.icon or 'fa fa-users'"/> </label>
</t>
</templates>

View File

@ -1,21 +0,0 @@
/** @odoo-module **/
import { useComponent, useChildSubEnv} from "@odoo/owl";
// We add here a custom hook
function extendUseCore(cc, newCore, subMode) {
if (!subMode) {
const currentCore = Object.create(cc.env);
const newCoreDescriptors = Object.getOwnPropertyDescriptors(newCore);
cc.env = Object.freeze(Object.defineProperties(currentCore, newCoreDescriptors));
}
useChildSubEnv(newCore)
}
export function useCore({core = false, subMode = false}) {
const cc = useComponent();
core = core || cc._coreProps;
if (core) {
extendUseCore(cc, core, subMode)
}
}

View File

@ -1,10 +0,0 @@
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { ThemeConfigDialog } from '../components/theme_config';
registry.category('website_custom_menus').add('droggol_theme_common.menu_theme_prime_config', {
Component: ThemeConfigDialog,
isDisplayed: (env) => !!env.services.website.currentWebsite
&& env.services.website.isDesigner
});

View File

@ -1,56 +1,56 @@
//------------------------------------------------------------------------------
// Variants
//------------------------------------------------------------------------------
.dr-attribute-info-btn {
display: none;
}
.dr-attribute-item {
.dr-value-item {
&.circle {
padding: 0;
height: 38px;
width: 38px;
line-height: 38px;
text-align: center;
border-radius: 50%;
}
&.square {
padding: 6px 12px;
border-radius: $border-radius;
}
&.circle, &.square {
background-color: o-color('white');
border: 1px solid o-color('300');
transition: 0.2s;
font-weight: $font-weight-normal;
cursor: pointer;
&:hover {
border-color: o-color('primary');
color: o-color('primary');
.dr-variant {
.radio_input_value {
margin-right: 0.4rem;
.dr-variant-item {
&.circle {
padding: 0;
height: 38px;
width: 38px;
line-height: 38px;
text-align: center;
border-radius: 50%;
}
}
&.image {
margin-right: 0.4rem;
border-width: 0;
transition: 0.2s;
cursor: pointer;
box-shadow: 0px 0px 0px 2px o-color('300');
&:hover {
box-shadow: 0px 0px 0px 2px o-color('primary');
&.square {
padding: 6px 12px;
border-radius: $border-radius;
}
img {
padding: 2px;
object-fit: contain;
height: 40px;
width: 40px;
&.circle, &.square {
background-color: o-color('white');
border: 1px solid o-color('300');
transition: 0.2s;
font-weight: $font-weight-normal;
cursor: pointer;
@include hover {
border-color: o-color('primary');
color: o-color('primary');
}
}
&.image {
margin-right: 0.4rem;
border-width: 0;
transition: 0.2s;
cursor: pointer;
box-shadow: 0px 0px 0px 2px o-color('300');
@include hover {
box-shadow: 0px 0px 0px 2px o-color('primary');
}
img {
padding: 2px;
object-fit: contain;
height: 40px;
width: 40px;
}
}
}
}
input:checked ~ .radio_input_value .dr-value-item {
input:checked ~ .radio_input_value .dr-variant-item {
&.circle, &.square {
background-color: o-color('primary');
border-color: o-color('primary');
color: color-contrast(o-color('primary'));
color: color-yiq(o-color('primary'));
}
&.image {
box-shadow: 0px 0px 0px 2px o-color('primary');

View File

@ -1,11 +0,0 @@
.s_mega_menu_prime_3 .s_badge {
margin: 0;
margin-left: 0.4rem;
padding: 0.4em 0.6em;
font-size: 0.66rem;
border-radius: 3px;
padding-top: 5px;
i {
margin-right: 0.3rem;
}
}

View File

@ -1,7 +0,0 @@
.s_mega_menu_prime_6 .tp-banner-block {
min-height: 400px;
.tp-banner-text {
@include o-position-absolute($right: 18px, $bottom: 20px, $left: 18px);
padding: 1rem;
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-extend="ListView.buttons" t-name="BrandListView.buttons">
<t t-jquery="button.o_list_button_add" t-operation="after">
<button type="button" class="btn btn-secondary o_button_reorder">
Reorder Sequence
</button>
</t>
</t>
</templates>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="assets_frontend" inherit_id="website.assets_frontend">
<xpath expr="//link[last()]" position="after">
<link rel="stylesheet" type="text/scss" href="/droggol_theme_common/static/src/scss/variants.scss"/>
</xpath>
</template>
<template id="assets_backend" inherit_id="web.assets_backend">
<xpath expr="//script[last()]" position="after">
<script type="text/javascript" src="/droggol_theme_common/static/src/js/backend/list_view_brand.js"/>
<script type="text/javascript" src="/droggol_theme_common/static/src/js/backend/res_config_settings.js"/>
</xpath>
</template>
<template id="assets_backend_inherit_sale" inherit_id="sale.assets_backend_inherit_sale">
<xpath expr="link[last()]" position="after">
<link rel="stylesheet" type="text/scss" href="/droggol_theme_common/static/src/scss/variants.scss"/>
</xpath>
</template>
</odoo>

View File

@ -1,18 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="dr_category_label_view_form" model="ir.ui.view">
<field name="name">dr.product.public.category.label.view.form</field>
<field name="model">dr.product.public.category.label</field>
<field name="arch" type="xml">
<form string="Label">
<sheet>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" type="object" name="action_open_category" icon="fa-bars" attrs="{'invisible': [('category_count', '=', 0)]}">
<field string="Categories" name="category_count" widget="statinfo"/>
</button>
</div>
<div class="oe_title">
<label for="name"/>
<h1><field name="name"/></h1>
</div>
<group>
<group>
<field name="color"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="dr_category_label_view_tree" model="ir.ui.view">
<field name="name">dr.product.public.category.label.view.tree</field>
<field name="model">dr.product.public.category.label</field>
<field name="arch" type="xml">
<tree string="Labels" editable="bottom">
<tree string="Labels">
<field name="name"/>
<field name="background_color" widget="color"/>
<field name="text_color" widget="color"/>
<field name="color"/>
</tree>
</field>
</record>
<record id="dr_category_label_view_search" model="ir.ui.view">
<field name="name">dr.product.public.category.label.view.search</field>
<field name="model">dr.product.public.category.label</field>
<field name="arch" type="xml">
<search string="Labels">
<field name="name"/>
<field name="color"/>
<group>
<filter string="Color" name="color" domain="" context="{'group_by': 'color'}"/>
</group>
</search>
</field>
</record>
<record id="dr_category_label_action" model="ir.actions.act_window">
<field name="name">Category Labels</field>
<field name="type">ir.actions.act_window</field>
@ -20,6 +58,6 @@
<field name="view_mode">tree,form</field>
</record>
<menuitem id="menu_dr_category_label" action="dr_category_label_action" parent="website_sale.menu_catalog" sequence="5"/>
<menuitem id="menu_dr_category_lable" action="dr_category_label_action" parent="website_sale.menu_product_settings" sequence="5"/>
</odoo>

View File

@ -21,11 +21,4 @@
<menuitem id="dr_theme_config_menu" name="Droggol Theme Config" action="dr_theme_config_action" parent="base.menu_ir_property"/>
<menuitem id="menu_theme_prime_config"
parent="website.menu_site"
sequence="21"
name="Theme Prime Configuration"
action="website.website_preview"
/>
</odoo>

View File

@ -1,88 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="dr_website_content_view_form" model="ir.ui.view">
<field name="name">dr.website.content.view.form</field>
<field name="model">dr.website.content</field>
<field name="arch" type="xml">
<form string="Content">
<sheet>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" type="object" name="open_design_page" icon="fa-paint-brush">
<div class="o_stat_info">
<span class="o_stat_value">
Design
</span>
<span class="o_stat_text">
Content
</span>
</div>
</button>
</div>
<div class="oe_title">
<label for="name"/>
<h1>
<field name="name"/>
</h1>
</div>
<group>
<group>
<field name="content_type" widget="radio" attrs="{'readonly': [('id', '!=', False)]}"/>
<field name="identifier" groups="base.group_no_one"/>
<field name="description" attrs="{'invisible': [('content_type', 'in', ['tab', 'attribute_popup'])]}"/>
<field name="icon" attrs="{'invisible': [('content_type', 'in', ['attribute_popup'])]}"/>
</group>
</group>
<p attrs="{'invisible': [('content_type', 'in', ['attribute_popup'])]}">You can find icon at <a href="https://fontawesome.com/v4.7.0/icons/" target="_blank">FontAwesome</a>.</p>
<notebook>
<page name="tab_products" string="Products" attrs="{'invisible': [('content_type', 'in', ['offer_popup', 'attribute_popup'])]}">
<field name="dr_tab_products_ids" />
</page>
<page name="offer_products" string="Products" attrs="{'invisible': [('content_type', 'in', ['tab', 'attribute_popup'])]}">
<field name="dr_offer_products_ids" />
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="dr_website_content_view_tree" model="ir.ui.view">
<field name="name">dr.website.content.view.tree</field>
<field name="model">dr.website.content</field>
<field name="arch" type="xml">
<tree string="Content">
<field name="sequence" widget="handle"/>
<field name="content_type" widget="badge" decoration-info="content_type == 'tab'" decoration-success="content_type == 'offer_popup'" decoration-warning="content_type == 'attribute_popup'"/>
<field name="name"/>
</tree>
</field>
</record>
<record id="dr_website_content_view_search" model="ir.ui.view">
<field name="name">dr.website.content.view.search</field>
<field name="model">dr.website.content</field>
<field name="arch" type="xml">
<search string="Content">
<field name="name"/>
<field name="content_type"/>
<group expand="0" string="Group By">
<filter string="Content Type" name="group_by_content_type" domain="[]" context="{'group_by': 'content_type'}"/>
</group>
</search>
</field>
</record>
<record id="dr_website_content_action" model="ir.actions.act_window">
<field name="name">Contents</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">dr.website.content</field>
<field name="view_mode">tree,form</field>
<field name="context">{'search_default_group_by_content_type': True}</field>
</record>
<menuitem id="menu_dr_website_content"
action="dr_website_content_action"
parent="website_sale.menu_catalog" sequence="5"/>
</odoo>

View File

@ -1,18 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="dr_website_menu_label_view_form" model="ir.ui.view">
<field name="name">dr.website.menu.label.view.form</field>
<field name="model">dr.website.menu.label</field>
<field name="arch" type="xml">
<form string="Label">
<sheet>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" type="object" name="action_open_menus" icon="fa-bars" attrs="{'invisible': [('menu_count', '=', 0)]}">
<field string="Menus" name="menu_count" widget="statinfo"/>
</button>
</div>
<div class="oe_title">
<label for="name"/>
<h1>
<field name="name"/>
</h1>
</div>
<group>
<group>
<field name="color"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="dr_website_menu_label_view_tree" model="ir.ui.view">
<field name="name">dr.website.menu.label.view.tree</field>
<field name="model">dr.website.menu.label</field>
<field name="arch" type="xml">
<tree string="Labels" editable="bottom">
<tree string="Labels">
<field name="name"/>
<field name="background_color" widget="color"/>
<field name="text_color" widget="color"/>
<field name="color"/>
</tree>
</field>
</record>
<record id="dr_website_menu_label_view_search" model="ir.ui.view">
<field name="name">dr.website.menu.label.view.search</field>
<field name="model">dr.website.menu.label</field>
<field name="arch" type="xml">
<search string="Labels">
<field name="name"/>
<field name="color"/>
<group>
<filter string="Color" name="color" domain="" context="{'group_by': 'color'}"/>
</group>
</search>
</field>
</record>
<record id="dr_website_menu_label_action" model="ir.actions.act_window">
<field name="name">Menu Labels</field>
<field name="type">ir.actions.act_window</field>
@ -21,10 +61,10 @@
</record>
<menuitem name="Menu Labels"
id="menu_dr_website_menu_label"
action="dr_website_menu_label_action"
parent="website.menu_website_global_configuration"
sequence="46"
groups="base.group_no_one"/>
id="menu_dr_website_menu_label"
action="dr_website_menu_label_action"
parent="website.menu_website_global_configuration"
sequence="46"
groups="base.group_no_one"/>
</odoo>

View File

@ -4,43 +4,27 @@
<record id="product_attribute_view_form_inherit_droggol_theme_common" model="ir.ui.view">
<field name="name">product.attribute.view.form.inherit</field>
<field name="model">product.attribute</field>
<field name="inherit_id" ref="website_sale.product_attribute_view_form"/>
<field name="inherit_id" ref="product.product_attribute_view_form"/>
<field name="arch" type="xml">
<field name="visibility" position="replace"/>
<page name="attribute_values" position="after">
<page name="ecommerce" string="eCommerce">
<group class="o_label_nowrap">
<group>
<field name="visibility" string="eCommerce Filter Visibility" widget="radio"/>
<field name="dr_is_brand"/>
<field name="dr_is_show_shop_search"/>
<field name="dr_attribute_popup_id" context="{'default_content_type': 'attribute_popup'}"/>
<field name="dr_search_suggestion"/>
</group>
<group>
<field name="dr_radio_image_style" widget="radio" attrs="{'invisible': [('display_type', '!=', 'radio_image')]}"/>
</group>
</group>
</page>
</page>
<field name="create_variant" position="after">
<field name="dr_is_hide_shop_filter"/>
<field name="dr_is_show_shop_search"/>
</field>
<xpath expr="//field[@name='value_ids']/tree/field[last()]" position="after">
<field name="dr_brand_description" attrs="{'column_invisible': [('parent.dr_is_brand', '=', False)]}"/>
<field name="dr_image" attrs="{'column_invisible': [('parent.display_type', '!=', 'radio_image')]}" widget="image" class="oe_avatar"/>
</xpath>
<xpath expr="//field[@name='value_ids']/tree/field[@name='is_custom']" position="attributes">
<attribute name="attrs">{'column_invisible': [('parent.dr_is_brand', '=', True)]}</attribute>
<field name="dr_image" attrs="{'column_invisible': [('parent.display_type', '!=', 'radio_image')]}" widget="image"/>
</xpath>
</field>
</record>
<record id="product_template_attribute_value_inherit_droggol_theme_common" model="ir.ui.view">
<record id="product_template_attribute_value_view_form_inherit_droggol_theme_common" model="ir.ui.view">
<field name="name">product.template.attribute.value.view.form.inherit</field>
<field name="model">product.template.attribute.value</field>
<field name="inherit_id" ref="product.product_template_attribute_value_view_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='html_color']" position="after">
<field name="dr_thumb_image" widget="image" nolabele="1" attrs="{'invisible': [('display_type', '!=', 'color')]}" class="oe_avatar float-start"/>
</xpath>
<field name="html_color" position="after">
<field name="dr_image" widget="image" attrs="{'invisible': [('display_type', '!=', 'radio_image')]}"/>
</field>
</field>
</record>
</odoo>

View File

@ -1,68 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="dr_product_brand_values_view_form" model="ir.ui.view">
<field name="name">product.attribute.value.view.form</field>
<field name="model">product.attribute.value</field>
<record id="dr_product_brand_view_form" model="ir.ui.view">
<field name="name">dr.product.brand.view.form</field>
<field name="model">dr.product.brand</field>
<field name="arch" type="xml">
<form string="Brand" create="false">
<form string="Brand">
<sheet>
<field name="dr_image" widget="image" class="oe_avatar"/>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" type="object" name="action_open_products" icon="fa-cubes" attrs="{'invisible': [('product_count', '=', 0)]}">
<field string="Products" name="product_count" widget="statinfo"/>
</button>
</div>
<field name="image" widget="image" class="oe_avatar"/>
<div class="oe_title">
<label for="name" string="Name"/>
<label for="name"/>
<h1>
<field name="name"/>
</h1>
</div>
<group>
<group>
<field name="dr_brand_description"/>
<field name="description" widget="text"/>
</group>
<group>
<field name="website_id"/>
<field name="active" invisible="1"/>
</group>
</group>
<notebook>
<page name="products" string="Products">
<field name="product_ids" string="Products" mode="kanban" options="{'create_text':'Add a Product'}" context="{'default_dr_brand_id': active_id, 'default_website_id': website_id}"/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="dr_product_brand_values_view_tree" model="ir.ui.view">
<field name="name">product.attribute.value.view.tree</field>
<field name="model">product.attribute.value</field>
<record id="dr_product_brand_view_tree" model="ir.ui.view">
<field name="name">dr.product.brand.view.tree</field>
<field name="model">dr.product.brand</field>
<field name="arch" type="xml">
<tree string="Brands" expand="1" create="0">
<tree string="Brands" js_class="dr_list_view_brand">
<field name="sequence" widget="handle"/>
<field name="name" string="Name"/>
<field name="attribute_id" invisible="1"/>
<groupby name="attribute_id">
<button name="open_create_brand_value" string="Add New Brand" type="object" class=""/>
</groupby>
<field name="name"/>
<field name="description"/>
<field name="website_id"/>
</tree>
</field>
</record>
<record id="dr_product_brand_values_view_search" model="ir.ui.view">
<field name="name">product.attribute.value.view.search</field>
<field name="model">product.attribute.value</field>
<record id="dr_product_brand_view_kanban" model="ir.ui.view">
<field name="name">dr.product.brand.view.kanban</field>
<field name="model">dr.product.brand</field>
<field name="arch" type="xml">
<search string="Brands">
<kanban>
<field name="id"/>
<field name="name"/>
<group expand="0" string="Group By">
<filter string="Attributes" name="group_by_attributes" domain="[]" context="{'group_by': 'attribute_id'}"/>
<field name="description"/>
<field name="product_count"/>
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_card oe_kanban_global_click">
<div class="o_kanban_image mr-3">
<img t-att-src="kanban_image('dr.product.brand', 'image', record.id.raw_value)" alt="Product" class="o_image_64_contain"/>
</div>
<div class="oe_kanban_details">
<h4 class="mb-0">
<field name="name"/>
</h4>
<p class="mb-2" t-esc="record.description.value"/>
<h6 t-if="record.product_count.value > 0" class="rounded-pill d-inline-block border py-2 px-3 mb-0" t-attf-title="#{record.product_count.value} product(s) in this brand.">
<i class="fa fa-cubes" aria-label="Products"/> <span t-esc="record.product_count.value"/>
</h6>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record id="dr_product_brand_view_search" model="ir.ui.view">
<field name="name">dr.product.brand.view.search</field>
<field name="model">dr.product.brand</field>
<field name="arch" type="xml">
<search string="Product Brand">
<field name="name"/>
<field name="description"/>
<field name="website_id"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<group>
<filter string="Website" name="website" domain="" context="{'group_by':'website_id'}"/>
</group>
</search>
</field>
</record>
<record id="dr_product_brand_values_action" model="ir.actions.act_window">
<record id="dr_product_brand_action" model="ir.actions.act_window">
<field name="name">Brands</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.attribute.value</field>
<field name="view_mode">tree,form</field>
<field name="domain" eval="[('attribute_id.dr_is_brand', '=', True)]"/>
<field name="context">{'search_default_group_by_attributes': True}</field>
<field name="res_model">dr.product.brand</field>
<field name="view_mode">tree,kanban,form</field>
</record>
<menuitem id="menu_dr_product_brand_values"
action="dr_product_brand_values_action"
parent="website_sale.menu_catalog" sequence="5"/>
<menuitem id="menu_dr_product_brand"
action="dr_product_brand_action"
parent="website_sale.menu_product_settings" sequence="4"/>
</odoo>

View File

@ -6,23 +6,10 @@
<field name="model">product.public.category</field>
<field name="inherit_id" ref="website_sale.product_public_category_form_view"/>
<field name="arch" type="xml">
<div class="oe_left" position="after">
<notebook>
<page name="theme_prime" string="Theme Prime">
<group>
<group>
<field name="dr_category_label_id"/>
<field name="dr_search_formulate" groups="base.group_no_one"/>
</group>
<group>
<field name="dr_category_cover_image" class="oe_avatar" widget="image"/>
<field name="dr_category_icon" class="oe_avatar" widget="image"/>
<field name="dr_category_sidebar_cover" class="oe_avatar" widget="image"/>
</group>
</group>
</page>
</notebook>
</div>
<xpath expr="//field[@name='website_id']" position="after">
<field name="dr_category_label_id"></field>
<field name="dr_category_cover_image"></field>
</xpath>
</field>
</record>

View File

@ -12,7 +12,6 @@
<field string="Products" name="product_count" widget="statinfo"/>
</button>
</div>
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
<div class="oe_title">
<label for="name"/>
<h1>
@ -21,14 +20,16 @@
</div>
<group>
<group>
<field name="background_color" widget="color"/>
<field name="text_color" widget="color"/>
</group>
<group>
<field name="color"/>
<field name="style"/>
<field name="active" invisible="1"/>
</group>
</group>
<notebook>
<page name="products" string="Products">
<field name="product_ids" string="Products" mode="kanban" options="{'create_text':'Add a Product'}" context="{'default_dr_label_id': active_id}"/>
</page>
</notebook>
</sheet>
</form>
</field>
@ -40,8 +41,7 @@
<field name="arch" type="xml">
<tree string="Labels">
<field name="name"/>
<field name="background_color" widget="color"/>
<field name="text_color" widget="color"/>
<field name="color"/>
<field name="style"/>
</tree>
</field>
@ -53,8 +53,11 @@
<field name="arch" type="xml">
<search string="Labels">
<field name="name"/>
<field name="color"/>
<field name="style"/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<group>
<filter string="Color" name="color" domain="" context="{'group_by':'color'}"/>
<filter string="Style" name="style" domain="" context="{'group_by':'style'}"/>
</group>
</search>
@ -70,6 +73,6 @@
<menuitem id="menu_dr_product_label"
action="dr_product_label_action"
parent="website_sale.menu_catalog" sequence="5"/>
parent="website_sale.menu_product_settings" sequence="5"/>
</odoo>

View File

@ -6,21 +6,21 @@
<field name="model">product.pricelist.item</field>
<field name="inherit_id" ref="product.product_pricelist_item_form_view"/>
<field name="arch" type="xml">
<group name="pricelist_rule_limits" position="inside">
<field name="dr_offer_msg" attrs="{'invisible': ['|', ('date_end', '=', False), ('applied_on', '=', '0_product_variant')], 'required': [('date_end', '!=', False)]}"/>
<field name="dr_offer_finish_msg" attrs="{'invisible': ['|', ('date_end', '=', False), ('applied_on', '=', '0_product_variant')], 'required': [('date_end', '!=', False)]}"/>
</group>
<xpath expr="//field[@name='date_end']" position="after">
<field name="dr_offer_msg" attrs="{'invisible': [('date_end', '=', False)], 'required': [('date_end', '!=', False)]}"/>
<field name="dr_offer_finish_msg" attrs="{'invisible': [('date_end', '=', False)], 'required': [('date_end', '!=', False)]}"/>
</xpath>
</field>
</record>
<record id="website_sale_pricelist_form_view_inherit_droggol_theme_common" model="ir.ui.view">
<record id="product_pricelist_view_inherit_droggol_theme_common" model="ir.ui.view">
<field name="name">product.pricelist.form.inherit.droggol.theme.common</field>
<field name="model">product.pricelist</field>
<field name="inherit_id" ref="website_sale.website_sale_pricelist_form_view"/>
<field name="inherit_id" ref="product.product_pricelist_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='item_ids']/tree/field[@name='date_end']" position="after">
<field name="dr_offer_msg" optional="hide" attrs="{'invisible': [('date_end', '=', False)], 'required': [('date_end', '!=', False)]}"/>
<field name="dr_offer_finish_msg" optional="hide" attrs="{'invisible': [('date_end', '=', False)], 'required': [('date_end', '!=', False)]}"/>
<field name="dr_offer_msg" attrs="{'invisible': [('date_end', '=', False)], 'required': [('date_end', '!=', False)]}"/>
<field name="dr_offer_finish_msg" attrs="{'invisible': [('date_end', '=', False)], 'required': [('date_end', '!=', False)]}"/>
</xpath>
</field>
</record>

View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="dr_product_tags_view_form" model="ir.ui.view">
<field name="name">dr.product.tags.view.form</field>
<field name="model">dr.product.tags</field>
<field name="arch" type="xml">
<form string="Tag">
<sheet>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" type="object" name="action_open_products" icon="fa-cubes" attrs="{'invisible': [('product_count', '=', 0)]}">
<field string="Products" name="product_count" widget="statinfo"/>
</button>
</div>
<div class="oe_title">
<label for="name"/>
<h1>
<field name="name"/>
</h1>
</div>
<group>
<group>
<field name="website_id"/>
<field name="active" invisible="1"/>
</group>
</group>
<notebook>
<page name="products" string="Products">
<field name="product_ids" string="Products" mode="kanban" options="{'create_text':'Add a Product'}" context="{'default_dr_label_id': active_id, 'default_website_id': website_id}"/>
</page>
<page name="tabs" string="Products Tabs">
<div class="alert alert-info" role="alert">
Below tabs will appear on products having tag.
</div>
<field name="dr_tab_ids">
<tree string="Tabs">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="icon"/>
</tree>
<form>
<sheet>
<div class="oe_title">
<label for="name"/>
<h1>
<field name="name"/>
</h1>
</div>
<group>
<group>
<field name="icon"/>
</group>
</group>
<notebook>
<page name="content" string="Content">
<field name="content"/>
</page>
</notebook>
</sheet>
</form>
</field>
<div colspan="2" class="text-center">You can find icon at <a href="https://fontawesome.com/v4.7.0/icons/" target="_blank">FontAwesome</a>.</div>
</page>
<page name="offers" string="Products Offers">
<div class="alert alert-info" role="alert">
Below offers will appear on products having tag.
</div>
<field name="dr_offer_ids">
<tree string="Offers" editable="bottom">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="description"/>
<field name="icon"/>
</tree>
<form>
<sheet>
<div class="oe_title">
<label for="name"/>
<h1>
<field name="name"/>
</h1>
</div>
<group>
<group>
<field name="icon"/>
</group>
</group>
<notebook>
<page name="dialog_content" string="Dialog Content">
<field name="dialog_content"/>
</page>
</notebook>
</sheet>
</form>
</field>
<div colspan="2" class="text-center">You can find icon at <a href="https://fontawesome.com/v4.7.0/icons/" target="_blank">FontAwesome</a>.
</div>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="dr_product_tags_view_tree" model="ir.ui.view">
<field name="name">dr.product.tags.view.tree</field>
<field name="model">dr.product.tags</field>
<field name="arch" type="xml">
<tree string="Tags">
<field name="name"/>
<field name="website_id"/>
</tree>
</field>
</record>
<record id="dr_product_tags_view_search" model="ir.ui.view">
<field name="name">dr.product.tags.view.search</field>
<field name="model">dr.product.tags</field>
<field name="arch" type="xml">
<search string="Tags">
<field name="name"/>
<field name="website_id"/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<group>
<filter string="Website" name="website" domain="" context="{'group_by':'website_id'}"/>
</group>
</search>
</field>
</record>
<record id="dr_product_tags_action" model="ir.actions.act_window">
<field name="name">Tags</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">dr.product.tags</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="menu_dr_product_tags"
action="dr_product_tags_action"
parent="website_sale.menu_product_settings" sequence="6"/>
</odoo>

View File

@ -6,39 +6,87 @@
<field name="model">product.template</field>
<field name="inherit_id" ref="website_sale.product_template_form_view"/>
<field name="arch" type="xml">
<page name="sales" position="after">
<page name="theme_prime" string="Theme Prime">
<group>
<group name="default">
<field name="dr_label_id"/>
<field name="dr_product_tab_ids" widget="many2many_tags" context="{'default_content_type': 'tab'}" domain="[('content_type', '=', 'tab')]"/>
<field name="dr_product_offer_ids" widget="many2many_tags" context="{'default_content_type': 'offer_popup'}" domain="[('content_type', '=', 'offer_popup')]"/>
<field name="dr_document_ids" widget="many2many_binary"/>
</group>
</group>
</page>
</page>
</field>
</record>
<xpath expr="//group[@name='shop']" position="inside">
<group string="Theme Prime Configuration">
<field name="dr_brand_id" context="{'default_website_id': website_id}" domain="[('website_id', 'in', (False, website_id))]"/>
<field name="dr_label_id"/>
<field name="dr_tag_ids" widget="many2many_tags" context="{'default_website_id': website_id}" domain="[('website_id', 'in', (False, website_id))]"/>
</group>
</xpath>
<xpath expr="//group[@name='shop']" position="after">
<group string="Theme Prime Tabs and Offers">
<field name="dr_tab_ids">
<tree string="Tabs" editable="bottom">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="icon"/>
</tree>
<form>
<sheet>
<div class="oe_title">
<label for="name"/>
<h1>
<field name="name"/>
</h1>
</div>
<group>
<group>
<field name="icon"/>
</group>
</group>
<notebook>
<page name="content" string="Content">
<field name="content"/>
</page>
</notebook>
</sheet>
</form>
</field>
<record id="product_template_only_form_view" model="ir.ui.view">
<field name="name">product.template.only.form.inherit.droggol.theme.common</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_only_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='attribute_line_ids']/tree/field[@name='value_ids']" position="after">
<field name="dr_attribute_popup_id" context="{'default_content_type': 'attribute_popup'}" optional="show"/>
<field name="dr_offer_ids">
<tree string="Offers" editable="bottom">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="description"/>
<field name="icon"/>
</tree>
<form>
<sheet>
<div class="oe_title">
<label for="name"/>
<h1>
<field name="name"/>
</h1>
</div>
<group>
<group>
<field name="icon"/>
</group>
</group>
<notebook>
<page name="dialog_content" string="Dialog Content">
<field name="dialog_content"/>
</page>
</notebook>
</sheet>
</form>
</field>
<div colspan="2" class="text-center">You can find icon at <a href="https://fontawesome.com/v4.7.0/icons/" target="_blank">FontAwesome</a>.</div>
</group>
</xpath>
</field>
</record>
<record id="product_template_view_tree_inherit_droggol_theme_common" model="ir.ui.view">
<record id="product_template_view_tree_inherit_droggol_theme_common" model="ir.ui.view" >
<field name="name">product.template.view.tree.inherit.droggol.theme.common</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="website_sale.product_template_view_tree"/>
<field name="arch" type="xml">
<field name="website_id" position="after">
<field name="dr_label_id" options="{'no_create': True, 'no_open': True}" optional="hide"/>
<field name="dr_brand_id" options="{'no_create': True, 'no_open': True}" optional="hide"/>
<field name="dr_tag_ids" widget="many2many_tags" options="{'no_create': True, 'no_open': True}" optional="hide"/>
</field>
</field>
</record>

View File

@ -4,26 +4,14 @@
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.droggol.theme.common</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="website_sale.res_config_settings_view_form"/>
<field name="inherit_id" ref="website.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='action_website_create_new']" position="after">
<button name="dr_open_theme_custom_modules" type="object" string="Theme Customizations" class="col-auto btn-info ms-2 text-nowrap" style="line-height: 0.5;" icon="fa-cog" noSaveDialog="true" attrs="{'invisible': [('dr_has_custom_module', '=', False)]}"/>
<xpath expr="//button[@name='install_theme_on_current_website']" position="after">
<button name="dr_open_theme_custom_modules" type="object" string="Theme Customizations" class="ml-2 btn-info"
icon="fa-cog" attrs="{'invisible': [('dr_has_custom_module', '=', False)]}"/>
<field name="dr_has_custom_module" invisible="1"/>
</xpath>
<div id="sale_product_catalog_settings" position="inside">
<div class="col-12 col-lg-6 o_setting_box" id="discount_sale_order_lines" title="Apply manual discounts on sales order lines or display discounts computed from pricelists (option to activate in the pricelist configuration).">
<div class="o_setting_left_pane">
<field name="group_discount_per_so_line"/>
</div>
<div class="o_setting_right_pane">
<label for="group_discount_per_so_line"/>
<div class="text-muted">
Grant discounts on sales order lines
</div>
</div>
</div>
</div>
<div id="sale_product_catalog_settings" position="after">
<div id="webmaster_settings" position="after">
<h2>Progressive Web Apps (PWA)</h2>
<div class="row mt16 o_settings_container" id="pwa_settings">
<div class="col-12 o_setting_box">
@ -41,6 +29,7 @@
<div class="col-12 col-lg-6 o_setting_box" id="dr_pwa_name_setting" attrs="{'invisible': [('dr_pwa_activated', '=', False)]}">
<div class="o_setting_right_pane">
<label string="Name" for="dr_pwa_name"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Used in the app install prompt.
</div>
@ -50,6 +39,7 @@
<div class="col-12 col-lg-6 o_setting_box" id="dr_pwa_short_name_setting" attrs="{'invisible': [('dr_pwa_activated', '=', False)]}">
<div class="o_setting_right_pane">
<label string="Short Name" for="dr_pwa_short_name"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Used on the user's home screen, launcher, or other places.
</div>
@ -59,6 +49,7 @@
<div class="col-12 col-lg-6 o_setting_box" id="dr_pwa_background_color_setting" attrs="{'invisible': [('dr_pwa_activated', '=', False)]}">
<div class="o_setting_right_pane">
<label string="Background Color" for="dr_pwa_background_color"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Used on the splash screen when the application is first launched.
</div>
@ -68,6 +59,7 @@
<div class="col-12 col-lg-6 o_setting_box" id="dr_pwa_theme_color_setting" attrs="{'invisible': [('dr_pwa_activated', '=', False)]}">
<div class="o_setting_right_pane">
<label string="Theme Color" for="dr_pwa_theme_color"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Used on toolbar, and may be in the app's preview in task switchers.
</div>
@ -77,6 +69,7 @@
<div class="col-12 col-lg-6 o_setting_box" id="dr_pwa_icon_192_setting" attrs="{'invisible': [('dr_pwa_activated', '=', False)]}">
<div class="o_setting_right_pane">
<label string="Icon (192x192)" for="dr_pwa_icon_192"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
These icons are used in places like the home screen, app launcher, task switcher, splash screen, etc.
</div>
@ -86,6 +79,7 @@
<div class="col-12 col-lg-6 o_setting_box" id="dr_pwa_icon_512_setting" attrs="{'invisible': [('dr_pwa_activated', '=', False)]}">
<div class="o_setting_right_pane">
<label string="Icon (512x512)" for="dr_pwa_icon_512"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
These icons are used in places like the home screen, app launcher, task switcher, splash screen, etc.
</div>
@ -95,6 +89,7 @@
<div class="col-12 col-lg-6 o_setting_box" id="dr_pwa_start_url_setting" attrs="{'invisible': [('dr_pwa_activated', '=', False)]}">
<div class="o_setting_right_pane">
<label string="Start URL" for="dr_pwa_start_url"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Your application will start from this URL when it is launched.
</div>
@ -104,11 +99,12 @@
<div class="col-12 col-lg-6 o_setting_box" id="dr_pwa_shortcuts_setting" attrs="{'invisible': [('dr_pwa_activated', '=', False)]}">
<div class="o_setting_right_pane">
<label string="App Shortcuts" for="dr_pwa_shortcuts"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
App shortcuts help users quickly start common or recommended tasks within your web app.
</div>
<field name="dr_pwa_shortcuts" invisible="1"/>
<button name="dr_open_pwa_shortcuts" noSaveDialog="true" icon="fa-cogs me-1" type="object" string="Configure Shortcuts" class="btn-link"/>
<button name="dr_open_pwa_shortcuts" icon="fa-cogs mr-1" type="object" string="Configure Shortcuts" class="btn-link"/>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="dr_pwa_offline_page_setting" attrs="{'invisible': [('dr_pwa_activated', '=', False)]}">
@ -117,6 +113,7 @@
</div>
<div class="o_setting_right_pane">
<label string="Enable Offline Page" for="dr_pwa_offline_page"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Show offline page when there is no internet.
</div>

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--
Due to wrong placemenent odoo test case we need to enable few menus
Sale root menu is mandatory to test product configurator test case.
See: https://github.com/odoo/odoo/blob/15.0/addons/sale_product_configurator/static/tests/tours/product_configurator_advanced_ui.js#L12
-->
<record id="sale.sale_menu_root" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.menu_sale_quotations" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="view_website_sale_website_form" model="ir.ui.view">
<field name="name">website_sale.website.form</field>
<field name="model">website</field>
<field name="inherit_id" ref="website_sale.view_website_sale_website_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='shop_extra_field_ids']/tree" position="inside">
<field name="dr_label"/>
</xpath>
</field>
</record>
</odoo>

View File

@ -1,27 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="website_menus_form_view_inherit_droggol_theme_common" model="ir.ui.view">
<field name="name">website.menu.view.form.inherit</field>
<field name="model">website.menu</field>
<field name="inherit_id" ref="website.website_menus_form_view"/>
<field name="arch" type="xml">
<field name="is_mega_menu" position="after">
<field name="dr_menu_label_id"/>
<field name="dr_highlight_menu"/>
</field>
</field>
</record>
<record id="menu_tree_inherit_droggol_theme_common" model="ir.ui.view">
<field name="name">website.menu.tree.inherit.droggol.theme.common</field>
<field name="model">website.menu</field>
<field name="inherit_id" ref="website.menu_tree"/>
<field name="arch" type="xml">
<field name="url" position="after">
<xpath expr="//field[@name='url']" position="after">
<field name="dr_menu_label_id"/>
<field name="dr_highlight_menu"/>
</field>
</xpath>
</field>
</record>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--
============================================================================
Variants
============================================================================
-->
<template id="variants" inherit_id="sale.variants">
<xpath expr="//ul/t/li" position="inside">
<t t-if="ptal.attribute_id.display_type in ['radio_circle', 'radio_square', 'radio_image']">
<ul t-att-data-attribute_id="ptal.attribute_id.id" t-attf-class="list-unstyled d-flex flex-wrap align-items-start dr-variant #{'d-none' if single_and_custom else ''}">
<t t-foreach="ptal.product_template_value_ids._only_active()" t-as="ptav">
<li class="form-group js_attribute_value" style="margin: 0;">
<label>
<div>
<input type="radio"
t-attf-class="js_variant_change radio_input d-none #{ptal.attribute_id.create_variant}"
t-att-checked="ptav in combination"
t-att-name="'ptal-%s' % ptal.id"
t-att-value="ptav.id"
t-att-data-value_id="ptav.id"
t-att-data-value_name="ptav.name"
t-att-data-attribute_name="ptav.attribute_id.name"
t-att-data-is_custom="ptav.is_custom"
t-att-data-is_single_and_custom="single_and_custom" />
<div class="radio_input_value d-flex flex-column align-items-center">
<div t-if="not ptal.attribute_id.display_type == 'radio_image'" t-attf-class="dr-variant-item font-weight-normal #{ptal.attribute_id.display_type == 'radio_circle' and 'circle' or 'square'}" t-field="ptav.name"/>
<div t-else="" class="dr-variant-item image" t-att-title="ptav.name" t-field="ptav.dr_image" t-options="{'widget': 'image'}"/>
<span class="badge badge-pill badge-primary mt-1" t-if="ptav.price_extra">
<t t-esc="ptav.price_extra > 0 and '+' or '-'"/>
<span t-esc="abs(ptav.price_extra)" class="variant_price_extra" style="white-space: nowrap;"
t-options='{
"widget": "monetary",
"from_currency": product.currency_id,
"display_currency": (pricelist or product).currency_id
}'/>
</span>
</div>
</div>
</label>
</li>
</t>
</ul>
</t>
</xpath>
</template>
</odoo>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="frontend_layout" name="Droggol Frontend Layout" inherit_id="web.frontend_layout">
<xpath expr="//head/script" position="after">
<script type="text/javascript">
odoo.dr_theme_config = <t t-raw="json.dumps(request.env['ir.http'].get_dr_theme_config())"/>;
</script>
</xpath>
</template>
<template id="theme_config_page_menu" inherit_id="website.user_navbar">
<xpath expr="//a[@data-action='ace']" position="after">
<a t-if="website._get_dr_theme_config('theme_installed')" data-action="open-theme-prime-config-dialog" href="#" id="tp_prime_config" class="dropdown-item">
<span>Theme Prime Configurations</span>
</a>
</xpath>
</template>
</odoo>

View File

@ -1,513 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="s_mega_menu_prime_1" name="Prime - 1" groups="base.group_user">
<section class="s_mega_menu_prime_1 bg-white p-3 p-lg-4">
<div class="container">
<div class="row g-0 s_nb_column_fixed">
<div class="col-12 col-lg-6">
<div class="row g-0 s_col_no_bgcolor s_nb_column_fixed">
<div class="col-12 col-lg-6">
<h6>
Career
</h6>
<nav class="nav flex-column mb-4">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Listing</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Opening</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Overview</a>
</nav>
<h6>
Company
</h6>
<nav class="nav flex-column mb-4 mb-lg-0">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">About</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Pricing</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Terms</a>
</nav>
</div>
<div class="col-12 col-lg-6">
<h6>
Help center
</h6>
<nav class="nav flex-column mb-4">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Overview</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Article</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Search</a>
</nav>
<h6>
Contact
</h6>
<nav class="nav flex-column mb-4 mb-lg-0">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Basic</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Cover</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Search</a>
</nav>
</div>
</div>
</div>
<div class="col-12 col-lg-6">
<div class="row g-0">
<div class="col-12 col-lg-6">
<h6>
Blog
</h6>
<nav class="nav flex-column mb-4 mb-lg-0">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Rich View</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Article</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Showcase</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Search</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Rich</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Article</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Showcase</a>
</nav>
</div>
<div class="col-12 col-lg-6">
<h6>
Portfolio
</h6>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Masonry</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Grid Rows</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Parallax</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Case Study</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Sidebar</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Sidebar: Fluid</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Basic Grid</a>
</nav>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<template id="s_mega_menu_prime_2" name="Prime - 2" groups="base.group_user">
<section class="s_mega_menu_prime_2 bg-white">
<div class="container">
<div class="row s_nb_column_fixed p-3 p-lg-4">
<div class="col-lg-3 py-3">
<h6 class="mb-1">
Clothing
</h6>
<div class="s_hr pt8 pb8" data-name="Separator">
<hr class="w-25 me-auto border-primary"/>
</div>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Aenean</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Dapibus</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Proin</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Duis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Quisque</a>
</nav>
</div>
<div class="col-lg-3 py-3">
<h6 class="mb-1">
Shoes
</h6>
<div class="s_hr pt8 pb8" data-name="Separator">
<hr class="w-25 me-auto border-primary"/>
</div>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Proin lobortis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Aenean</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Vivamus</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Donec ultrices</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Etiam</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nullam sed</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Donec non</a>
</nav>
</div>
<div class="col-lg-3 py-3">
<h6 class="mb-1">
Bags
</h6>
<div class="s_hr pt8 pb8" data-name="Separator">
<hr class="w-25 me-auto border-primary"/>
</div>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nulla vehicula</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Proin eu</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Quisque</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Proin lobortis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Duis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Quisque</a>
</nav>
</div>
<div class="col-lg-3 py-3">
<h6 class="mb-1">
Accessories
</h6>
<div class="s_hr pt8 pb8" data-name="Separator">
<hr class="w-25 me-auto border-primary"/>
</div>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nullam mattis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nullam</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Duis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nulla vehicula</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Proin eu</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Quisque</a>
</nav>
</div>
</div>
</div>
<section class="s_parallax parallax s_parallax_is_fixed pt32 pb32 oe_img_bg o_bg_img_center" data-scroll-background-ratio="0" data-snippet="s_parallax" data-name="Parallax" style="background-image: url('/web/image/theme_prime.s_mega_menu_prime_2_1'); background-position: 50% 0;">
<div class="oe_structure oe_empty">
<section class="s_heading_3 pt32 pb32">
<div class="container pt32 pb32">
<div class="row justify-content-center s_nb_column_fixed">
<div class="col-12 col-lg-8 text-center">
<h2 class="mt-3">Want to explore our products?</h2>
<p class="lead">
See all the products at once.
</p>
<a href="#" class="btn btn-primary mt-4">View all products</a>
</div>
</div>
</div>
</section>
</div>
</section>
</section>
</template>
<template id="s_mega_menu_prime_3" name="Prime - 3" groups="base.group_user">
<section class="s_mega_menu_prime_3 bg-white">
<div class="container">
<div class="row s_nb_column_fixed">
<div class="col-12 col-lg-3 py-3">
<h6 class="mb-1">
Clothing
</h6>
<div class="s_hr pt8 pb8" data-name="Separator">
<hr class="w-25 me-auto border-primary"/>
</div>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Aenean</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Dapibus</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Proin <span class="s_badge badge text-bg-primary"><i class="fa fa-tag"></i>New</span></a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Duis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Aenean <span class="s_badge badge text-bg-warning"><i class="fa fa-star"></i>Sale</span></a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Vivamus</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Duis</a>
</nav>
</div>
<div class="col-12 col-lg-3 py-3">
<h6 class="mb-1">
Shoes
</h6>
<div class="s_hr pt8 pb8" data-name="Separator">
<hr class="w-25 me-auto border-primary"/>
</div>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nullam mattis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nullam <span class="s_badge badge text-bg-warning"><i class="fa fa-magic"></i>Popular</span></a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Duis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nulla vehicula</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Proin eu</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Quisque</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Proin <span class="s_badge badge text-bg-primary"><i class="fa fa-star"></i>New</span></a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nullam</a>
</nav>
</div>
<div class="col-12 col-lg-3 py-3">
<h6 class="mb-1">
Accessories
</h6>
<div class="s_hr pt8 pb8" data-name="Separator">
<hr class="w-25 me-auto border-primary"/>
</div>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Proin lobortis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Aenean <span class="s_badge badge text-bg-primary"><i class="fa fa-star"></i>Sale</span></a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Vivamus</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Donec ultrices</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Etiam</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nullam sed</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Donec non</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nullam mattis <span class="s_badge badge text-bg-success"><i class="fa fa-magic"></i>Exclusive</span></a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Aenean</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Vivamus</a>
</nav>
</div>
<div class="col-12 col-lg-3 py-3">
<div class="s_shop_offer_4">
<div class="position-relative">
<img src="/web/image/theme_prime.s_mega_menu_prime_3_1" class="img img-fluid" alt="Shop Offer Image 01"/>
<div class="tp-banner-text text-center w-100">
<h3>Newly Launched</h3>
<h5>Limited Collection</h5>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="s_clients_3 container pt8 pb8 tp-editor-bg-color-n-shadow" data-name="Clients">
<div class="row s_nb_column_fixed">
<div t-foreach="list(range(1, 7))" t-as="number" class="col-12 col-md-4 col-lg-2 tp-client-box">
<t t-set="number" t-value="'%02d' % number"/>
<div class="p-4 text-center">
<img class="img img-fluid tp-client-image" t-attf-src="/web/image/theme_prime.s_client_#{number}" t-attf-alt="Client Image #{number}"/>
</div>
</div>
</div>
</div>
</section>
</template>
<template id="s_mega_menu_prime_4" name="Prime - 4" groups="base.group_user">
<section class="s_mega_menu_prime_4 bg-white">
<div class="container px-0">
<div class="row s_nb_column_fixed">
<div class="col-12 col-lg-6">
<section class="s_parallax parallax s_parallax_is_fixed pt64 pb64 oe_img_bg o_bg_img_center" data-scroll-background-ratio="0" data-snippet="s_parallax" data-name="Parallax" style="background-image: url('/web/image/theme_prime.s_mega_menu_prime_4_1'); background-position: 50% 0;">
<div class="oe_structure oe_empty">
<section class="s_heading_3 pt32 pb32">
<div class="container pt32 pb32">
<div class="row justify-content-center s_nb_column_fixed">
<div class="col-12 col-lg-8 text-center">
<h2 class="mt-3">Want to explore our products?</h2>
<p class="lead">
See all the products at once.
</p>
<a href="#" class="btn btn-primary mt-4">View all products</a>
</div>
</div>
</div>
</section>
</div>
</section>
</div>
<div class="col-12 col-lg-6">
<div class="row g-0 p-4">
<div class="col-12 col-lg-4 py-2">
<h6 class="mb-1">
Clothing
</h6>
<div class="s_hr pt8 pb8" data-name="Separator">
<hr class="w-25 me-auto border-primary"/>
</div>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Aenean</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Dapibus</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Proin</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Duis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Aenean</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Vivamus</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Duis</a>
</nav>
</div>
<div class="col-12 col-lg-4 py-2">
<h6 class="mb-1">
Shoes
</h6>
<div class="s_hr pt8 pb8" data-name="Separator">
<hr class="w-25 me-auto border-primary"/>
</div>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nullam mattis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nullam</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Duis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nulla vehicula</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Proin eu</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Quisque</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Proin</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Morbi vel</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nullam</a>
</nav>
</div>
<div class="col-12 col-lg-4 py-2">
<h6 class="mb-1">
Accessories
</h6>
<div class="s_hr pt8 pb8" data-name="Separator">
<hr class="w-25 me-auto border-primary"/>
</div>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Proin lobortis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Aenean</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Vivamus</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Donec ultrices</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Etiam</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nullam sed</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Donec non</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Nullam mattis</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Aenean</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Vivamus</a>
</nav>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<template id="s_mega_menu_prime_5" name="Prime - 5" groups="base.group_user">
<section class="s_mega_menu_prime_5 bg-white">
<div class="container">
<div class="row">
<t t-set="titles" t-value="['Watches', 'Tablets', 'Gaming', 'Laptops']"/>
<div class="col-12 col-md-6 col-lg-3 pt24 pb24" t-foreach="titles" t-as="title">
<div class="card border-0">
<a class="d-block tp-animation-scale" href="#">
<img class="img img-fluid rounded" t-attf-src="/web/image/theme_prime.s_mega_menu_prime_5_#{title_index + 1}" t-attf-alt="Mega Menu Image 0#{title}"/>
</a>
<div class="card-body">
<h5 t-out="title"/>
<nav class="nav flex-column tp-list-arrow">
<a href="#" class="nav-link py-1" data-name="Menu Item">Proin lobortis</a>
<a href="#" class="nav-link py-1" data-name="Menu Item">Aenean</a>
<a href="#" class="nav-link py-1" data-name="Menu Item">Vivamus</a>
<a href="#" class="nav-link py-1" data-name="Menu Item">Donec ultrices</a>
<a href="#" class="nav-link py-1" data-name="Menu Item">Etiam</a>
<a href="#" class="nav-link py-1" data-name="Menu Item">Nullam sed</a>
<a href="#" class="nav-link py-1" data-name="Menu Item">Donec non</a>
<a href="#" class="nav-link py-1" data-name="Menu Item">Nullam mattis</a>
</nav>
</div>
</div>
</div>
</div>
</div>
</section>
<t t-call="theme_prime.s_icon_block_12"/>
</template>
<template id="s_mega_menu_prime_6" name="Prime - 6" groups="base.group_user">
<section class="s_mega_menu_prime_6 bg-white">
<div class="container">
<div class="row">
<div class="col-12 pt24 pb24 col-lg-3">
<div class="position-relative tp-banner-block oe_img_bg tp-editor-bg-image" style="background-image: url('/web/image/theme_prime.s_mega_menu_prime_6_1');">
<div class="tp-banner-text text-center tp-editor-bg-color-n-shadow bg-white-85">
<h6><span style="font-weight: bolder;">Starting at $30</span></h6>
<a href="/shop" class="btn btn-primary btn-sm">Shop Now</a>
</div>
</div>
</div>
<div class="col-12 pt24 pb24 col-lg-6">
<div class="row">
<div class="col-12 col-lg-4 mb-4">
<h6 class="mb-1">Clothing</h6>
<div class="s_hr pt8 pb8" data-name="Separator">
<hr class="w-25 me-auto border-primary"/>
</div>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">New in</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Coats &amp; Jackets</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Jeans</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Dresses</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Shorts</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Skirts</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Donec non</a>
</nav>
</div>
<div class="col-12 col-lg-4 mb-4">
<h6 class="mb-1">Shoes</h6>
<div class="s_hr pt8 pb8" data-name="Separator">
<hr class="w-25 me-auto border-primary"/>
</div>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Boots</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Flats</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Heels</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Donec ultrices</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Sandals</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Slippers</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Socks</a>
</nav>
</div>
<div class="col-12 col-lg-4 mb-4">
<h6 class="mb-1">Accessories</h6>
<div class="s_hr pt8 pb8" data-name="Separator">
<hr class="w-25 me-auto border-primary"/>
</div>
<nav class="nav flex-column">
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Bags &amp; Purses</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Aenean</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Vivamus</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Scarves &amp; Hats</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Etiam</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Jewelry</a>
<a href="#" class="nav-link px-0 py-1" data-name="Menu Item">Donec non</a>
</nav>
</div>
<div class="col-12 mt-3">
<img class="img img-fluid" src="/web/image/theme_prime.s_mega_menu_prime_6_2" alt="Mega Menu Image 01"/>
</div>
</div>
</div>
<div class="col-12 pt24 pb24 col-lg-3">
<div class="position-relative tp-banner-block oe_img_bg tp-editor-bg-image" style="background-image: url('/web/image/theme_prime.s_mega_menu_prime_6_3');">
<div class="tp-banner-text text-center tp-editor-bg-color-n-shadow bg-white-85">
<h6><span style="font-weight: bolder;">Starting at $40</span></h6>
<a href="/shop" class="btn btn-primary btn-sm">Shop Now</a>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<!-- Mega Menu -->
<template id="s_tp_mega_menu_category_snippet" name="Categories Listing" groups="base.group_user">
<section contenteditable="false" class="s_tp_mega_menu_category_snippet tp-mega-menu-snippet tp-droggol-dynamic-snippet bg-white pt32 pb32" data-tp-snippet-id="s_tp_mega_menu_category_snippet">
<div class="container s_tp_mega_menu_category_snippet_wrapper">
<div class="alert alert-primary w-50 mx-auto text-center" role="alert">
<span class="tp-config-link fw-bold tp-cursor-pointer">Click Here!</span> to configure snippet.
</div>
</div>
</section>
</template>
<template id="s_category_mega_menu_snippet" name="Categories Grids" groups="base.group_user">
<section contenteditable="false" class="tp-droggol-dynamic-snippet tp-mega-menu-snippet bg-white s_category_snippet_wrapper pt64 pb64 " data-tp-snippet-id="s_category_snippet">
<div class="container s_category_snippet dr_not_editable">
<div class="alert alert-primary w-50 mx-auto text-center" role="alert">
<span class="tp-config-link fw-bold tp-cursor-pointer">Click Here!</span> to configure snippet.
</div>
</div>
</section>
</template>
<template id="s_mega_menu_category_tabs_snippet" name="Categories Tabs" groups="base.group_user">
<section contenteditable="false" class="tp-droggol-dynamic-snippet bg-white tp-mega-menu-snippet s_category_tabs_snippet_wrapper" data-tp-snippet-id="s_mega_menu_category_tabs_snippet">
<div class="container-fluid p-0 s_category_tabs_snippet">
<div class="alert alert-primary w-50 mx-auto text-center" role="alert">
<span class="tp-config-link fw-bold tp-cursor-pointer">Click Here!</span> to configure snippet.
</div>
</div>
</section>
</template>
<!-- Assets -->
<record id="droggol_theme_common.s_mega_menu_prime_3_000_scss" model="ir.asset">
<field name="name">Mega Menu Prime 3 000 SCSS</field>
<field name="bundle">web.assets_frontend</field>
<field name="path">droggol_theme_common/static/src/snippets/s_mega_menu_prime_3/000.scss</field>
</record>
<record id="droggol_theme_common.s_mega_menu_prime_6_000_scss" model="ir.asset">
<field name="name">Mega Menu Prime 6 000 SCSS</field>
<field name="bundle">web.assets_frontend</field>
<field name="path">droggol_theme_common/static/src/snippets/s_mega_menu_prime_6/000.scss</field>
</record>
</odoo>

View File

@ -1,80 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--
============================================================================
Theme Configuration
============================================================================
-->
<template id="frontend_layout" name="Droggol Frontend Layout" inherit_id="web.frontend_layout">
<xpath expr="//head/script[@id='web.layout.odooscript']" position="after">
<script type="text/javascript">
odoo.dr_theme_config = <t t-out="json.dumps(request.website.get_dr_theme_config())"/>;
</script>
</xpath>
</template>
<!--
============================================================================
Variants
============================================================================
-->
<template id="variants" inherit_id="sale.variants">
<xpath expr="//strong[hasclass('attribute_name')]" position="replace">
<div class="d-flex align-items-center mb-2">
<h6 t-field="ptal.attribute_id.name" class="attribute_name mb-0 pb-0"/>
<t t-set="dr_attribute_popup_id" t-value="ptal.dr_attribute_popup_id or ptal.attribute_id.dr_attribute_popup_id"/>
<a t-if="dr_attribute_popup_id" class="dr-attribute-instruction-btn tp-lazy-dialog link-primary ms-4" style="display: none;" href="#" data-res-model="dr.website.content" t-att-data-res-id="dr_attribute_popup_id.id" data-field="content">
<span t-field="dr_attribute_popup_id.name"/> <i class="fa fa-angle-right"/>
</a>
</div>
</xpath>
<xpath expr="//ul/t/li" position="inside">
<t t-if="ptal.attribute_id.display_type in ['radio_circle', 'radio_square', 'radio_image']">
<ul t-att-data-attribute_id="ptal.attribute_id.id" t-attf-class="list-inline dr-attribute-item o_wsale_product_attribute #{'d-none' if single_and_custom else ''}">
<t t-foreach="ptal.product_template_value_ids._only_active()" t-as="ptav">
<li class="list-inline-item me-1">
<label>
<div>
<input type="radio"
t-attf-class="js_variant_change radio_input d-none #{ptal.attribute_id.create_variant}"
t-att-checked="ptav in combination"
t-att-name="'ptal-%s' % ptal.id"
t-att-value="ptav.id"
t-att-data-value_id="ptav.id"
t-att-data-value_name="ptav.name"
t-att-data-attribute_name="ptav.attribute_id.name"
t-att-data-is_custom="ptav.is_custom"
t-att-data-is_single="single"
t-att-data-is_single_and_custom="single_and_custom" />
<div class="radio_input_value d-flex flex-column align-items-center me-0">
<div t-if="not ptal.attribute_id.display_type == 'radio_image'" t-attf-class="dr-value-item fw-normal #{ptal.attribute_id.display_type == 'radio_circle' and 'circle' or 'square'}" t-field="ptav.name"/>
<div t-else="" class="dr-value-item image" t-att-title="ptav.name" t-field="ptav.dr_image" t-options="{'widget': 'image'}"/>
<t t-call="sale.badge_extra_price"/>
</div>
</div>
</label>
</li>
</t>
</ul>
</t>
</xpath>
<xpath expr="//t[contains(@t-if, 'color')]//label" position="attributes">
<attribute name="t-attf-style">#{'background-image: url(/web/image/product.template.attribute.value/%s/dr_thumb_image); background-size: cover;' % ptav.id if ptav.dr_thumb_image else 'background-color:%s' % (ptav.html_color or ptav.product_attribute_value_id.name if not ptav.is_custom else '')}</attribute>
</xpath>
</template>
<!--
============================================================================
Design Page
============================================================================
-->
<template id="design_content" name="Design Content">
<t t-call="website.layout">
<div id="wrap">
<div t-field="content.content"/>
</div>
</t>
</template>
</odoo>

View File

@ -1,30 +1,99 @@
## [16.0.0.0.7] - 02/02/2023
### Fixed
- Cart lines issue when loyalty installed
<!-- # Changelog
## [16.0.0.0.5] - 07/01/2023
### Improved
- Apply color for mobile menu same as header which containing logo
## [14.0.0.3.7]
- [FIX] make 404 page dropable and make svg images not editable
## [16.0.0.0.4] - 27/12/2022
### Fixed
- Don't cache user info in header
## [14.0.0.3.6]
- [FIX] tax inc/exc subtotal cart
- [FIX] submit no variant based on new code
## [16.0.0.0.3] - 26/12/2022
### Fixed
- Highlight active menu in menu sidebar
## [14.0.0.3.5]
- [FIX] Resequence brand correctly
## [16.0.0.0.2] - 22/12/2022
### Fixed
- Fix product color preview swatches
## [14.0.0.3.4]
- [FIX] Trigger click event properly to handle add to cart
## [16.0.0.0.1] - 20/12/2022
### Added
- User Guide links
## [14.0.0.3.3]
- [FIX] fix search issue due to last release (performance improvements count)
### Fixed
- Open Sidebar for public user
## [14.0.0.3.2]
- [IMP] performance improvements count
## [16.0.0.0.0]
### Added
- Initial release.
## [14.0.0.3.1]
- [FIX] fix issue of form builder in custom product tabs
## [14.0.0.3.0]
- [New] Added a search on all brands page.
- [New] Added new card styles in dynamic brands snippet
- [New] Added option to ajax load products in shop page on button click.
- [New] Make dynamic brands snippet more informative now snippet will able to display product count, brand name etc.
- [Updated] Fetch only brands that are having products in brands page as well as in dynamic brands snippet
- [Updated] Allow to move blocks in "Info Block - 6" snippet
- [FIX] Minor bug fixes and improvements.
## [14.0.0.2.2]
- [FIX] Fix traceback while editing some snippets with border style.
## [14.0.0.2.1]
- [FIX] make HTML fields translatable
## [14.0.0.2]
- [New] Added a new snippet to attach documents.
- [New] Added configuration options for price slider.
- [New] SEO improvements.
- [Updated] Top category snippet improvements.
- [Updated] Better product form view usability.
- [Updated] Make rule builder multi website compatible
- [Updated] Improved product search.
- [Updated] Improved blog snippet.
- [Fixed] Minor bug fixes and improvements.
## [14.0.0.1.5]
- [Fixed] Recent view grid size break on some resolution devices.
## [14.0.0.1.4]
- [Fixed] Show tooltip for color attribute.
## [14.0.0.1.3]
- [Fixed] Pricelist offer timer should consider time.
## [14.0.0.1.2]
- [New] Added option lazy load product snippet.
- [New] Added new style-5 in categories snippet.
- [Updated] SEO improvements.
- [Fixed] Fixed header not render properly in firefox.
## [14.0.0.1.1]
- [Update] Restore blog snippet
## [14.0.0.1]
- [New] Added option to list bestseller products.
- [New] Added option to list discounted products.
- [New] Added rules templates in advance product selector.
- [New] Added option to show offers popup on product page.
- [New] Show offers popups on product page based on tags.
- [New] Revamped portal with elegant new UI.
- [New] Added new cover snippet.
- [New] Added new styles for shop categories pills.
- [New] Add options to show similar products from snippet cards style 3 and 6.
- [New] Add options to show similar products from shop page.
- [New] Added option to hide pre header.
- [New] Added option hide flags from the language selector.
- [New] Allow product mass edit for label, brand, tag.
- [New] Allow dynamic snippets in custom product tabs.
- [New] Added new hotspot style.
- [New] Show image swatches in the shop filters.
- [New] Added option to hide unmatched filters.
- [New] Added brands filter styles in shop.
- [New] Added tags filter styles in shop.
- [New] Added label filter in shop.
- [New] Snippet thumbnail now changes color based on configured theme color.
- [Updated] Product pages loading is 2x faster now.
- [Updated] Improved mega menus.
- [Updated] Improved accessibility.
- [Updated] RTL improvements.
- [Updated] SEO improvements.
- [Updated] PWA improvements.
- [Fixed] Minor bug fixes and improvements.
## [14.0.0.0]
- Initial Release -->

View File

@ -1,7 +1,7 @@
Most of the files are
Copyright (c) 2019 - present Droggol Infotech Private Limited.
Copyright (c) 2019 - present Droggol.
Some javascript files might be from from third
parties libraries. In that case the original

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from . import controllers
from . import models

View File

@ -1,175 +1,189 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
{
'name': 'Theme Prime',
'description': 'Powerful multipurpose eCommerce theme suitable for all kind of businesses like Electronics, Fashion, Sports, Beauty, Furniture and many more.',
'summary': 'Powerful multipurpose eCommerce theme suitable for all kind of businesses like Electronics, Fashion, Sports, Beauty, Furniture and many more.',
'category': 'Theme/eCommerce',
'version': '16.0.0.0.8',
'version': '14.0.0.3.8',
'depends': ['droggol_theme_common'],
'license': 'OPL-1',
'author': 'Droggol Infotech Private Limited',
'company': 'Droggol Infotech Private Limited',
'maintainer': 'Droggol Infotech Private Limited',
'author': 'Droggol',
'company': 'Droggol',
'maintainer': 'Droggol',
'website': 'https://www.droggol.com/',
'price': 289.00,
'price': 275.00,
'currency': 'USD',
'live_test_url': 'https://prime-16-electronics-1.droggol.com/',
'live_test_url': 'https://prime-14-electronics-2.droggol.com/',
'images': [
'static/description/prime_cover.png',
'static/description/prime_screenshot.gif',
],
'data': [
'data/theme.ir.attachment.csv',
'data/data.xml',
'data/images_library.xml',
'views/sidebar.xml',
'views/assets.xml',
'views/templates.xml',
'views/components.xml',
'views/layout.xml',
'views/shop_layout.xml',
'views/product_detail_page.xml',
'views/pages.xml',
'views/snippets.xml',
'views/svg_images.xml',
# Headers / Footers
'views/headers.xml',
'views/preheaders.xml',
'views/footers.xml',
# Headers
'views/headers/style_1.xml',
'views/headers/style_2.xml',
'views/headers/style_3.xml',
'views/headers/style_4.xml',
'views/headers/style_5.xml',
'views/headers/style_6.xml',
'views/headers/style_7.xml',
'views/headers/style_8.xml',
# Footers
'views/footers/style_1.xml',
'views/footers/style_2.xml',
'views/footers/style_3.xml',
'views/footers/style_4.xml',
'views/footers/style_5.xml',
'views/footers/style_6.xml',
'views/footers/style_7.xml',
'views/footers/style_8.xml',
'views/footers/style_9.xml',
'views/footers/style_10.xml',
# Snippets
'views/snippets/dynamic_snippets.xml',
'views/snippets/s_banner.xml',
'views/snippets/s_blog.xml',
'views/snippets/s_clients.xml',
'views/snippets/s_coming_soon.xml',
'views/snippets/s_countdown.xml',
'views/snippets/s_cover.xml',
'views/snippets/s_cta.xml',
'views/snippets/s_gallery.xml',
'views/snippets/s_heading.xml',
'views/snippets/s_icon_block.xml',
'views/snippets/s_info_block.xml',
'views/snippets/s_pricing.xml',
'views/snippets/s_shop_offer.xml',
'views/snippets/s_stats.xml',
'views/snippets/s_subscribe.xml',
'views/snippets/s_team.xml',
'views/snippets/s_testimonial.xml',
'views/snippets/s_call_to_action_1.xml',
'views/snippets/s_call_to_action_2.xml',
'views/snippets/s_call_to_action_3.xml',
'views/snippets/s_call_to_action_4.xml',
'views/snippets/s_call_to_action_5.xml',
'views/snippets/s_category_1.xml',
'views/snippets/s_category_2.xml',
'views/snippets/s_category_3.xml',
'views/snippets/s_category_4.xml',
# Dynamic
'views/snippets/dynamic_snippets/snippets.xml',
'views/snippets/dynamic_snippets/s_countdown.xml',
# Static
'views/snippets/s_banner_1.xml',
'views/snippets/s_banner_2.xml',
'views/snippets/s_banner_3.xml',
'views/snippets/s_banner_4.xml',
'views/snippets/s_banner_5.xml',
'views/snippets/s_banner_6.xml',
'views/snippets/s_banner_7.xml',
'views/snippets/s_banner_8.xml',
'views/snippets/s_banner_9.xml',
'views/snippets/s_banner_10.xml',
'views/snippets/s_banner_11.xml',
'views/snippets/s_banner_12.xml',
'views/snippets/s_blog_1.xml',
'views/snippets/s_blog_2.xml',
'views/snippets/s_blog_3.xml',
'views/snippets/s_clients_1.xml',
'views/snippets/s_clients_2.xml',
'views/snippets/s_clients_3.xml',
'views/snippets/s_clients_4.xml',
'views/snippets/s_coming_soon_1.xml',
'views/snippets/s_coming_soon_2.xml',
'views/snippets/s_counters_1.xml',
'views/snippets/s_counters_2.xml',
'views/snippets/s_counters_3.xml',
'views/snippets/s_counters_4.xml',
'views/snippets/s_counters_5.xml',
'views/snippets/s_cover_1.xml',
'views/snippets/s_cover_2.xml',
'views/snippets/s_cover_3.xml',
'views/snippets/s_cover_4.xml',
'views/snippets/s_cover_5.xml',
'views/snippets/s_cover_6.xml',
'views/snippets/s_gallery_1.xml',
'views/snippets/s_gallery_2.xml',
'views/snippets/s_gallery_3.xml',
'views/snippets/s_gallery_4.xml',
'views/snippets/s_gallery_5.xml',
'views/snippets/s_heading_1.xml',
'views/snippets/s_heading_2.xml',
'views/snippets/s_heading_3.xml',
'views/snippets/s_heading_4.xml',
'views/snippets/s_heading_5.xml',
'views/snippets/s_heading_6.xml',
'views/snippets/s_icon_block_1.xml',
'views/snippets/s_icon_block_2.xml',
'views/snippets/s_icon_block_3.xml',
'views/snippets/s_icon_block_4.xml',
'views/snippets/s_icon_block_5.xml',
'views/snippets/s_icon_block_6.xml',
'views/snippets/s_icon_block_7.xml',
'views/snippets/s_icon_block_8.xml',
'views/snippets/s_icon_block_9.xml',
'views/snippets/s_icon_block_10.xml',
'views/snippets/s_icon_block_11.xml',
'views/snippets/s_icon_block_12.xml',
'views/snippets/s_icon_block_13.xml',
'views/snippets/s_mega_menu_1.xml',
'views/snippets/s_mega_menu_2.xml',
'views/snippets/s_mega_menu_3.xml',
'views/snippets/s_mega_menu_4.xml',
'views/snippets/s_mega_menu_5.xml',
'views/snippets/s_mega_menu_6.xml',
'views/snippets/s_mega_menu_7.xml',
'views/snippets/s_mega_menu_8.xml',
'views/snippets/s_mega_menu_9.xml',
'views/snippets/s_info_block_1.xml',
'views/snippets/s_info_block_2.xml',
'views/snippets/s_info_block_3.xml',
'views/snippets/s_info_block_4.xml',
'views/snippets/s_info_block_5.xml',
'views/snippets/s_info_block_6.xml',
'views/snippets/s_info_block_7.xml',
'views/snippets/s_offer_1.xml',
'views/snippets/s_offer_2.xml',
'views/snippets/s_offer_3.xml',
'views/snippets/s_offer_4.xml',
'views/snippets/s_pricing_1.xml',
'views/snippets/s_pricing_2.xml',
'views/snippets/s_pricing_3.xml',
'views/snippets/s_pricing_4.xml',
'views/snippets/s_pricing_5.xml',
'views/snippets/s_pricing_6.xml',
'views/snippets/s_subscribe_1.xml',
'views/snippets/s_subscribe_2.xml',
'views/snippets/s_subscribe_3.xml',
'views/snippets/s_subscribe_4.xml',
'views/snippets/s_team_1.xml',
'views/snippets/s_team_2.xml',
'views/snippets/s_team_3.xml',
'views/snippets/s_team_4.xml',
'views/snippets/s_team_5.xml',
'views/snippets/s_testimonial_1.xml',
'views/snippets/s_testimonial_2.xml',
'views/snippets/s_testimonial_3.xml',
'views/snippets/s_testimonial_4.xml',
'views/snippets/s_testimonial_5.xml',
],
'assets': {
'web.assets_backend': [
'theme_prime/static/src/components/dialog.xml',
'theme_prime/static/src/components/record_selection.xml',
'theme_prime/static/src/components/ui_component.xml',
'theme_prime/static/src/components/search_input.xml',
'theme_prime/static/src/components/dropdown.xml',
'theme_prime/static/src/components/dialog.js',
'theme_prime/static/src/components/abstract_component.js',
'theme_prime/static/src/components/theme_service.js',
'theme_prime/static/src/components/dialog.scss',
'theme_prime/static/src/components/record_selection.js',
'theme_prime/static/src/components/ui_component.js',
'theme_prime/static/src/components/search_input.js',
],
'web.assets_frontend': [
# Libraries
'theme_prime/static/lib/OwlCarousel2-2.3.4/assets/owl.carousel.css',
'theme_prime/static/lib/OwlCarousel2-2.3.4/assets/owl.theme.default.css',
# Frontend
'theme_prime/static/src/js/website.js',
'theme_prime/static/src/js/website_sale.js',
'theme_prime/static/src/js/website_sale_wishlist.js',
'theme_prime/static/src/js/sidebar.js',
'theme_prime/static/src/xml/sidebar.xml',
'theme_prime/static/src/js/suggested_product_slider.js',
'theme_prime/static/src/xml/frontend/suggested_product_slider.xml',
'theme_prime/static/src/js/service_worker_register.js',
'theme_prime/static/src/xml/pwa.xml',
'theme_prime/static/src/js/core/mixins.js',
'theme_prime/static/src/js/frontend/comparison.js',
'theme_prime/static/src/js/frontend/quick_view_dialog.js',
'theme_prime/static/src/js/frontend/bottombar.js',
'theme_prime/static/src/scss/theme.scss',
'theme_prime/static/src/scss/rtl.scss',
'theme_prime/static/src/scss/website.scss',
'theme_prime/static/src/scss/website_sale.scss',
'theme_prime/static/src/scss/sliders.scss',
'theme_prime/static/src/scss/icon-packs/website.scss',
'theme_prime/static/src/scss/utils.scss',
'theme_prime/static/src/scss/snippets/cards.scss',
'theme_prime/static/src/scss/front_end/quick_view.scss',
'theme_prime/static/src/scss/front_end/dynamic_snippets.scss',
'theme_prime/static/src/scss/front_end/category_filters.scss',
'theme_prime/static/src/scss/front_end/image_hotspot.scss',
'theme_prime/static/src/scss/snippets/2_col_deal.scss',
'theme_prime/static/src/scss/snippets/image_products.scss',
'theme_prime/static/src/scss/front_end/bottom_bar.scss',
'theme_prime/static/src/snippets/s_blog_posts/000.scss',
# Core
'theme_prime/static/src/js/core/snippet_root_widget.js',
'theme_prime/static/src/xml/core/snippet_root_widget.xml',
'theme_prime/static/src/js/core/product_root_widget.js',
'theme_prime/static/src/js/core/cart_manager.js',
'theme_prime/static/src/xml/frontend/notification_template.xml',
'theme_prime/static/src/js/core/cart_confirmation_dialog.js',
'theme_prime/static/src/xml/core/cart_confirmation_dialog.xml',
# Snippets
'theme_prime/static/src/snippets/s_tp_countdown/000.xml',
'theme_prime/static/src/js/frontend/dynamic_snippets.js',
'theme_prime/static/src/xml/frontend/dynamic_snippets.xml',
'theme_prime/static/src/xml/cards.xml',
'theme_prime/static/src/xml/listing_cards.xml',
'theme_prime/static/src/xml/frontend/utils.xml',
'theme_prime/static/src/xml/frontend/category_filters.xml',
'theme_prime/static/src/xml/frontend/2_col_deal.xml',
'theme_prime/static/src/xml/frontend/s_image_products.xml',
'theme_prime/static/src/xml/frontend/s_product_grid.xml',
'theme_prime/static/src/xml/frontend/hierarchical_category_templates.xml',
'theme_prime/static/src/xml/frontend/s_category.xml',
'theme_prime/static/src/xml/frontend/brands.xml',
'theme_prime/static/src/xml/frontend/image_hotspot.xml', # TODO: kishan
# Editor
('replace', 'web_editor/static/src/scss/web_editor.frontend.scss', 'theme_prime/static/src/scss/web_editor.frontend.scss'),
# Search
'theme_prime/static/src/js/frontend/search.js',
'theme_prime/static/src/xml/frontend/search_autocomplete.xml',
],
'web._assets_primary_variables': [
'theme_prime/static/src/scss/primary_variables.scss',
'theme_prime/static/src/scss/mixins.scss',
],
'web._assets_frontend_helpers': [
'theme_prime/static/src/scss/bootstrap_overridden.scss',
],
'website.assets_wysiwyg': [
'theme_prime/static/src/js/editor/snippets.editor.js',
'theme_prime/static/src/scss/editor/editor.scss',
# 'theme_prime/static/src/scss/editor/dialogs/dialog_snippet_configurator.scss',
'theme_prime/static/src/xml/editor/dialogs/snippet_configurator_dialog.xml',
'theme_prime/static/src/xml/frontend/image_hotspot.xml',
'theme_prime/static/src/js/editor/snippets/snippets.options.js',
'theme_prime/static/src/js/editor/registries.js',
'theme_prime/static/src/xml/frontend/documents.xml',
],
},
}

View File

@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from . import main
from . import brand
from . import pwa

View File

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
import string
from collections import defaultdict
from odoo import http
from odoo.http import request
class ThemePrimeBrand(http.Controller):
@http.route('/shop/all_brands', type='http', auth='public', website=True)
def all_brands(self, **args):
brands = request.env['dr.product.brand'].search(request.website.website_domain()).filtered(lambda line: line.product_count)
is_disable_grouping = request.website._get_dr_theme_config('json_brands_page')['disable_brands_grouping']
if is_disable_grouping:
brands_group_by_alphabet = {'All Brands': brands}
else:
alphabet_range = string.ascii_uppercase
brands_group_by_alphabet = defaultdict(list)
brands_group_by_alphabet.update((alphabet, []) for alphabet in alphabet_range)
for brand in brands:
first_char = str.upper(brand.name[:1])
brands_group_by_alphabet[first_char].append(brand)
return request.render('theme_prime.all_brands', {
'is_disable_grouping': is_disable_grouping,
'grouped_brands': brands_group_by_alphabet
})

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
import json
import base64
import io
from functools import partial
from odoo import http
from odoo.http import request
from odoo.modules.module import get_resource_path
from odoo.tools.mimetypes import guess_mimetype
class ThemePrimePWA(http.Controller):
@http.route('/pwa/<int:website_id>/manifest.json', type='http', auth='public', website=True)
def get_pwa_manifest(self, website_id, **kargs):
manifest_data = {"fake": 1}
website = request.website
if website and website.id == website_id and website.dr_pwa_activated:
manifest_data = {
"name": website.dr_pwa_name,
"short_name": website.dr_pwa_short_name,
"display": "standalone",
"background_color": website.dr_pwa_background_color,
"theme_color": website.dr_pwa_theme_color,
"start_url": website.dr_pwa_start_url,
"scope": "/",
"icons": [{
"src": "/web/image/website/%s/dr_pwa_icon_192/192x192" % website.id,
"sizes": "192x192",
"type": "image/png",
}, {
"src": "/web/image/website/%s/dr_pwa_icon_512/512x512" % website.id,
"sizes": "512x512",
"type": "image/png",
}]
}
if website.dr_pwa_shortcuts:
manifest_data['shortcuts'] = [{
"name": shortcut.name,
"short_name": shortcut.short_name or '',
"description": shortcut.description or '',
"url": shortcut.url,
"icons": [{"src": "/web/image/dr.pwa.shortcuts/%s/icon/192x192" % shortcut.id, "sizes": "192x192"}]
} for shortcut in website.dr_pwa_shortcuts]
return request.make_response(
data=json.dumps(manifest_data),
headers=[('Content-Type', 'application/json')]
)
@http.route('/service_worker.js', type='http', auth='public', website=True, sitemap=False)
def get_pwa_service_worker(self, **kargs):
website = request.website
js_folder = partial(get_resource_path, 'theme_prime', 'static', 'src', 'js')
file_path = js_folder('service_worker.js')
offline_bool = 'true' if website.dr_pwa_offline_page else 'false'
data = open(file_path).read()
data = data.replace('"##1##"', str(website.dr_pwa_version))
data = data.replace('"##2##"', offline_bool)
return request.make_response(
data=data,
headers=[('Content-Type', 'text/javascript')]
)
@http.route('/pwa/offline_page', type='http', auth='public', website=True, cors='*', sitemap=False)
def get_pwa_offline_page(self, **kargs):
return request.render('theme_prime.pwa_offline_page', {})
@http.route('/pwa/logo.png', type='http', auth='public', website=True, cors='*', sitemap=False)
def get_pwa_logo(self, **kargs):
website = request.website
imgname = 'logo'
imgext = '.png'
placeholder = partial(get_resource_path, 'web', 'static', 'src', 'img')
if not website.logo:
response = http.send_file(placeholder('nologo.png'))
else:
b64 = website.logo
image_base64 = base64.b64decode(b64)
image_data = io.BytesIO(image_base64)
mimetype = guess_mimetype(image_base64, default='image/png')
imgext = '.' + mimetype.split('/')[1]
if imgext == '.svg+xml':
imgext = '.svg'
response = http.send_file(image_data, filename=imgname + imgext, mimetype=mimetype, mtime=website.write_date)
return response
@http.route('/pwa/is_pwa_actived', type='http', auth='public', website=True, sitemap=False)
def get_pwa_is_actived(self, **kargs):
data = {'pwa': request.website.dr_pwa_activated}
return request.make_response(
data=json.dumps(data),
headers=[('Content-Type', 'application/json')]
)

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<!-- FIXME: Should update priority only for theme view -->
<function model="ir.ui.view" name="write">
<value model="ir.ui.view" eval="obj().with_context(active_test=False).search([('key','=', 'website_sale.products_categories')], limit=1).id"/>
<value eval="{'priority': 15}"/>
</function>
</data>
</odoo>

View File

@ -0,0 +1,599 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="s_banner_1_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_1_1</field>
<field name="name">theme_prime.s_banner_1_1</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_1_1.jpg</field>
</record>
<record id="s_banner_1_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_1_2</field>
<field name="name">theme_prime.s_banner_1_2</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_1_2.jpg</field>
</record>
<record id="s_banner_2_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_2_1</field>
<field name="name">theme_prime.s_banner_2_1</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_2_1.jpg</field>
</record>
<record id="s_banner_2_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_2_2</field>
<field name="name">theme_prime.s_banner_2_2</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_2_2.jpg</field>
</record>
<record id="s_banner_2_3" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_2_3</field>
<field name="name">theme_prime.s_banner_2_3</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_2_3.jpg</field>
</record>
<record id="s_banner_3_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_3_1</field>
<field name="name">theme_prime.s_banner_3_1</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_3_1.png</field>
</record>
<record id="s_banner_3_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_3_2</field>
<field name="name">theme_prime.s_banner_3_2</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_3_2.png</field>
</record>
<record id="s_banner_4_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_4_1</field>
<field name="name">theme_prime.s_banner_4_1</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_4_1.png</field>
</record>
<record id="s_banner_4_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_4_2</field>
<field name="name">theme_prime.s_banner_4_2</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_4_2.png</field>
</record>
<record id="s_banner_4_3" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_4_3</field>
<field name="name">theme_prime.s_banner_4_3</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_4_3.png</field>
</record>
<record id="s_banner_4_brand_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_4_brand_1</field>
<field name="name">theme_prime.s_banner_4_brand_1</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_4_brand_1.png</field>
</record>
<record id="s_banner_4_brand_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_4_brand_2</field>
<field name="name">theme_prime.s_banner_4_brand_2</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_4_brand_2.png</field>
</record>
<record id="s_banner_4_brand_3" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_4_brand_3</field>
<field name="name">theme_prime.s_banner_4_brand_3</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_4_brand_3.png</field>
</record>
<record id="s_banner_5_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_5_1</field>
<field name="name">theme_prime.s_banner_5_1</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_5_1.png</field>
</record>
<record id="s_banner_6_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_6_1</field>
<field name="name">theme_prime.s_banner_6_1</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_6_1.png</field>
</record>
<record id="s_banner_6_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_6_2</field>
<field name="name">theme_prime.s_banner_6_2</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_6_2.png</field>
</record>
<record id="s_banner_7_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_7_1</field>
<field name="name">theme_prime.s_banner_7_1</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_7_1.jpg</field>
</record>
<record id="s_banner_7_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_7_2</field>
<field name="name">theme_prime.s_banner_7_2</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_7_2.jpg</field>
</record>
<record id="s_banner_7_3" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_7_3</field>
<field name="name">theme_prime.s_banner_7_3</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_7_3.jpg</field>
</record>
<record id="s_banner_7_4" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_7_4</field>
<field name="name">theme_prime.s_banner_7_4</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_7_4.jpg</field>
</record>
<record id="s_banner_8_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_8_1</field>
<field name="name">theme_prime.s_banner_8_1</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_8_1.jpg</field>
</record>
<record id="s_banner_8_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_8_2</field>
<field name="name">theme_prime.s_banner_8_2</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_8_2.jpg</field>
</record>
<record id="s_banner_8_3" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_8_3</field>
<field name="name">theme_prime.s_banner_8_3</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_8_3.jpg</field>
</record>
<record id="s_banner_9_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_9_1</field>
<field name="name">theme_prime.s_banner_9_1</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_9_1.jpg</field>
</record>
<record id="s_banner_9_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_9_2</field>
<field name="name">theme_prime.s_banner_9_2</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_9_2.jpg</field>
</record>
<record id="s_banner_9_3" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_9_3</field>
<field name="name">theme_prime.s_banner_9_3</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_9_3.jpg</field>
</record>
<record id="s_banner_10_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_10_1</field>
<field name="name">theme_prime.s_banner_10_1</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_10_1.jpg</field>
</record>
<record id="s_banner_11_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_11_1</field>
<field name="name">theme_prime.s_banner_11_1</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_11_1.jpg</field>
</record>
<record id="s_banner_11_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_11_2</field>
<field name="name">theme_prime.s_banner_11_2</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_11_2.jpg</field>
</record>
<record id="s_banner_11_3" model="theme.ir.attachment">
<field name="key">theme_prime.s_banner_11_3</field>
<field name="name">theme_prime.s_banner_11_3</field>
<field name="url">/theme_prime/static/src/img/content/s_banner_11_3.jpg</field>
</record>
<record id="s_call_to_action_5_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_call_to_action_5_1</field>
<field name="name">theme_prime.s_call_to_action_5_1</field>
<field name="url">/theme_prime/static/src/img/content/s_call_to_action_5_1.jpg</field>
</record>
<record id="s_category_1_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_category_1_1</field>
<field name="name">theme_prime.s_category_1_1</field>
<field name="url">/theme_prime/static/src/img/content/s_category_1_1.jpg</field>
</record>
<record id="s_category_2_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_category_2_1</field>
<field name="name">theme_prime.s_category_2_1</field>
<field name="url">/theme_prime/static/src/img/content/s_category_2_1.jpg</field>
</record>
<record id="s_category_3_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_category_3_1</field>
<field name="name">theme_prime.s_category_3_1</field>
<field name="url">/theme_prime/static/src/img/content/s_category_3_1.jpg</field>
</record>
<record id="s_category_4_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_category_4_1</field>
<field name="name">theme_prime.s_category_4_1</field>
<field name="url">/theme_prime/static/src/img/content/s_category_4_1.png</field>
</record>
<record id="s_client_01" model="theme.ir.attachment">
<field name="key">theme_prime.s_client_01</field>
<field name="name">theme_prime.s_client_01</field>
<field name="url">/theme_prime/static/src/img/content/s_client_01.png</field>
</record>
<record id="s_client_02" model="theme.ir.attachment">
<field name="key">theme_prime.s_client_02</field>
<field name="name">theme_prime.s_client_02</field>
<field name="url">/theme_prime/static/src/img/content/s_client_02.png</field>
</record>
<record id="s_client_03" model="theme.ir.attachment">
<field name="key">theme_prime.s_client_03</field>
<field name="name">theme_prime.s_client_03</field>
<field name="url">/theme_prime/static/src/img/content/s_client_03.png</field>
</record>
<record id="s_client_04" model="theme.ir.attachment">
<field name="key">theme_prime.s_client_04</field>
<field name="name">theme_prime.s_client_04</field>
<field name="url">/theme_prime/static/src/img/content/s_client_04.png</field>
</record>
<record id="s_client_05" model="theme.ir.attachment">
<field name="key">theme_prime.s_client_05</field>
<field name="name">theme_prime.s_client_05</field>
<field name="url">/theme_prime/static/src/img/content/s_client_05.png</field>
</record>
<record id="s_client_06" model="theme.ir.attachment">
<field name="key">theme_prime.s_client_06</field>
<field name="name">theme_prime.s_client_06</field>
<field name="url">/theme_prime/static/src/img/content/s_client_06.png</field>
</record>
<record id="s_client_07" model="theme.ir.attachment">
<field name="key">theme_prime.s_client_07</field>
<field name="name">theme_prime.s_client_07</field>
<field name="url">/theme_prime/static/src/img/content/s_client_07.png</field>
</record>
<record id="s_client_08" model="theme.ir.attachment">
<field name="key">theme_prime.s_client_08</field>
<field name="name">theme_prime.s_client_08</field>
<field name="url">/theme_prime/static/src/img/content/s_client_08.png</field>
</record>
<record id="s_client_09" model="theme.ir.attachment">
<field name="key">theme_prime.s_client_09</field>
<field name="name">theme_prime.s_client_09</field>
<field name="url">/theme_prime/static/src/img/content/s_client_09.png</field>
</record>
<record id="s_client_10" model="theme.ir.attachment">
<field name="key">theme_prime.s_client_10</field>
<field name="name">theme_prime.s_client_10</field>
<field name="url">/theme_prime/static/src/img/content/s_client_10.png</field>
</record>
<record id="s_client_11" model="theme.ir.attachment">
<field name="key">theme_prime.s_client_11</field>
<field name="name">theme_prime.s_client_11</field>
<field name="url">/theme_prime/static/src/img/content/s_client_11.png</field>
</record>
<record id="s_client_12" model="theme.ir.attachment">
<field name="key">theme_prime.s_client_12</field>
<field name="name">theme_prime.s_client_12</field>
<field name="url">/theme_prime/static/src/img/content/s_client_12.png</field>
</record>
<record id="s_coming_soon_2_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_coming_soon_2_1</field>
<field name="name">theme_prime.s_coming_soon_2_1</field>
<field name="url">/theme_prime/static/src/img/content/s_coming_soon_2_1.png</field>
</record>
<record id="s_coming_soon_2_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_coming_soon_2_2</field>
<field name="name">theme_prime.s_coming_soon_2_2</field>
<field name="url">/theme_prime/static/src/img/content/s_coming_soon_2_2.jpg</field>
</record>
<record id="s_cover_1_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_1_1</field>
<field name="name">theme_prime.s_cover_1_1</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_1_1.jpg</field>
</record>
<record id="s_cover_1_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_1_2</field>
<field name="name">theme_prime.s_cover_1_2</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_1_2.jpg</field>
</record>
<record id="s_cover_1_3" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_1_3</field>
<field name="name">theme_prime.s_cover_1_3</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_1_3.jpg</field>
</record>
<record id="s_cover_2_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_2_1</field>
<field name="name">theme_prime.s_cover_2_1</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_2_1.png</field>
</record>
<record id="s_cover_2_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_2_2</field>
<field name="name">theme_prime.s_cover_2_2</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_2_2.png</field>
</record>
<record id="s_cover_2_brand_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_2_brand_1</field>
<field name="name">theme_prime.s_cover_2_brand_1</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_2_brand_1.png</field>
</record>
<record id="s_cover_2_brand_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_2_brand_2</field>
<field name="name">theme_prime.s_cover_2_brand_2</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_2_brand_2.png</field>
</record>
<record id="s_cover_3_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_3_1</field>
<field name="name">theme_prime.s_cover_3_1</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_3_1.jpg</field>
</record>
<record id="s_cover_3_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_3_2</field>
<field name="name">theme_prime.s_cover_3_2</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_3_2.jpg</field>
</record>
<record id="s_cover_4_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_4_1</field>
<field name="name">theme_prime.s_cover_4_1</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_4_1.jpg</field>
</record>
<record id="s_cover_5_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_5_1</field>
<field name="name">theme_prime.s_cover_5_1</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_5_1.jpg</field>
</record>
<record id="s_cover_5_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_5_2</field>
<field name="name">theme_prime.s_cover_5_2</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_5_2.jpg</field>
</record>
<record id="s_cover_5_3" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_5_3</field>
<field name="name">theme_prime.s_cover_5_3</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_5_3.jpg</field>
</record>
<record id="s_cover_5_4" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_5_4</field>
<field name="name">theme_prime.s_cover_5_4</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_5_4.jpg</field>
</record>
<record id="s_cover_6_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_cover_6_1</field>
<field name="name">theme_prime.s_cover_6_1</field>
<field name="url">/theme_prime/static/src/img/content/s_cover_6_1.jpg</field>
</record>
<record id="s_offer_1_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_offer_1_1</field>
<field name="name">theme_prime.s_offer_1_1</field>
<field name="url">/theme_prime/static/src/img/content/s_offer_1_1.jpg</field>
</record>
<record id="s_offer_2_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_offer_2_1</field>
<field name="name">theme_prime.s_offer_2_1</field>
<field name="url">/theme_prime/static/src/img/content/s_offer_2_1.jpg</field>
</record>
<record id="s_offer_3_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_offer_3_1</field>
<field name="name">theme_prime.s_offer_3_1</field>
<field name="url">/theme_prime/static/src/img/content/s_offer_3_1.jpg</field>
</record>
<record id="s_offer_4_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_offer_4_1</field>
<field name="name">theme_prime.s_offer_4_1</field>
<field name="url">/theme_prime/static/src/img/content/s_offer_4_1.jpg</field>
</record>
<record id="s_gallery_01" model="theme.ir.attachment">
<field name="key">theme_prime.s_gallery_01</field>
<field name="name">theme_prime.s_gallery_01</field>
<field name="url">/theme_prime/static/src/img/content/s_gallery_01.jpg</field>
</record>
<record id="s_gallery_02" model="theme.ir.attachment">
<field name="key">theme_prime.s_gallery_02</field>
<field name="name">theme_prime.s_gallery_02</field>
<field name="url">/theme_prime/static/src/img/content/s_gallery_02.jpg</field>
</record>
<record id="s_gallery_03" model="theme.ir.attachment">
<field name="key">theme_prime.s_gallery_03</field>
<field name="name">theme_prime.s_gallery_03</field>
<field name="url">/theme_prime/static/src/img/content/s_gallery_03.jpg</field>
</record>
<record id="s_gallery_04" model="theme.ir.attachment">
<field name="key">theme_prime.s_gallery_04</field>
<field name="name">theme_prime.s_gallery_04</field>
<field name="url">/theme_prime/static/src/img/content/s_gallery_04.jpg</field>
</record>
<record id="s_gallery_05" model="theme.ir.attachment">
<field name="key">theme_prime.s_gallery_05</field>
<field name="name">theme_prime.s_gallery_05</field>
<field name="url">/theme_prime/static/src/img/content/s_gallery_05.jpg</field>
</record>
<record id="s_gallery_06" model="theme.ir.attachment">
<field name="key">theme_prime.s_gallery_06</field>
<field name="name">theme_prime.s_gallery_06</field>
<field name="url">/theme_prime/static/src/img/content/s_gallery_06.jpg</field>
</record>
<record id="s_gallery_07" model="theme.ir.attachment">
<field name="key">theme_prime.s_gallery_07</field>
<field name="name">theme_prime.s_gallery_07</field>
<field name="url">/theme_prime/static/src/img/content/s_gallery_07.jpg</field>
</record>
<record id="s_gallery_08" model="theme.ir.attachment">
<field name="key">theme_prime.s_gallery_08</field>
<field name="name">theme_prime.s_gallery_08</field>
<field name="url">/theme_prime/static/src/img/content/s_gallery_08.jpg</field>
</record>
<record id="s_gallery_09" model="theme.ir.attachment">
<field name="key">theme_prime.s_gallery_09</field>
<field name="name">theme_prime.s_gallery_09</field>
<field name="url">/theme_prime/static/src/img/content/s_gallery_09.jpg</field>
</record>
<record id="s_gallery_10" model="theme.ir.attachment">
<field name="key">theme_prime.s_gallery_10</field>
<field name="name">theme_prime.s_gallery_10</field>
<field name="url">/theme_prime/static/src/img/content/s_gallery_10.jpg</field>
</record>
<record id="s_gallery_11" model="theme.ir.attachment">
<field name="key">theme_prime.s_gallery_11</field>
<field name="name">theme_prime.s_gallery_11</field>
<field name="url">/theme_prime/static/src/img/content/s_gallery_11.jpg</field>
</record>
<record id="s_gallery_12" model="theme.ir.attachment">
<field name="key">theme_prime.s_gallery_12</field>
<field name="name">theme_prime.s_gallery_12</field>
<field name="url">/theme_prime/static/src/img/content/s_gallery_12.jpg</field>
</record>
<record id="s_info_block_1_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_info_block_1_1</field>
<field name="name">theme_prime.s_info_block_1_1</field>
<field name="url">/theme_prime/static/src/img/content/s_info_block_1_1.jpg</field>
</record>
<record id="s_info_block_2_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_info_block_2_1</field>
<field name="name">theme_prime.s_info_block_2_1</field>
<field name="url">/theme_prime/static/src/img/content/s_info_block_2_1.jpg</field>
</record>
<record id="s_info_block_3_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_info_block_3_1</field>
<field name="name">theme_prime.s_info_block_3_1</field>
<field name="url">/theme_prime/static/src/img/content/s_info_block_3_1.jpg</field>
</record>
<record id="s_info_block_3_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_info_block_3_2</field>
<field name="name">theme_prime.s_info_block_3_2</field>
<field name="url">/theme_prime/static/src/img/content/s_info_block_3_2.jpg</field>
</record>
<record id="s_info_block_4_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_info_block_4_1</field>
<field name="name">theme_prime.s_info_block_4_1</field>
<field name="url">/theme_prime/static/src/img/content/s_info_block_4_1.jpg</field>
</record>
<record id="s_info_block_5_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_info_block_5_1</field>
<field name="name">theme_prime.s_info_block_5_1</field>
<field name="url">/theme_prime/static/src/img/content/s_info_block_5_1.jpg</field>
</record>
<record id="s_info_block_5_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_info_block_5_2</field>
<field name="name">theme_prime.s_info_block_5_2</field>
<field name="url">/theme_prime/static/src/img/content/s_info_block_5_2.jpg</field>
</record>
<record id="s_info_block_6_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_info_block_6_1</field>
<field name="name">theme_prime.s_info_block_6_1</field>
<field name="url">/theme_prime/static/src/img/content/s_info_block_6_1.jpg</field>
</record>
<record id="s_info_block_6_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_info_block_6_2</field>
<field name="name">theme_prime.s_info_block_6_2</field>
<field name="url">/theme_prime/static/src/img/content/s_info_block_6_2.jpg</field>
</record>
<record id="s_info_block_7_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_info_block_7_1</field>
<field name="name">theme_prime.s_info_block_7_1</field>
<field name="url">/theme_prime/static/src/img/content/s_info_block_7_1.jpg</field>
</record>
<record id="s_mega_menu_3_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_mega_menu_3_1</field>
<field name="name">theme_prime.s_mega_menu_3_1</field>
<field name="url">/theme_prime/static/src/img/content/s_mega_menu_3_1.jpg</field>
</record>
<record id="s_mega_menu_4_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_mega_menu_4_1</field>
<field name="name">theme_prime.s_mega_menu_4_1</field>
<field name="url">/theme_prime/static/src/img/content/s_mega_menu_4_1.jpg</field>
</record>
<record id="s_mega_menu_5_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_mega_menu_5_1</field>
<field name="name">theme_prime.s_mega_menu_5_1</field>
<field name="url">/theme_prime/static/src/img/content/s_mega_menu_5_1.jpg</field>
</record>
<record id="s_mega_menu_6_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_mega_menu_6_1</field>
<field name="name">theme_prime.s_mega_menu_6_1</field>
<field name="url">/theme_prime/static/src/img/content/s_mega_menu_6_1.jpg</field>
</record>
<record id="s_mega_menu_6_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_mega_menu_6_2</field>
<field name="name">theme_prime.s_mega_menu_6_2</field>
<field name="url">/theme_prime/static/src/img/content/s_mega_menu_6_2.jpg</field>
</record>
<record id="s_mega_menu_6_3" model="theme.ir.attachment">
<field name="key">theme_prime.s_mega_menu_6_3</field>
<field name="name">theme_prime.s_mega_menu_6_3</field>
<field name="url">/theme_prime/static/src/img/content/s_mega_menu_6_3.jpg</field>
</record>
<record id="s_mega_menu_7_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_mega_menu_7_1</field>
<field name="name">theme_prime.s_mega_menu_7_1</field>
<field name="url">/theme_prime/static/src/img/content/s_mega_menu_7_1.jpg</field>
</record>
<record id="s_mega_menu_8_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_mega_menu_8_1</field>
<field name="name">theme_prime.s_mega_menu_8_1</field>
<field name="url">/theme_prime/static/src/img/content/s_mega_menu_8_1.png</field>
</record>
<record id="s_mega_menu_8_2" model="theme.ir.attachment">
<field name="key">theme_prime.s_mega_menu_8_2</field>
<field name="name">theme_prime.s_mega_menu_8_2</field>
<field name="url">/theme_prime/static/src/img/content/s_mega_menu_8_2.jpg</field>
</record>
<record id="s_mega_menu_8_3" model="theme.ir.attachment">
<field name="key">theme_prime.s_mega_menu_8_3</field>
<field name="name">theme_prime.s_mega_menu_8_3</field>
<field name="url">/theme_prime/static/src/img/content/s_mega_menu_8_3.png</field>
</record>
<record id="s_pricing_01" model="theme.ir.attachment">
<field name="key">theme_prime.s_pricing_01</field>
<field name="name">theme_prime.s_pricing_01</field>
<field name="url">/theme_prime/static/src/img/content/s_pricing_01.jpg</field>
</record>
<record id="s_pricing_02" model="theme.ir.attachment">
<field name="key">theme_prime.s_pricing_02</field>
<field name="name">theme_prime.s_pricing_02</field>
<field name="url">/theme_prime/static/src/img/content/s_pricing_02.jpg</field>
</record>
<record id="s_pricing_03" model="theme.ir.attachment">
<field name="key">theme_prime.s_pricing_03</field>
<field name="name">theme_prime.s_pricing_03</field>
<field name="url">/theme_prime/static/src/img/content/s_pricing_03.jpg</field>
</record>
<record id="s_pricing_04" model="theme.ir.attachment">
<field name="key">theme_prime.s_pricing_04</field>
<field name="name">theme_prime.s_pricing_04</field>
<field name="url">/theme_prime/static/src/img/content/s_pricing_04.jpg</field>
</record>
<record id="s_subscribe_4_1" model="theme.ir.attachment">
<field name="key">theme_prime.s_subscribe_4_1</field>
<field name="name">theme_prime.s_subscribe_4_1</field>
<field name="url">/theme_prime/static/src/img/content/s_subscribe_4_1.jpg</field>
</record>
<record id="s_team_01" model="theme.ir.attachment">
<field name="key">theme_prime.s_team_01</field>
<field name="name">theme_prime.s_team_01</field>
<field name="url">/theme_prime/static/src/img/content/s_team_01.png</field>
</record>
<record id="s_team_02" model="theme.ir.attachment">
<field name="key">theme_prime.s_team_02</field>
<field name="name">theme_prime.s_team_02</field>
<field name="url">/theme_prime/static/src/img/content/s_team_02.png</field>
</record>
<record id="s_team_03" model="theme.ir.attachment">
<field name="key">theme_prime.s_team_03</field>
<field name="name">theme_prime.s_team_03</field>
<field name="url">/theme_prime/static/src/img/content/s_team_03.png</field>
</record>
<record id="s_team_04" model="theme.ir.attachment">
<field name="key">theme_prime.s_team_04</field>
<field name="name">theme_prime.s_team_04</field>
<field name="url">/theme_prime/static/src/img/content/s_team_04.png</field>
</record>
<record id="s_team_square_01" model="theme.ir.attachment">
<field name="key">theme_prime.s_team_square_01</field>
<field name="name">theme_prime.s_team_square_01</field>
<field name="url">/theme_prime/static/src/img/content/s_team_square_01.png</field>
</record>
<record id="s_team_square_02" model="theme.ir.attachment">
<field name="key">theme_prime.s_team_square_02</field>
<field name="name">theme_prime.s_team_square_02</field>
<field name="url">/theme_prime/static/src/img/content/s_team_square_02.png</field>
</record>
<record id="s_team_square_03" model="theme.ir.attachment">
<field name="key">theme_prime.s_team_square_03</field>
<field name="name">theme_prime.s_team_square_03</field>
<field name="url">/theme_prime/static/src/img/content/s_team_square_03.png</field>
</record>
<record id="s_team_square_04" model="theme.ir.attachment">
<field name="key">theme_prime.s_team_square_04</field>
<field name="name">theme_prime.s_team_square_04</field>
<field name="url">/theme_prime/static/src/img/content/s_team_square_04.png</field>
</record>
<record id="s_testimonial_author_01" model="theme.ir.attachment">
<field name="key">theme_prime.s_testimonial_author_01</field>
<field name="name">theme_prime.s_testimonial_author_01</field>
<field name="url">/theme_prime/static/src/img/content/s_testimonial_author_01.jpg</field>
</record>
<record id="s_testimonial_author_02" model="theme.ir.attachment">
<field name="key">theme_prime.s_testimonial_author_02</field>
<field name="name">theme_prime.s_testimonial_author_02</field>
<field name="url">/theme_prime/static/src/img/content/s_testimonial_author_02.jpg</field>
</record>
<record id="s_testimonial_author_03" model="theme.ir.attachment">
<field name="key">theme_prime.s_testimonial_author_03</field>
<field name="name">theme_prime.s_testimonial_author_03</field>
<field name="url">/theme_prime/static/src/img/content/s_testimonial_author_03.jpg</field>
</record>
</odoo>

View File

@ -1,117 +0,0 @@
id,key,name,url
s_banner_1_1,theme_prime.s_banner_1_1,theme_prime.s_banner_1_1,/theme_prime/static/src/img/snippets/s_banner_1_1.jpg
s_banner_1_2,theme_prime.s_banner_1_2,theme_prime.s_banner_1_2,/theme_prime/static/src/img/snippets/s_banner_1_2.jpg
s_banner_1_3,theme_prime.s_banner_1_3,theme_prime.s_banner_1_3,/theme_prime/static/src/img/snippets/s_banner_1_3.jpg
s_banner_3_1,theme_prime.s_banner_3_1,theme_prime.s_banner_3_1,/theme_prime/static/src/img/snippets/s_banner_3_1.jpg
s_banner_3_2,theme_prime.s_banner_3_2,theme_prime.s_banner_3_2,/theme_prime/static/src/img/snippets/s_banner_3_2.jpg
s_banner_3_3,theme_prime.s_banner_3_3,theme_prime.s_banner_3_3,/theme_prime/static/src/img/snippets/s_banner_3_3.jpg
s_banner_4_1,theme_prime.s_banner_4_1,theme_prime.s_banner_4_1,/theme_prime/static/src/img/snippets/s_banner_4_1.jpg
s_banner_4_2,theme_prime.s_banner_4_2,theme_prime.s_banner_4_2,/theme_prime/static/src/img/snippets/s_banner_4_2.jpg
s_banner_4_3,theme_prime.s_banner_4_3,theme_prime.s_banner_4_3,/theme_prime/static/src/img/snippets/s_banner_4_3.jpg
s_banner_5_1,theme_prime.s_banner_5_1,theme_prime.s_banner_5_1,/theme_prime/static/src/img/snippets/s_banner_5_1.png
s_banner_5_2,theme_prime.s_banner_5_2,theme_prime.s_banner_5_2,/theme_prime/static/src/img/snippets/s_banner_5_2.png
s_banner_6_1,theme_prime.s_banner_6_1,theme_prime.s_banner_6_1,/theme_prime/static/src/img/snippets/s_banner_6_1.jpg
s_banner_6_2,theme_prime.s_banner_6_2,theme_prime.s_banner_6_2,/theme_prime/static/src/img/snippets/s_banner_6_2.jpg
s_banner_6_3,theme_prime.s_banner_6_3,theme_prime.s_banner_6_3,/theme_prime/static/src/img/snippets/s_banner_6_3.jpg
s_brand_1,theme_prime.s_brand_1,theme_prime.s_brand_1,/theme_prime/static/src/img/snippets/s_brand_1.png
s_brand_2,theme_prime.s_brand_2,theme_prime.s_brand_2,/theme_prime/static/src/img/snippets/s_brand_2.png
s_brand_3,theme_prime.s_brand_3,theme_prime.s_brand_3,/theme_prime/static/src/img/snippets/s_brand_3.png
s_banner_7_1,theme_prime.s_banner_7_1,theme_prime.s_banner_7_1,/theme_prime/static/src/img/snippets/s_banner_7_1.jpg
s_banner_7_2,theme_prime.s_banner_7_2,theme_prime.s_banner_7_2,/theme_prime/static/src/img/snippets/s_banner_7_2.jpg
s_banner_7_3,theme_prime.s_banner_7_3,theme_prime.s_banner_7_3,/theme_prime/static/src/img/snippets/s_banner_7_3.jpg
s_banner_8_1,theme_prime.s_banner_8_1,theme_prime.s_banner_8_1,/theme_prime/static/src/img/snippets/s_banner_8_1.jpg
s_banner_8_2,theme_prime.s_banner_8_2,theme_prime.s_banner_8_2,/theme_prime/static/src/img/snippets/s_banner_8_2.jpg
s_banner_8_3,theme_prime.s_banner_8_3,theme_prime.s_banner_8_3,/theme_prime/static/src/img/snippets/s_banner_8_3.jpg
s_banner_9_1,theme_prime.s_banner_9_1,theme_prime.s_banner_9_1,/theme_prime/static/src/img/snippets/s_banner_9_1.jpg
s_banner_9_2,theme_prime.s_banner_9_2,theme_prime.s_banner_9_2,/theme_prime/static/src/img/snippets/s_banner_9_2.jpg
s_banner_9_3,theme_prime.s_banner_9_3,theme_prime.s_banner_9_3,/theme_prime/static/src/img/snippets/s_banner_9_3.jpg
s_banner_10_1,theme_prime.s_banner_10_1,theme_prime.s_banner_10_1,/theme_prime/static/src/img/snippets/s_banner_10_1.png
s_banner_12_1,theme_prime.s_banner_12_1,theme_prime.s_banner_12_1,/theme_prime/static/src/img/snippets/s_banner_12_1.jpg
s_banner_12_2,theme_prime.s_banner_12_2,theme_prime.s_banner_12_2,/theme_prime/static/src/img/snippets/s_banner_12_2.jpg
s_banner_13_1,theme_prime.s_banner_13_1,theme_prime.s_banner_13_1,/theme_prime/static/src/img/snippets/s_banner_13_1.jpg
s_banner_13_2,theme_prime.s_banner_13_2,theme_prime.s_banner_13_2,/theme_prime/static/src/img/snippets/s_banner_13_2.jpg
s_banner_13_3,theme_prime.s_banner_13_3,theme_prime.s_banner_13_3,/theme_prime/static/src/img/snippets/s_banner_13_3.jpg
s_banner_13_4,theme_prime.s_banner_13_4,theme_prime.s_banner_13_4,/theme_prime/static/src/img/snippets/s_banner_13_4.jpg
s_banner_14_1,theme_prime.s_banner_14_1,theme_prime.s_banner_14_1,/theme_prime/static/src/img/snippets/s_banner_14_1.png
s_banner_14_2,theme_prime.s_banner_14_2,theme_prime.s_banner_14_2,/theme_prime/static/src/img/snippets/s_banner_14_2.png
s_banner_15_1,theme_prime.s_banner_15_1,theme_prime.s_banner_15_1,/theme_prime/static/src/img/snippets/s_banner_15_1.jpg
s_client_01,theme_prime.s_client_01,theme_prime.s_client_01,/theme_prime/static/src/img/snippets/s_client_01.png
s_client_02,theme_prime.s_client_02,theme_prime.s_client_02,/theme_prime/static/src/img/snippets/s_client_02.png
s_client_03,theme_prime.s_client_03,theme_prime.s_client_03,/theme_prime/static/src/img/snippets/s_client_03.png
s_client_04,theme_prime.s_client_04,theme_prime.s_client_04,/theme_prime/static/src/img/snippets/s_client_04.png
s_client_05,theme_prime.s_client_05,theme_prime.s_client_05,/theme_prime/static/src/img/snippets/s_client_05.png
s_client_06,theme_prime.s_client_06,theme_prime.s_client_06,/theme_prime/static/src/img/snippets/s_client_06.png
s_client_07,theme_prime.s_client_07,theme_prime.s_client_07,/theme_prime/static/src/img/snippets/s_client_07.png
s_client_08,theme_prime.s_client_08,theme_prime.s_client_08,/theme_prime/static/src/img/snippets/s_client_08.png
s_client_09,theme_prime.s_client_09,theme_prime.s_client_09,/theme_prime/static/src/img/snippets/s_client_09.png
s_client_10,theme_prime.s_client_10,theme_prime.s_client_10,/theme_prime/static/src/img/snippets/s_client_10.png
s_client_11,theme_prime.s_client_11,theme_prime.s_client_11,/theme_prime/static/src/img/snippets/s_client_11.png
s_client_12,theme_prime.s_client_12,theme_prime.s_client_12,/theme_prime/static/src/img/snippets/s_client_12.png
s_coming_soon_2_1,theme_prime.s_coming_soon_2_1,theme_prime.s_coming_soon_2_1,/theme_prime/static/src/img/snippets/s_coming_soon_2_1.png
s_coming_soon_2_2,theme_prime.s_coming_soon_2_2,theme_prime.s_coming_soon_2_2,/theme_prime/static/src/img/snippets/s_coming_soon_2_2.jpg
s_info_block_1_1,theme_prime.s_info_block_1_1,theme_prime.s_info_block_1_1,/theme_prime/static/src/img/snippets/s_info_block_1_1.jpg
s_info_block_2_1,theme_prime.s_info_block_2_1,theme_prime.s_info_block_2_1,/theme_prime/static/src/img/snippets/s_info_block_2_1.jpg
s_info_block_3_1,theme_prime.s_info_block_3_1,theme_prime.s_info_block_3_1,/theme_prime/static/src/img/snippets/s_info_block_3_1.jpg
s_info_block_3_2,theme_prime.s_info_block_3_2,theme_prime.s_info_block_3_2,/theme_prime/static/src/img/snippets/s_info_block_3_2.jpg
s_info_block_4_1,theme_prime.s_info_block_4_1,theme_prime.s_info_block_4_1,/theme_prime/static/src/img/snippets/s_info_block_4_1.jpg
s_info_block_4_2,theme_prime.s_info_block_4_2,theme_prime.s_info_block_4_2,/theme_prime/static/src/img/snippets/s_info_block_4_2.jpg
s_info_block_4_3,theme_prime.s_info_block_4_3,theme_prime.s_info_block_4_3,/theme_prime/static/src/img/snippets/s_info_block_4_3.jpg
s_info_block_5_1,theme_prime.s_info_block_5_1,theme_prime.s_info_block_5_1,/theme_prime/static/src/img/snippets/s_info_block_5_1.jpg
s_info_block_5_2,theme_prime.s_info_block_5_2,theme_prime.s_info_block_5_2,/theme_prime/static/src/img/snippets/s_info_block_5_2.jpg
s_info_block_6_1,theme_prime.s_info_block_6_1,theme_prime.s_info_block_6_1,/theme_prime/static/src/img/snippets/s_info_block_6_1.jpg
s_info_block_7_1,theme_prime.s_info_block_7_1,theme_prime.s_info_block_7_1,/theme_prime/static/src/img/snippets/s_info_block_7_1.jpeg
s_info_block_8_1,theme_prime.s_info_block_8_1,theme_prime.s_info_block_8_1,/theme_prime/static/src/img/snippets/s_info_block_8_1.png
s_cover_1_1,theme_prime.s_cover_1_1,theme_prime.s_cover_1_1,/theme_prime/static/src/img/snippets/s_cover_1_1.png
s_cover_1_2,theme_prime.s_cover_1_2,theme_prime.s_cover_1_2,/theme_prime/static/src/img/snippets/s_cover_1_2.png
s_cover_1_brand_1,theme_prime.s_cover_1_brand_1,theme_prime.s_cover_1_brand_1,/theme_prime/static/src/img/snippets/s_cover_1_brand_1.png
s_cover_1_brand_2,theme_prime.s_cover_1_brand_2,theme_prime.s_cover_1_brand_2,/theme_prime/static/src/img/snippets/s_cover_1_brand_2.png
s_cover_2_1,theme_prime.s_cover_2_1,theme_prime.s_cover_2_1,/theme_prime/static/src/img/snippets/s_cover_2_1.jpg
s_cover_2_2,theme_prime.s_cover_2_2,theme_prime.s_cover_2_2,/theme_prime/static/src/img/snippets/s_cover_2_2.jpg
s_cover_3_1,theme_prime.s_cover_3_1,theme_prime.s_cover_3_1,/theme_prime/static/src/img/snippets/s_cover_3_1.jpg
s_cover_4_1,theme_prime.s_cover_4_1,theme_prime.s_cover_4_1,/theme_prime/static/src/img/snippets/s_cover_4_1.png
s_cover_4_2,theme_prime.s_cover_4_2,theme_prime.s_cover_4_2,/theme_prime/static/src/img/snippets/s_cover_4_2.png
s_cover_4_3,theme_prime.s_cover_4_3,theme_prime.s_cover_4_3,/theme_prime/static/src/img/snippets/s_cover_4_3.png
s_cover_4_4,theme_prime.s_cover_4_4,theme_prime.s_cover_4_4,/theme_prime/static/src/img/snippets/s_cover_4_4.png
s_cover_4_5,theme_prime.s_cover_4_5,theme_prime.s_cover_4_5,/theme_prime/static/src/img/snippets/s_cover_4_5.png
s_call_to_action_5_1,theme_prime.s_call_to_action_5_1,theme_prime.s_call_to_action_5_1,/theme_prime/static/src/img/snippets/s_call_to_action_5_1.jpg
s_gallery_01,theme_prime.s_gallery_01,theme_prime.s_gallery_01,/theme_prime/static/src/img/snippets/s_gallery_01.jpg
s_gallery_02,theme_prime.s_gallery_02,theme_prime.s_gallery_02,/theme_prime/static/src/img/snippets/s_gallery_02.jpg
s_gallery_03,theme_prime.s_gallery_03,theme_prime.s_gallery_03,/theme_prime/static/src/img/snippets/s_gallery_03.jpg
s_gallery_04,theme_prime.s_gallery_04,theme_prime.s_gallery_04,/theme_prime/static/src/img/snippets/s_gallery_04.jpg
s_gallery_05,theme_prime.s_gallery_05,theme_prime.s_gallery_05,/theme_prime/static/src/img/snippets/s_gallery_05.jpg
s_gallery_06,theme_prime.s_gallery_06,theme_prime.s_gallery_06,/theme_prime/static/src/img/snippets/s_gallery_06.jpg
s_gallery_07,theme_prime.s_gallery_07,theme_prime.s_gallery_07,/theme_prime/static/src/img/snippets/s_gallery_07.jpg
s_gallery_08,theme_prime.s_gallery_08,theme_prime.s_gallery_08,/theme_prime/static/src/img/snippets/s_gallery_08.jpg
s_gallery_09,theme_prime.s_gallery_09,theme_prime.s_gallery_09,/theme_prime/static/src/img/snippets/s_gallery_09.jpg
s_gallery_10,theme_prime.s_gallery_10,theme_prime.s_gallery_10,/theme_prime/static/src/img/snippets/s_gallery_10.jpg
s_gallery_11,theme_prime.s_gallery_11,theme_prime.s_gallery_11,/theme_prime/static/src/img/snippets/s_gallery_11.jpg
s_gallery_12,theme_prime.s_gallery_12,theme_prime.s_gallery_12,/theme_prime/static/src/img/snippets/s_gallery_12.jpg
s_mega_menu_prime_2_1,theme_prime.s_mega_menu_prime_2_1,theme_prime.s_mega_menu_prime_2_1,/theme_prime/static/src/img/snippets/s_mega_menu_prime_2_1.jpg
s_mega_menu_prime_3_1,theme_prime.s_mega_menu_prime_3_1,theme_prime.s_mega_menu_prime_3_1,/theme_prime/static/src/img/snippets/s_mega_menu_prime_3_1.png
s_mega_menu_prime_4_1,theme_prime.s_mega_menu_prime_4_1,theme_prime.s_mega_menu_prime_4_1,/theme_prime/static/src/img/snippets/s_mega_menu_prime_4_1.jpg
s_mega_menu_prime_5_1,theme_prime.s_mega_menu_prime_5_1,theme_prime.s_mega_menu_prime_5_1,/theme_prime/static/src/img/snippets/s_mega_menu_prime_5_1.jpg
s_mega_menu_prime_5_2,theme_prime.s_mega_menu_prime_5_2,theme_prime.s_mega_menu_prime_5_2,/theme_prime/static/src/img/snippets/s_mega_menu_prime_5_2.jpg
s_mega_menu_prime_5_3,theme_prime.s_mega_menu_prime_5_3,theme_prime.s_mega_menu_prime_5_3,/theme_prime/static/src/img/snippets/s_mega_menu_prime_5_3.jpg
s_mega_menu_prime_5_4,theme_prime.s_mega_menu_prime_5_4,theme_prime.s_mega_menu_prime_5_4,/theme_prime/static/src/img/snippets/s_mega_menu_prime_5_4.jpg
s_mega_menu_prime_6_1,theme_prime.s_mega_menu_prime_6_1,theme_prime.s_mega_menu_prime_6_1,/theme_prime/static/src/img/snippets/s_mega_menu_prime_6_1.jpg
s_mega_menu_prime_6_2,theme_prime.s_mega_menu_prime_6_2,theme_prime.s_mega_menu_prime_6_2,/theme_prime/static/src/img/snippets/s_mega_menu_prime_6_2.png
s_mega_menu_prime_6_3,theme_prime.s_mega_menu_prime_6_3,theme_prime.s_mega_menu_prime_6_3,/theme_prime/static/src/img/snippets/s_mega_menu_prime_6_3.jpg
s_pricing_01,theme_prime.s_pricing_01,theme_prime.s_pricing_01,/theme_prime/static/src/img/snippets/s_pricing_01.jpg
s_pricing_02,theme_prime.s_pricing_02,theme_prime.s_pricing_02,/theme_prime/static/src/img/snippets/s_pricing_02.jpg
s_pricing_03,theme_prime.s_pricing_03,theme_prime.s_pricing_03,/theme_prime/static/src/img/snippets/s_pricing_03.jpg
s_pricing_04,theme_prime.s_pricing_04,theme_prime.s_pricing_04,/theme_prime/static/src/img/snippets/s_pricing_04.jpg
s_shop_offer_1_1,theme_prime.s_shop_offer_1_1,theme_prime.s_shop_offer_1_1,/theme_prime/static/src/img/snippets/s_shop_offer_1_1.jpg
s_shop_offer_3_1,theme_prime.s_shop_offer_3_1,theme_prime.s_shop_offer_3_1,/theme_prime/static/src/img/snippets/s_shop_offer_3_1.jpg
s_shop_offer_4_1,theme_prime.s_shop_offer_4_1,theme_prime.s_shop_offer_4_1,/theme_prime/static/src/img/snippets/s_shop_offer_4_1.jpg
s_subscribe_4_1,theme_prime.s_subscribe_4_1,theme_prime.s_subscribe_4_1,/theme_prime/static/src/img/snippets/s_subscribe_4_1.jpg
s_team_01,theme_prime.s_team_01,theme_prime.s_team_01,/theme_prime/static/src/img/snippets/s_team_01.png
s_team_02,theme_prime.s_team_02,theme_prime.s_team_02,/theme_prime/static/src/img/snippets/s_team_02.png
s_team_03,theme_prime.s_team_03,theme_prime.s_team_03,/theme_prime/static/src/img/snippets/s_team_03.png
s_team_04,theme_prime.s_team_04,theme_prime.s_team_04,/theme_prime/static/src/img/snippets/s_team_04.png
s_team_square_01,theme_prime.s_team_square_01,theme_prime.s_team_square_01,/theme_prime/static/src/img/snippets/s_team_square_01.png
s_team_square_02,theme_prime.s_team_square_02,theme_prime.s_team_square_02,/theme_prime/static/src/img/snippets/s_team_square_02.png
s_team_square_03,theme_prime.s_team_square_03,theme_prime.s_team_square_03,/theme_prime/static/src/img/snippets/s_team_square_03.png
s_team_square_04,theme_prime.s_team_square_04,theme_prime.s_team_square_04,/theme_prime/static/src/img/snippets/s_team_square_04.png
s_testimonial_author_01,theme_prime.s_testimonial_author_01,theme_prime.s_testimonial_author_01,/theme_prime/static/src/img/snippets/s_testimonial_author_01.jpg
s_testimonial_author_02,theme_prime.s_testimonial_author_02,theme_prime.s_testimonial_author_02,/theme_prime/static/src/img/snippets/s_testimonial_author_02.jpg
s_testimonial_author_03,theme_prime.s_testimonial_author_03,theme_prime.s_testimonial_author_03,/theme_prime/static/src/img/snippets/s_testimonial_author_03.jpg
1 id key name url
2 s_banner_1_1 theme_prime.s_banner_1_1 theme_prime.s_banner_1_1 /theme_prime/static/src/img/snippets/s_banner_1_1.jpg
3 s_banner_1_2 theme_prime.s_banner_1_2 theme_prime.s_banner_1_2 /theme_prime/static/src/img/snippets/s_banner_1_2.jpg
4 s_banner_1_3 theme_prime.s_banner_1_3 theme_prime.s_banner_1_3 /theme_prime/static/src/img/snippets/s_banner_1_3.jpg
5 s_banner_3_1 theme_prime.s_banner_3_1 theme_prime.s_banner_3_1 /theme_prime/static/src/img/snippets/s_banner_3_1.jpg
6 s_banner_3_2 theme_prime.s_banner_3_2 theme_prime.s_banner_3_2 /theme_prime/static/src/img/snippets/s_banner_3_2.jpg
7 s_banner_3_3 theme_prime.s_banner_3_3 theme_prime.s_banner_3_3 /theme_prime/static/src/img/snippets/s_banner_3_3.jpg
8 s_banner_4_1 theme_prime.s_banner_4_1 theme_prime.s_banner_4_1 /theme_prime/static/src/img/snippets/s_banner_4_1.jpg
9 s_banner_4_2 theme_prime.s_banner_4_2 theme_prime.s_banner_4_2 /theme_prime/static/src/img/snippets/s_banner_4_2.jpg
10 s_banner_4_3 theme_prime.s_banner_4_3 theme_prime.s_banner_4_3 /theme_prime/static/src/img/snippets/s_banner_4_3.jpg
11 s_banner_5_1 theme_prime.s_banner_5_1 theme_prime.s_banner_5_1 /theme_prime/static/src/img/snippets/s_banner_5_1.png
12 s_banner_5_2 theme_prime.s_banner_5_2 theme_prime.s_banner_5_2 /theme_prime/static/src/img/snippets/s_banner_5_2.png
13 s_banner_6_1 theme_prime.s_banner_6_1 theme_prime.s_banner_6_1 /theme_prime/static/src/img/snippets/s_banner_6_1.jpg
14 s_banner_6_2 theme_prime.s_banner_6_2 theme_prime.s_banner_6_2 /theme_prime/static/src/img/snippets/s_banner_6_2.jpg
15 s_banner_6_3 theme_prime.s_banner_6_3 theme_prime.s_banner_6_3 /theme_prime/static/src/img/snippets/s_banner_6_3.jpg
16 s_brand_1 theme_prime.s_brand_1 theme_prime.s_brand_1 /theme_prime/static/src/img/snippets/s_brand_1.png
17 s_brand_2 theme_prime.s_brand_2 theme_prime.s_brand_2 /theme_prime/static/src/img/snippets/s_brand_2.png
18 s_brand_3 theme_prime.s_brand_3 theme_prime.s_brand_3 /theme_prime/static/src/img/snippets/s_brand_3.png
19 s_banner_7_1 theme_prime.s_banner_7_1 theme_prime.s_banner_7_1 /theme_prime/static/src/img/snippets/s_banner_7_1.jpg
20 s_banner_7_2 theme_prime.s_banner_7_2 theme_prime.s_banner_7_2 /theme_prime/static/src/img/snippets/s_banner_7_2.jpg
21 s_banner_7_3 theme_prime.s_banner_7_3 theme_prime.s_banner_7_3 /theme_prime/static/src/img/snippets/s_banner_7_3.jpg
22 s_banner_8_1 theme_prime.s_banner_8_1 theme_prime.s_banner_8_1 /theme_prime/static/src/img/snippets/s_banner_8_1.jpg
23 s_banner_8_2 theme_prime.s_banner_8_2 theme_prime.s_banner_8_2 /theme_prime/static/src/img/snippets/s_banner_8_2.jpg
24 s_banner_8_3 theme_prime.s_banner_8_3 theme_prime.s_banner_8_3 /theme_prime/static/src/img/snippets/s_banner_8_3.jpg
25 s_banner_9_1 theme_prime.s_banner_9_1 theme_prime.s_banner_9_1 /theme_prime/static/src/img/snippets/s_banner_9_1.jpg
26 s_banner_9_2 theme_prime.s_banner_9_2 theme_prime.s_banner_9_2 /theme_prime/static/src/img/snippets/s_banner_9_2.jpg
27 s_banner_9_3 theme_prime.s_banner_9_3 theme_prime.s_banner_9_3 /theme_prime/static/src/img/snippets/s_banner_9_3.jpg
28 s_banner_10_1 theme_prime.s_banner_10_1 theme_prime.s_banner_10_1 /theme_prime/static/src/img/snippets/s_banner_10_1.png
29 s_banner_12_1 theme_prime.s_banner_12_1 theme_prime.s_banner_12_1 /theme_prime/static/src/img/snippets/s_banner_12_1.jpg
30 s_banner_12_2 theme_prime.s_banner_12_2 theme_prime.s_banner_12_2 /theme_prime/static/src/img/snippets/s_banner_12_2.jpg
31 s_banner_13_1 theme_prime.s_banner_13_1 theme_prime.s_banner_13_1 /theme_prime/static/src/img/snippets/s_banner_13_1.jpg
32 s_banner_13_2 theme_prime.s_banner_13_2 theme_prime.s_banner_13_2 /theme_prime/static/src/img/snippets/s_banner_13_2.jpg
33 s_banner_13_3 theme_prime.s_banner_13_3 theme_prime.s_banner_13_3 /theme_prime/static/src/img/snippets/s_banner_13_3.jpg
34 s_banner_13_4 theme_prime.s_banner_13_4 theme_prime.s_banner_13_4 /theme_prime/static/src/img/snippets/s_banner_13_4.jpg
35 s_banner_14_1 theme_prime.s_banner_14_1 theme_prime.s_banner_14_1 /theme_prime/static/src/img/snippets/s_banner_14_1.png
36 s_banner_14_2 theme_prime.s_banner_14_2 theme_prime.s_banner_14_2 /theme_prime/static/src/img/snippets/s_banner_14_2.png
37 s_banner_15_1 theme_prime.s_banner_15_1 theme_prime.s_banner_15_1 /theme_prime/static/src/img/snippets/s_banner_15_1.jpg
38 s_client_01 theme_prime.s_client_01 theme_prime.s_client_01 /theme_prime/static/src/img/snippets/s_client_01.png
39 s_client_02 theme_prime.s_client_02 theme_prime.s_client_02 /theme_prime/static/src/img/snippets/s_client_02.png
40 s_client_03 theme_prime.s_client_03 theme_prime.s_client_03 /theme_prime/static/src/img/snippets/s_client_03.png
41 s_client_04 theme_prime.s_client_04 theme_prime.s_client_04 /theme_prime/static/src/img/snippets/s_client_04.png
42 s_client_05 theme_prime.s_client_05 theme_prime.s_client_05 /theme_prime/static/src/img/snippets/s_client_05.png
43 s_client_06 theme_prime.s_client_06 theme_prime.s_client_06 /theme_prime/static/src/img/snippets/s_client_06.png
44 s_client_07 theme_prime.s_client_07 theme_prime.s_client_07 /theme_prime/static/src/img/snippets/s_client_07.png
45 s_client_08 theme_prime.s_client_08 theme_prime.s_client_08 /theme_prime/static/src/img/snippets/s_client_08.png
46 s_client_09 theme_prime.s_client_09 theme_prime.s_client_09 /theme_prime/static/src/img/snippets/s_client_09.png
47 s_client_10 theme_prime.s_client_10 theme_prime.s_client_10 /theme_prime/static/src/img/snippets/s_client_10.png
48 s_client_11 theme_prime.s_client_11 theme_prime.s_client_11 /theme_prime/static/src/img/snippets/s_client_11.png
49 s_client_12 theme_prime.s_client_12 theme_prime.s_client_12 /theme_prime/static/src/img/snippets/s_client_12.png
50 s_coming_soon_2_1 theme_prime.s_coming_soon_2_1 theme_prime.s_coming_soon_2_1 /theme_prime/static/src/img/snippets/s_coming_soon_2_1.png
51 s_coming_soon_2_2 theme_prime.s_coming_soon_2_2 theme_prime.s_coming_soon_2_2 /theme_prime/static/src/img/snippets/s_coming_soon_2_2.jpg
52 s_info_block_1_1 theme_prime.s_info_block_1_1 theme_prime.s_info_block_1_1 /theme_prime/static/src/img/snippets/s_info_block_1_1.jpg
53 s_info_block_2_1 theme_prime.s_info_block_2_1 theme_prime.s_info_block_2_1 /theme_prime/static/src/img/snippets/s_info_block_2_1.jpg
54 s_info_block_3_1 theme_prime.s_info_block_3_1 theme_prime.s_info_block_3_1 /theme_prime/static/src/img/snippets/s_info_block_3_1.jpg
55 s_info_block_3_2 theme_prime.s_info_block_3_2 theme_prime.s_info_block_3_2 /theme_prime/static/src/img/snippets/s_info_block_3_2.jpg
56 s_info_block_4_1 theme_prime.s_info_block_4_1 theme_prime.s_info_block_4_1 /theme_prime/static/src/img/snippets/s_info_block_4_1.jpg
57 s_info_block_4_2 theme_prime.s_info_block_4_2 theme_prime.s_info_block_4_2 /theme_prime/static/src/img/snippets/s_info_block_4_2.jpg
58 s_info_block_4_3 theme_prime.s_info_block_4_3 theme_prime.s_info_block_4_3 /theme_prime/static/src/img/snippets/s_info_block_4_3.jpg
59 s_info_block_5_1 theme_prime.s_info_block_5_1 theme_prime.s_info_block_5_1 /theme_prime/static/src/img/snippets/s_info_block_5_1.jpg
60 s_info_block_5_2 theme_prime.s_info_block_5_2 theme_prime.s_info_block_5_2 /theme_prime/static/src/img/snippets/s_info_block_5_2.jpg
61 s_info_block_6_1 theme_prime.s_info_block_6_1 theme_prime.s_info_block_6_1 /theme_prime/static/src/img/snippets/s_info_block_6_1.jpg
62 s_info_block_7_1 theme_prime.s_info_block_7_1 theme_prime.s_info_block_7_1 /theme_prime/static/src/img/snippets/s_info_block_7_1.jpeg
63 s_info_block_8_1 theme_prime.s_info_block_8_1 theme_prime.s_info_block_8_1 /theme_prime/static/src/img/snippets/s_info_block_8_1.png
64 s_cover_1_1 theme_prime.s_cover_1_1 theme_prime.s_cover_1_1 /theme_prime/static/src/img/snippets/s_cover_1_1.png
65 s_cover_1_2 theme_prime.s_cover_1_2 theme_prime.s_cover_1_2 /theme_prime/static/src/img/snippets/s_cover_1_2.png
66 s_cover_1_brand_1 theme_prime.s_cover_1_brand_1 theme_prime.s_cover_1_brand_1 /theme_prime/static/src/img/snippets/s_cover_1_brand_1.png
67 s_cover_1_brand_2 theme_prime.s_cover_1_brand_2 theme_prime.s_cover_1_brand_2 /theme_prime/static/src/img/snippets/s_cover_1_brand_2.png
68 s_cover_2_1 theme_prime.s_cover_2_1 theme_prime.s_cover_2_1 /theme_prime/static/src/img/snippets/s_cover_2_1.jpg
69 s_cover_2_2 theme_prime.s_cover_2_2 theme_prime.s_cover_2_2 /theme_prime/static/src/img/snippets/s_cover_2_2.jpg
70 s_cover_3_1 theme_prime.s_cover_3_1 theme_prime.s_cover_3_1 /theme_prime/static/src/img/snippets/s_cover_3_1.jpg
71 s_cover_4_1 theme_prime.s_cover_4_1 theme_prime.s_cover_4_1 /theme_prime/static/src/img/snippets/s_cover_4_1.png
72 s_cover_4_2 theme_prime.s_cover_4_2 theme_prime.s_cover_4_2 /theme_prime/static/src/img/snippets/s_cover_4_2.png
73 s_cover_4_3 theme_prime.s_cover_4_3 theme_prime.s_cover_4_3 /theme_prime/static/src/img/snippets/s_cover_4_3.png
74 s_cover_4_4 theme_prime.s_cover_4_4 theme_prime.s_cover_4_4 /theme_prime/static/src/img/snippets/s_cover_4_4.png
75 s_cover_4_5 theme_prime.s_cover_4_5 theme_prime.s_cover_4_5 /theme_prime/static/src/img/snippets/s_cover_4_5.png
76 s_call_to_action_5_1 theme_prime.s_call_to_action_5_1 theme_prime.s_call_to_action_5_1 /theme_prime/static/src/img/snippets/s_call_to_action_5_1.jpg
77 s_gallery_01 theme_prime.s_gallery_01 theme_prime.s_gallery_01 /theme_prime/static/src/img/snippets/s_gallery_01.jpg
78 s_gallery_02 theme_prime.s_gallery_02 theme_prime.s_gallery_02 /theme_prime/static/src/img/snippets/s_gallery_02.jpg
79 s_gallery_03 theme_prime.s_gallery_03 theme_prime.s_gallery_03 /theme_prime/static/src/img/snippets/s_gallery_03.jpg
80 s_gallery_04 theme_prime.s_gallery_04 theme_prime.s_gallery_04 /theme_prime/static/src/img/snippets/s_gallery_04.jpg
81 s_gallery_05 theme_prime.s_gallery_05 theme_prime.s_gallery_05 /theme_prime/static/src/img/snippets/s_gallery_05.jpg
82 s_gallery_06 theme_prime.s_gallery_06 theme_prime.s_gallery_06 /theme_prime/static/src/img/snippets/s_gallery_06.jpg
83 s_gallery_07 theme_prime.s_gallery_07 theme_prime.s_gallery_07 /theme_prime/static/src/img/snippets/s_gallery_07.jpg
84 s_gallery_08 theme_prime.s_gallery_08 theme_prime.s_gallery_08 /theme_prime/static/src/img/snippets/s_gallery_08.jpg
85 s_gallery_09 theme_prime.s_gallery_09 theme_prime.s_gallery_09 /theme_prime/static/src/img/snippets/s_gallery_09.jpg
86 s_gallery_10 theme_prime.s_gallery_10 theme_prime.s_gallery_10 /theme_prime/static/src/img/snippets/s_gallery_10.jpg
87 s_gallery_11 theme_prime.s_gallery_11 theme_prime.s_gallery_11 /theme_prime/static/src/img/snippets/s_gallery_11.jpg
88 s_gallery_12 theme_prime.s_gallery_12 theme_prime.s_gallery_12 /theme_prime/static/src/img/snippets/s_gallery_12.jpg
89 s_mega_menu_prime_2_1 theme_prime.s_mega_menu_prime_2_1 theme_prime.s_mega_menu_prime_2_1 /theme_prime/static/src/img/snippets/s_mega_menu_prime_2_1.jpg
90 s_mega_menu_prime_3_1 theme_prime.s_mega_menu_prime_3_1 theme_prime.s_mega_menu_prime_3_1 /theme_prime/static/src/img/snippets/s_mega_menu_prime_3_1.png
91 s_mega_menu_prime_4_1 theme_prime.s_mega_menu_prime_4_1 theme_prime.s_mega_menu_prime_4_1 /theme_prime/static/src/img/snippets/s_mega_menu_prime_4_1.jpg
92 s_mega_menu_prime_5_1 theme_prime.s_mega_menu_prime_5_1 theme_prime.s_mega_menu_prime_5_1 /theme_prime/static/src/img/snippets/s_mega_menu_prime_5_1.jpg
93 s_mega_menu_prime_5_2 theme_prime.s_mega_menu_prime_5_2 theme_prime.s_mega_menu_prime_5_2 /theme_prime/static/src/img/snippets/s_mega_menu_prime_5_2.jpg
94 s_mega_menu_prime_5_3 theme_prime.s_mega_menu_prime_5_3 theme_prime.s_mega_menu_prime_5_3 /theme_prime/static/src/img/snippets/s_mega_menu_prime_5_3.jpg
95 s_mega_menu_prime_5_4 theme_prime.s_mega_menu_prime_5_4 theme_prime.s_mega_menu_prime_5_4 /theme_prime/static/src/img/snippets/s_mega_menu_prime_5_4.jpg
96 s_mega_menu_prime_6_1 theme_prime.s_mega_menu_prime_6_1 theme_prime.s_mega_menu_prime_6_1 /theme_prime/static/src/img/snippets/s_mega_menu_prime_6_1.jpg
97 s_mega_menu_prime_6_2 theme_prime.s_mega_menu_prime_6_2 theme_prime.s_mega_menu_prime_6_2 /theme_prime/static/src/img/snippets/s_mega_menu_prime_6_2.png
98 s_mega_menu_prime_6_3 theme_prime.s_mega_menu_prime_6_3 theme_prime.s_mega_menu_prime_6_3 /theme_prime/static/src/img/snippets/s_mega_menu_prime_6_3.jpg
99 s_pricing_01 theme_prime.s_pricing_01 theme_prime.s_pricing_01 /theme_prime/static/src/img/snippets/s_pricing_01.jpg
100 s_pricing_02 theme_prime.s_pricing_02 theme_prime.s_pricing_02 /theme_prime/static/src/img/snippets/s_pricing_02.jpg
101 s_pricing_03 theme_prime.s_pricing_03 theme_prime.s_pricing_03 /theme_prime/static/src/img/snippets/s_pricing_03.jpg
102 s_pricing_04 theme_prime.s_pricing_04 theme_prime.s_pricing_04 /theme_prime/static/src/img/snippets/s_pricing_04.jpg
103 s_shop_offer_1_1 theme_prime.s_shop_offer_1_1 theme_prime.s_shop_offer_1_1 /theme_prime/static/src/img/snippets/s_shop_offer_1_1.jpg
104 s_shop_offer_3_1 theme_prime.s_shop_offer_3_1 theme_prime.s_shop_offer_3_1 /theme_prime/static/src/img/snippets/s_shop_offer_3_1.jpg
105 s_shop_offer_4_1 theme_prime.s_shop_offer_4_1 theme_prime.s_shop_offer_4_1 /theme_prime/static/src/img/snippets/s_shop_offer_4_1.jpg
106 s_subscribe_4_1 theme_prime.s_subscribe_4_1 theme_prime.s_subscribe_4_1 /theme_prime/static/src/img/snippets/s_subscribe_4_1.jpg
107 s_team_01 theme_prime.s_team_01 theme_prime.s_team_01 /theme_prime/static/src/img/snippets/s_team_01.png
108 s_team_02 theme_prime.s_team_02 theme_prime.s_team_02 /theme_prime/static/src/img/snippets/s_team_02.png
109 s_team_03 theme_prime.s_team_03 theme_prime.s_team_03 /theme_prime/static/src/img/snippets/s_team_03.png
110 s_team_04 theme_prime.s_team_04 theme_prime.s_team_04 /theme_prime/static/src/img/snippets/s_team_04.png
111 s_team_square_01 theme_prime.s_team_square_01 theme_prime.s_team_square_01 /theme_prime/static/src/img/snippets/s_team_square_01.png
112 s_team_square_02 theme_prime.s_team_square_02 theme_prime.s_team_square_02 /theme_prime/static/src/img/snippets/s_team_square_02.png
113 s_team_square_03 theme_prime.s_team_square_03 theme_prime.s_team_square_03 /theme_prime/static/src/img/snippets/s_team_square_03.png
114 s_team_square_04 theme_prime.s_team_square_04 theme_prime.s_team_square_04 /theme_prime/static/src/img/snippets/s_team_square_04.png
115 s_testimonial_author_01 theme_prime.s_testimonial_author_01 theme_prime.s_testimonial_author_01 /theme_prime/static/src/img/snippets/s_testimonial_author_01.jpg
116 s_testimonial_author_02 theme_prime.s_testimonial_author_02 theme_prime.s_testimonial_author_02 /theme_prime/static/src/img/snippets/s_testimonial_author_02.jpg
117 s_testimonial_author_03 theme_prime.s_testimonial_author_03 theme_prime.s_testimonial_author_03 /theme_prime/static/src/img/snippets/s_testimonial_author_03.jpg

View File

@ -1 +1 @@
The documentation is available at https://prime-docs-v16-25092021.droggol.com/
The documentation is available at https://prime-docs-v14-29101994.droggol.com/

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
# Copyright (c) 2019-Present Droggol. (<https://www.droggol.com/>)
from . import theme_prime
from . import ir_http

View File

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
from odoo import models

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
from odoo import models, fields, api, tools
from odoo.tools import float_round
class ProductTemplate(models.Model):
@ -71,13 +71,16 @@ class ProductTemplate(models.Model):
for product in self:
product.dr_has_discount = False
def _get_product_category_count(self, domain=[]):
tables, where_clause, where_clause_params = self._dr_prepare_query_parts(domain)
def _get_product_category_count(self, website_ids=[], product_ids=[], domain=[]):
query = self._where_calc(domain)
self._apply_ir_rules(query)
tables, where_clause, where_clause_params = query.get_sql()
tables = tables.replace('"product_template"', ' ', 1)
query = """
SELECT
count(product_template.id),
product_public_category.parent_path as path,
product_public_category.parent_id as parent_id,
min(product_public_category.parent_path) as path,
min(product_public_category.parent_id) as parent_id,
product_public_category.id as product_public_category_id
FROM product_public_category_product_template_rel
JOIN product_template ON product_template.id = product_public_category_product_template_rel.product_template_id
@ -105,9 +108,11 @@ class ProductTemplate(models.Model):
return result_count
def _get_product_attrib_count(self, attrib_values, domain=[]):
tables, where_clause, where_clause_params = self._dr_prepare_query_parts(domain)
def _get_product_attrib_count(self, website_ids=[], product_ids=[], attrib_values=[], domain=[]):
query = self._where_calc(domain)
self._apply_ir_rules(query)
tables, where_clause, where_clause_params = query.get_sql()
tables = tables.replace('"product_template"', ' ', 1)
query = """
SELECT
array_agg(product_template_attribute_line.product_tmpl_id) as product_tmpl_ids,
@ -143,6 +148,7 @@ class ProductTemplate(models.Model):
attrib_vals_map[line['product_attrib_id']] = []
attrib_vals_map[line['product_attrib_id']].append(line['id'])
# Attribute -> active product list
attrib_p_list = {}
for line in query_res:
@ -157,6 +163,7 @@ class ProductTemplate(models.Model):
if value_id_1 in attrib_values_ids:
attrib_p_list[attrib_id_1] = attrib_p_list[attrib_id_1] | set(product_ids_1)
# Attribute -> final list
attrib_product_list = {}
for line in query_res:
@ -179,33 +186,3 @@ class ProductTemplate(models.Model):
else:
result_count = dict([(line.get('id'), len(line.get('product_tmpl_ids') or [])) for line in query_res])
return result_count
def _get_product_rating_count(self, domain=[]):
tables, where_clause, where_clause_params = self._dr_prepare_query_parts(domain)
query = """
SELECT avg_rating, count(*) FROM (
SELECT FLOOR(avg(rating)) as avg_rating, rating_rating.res_id FROM rating_rating JOIN product_template ON product_template.id = rating_rating.res_id """ + tables + """
WHERE (""" + where_clause + """) AND rating_rating.res_model = 'product.template' AND rating_rating.is_internal = False
GROUP BY rating_rating.res_id) AS rating_count group by avg_rating; """
self.env.cr.execute(query, where_clause_params)
query_result = dict(self.env.cr.fetchall())
total = 0
ratings_result = {rating: 0 for rating in range(1, 6)}
for result in range(5, 0, -1):
total += query_result.get(result, 0)
ratings_result[result] = total
return ratings_result
def _dr_prepare_query_parts(self, domain):
query = self._where_calc(domain)
self._apply_ir_rules(query)
tables, where_clause, where_clause_params = query.get_sql()
tables = tables.replace('"product_template"', ' ', 1)
return tables, where_clause, where_clause_params
def _search_render_results(self, fetch_fields, mapping, icon, limit):
current_website = self.env['website'].get_current_website()
if not current_website._dr_has_b2b_access():
mapping.pop("detail", None)
return super()._search_render_results(fetch_fields, mapping, icon, limit)

View File

@ -1,20 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-Present Droggol Infotech Private Limited. (<https://www.droggol.com/>)
from odoo import api, models
from odoo import models
class ThemePrime(models.AbstractModel):
_inherit = 'theme.utils'
@api.model
def _reset_default_config(self):
header_styles = list(range(1, 9))
for style in header_styles:
self.disable_view('theme_prime.template_header_style_%s' % style)
footer_styles = list(range(1, 11))
for style in footer_styles:
self.disable_view('theme_prime.template_footer_style_%s' % style)
super()._reset_default_config()
def _theme_prime_post_copy(self, mod):
pass

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 567 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 762 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 671 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 607 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 332 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

Some files were not shown because too many files have changed in this diff Show More