@ -0,0 +1,46 @@ |
|||||
|
.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg |
||||
|
:target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html |
||||
|
:alt: License: LGPL-3 |
||||
|
|
||||
|
Theme Classic Store |
||||
|
=================== |
||||
|
* Design Web Pages with theme classic store |
||||
|
|
||||
|
Installation |
||||
|
============ |
||||
|
- www.odoo.com/documentation/15.0/setup/install.html |
||||
|
- Install our custom addon |
||||
|
|
||||
|
License |
||||
|
------- |
||||
|
General Public License, Version 3 (LGPL v3). |
||||
|
(https://www.gnu.org/licenses/lgpl-3.0-standalone.html) |
||||
|
|
||||
|
Company |
||||
|
------- |
||||
|
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Credits |
||||
|
------- |
||||
|
* Developer: (V15) Vivek S, Contact: odoo@cybrosys.com |
||||
|
|
||||
|
Contacts |
||||
|
-------- |
||||
|
* Mail Contact : odoo@cybrosys.com |
||||
|
|
||||
|
Bug Tracker |
||||
|
----------- |
||||
|
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
||||
|
|
||||
|
Maintainer |
||||
|
========== |
||||
|
.. image:: https://cybrosys.com/images/logo.png |
||||
|
:target: https://cybrosys.com |
||||
|
|
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
|
||||
|
For support and more information, please visit https://www.cybrosys.com |
||||
|
|
||||
|
Further information |
||||
|
=================== |
||||
|
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,23 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Vivek @ cybrosys,(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from . import controllers |
||||
|
from . import models |
@ -0,0 +1,81 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Vivek @ cybrosys,(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
{ |
||||
|
'name': 'Theme Classic Store', |
||||
|
'version': '15.0.1.0.0', |
||||
|
'category': 'Theme/eCommerce', |
||||
|
'summary': 'Theme Classic Store for Odoo Website and e-Commerce', |
||||
|
'description': 'Theme Classic Store is an attractive eCommerce theme.' |
||||
|
'The theme comes with many useful and stylish snippets', |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'maintainer': 'Cybrosys Techno Solutions', |
||||
|
'website': 'https://www.cybrosys.com', |
||||
|
'depends': ['website_blog', 'website_sale_wishlist', |
||||
|
'website_sale_comparison', 'website_sale', 'website'], |
||||
|
'data': [ |
||||
|
'security/ir.model.access.csv', |
||||
|
'data/classic_store_config_data.xml', |
||||
|
'views/classic_store_config_views.xml', |
||||
|
'views/website_templates.xml', |
||||
|
'views/website_contactus_templates.xml', |
||||
|
'views/website_blog_templates.xml', |
||||
|
'views/http_routing_templates.xml', |
||||
|
'views/website_sale_templates.xml', |
||||
|
'views/snippets/classic_store_aboutus_templates.xml', |
||||
|
'views/snippets/classic_store_banner_templates.xml', |
||||
|
'views/snippets/classic_store_categories_templates.xml', |
||||
|
'views/snippets/classic_store_listing_templates.xml', |
||||
|
'views/snippets/classic_store_package_templates.xml', |
||||
|
'views/snippets/classic_store_team_templates.xml', |
||||
|
'views/snippets/classic_store_counter_templates.xml', |
||||
|
'views/snippets/classic_store_sub_header_templates.xml', |
||||
|
'views/snippets/classic_store_search_templates.xml', |
||||
|
'views/snippets/classic_store_trending_templates.xml', |
||||
|
'views/snippets/snippet_templates.xml', |
||||
|
], |
||||
|
'assets': { |
||||
|
'web.assets_frontend': [ |
||||
|
('replace', 'website_sale/static/src/js/website_sale_utils.js', |
||||
|
'theme_classic_store/static/src/js/sale_utils.js'), |
||||
|
"/theme_classic_store/static/src/css/style.css", |
||||
|
"/theme_classic_store/static/src/css/style.css.map", |
||||
|
"/theme_classic_store/static/src/css/animate.min.css", |
||||
|
"/theme_classic_store/static/src/css/classic_store.css", |
||||
|
"/theme_classic_store/static/src/css/owl.carousel.min.css", |
||||
|
"/theme_classic_store/static/src/css/owl.theme.default.min.css", |
||||
|
"/theme_classic_store/static/src/js/owl.carousel.js", |
||||
|
"/theme_classic_store/static/src/js/owl.carousel.min.js", |
||||
|
"/theme_classic_store/static/src/js/snippets_category.js", |
||||
|
"/theme_classic_store/static/src/js/snippets_trending.js", |
||||
|
"/theme_classic_store/static/src/js/shop_sidebar.js", |
||||
|
], |
||||
|
}, |
||||
|
'images': [ |
||||
|
'static/description/banner.png', |
||||
|
'static/description/theme_screenshot.png', |
||||
|
], |
||||
|
'license': 'LGPL-3', |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
'application': True, |
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Vivek @ cybrosys,(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from . import theme_classic_store |
@ -0,0 +1,104 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Vivek @ cybrosys,(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
import datetime |
||||
|
from odoo import fields, http |
||||
|
from odoo.http import request |
||||
|
|
||||
|
|
||||
|
class WebsiteClassicCategory(http.Controller): |
||||
|
""" |
||||
|
This controller method returns a JSON object that categorizes products |
||||
|
based on their product categories. """ |
||||
|
@http.route('/classic_product_category', auth="public", type='json', |
||||
|
website=True) |
||||
|
def get_product_categories(self): |
||||
|
""" |
||||
|
Categorize products based on product categories |
||||
|
The counter "category_counter" is used to keep track of the product |
||||
|
count in each category """ |
||||
|
product_ids = request.env['product.template'].sudo().search( |
||||
|
[('website_published', '=', True)]) |
||||
|
product_category_ids = request.env[ |
||||
|
'product.public.category'].sudo().search([]) |
||||
|
product_categories_main_list = [] |
||||
|
for rec in product_category_ids: |
||||
|
if rec.child_id: |
||||
|
product_categories_main_list.append(rec) |
||||
|
category_counter = {} |
||||
|
for rec in product_category_ids: |
||||
|
category_counter[rec] = 0 |
||||
|
for rec in product_ids: |
||||
|
for cat in rec.public_categ_ids: |
||||
|
if cat in product_category_ids: |
||||
|
category_counter[cat] += 1 |
||||
|
values = { |
||||
|
'product_categories_main': product_categories_main_list, |
||||
|
'counter': category_counter |
||||
|
} |
||||
|
response = http.Response( |
||||
|
template='theme_classic_store.s_classic_store_categories', |
||||
|
qcontext=values) |
||||
|
return response.render() |
||||
|
|
||||
|
|
||||
|
class WebsiteClassicTrending(http.Controller): |
||||
|
""" |
||||
|
This module defines a controller for the website that showcases trending |
||||
|
products. It contains a class `WebsiteClassicTrending` with a method |
||||
|
`get_trending_products()` that is called when the route |
||||
|
`/classic_product_trending` is accessed.""" |
||||
|
@http.route('/classic_product_trending', auth="public", type='json', |
||||
|
website=True) |
||||
|
def get_trending_products(self): |
||||
|
""" |
||||
|
Showcase trending products based on their number of views between a |
||||
|
defined period |
||||
|
number of views for a product is tracked and then the most viewed |
||||
|
products are shown in order of views |
||||
|
""" |
||||
|
classic_config = request.env[ |
||||
|
'classic_store.config'].sudo().search([]) |
||||
|
trending_products = classic_config.trending_product_ids |
||||
|
if not trending_products: |
||||
|
products = request.env['product.template'].sudo().search([]) |
||||
|
for each in products: |
||||
|
each.views = 0 |
||||
|
each.is_most_viewed = False |
||||
|
date = fields.Datetime.now() |
||||
|
date_before = date - datetime.timedelta(days=7) |
||||
|
products = request.env['website.track'].sudo().search( |
||||
|
[('visit_datetime', '<=', date), |
||||
|
('visit_datetime', '>=', date_before), |
||||
|
('product_id', '!=', False)]) |
||||
|
for pro in products: |
||||
|
pro.product_id.views = pro.product_id.views + 1 |
||||
|
trending_products = request.env['product.template'].sudo().search( |
||||
|
[('is_published', '=', True), |
||||
|
('views', '!=', 0)], |
||||
|
order='views desc', limit=4) |
||||
|
values = { |
||||
|
'trending_products': trending_products |
||||
|
} |
||||
|
response = http.Response( |
||||
|
template='theme_classic_store.s_classic_store_trending', |
||||
|
qcontext=values) |
||||
|
return response.render() |
@ -0,0 +1,12 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!--This XML file defines the configuration data for the Classic Store. |
||||
|
It contains information such as the store name and the maximum price. |
||||
|
Modify the values as needed.--> |
||||
|
<data noupdate="1"> |
||||
|
<record id="classic_store_config_data" model="classic_store.config"> |
||||
|
<field name="name">Classic Store Configuration</field> |
||||
|
<field name="max_price">100000</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,6 @@ |
|||||
|
## Module <theme_classic_store> |
||||
|
|
||||
|
#### 26.07.2023 |
||||
|
#### Version 15.0.1.0.0 |
||||
|
#### ADD |
||||
|
- Initial commit for Theme Classic Store |
@ -0,0 +1,25 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Vivek @ cybrosys,(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from . import classic_store_config |
||||
|
from . import product_public_category |
||||
|
from . import product_template |
||||
|
from . import theme_utils |
@ -0,0 +1,43 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Vivek @ cybrosys,(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import models, fields |
||||
|
|
||||
|
|
||||
|
class ClassicStoreConfig(models.Model): |
||||
|
"""Creating 'name', 'max_price', 'trending_product_ids', field in |
||||
|
classic_store.config settings""" |
||||
|
_name = 'classic_store.config' |
||||
|
_description = 'Configuration Model For Theme Classic Store' |
||||
|
|
||||
|
name = fields.Char(string="Name", |
||||
|
help="Enter the name for the configuration.") |
||||
|
max_price = fields.Integer(string="Maximum Price", default=100000, |
||||
|
help="Maximum amount to apply in " |
||||
|
"product filter.") |
||||
|
trending_product_ids = fields.Many2many('product.template', |
||||
|
string="Trending Products", |
||||
|
help="Manually enter trending " |
||||
|
"products or leave the field" |
||||
|
"blank to automatically " |
||||
|
"add the trending products.", |
||||
|
domain=[ |
||||
|
('is_published', '=', True)]) |
@ -0,0 +1,46 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Vivek @ cybrosys,(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import models, fields |
||||
|
|
||||
|
|
||||
|
class ProductPublicCategory(models.Model): |
||||
|
"""Adding 'category_count' field to the 'product.public.category' model.""" |
||||
|
_inherit = 'product.public.category' |
||||
|
|
||||
|
category_count = fields.Integer(string="Count", |
||||
|
help="The count of different products" |
||||
|
" in each category.", |
||||
|
compute="_compute_category_count") |
||||
|
|
||||
|
def _compute_category_count(self): |
||||
|
""" |
||||
|
Compute function for calculating the value of category_count |
||||
|
Calculates the count of different products in each category |
||||
|
""" |
||||
|
product_ids = self.env['product.template'].search( |
||||
|
[('website_published', '=', True)]) |
||||
|
for category in self: |
||||
|
category_ids = category.search( |
||||
|
[('id', 'child_of', category.id)]).ids |
||||
|
category.category_count = sum( |
||||
|
1 for rec in product_ids for cat in rec.public_categ_ids if |
||||
|
cat.id in category_ids) |
@ -0,0 +1,34 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Vivek @ cybrosys,(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import models, fields |
||||
|
|
||||
|
|
||||
|
class ProductTemplate(models.Model): |
||||
|
"""Adding 'views' and 'most_viewed' fields to the 'product.template' |
||||
|
model""" |
||||
|
_inherit = 'product.template' |
||||
|
|
||||
|
views = fields.Integer(string="Views", |
||||
|
help="The total views for the product through " |
||||
|
"website.") |
||||
|
is_most_viewed = fields.Boolean(string="Most Viewed", |
||||
|
help='Set true if the product is most viewed') |
@ -0,0 +1,60 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Vivek @ cybrosys,(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import models |
||||
|
|
||||
|
|
||||
|
class ThemeClassicStore(models.AbstractModel): |
||||
|
""" |
||||
|
This class extends the 'theme.utils' abstract model to provide |
||||
|
theme-specific functionalities.""" |
||||
|
_inherit = 'theme.utils' |
||||
|
|
||||
|
def _theme_classic_store_post_copy(self, mod): |
||||
|
""" |
||||
|
Disable certain views in the website sale and wishlist functionality |
||||
|
of the Odoo e-commerce module for the "Classic" theme. |
||||
|
This method disables certain views related to features such as product |
||||
|
comparison, grid or list views,adding products to the cart or wishlist, |
||||
|
displaying product attributes and variants, displaying recommended or |
||||
|
recently viewed products, and other product-related features in the |
||||
|
e-commerce website. |
||||
|
""" |
||||
|
self.disable_view('website_sale_comparison.add_to_compare') |
||||
|
self.disable_view('website_sale_comparison.product_attributes_body') |
||||
|
self.disable_view('website_sale.add_grid_or_list_option') |
||||
|
self.disable_view('website_sale.products_add_to_cart') |
||||
|
self.disable_view('website_sale_comparison.add_to_compare') |
||||
|
self.disable_view('website_sale.product_buy_now') |
||||
|
self.disable_view('website_sale_wishlist.add_to_wishlist') |
||||
|
self.disable_view('website_sale.add_grid_or_list_option') |
||||
|
self.disable_view('website_sale.products_images_full') |
||||
|
self.disable_view('website_sale.products_list_view') |
||||
|
self.disable_view('website_sale.recommended_products') |
||||
|
self.disable_view('website_sale.product_picture_magnify_auto') |
||||
|
self.disable_view('website_sale.product_buy_now') |
||||
|
self.disable_view('website_sale.product_comment') |
||||
|
self.disable_view('website_sale.product_picture_magnify') |
||||
|
self.disable_view('website_sale.product_variants') |
||||
|
self.disable_view('website_sale_comparison.product_attributes_body') |
||||
|
self.disable_view('website_sale.ecom_show_extra_fields') |
||||
|
self.disable_view('website_sale.product_custom_text') |
||||
|
self.disable_view('website_sale_wishlist.product_add_to_wishlist') |
|
After Width: | Height: | Size: 141 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 322 KiB |
After Width: | Height: | Size: 342 KiB |
After Width: | Height: | Size: 440 KiB |
After Width: | Height: | Size: 274 KiB |
After Width: | Height: | Size: 363 KiB |
After Width: | Height: | Size: 383 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 361 KiB |
After Width: | Height: | Size: 522 KiB |
After Width: | Height: | Size: 636 KiB |
@ -0,0 +1,332 @@ |
|||||
|
<!-- Hero Section --> |
||||
|
<div class="container pt-4 mt-4 rounded" |
||||
|
style="background-color: #f0f2f4; font-family: Montserrat, 'sans-serif';"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 mb-4"> |
||||
|
<img src="images/Cybrosys.png" alt="Cybrosys Logo" |
||||
|
style="width: 120px; height: auto;"> |
||||
|
<hr style="border-color: #e1e5e9;"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 text-center"> |
||||
|
<img src="images/hero.png" width=60% height="auto" class="mb-4" |
||||
|
alt="Theme Screenshot"> |
||||
|
</div> |
||||
|
<div class="col-lg-12 text-center"> |
||||
|
<h1 class="mt-4">Theme Classic Store</h1> |
||||
|
<p class="lead mb-4" style="max-width: 700px; margin: 0 auto;"> |
||||
|
Theme Classic Store is an attractive and unique front-end theme |
||||
|
mainly suitable for eCommerce website. |
||||
|
Many |
||||
|
custom designed snippets facilitates to add better user |
||||
|
experience. Contains Categories Snippet with |
||||
|
subcategories and its product count, Shop categories sidebar |
||||
|
with product count, Shop price filter. This |
||||
|
theme fully customized the eCommerce website, shop view, custom |
||||
|
categories view, product view, |
||||
|
contact-us page...etc. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- End of Hero Section --> |
||||
|
|
||||
|
<!-- Alternate Section --> |
||||
|
<div class="row p-4"> |
||||
|
<div class="col-lg-6 px-4" style="margin-top: 100px;"> |
||||
|
<h2>Desktop View</h2> |
||||
|
<p class="lead"> |
||||
|
Attractive webpages with elegant desktop view. User-friendly |
||||
|
and Modern looking theme makes your page |
||||
|
more Stylish and Beautiful. |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="col-lg-6 px-4"> |
||||
|
<img style="border-radius: 0.5em;" |
||||
|
src="images/laptop-screenshots.jpg" width="90%" height="auto" |
||||
|
class="mb-4 shadow-sm" alt="Theme Screenshot"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row p-4"> |
||||
|
<div class="col-lg-6 px-4"> |
||||
|
<img style="border-radius: 0.5em;" |
||||
|
src="images/phone-screenshots.jpg" width="90%" height="auto" |
||||
|
class="mb-4 shadow-sm" alt="Theme Screenshot"> |
||||
|
</div> |
||||
|
<div class="col-lg-6 px-4" style="margin-top: 100px;"> |
||||
|
<h2>Mobile View</h2> |
||||
|
<p class="lead"> |
||||
|
The webpages are Stylish, Attractive and Easy to use in mobile |
||||
|
view also. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- End of Alternate Section --> |
||||
|
|
||||
|
|
||||
|
<!-- Two Columns Section --> |
||||
|
<div class="row p-4"> |
||||
|
<!-- Column 1 --> |
||||
|
<div class="col-lg-6"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12"> |
||||
|
<img style="border-radius: 0.5em;" src="images/1.jpg" |
||||
|
width="100%" height="auto" |
||||
|
class="mb-4 shadow-sm" alt="Theme Screenshot"> |
||||
|
</div> |
||||
|
<div class="col-lg-12 mt-4"> |
||||
|
<h2 class="text-center">Home Page</h2> |
||||
|
<p class="lead text-center"> |
||||
|
Stylish Home page which is easily customizable. Simple |
||||
|
and attractive header with |
||||
|
page menus that has animated styles. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- End of Column 1 --> |
||||
|
|
||||
|
<!-- Column 2 --> |
||||
|
<div class="col-lg-6"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12"> |
||||
|
<img style="border-radius: 0.5em;" src="images/2.jpg" |
||||
|
width="100%" height="auto" |
||||
|
class="mb-4 shadow-sm" alt="Theme Screenshot"> |
||||
|
</div> |
||||
|
<div class="col-lg-12 mt-4"> |
||||
|
<h2 class="text-center">Shop page</h2> |
||||
|
<p class="lead text-center"> |
||||
|
Shop Page with additional features like Category |
||||
|
sidebar with product counts and Price filter. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- End of Column 2 --> |
||||
|
</div> |
||||
|
<!-- End of Two Columns Section --> |
||||
|
|
||||
|
|
||||
|
<!-- One Column Section --> |
||||
|
<div class="row p-4"> |
||||
|
<div class="col-lg-6"> |
||||
|
<img style="border-radius: 0.5em;" src="images/3.jpg" width="90%" |
||||
|
height="auto" class="mb-4 shadow-sm" |
||||
|
alt="Theme Screenshot"> |
||||
|
</div> |
||||
|
<div class="col-lg-6" style="padding-top: 40px;"> |
||||
|
<h2>Overview</h2> |
||||
|
<p class="lead"> |
||||
|
Theme Classic Store is a simple and elegant theme for your odoo |
||||
|
website. It is easy to customize and |
||||
|
use. It comes with customizable snippets that can be dragged |
||||
|
and dropped to make attractive webpages. |
||||
|
Simple and stylish header, footer and page banners. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- End of One Column Section --> |
||||
|
|
||||
|
<!-- Categories Section --> |
||||
|
<div class="row p-4"> |
||||
|
<div class="col-lg-6"> |
||||
|
<h2>Categories</h2> |
||||
|
<p class="lead"> |
||||
|
Categories Snippet which shows all the main categories of the |
||||
|
e-commerce shop with its sub categories |
||||
|
and corresponding product count. The sequence of appearance, |
||||
|
image and count is dynamically updated from |
||||
|
backend data. |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="col-lg-6 d-flex justify-content-center align-items-center mt-4"> |
||||
|
<img style="border-radius: 0.5em;" src="images/categories.jpg" |
||||
|
width="90%" height="auto" |
||||
|
class="mb-4 shadow-sm" alt="Theme Screenshot"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- End of Categories Section --> |
||||
|
|
||||
|
<!-- Two Columns Section --> |
||||
|
<div class="row p-4"> |
||||
|
<!-- Column 1 --> |
||||
|
<div class="col-lg-4"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12"> |
||||
|
<img style="border-radius: 0.5em;" src="images/4.jpg" |
||||
|
width="100%" height="auto" |
||||
|
class="mb-4 shadow-sm" alt="Theme Screenshot"> |
||||
|
</div> |
||||
|
<div class="col-lg-12 mt-4"> |
||||
|
<h2 class="text-center">Product Preview</h2> |
||||
|
<p class="lead text-center"> |
||||
|
Product preview page with simple and stylish display |
||||
|
features and additional Product Details, |
||||
|
Specification and Review Tabs. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- End of Column 1 --> |
||||
|
|
||||
|
<!-- Column 2 --> |
||||
|
<div class="col-lg-4"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12"> |
||||
|
<img style="border-radius: 0.5em;" src="images/5.jpg" |
||||
|
width="100%" height="auto" |
||||
|
class="mb-4 shadow-sm" alt="Theme Screenshot"> |
||||
|
</div> |
||||
|
<div class="col-lg-12 mt-4"> |
||||
|
<h2 class="text-center">Blog</h2> |
||||
|
<p class="lead text-center"> |
||||
|
Blog Page with stylish banner and list view. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- End of Column 2 --> |
||||
|
|
||||
|
|
||||
|
<!-- Column 4 --> |
||||
|
<div class="col-lg-4"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12"> |
||||
|
<img style="border-radius: 0.5em;" src="images/6.jpg" |
||||
|
width="100%" height="auto" |
||||
|
class="mb-4 shadow-sm" alt="Theme Screenshot"> |
||||
|
</div> |
||||
|
<div class="col-lg-12 mt-4"> |
||||
|
<h2 class="text-center">About Us</h2> |
||||
|
<p class="lead text-center"> |
||||
|
About Us page which can be easily created and |
||||
|
customized using snippets. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- End of Column 4 --> |
||||
|
</div> |
||||
|
<!-- End of Two Columns Section --> |
||||
|
|
||||
|
<!-- Demo Pages --> |
||||
|
<section class="oe_container"> |
||||
|
<div class="row" style="margin: 60px auto -30px;"> |
||||
|
<div class="col-lg-12 text-center"> |
||||
|
<h4 class="mt-4">Demo Pages</h4> |
||||
|
<hr style="border-width: 3px; border-color: #0984e3; width: 100px;"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="row" |
||||
|
style="margin: 40px auto; border-radius: 15px; padding: 38px;"> |
||||
|
<div class="col-sm-6 col-md-4 px-2"> |
||||
|
<div class="bg-white shadow overflow-hidden mb32" |
||||
|
style="border-radius: 15px; width: 300px; padding-bottom: 0; margin-right: 30px;"> |
||||
|
<img src="./images/demo1.png" width="300px" height="500px"> |
||||
|
<h6 class="text-center my-3">Home</h6> |
||||
|
<hr style="border-width: 5px; border-color: #0984e3; width: 150px; margin-bottom: 0;"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-sm-6 col-md-4 px-2"> |
||||
|
<div class="bg-white shadow overflow-hidden mb32" |
||||
|
style="border-radius: 15px; width: 300px; padding-bottom: 0;"> |
||||
|
<img src="./images/demo2.png" width="300px" height="500px"> |
||||
|
<h6 class="text-center my-3">Shop</h6> |
||||
|
<hr style="border-width: 5px; border-color: #05c46b; width: 150px; margin-bottom: 0;"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-sm-6 col-md-4 px-2"> |
||||
|
<div class="bg-white shadow overflow-hidden mb32" |
||||
|
style="border-radius: 15px; width: 300px; padding-bottom: 0;"> |
||||
|
<img src="./images/demo3.png" width="300px" height="500px"> |
||||
|
<h6 class="text-center my-3">Product Page</h6> |
||||
|
<hr style="border-width: 5px; border-color: #f44f52; width: 150px; margin-bottom: 0;"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<div class="row d-flex justify-content-center" |
||||
|
style="margin: 40px auto; border-radius: 15px; padding: 38px;"> |
||||
|
<div class="col-sm-6 col-md-4 px-2"> |
||||
|
<div class="bg-white shadow overflow-hidden mb32" |
||||
|
style="border-radius: 15px; width: 300px; padding-bottom: 0;"> |
||||
|
<img src="./images/demo4.png" width="300px" height="500px"> |
||||
|
<h6 class="text-center my-3">Blog</h6> |
||||
|
<hr style="border-width: 5px; border-color: #ffa801; width: 150px; margin-bottom: 0;"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</section> |
||||
|
<!-- End of Demo Pages --> |
||||
|
|
||||
|
<!-- Footer --> |
||||
|
<div class="row" style="margin-top: 4rem;"> |
||||
|
<div class="col-lg-12 text-center"> |
||||
|
<h2>Get Help</h2> |
||||
|
<hr style=" border: 2px solid #b22126; margin-top: 2px;" |
||||
|
width="40px"> |
||||
|
<p class="text-center" style="max-width: 650px; margin: 0 auto;">If |
||||
|
you have anything to share with us |
||||
|
based |
||||
|
on |
||||
|
your use of this module, please let us know. We are ready to |
||||
|
offer our support.</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row"> |
||||
|
<div class="col px-4 pt-3 pb-2 shadow-sm" |
||||
|
style="background-color: #fff; max-width: 450px; border-radius: 0.5em; margin: 1em auto;"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-8"> |
||||
|
<h6><a href="mailto:odoo@cybrosys.com" target="_blank" |
||||
|
style="color: #050505; text-decoration: none;"><i |
||||
|
class="fa fa-envelope mr-2"></i>odoo@cybrosys.com</a> |
||||
|
</h6> |
||||
|
</div> |
||||
|
<div class="col-lg-4 d-flex justify-content-end" |
||||
|
style="position: relative;"> |
||||
|
<h6><a href="mailto:odoo@cybrosys.com" target="_blank" |
||||
|
style="color: #050505; text-decoration: none;"><i |
||||
|
class="fa fa-chevron-right"></i></a> |
||||
|
</h6> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row"> |
||||
|
<div class="col px-4 pt-3 pb-2 shadow-sm" |
||||
|
style="background-color: #fff; max-width: 450px; border-radius: 0.5em; margin: 1em auto;"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-8"> |
||||
|
<h6><a href="https://www.cybrosys.com" target="_blank" |
||||
|
style="color: #050505; text-decoration: none;"><i |
||||
|
class="fa fa-globe mr-2"></i>www.cybrosys.com</a> |
||||
|
</h6> |
||||
|
</div> |
||||
|
<div class="col-lg-4 d-flex justify-content-end" |
||||
|
style="position: relative;"> |
||||
|
<h6><a href="https://www.cybrosys.com" target="_blank" |
||||
|
style="color: #050505; text-decoration: none;"><i |
||||
|
class="fa fa-chevron-right"></i></a> |
||||
|
</h6> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 mt-4 mb-2 text-center"> |
||||
|
<p style="font-weight: bold">A Quality Theme From</p> |
||||
|
</div> |
||||
|
<div class="col-lg-12 text-center"> |
||||
|
<img src="images/cybro-logo-oca.png" width="80px" height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- End of Footer --> |
||||
|
</div> |
After Width: | Height: | Size: 442 KiB |
@ -0,0 +1,25 @@ |
|||||
|
.page-link { |
||||
|
position: relative; |
||||
|
display: block; |
||||
|
padding: .5rem .75rem; |
||||
|
margin-left: -1px; |
||||
|
line-height: 1.25; |
||||
|
color: #763242 !important; |
||||
|
background-color: #fff; |
||||
|
border: 1px solid #dee2e6; |
||||
|
} |
||||
|
|
||||
|
.page-item.active .page-link { |
||||
|
z-index: 3; |
||||
|
color: #fff; |
||||
|
background-color: #c09f7f !important; |
||||
|
border-color: #c09f7f !important; |
||||
|
} |
||||
|
|
||||
|
.page-link:hover { |
||||
|
z-index: 2; |
||||
|
color: #0056b3; |
||||
|
text-decoration: none; |
||||
|
background-color: #763242 !important; |
||||
|
border-color: #dee2e6; |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
/** |
||||
|
* Owl Carousel v2.3.4 |
||||
|
* Copyright 2013-2018 David Deutsch |
||||
|
* Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE |
||||
|
*/ |
||||
|
.owl-carousel,.owl-carousel .owl-item{-webkit-tap-highlight-color:transparent;position:relative}.owl-carousel{display:none;width:100%;z-index:1}.owl-carousel .owl-stage{position:relative;-ms-touch-action:pan-Y;touch-action:manipulation;-moz-backface-visibility:hidden}.owl-carousel .owl-stage:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}.owl-carousel .owl-stage-outer{position:relative;overflow:hidden;-webkit-transform:translate3d(0,0,0)}.owl-carousel .owl-item,.owl-carousel .owl-wrapper{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0)}.owl-carousel .owl-item{min-height:1px;float:left;-webkit-backface-visibility:hidden;-webkit-touch-callout:none}.owl-carousel .owl-item img{display:block;width:100%}.owl-carousel .owl-dots.disabled,.owl-carousel .owl-nav.disabled{display:none}.no-js .owl-carousel,.owl-carousel.owl-loaded{display:block}.owl-carousel .owl-dot,.owl-carousel .owl-nav .owl-next,.owl-carousel .owl-nav .owl-prev{cursor:pointer;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.owl-carousel .owl-nav button.owl-next,.owl-carousel .owl-nav button.owl-prev,.owl-carousel button.owl-dot{background:0 0;color:inherit;border:none;padding:0!important;font:inherit}.owl-carousel.owl-loading{opacity:0;display:block}.owl-carousel.owl-hidden{opacity:0}.owl-carousel.owl-refresh .owl-item{visibility:hidden}.owl-carousel.owl-drag .owl-item{-ms-touch-action:pan-y;touch-action:pan-y;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.owl-carousel.owl-grab{cursor:move;cursor:grab}.owl-carousel.owl-rtl{direction:rtl}.owl-carousel.owl-rtl .owl-item{float:right}.owl-carousel .animated{animation-duration:1s;animation-fill-mode:both}.owl-carousel .owl-animated-in{z-index:0}.owl-carousel .owl-animated-out{z-index:1}.owl-carousel .fadeOut{animation-name:fadeOut}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.owl-height{transition:height .5s ease-in-out}.owl-carousel .owl-item .owl-lazy{opacity:0;transition:opacity .4s ease}.owl-carousel .owl-item .owl-lazy:not([src]),.owl-carousel .owl-item .owl-lazy[src^=""]{max-height:0}.owl-carousel .owl-item img.owl-lazy{transform-style:preserve-3d}.owl-carousel .owl-video-wrapper{position:relative;height:100%;background:#000}.owl-carousel .owl-video-play-icon{position:absolute;height:80px;width:80px;left:50%;top:50%;margin-left:-40px;margin-top:-40px;background:url(owl.video.play.png) no-repeat;cursor:pointer;z-index:1;-webkit-backface-visibility:hidden;transition:transform .1s ease}.owl-carousel .owl-video-play-icon:hover{-ms-transform:scale(1.3,1.3);transform:scale(1.3,1.3)}.owl-carousel .owl-video-playing .owl-video-play-icon,.owl-carousel .owl-video-playing .owl-video-tn{display:none}.owl-carousel .owl-video-tn{opacity:0;height:100%;background-position:center center;background-repeat:no-repeat;background-size:contain;transition:opacity .4s ease}.owl-carousel .owl-video-frame{position:relative;z-index:1;height:100%;width:100%} |
@ -0,0 +1,6 @@ |
|||||
|
/** |
||||
|
* Owl Carousel v2.3.4 |
||||
|
* Copyright 2013-2018 David Deutsch |
||||
|
* Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE |
||||
|
*/ |
||||
|
.owl-theme .owl-dots,.owl-theme .owl-nav{text-align:center;-webkit-tap-highlight-color:transparent}.owl-theme .owl-nav{margin-top:10px}.owl-theme .owl-nav [class*=owl-]{color:#FFF;font-size:14px;margin:5px;padding:4px 7px;background:#D6D6D6;display:inline-block;cursor:pointer;border-radius:3px}.owl-theme .owl-nav [class*=owl-]:hover{background:#869791;color:#FFF;text-decoration:none}.owl-theme .owl-nav .disabled{opacity:.5;cursor:default}.owl-theme .owl-nav.disabled+.owl-dots{margin-top:10px}.owl-theme .owl-dots .owl-dot{display:inline-block;zoom:1}.owl-theme .owl-dots .owl-dot span{width:10px;height:10px;margin:5px 7px;background:#D6D6D6;display:block;-webkit-backface-visibility:visible;transition:opacity .2s ease;border-radius:30px}.owl-theme .owl-dots .owl-dot.active span,.owl-theme .owl-dots .owl-dot:hover span{background:#869791} |
After Width: | Height: | Size: 304 KiB |
After Width: | Height: | Size: 491 KiB |
After Width: | Height: | Size: 1.9 MiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 3.6 MiB |
After Width: | Height: | Size: 2.6 MiB |
After Width: | Height: | Size: 670 KiB |
After Width: | Height: | Size: 812 KiB |
After Width: | Height: | Size: 2.7 MiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 3.8 MiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 211 KiB |
After Width: | Height: | Size: 272 KiB |
After Width: | Height: | Size: 1.4 MiB |
After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 635 KiB |
After Width: | Height: | Size: 5.5 MiB |
After Width: | Height: | Size: 1.7 MiB |
After Width: | Height: | Size: 4.6 MiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 5.6 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 458 KiB |
After Width: | Height: | Size: 161 KiB |
After Width: | Height: | Size: 235 KiB |
After Width: | Height: | Size: 299 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 718 KiB |
After Width: | Height: | Size: 2.0 MiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 50 KiB |
@ -0,0 +1,128 @@ |
|||||
|
odoo.define('website_sale.utils', function (require) { |
||||
|
'use strict'; |
||||
|
|
||||
|
const wUtils = require('website.utils'); |
||||
|
|
||||
|
/** |
||||
|
* Mixin providing common functionality for handling cart updates. |
||||
|
*/ |
||||
|
const cartHandlerMixin = { |
||||
|
/** |
||||
|
* Determines whether to redirect after adding to cart or stay on the same page. |
||||
|
*/ |
||||
|
getRedirectOption() { |
||||
|
const html = document.documentElement; |
||||
|
this.stayOnPageOption = html.dataset.add2cartRedirect !== '0'; |
||||
|
}, |
||||
|
/** |
||||
|
* Determines whether the "Buy Now" option was selected and gets the item image container. |
||||
|
* @param {Event} ev - The event that triggered the cart update. |
||||
|
*/ |
||||
|
getCartHandlerOptions(ev) { |
||||
|
this.isBuyNow = ev.currentTarget.classList.contains('o_we_buy_now'); |
||||
|
const targetSelector = ev.currentTarget.dataset.animationSelector || 'img'; |
||||
|
this.$itemImgContainer = this.$(ev.currentTarget).closest(`:has(${targetSelector})`); |
||||
|
}, |
||||
|
/** |
||||
|
* Adds a product to the cart. |
||||
|
* @param {Object} params - The parameters for the cart update. |
||||
|
* @returns {Promise} - A promise that resolves when the cart is updated. |
||||
|
*/ |
||||
|
addToCart(params) { |
||||
|
if (this.isBuyNow) { |
||||
|
params.express = true; |
||||
|
} else if (this.stayOnPageOption) { |
||||
|
return this._addToCartInPage(params); |
||||
|
} |
||||
|
return wUtils.sendRequest('/shop/cart/update', params); |
||||
|
}, |
||||
|
/** |
||||
|
* Adds a product to the cart on the same page. |
||||
|
* @private |
||||
|
* @param {Object} params - The parameters for the cart update. |
||||
|
* @returns {Promise} - A promise that resolves when the cart is updated. |
||||
|
*/ |
||||
|
_addToCartInPage(params) { |
||||
|
params.force_create = true; |
||||
|
return this._rpc({ |
||||
|
route: "/shop/cart/update_json", |
||||
|
params: params, |
||||
|
}).then(async data => { |
||||
|
await animateClone($('header .o_wsale_my_cart').first(), this.$itemImgContainer, 25, 40); |
||||
|
updateCartNavBar(data); |
||||
|
}); |
||||
|
}, |
||||
|
}; |
||||
|
/** |
||||
|
* Animates the image of the product being added to the cart. |
||||
|
* @param {jQuery} $cart - The cart element. |
||||
|
* @param {jQuery} $elem - The element representing the product being added. |
||||
|
* @param {number} offsetTop - The top offset of the animated image. |
||||
|
* @param {number} offsetLeft - The left offset of the animated image. |
||||
|
* @returns {Promise} - A promise that resolves when the animation is complete. |
||||
|
*/ |
||||
|
function animateClone($cart, $elem, offsetTop, offsetLeft) { |
||||
|
$cart.find('.o_animate_blink').addClass('o_red_highlight o_shadow_animation').delay(500).queue(function () { |
||||
|
$(this).removeClass("o_shadow_animation").dequeue(); |
||||
|
}).delay(2000).queue(function () { |
||||
|
$(this).removeClass("o_red_highlight").dequeue(); |
||||
|
}); |
||||
|
return new Promise(function (resolve, reject) { |
||||
|
var $imgtodrag = $elem.find('img').eq(0); |
||||
|
if ($imgtodrag.length) { |
||||
|
var $imgclone = $imgtodrag.clone() |
||||
|
.offset({ |
||||
|
top: $imgtodrag.offset().top, |
||||
|
left: $imgtodrag.offset().left |
||||
|
}) |
||||
|
.addClass('o_website_sale_animate') |
||||
|
.appendTo(document.body) |
||||
|
.css({ |
||||
|
// Keep the same size on cloned img.
|
||||
|
width: $imgtodrag.width(), |
||||
|
height: $imgtodrag.height(), |
||||
|
}) |
||||
|
.animate({ |
||||
|
top: 100, |
||||
|
left: 1400, |
||||
|
width: 75, |
||||
|
height: 75, |
||||
|
}, 1000, 'easeInOutExpo'); |
||||
|
|
||||
|
$imgclone.animate({ |
||||
|
width: 0, |
||||
|
height: 0, |
||||
|
}, function () { |
||||
|
resolve(); |
||||
|
$(this).detach(); |
||||
|
}); |
||||
|
} else { |
||||
|
resolve(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Updates both navbar cart |
||||
|
* @param {Object} data |
||||
|
*/ |
||||
|
function updateCartNavBar(data) { |
||||
|
var $qtyNavBar = $(".my_cart_quantity"); |
||||
|
_.each($qtyNavBar, function (qty) { |
||||
|
var $qty = $(qty); |
||||
|
$qty.parents('li:first').removeClass('d-none'); |
||||
|
$qty.addClass('o_mycart_zoom_animation').delay(300).queue(function () { |
||||
|
$(this).text(data.cart_quantity); |
||||
|
$(this).removeClass("o_mycart_zoom_animation").dequeue(); |
||||
|
}); |
||||
|
}); |
||||
|
$(".js_cart_lines").first().before(data['website_sale.cart_lines']).end().remove(); |
||||
|
$(".js_cart_summary").first().before(data['website_sale.short_cart_summary']).end().remove(); |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
animateClone: animateClone, |
||||
|
updateCartNavBar: updateCartNavBar, |
||||
|
cartHandlerMixin: cartHandlerMixin, |
||||
|
}; |
||||
|
}); |
@ -0,0 +1,35 @@ |
|||||
|
/* |
||||
|
This JavaScript file defines a custom widget for the Classic Store theme. |
||||
|
The widget adds functionality to show or hide a product sidebar when a arrow is clicked. |
||||
|
*/ |
||||
|
odoo.define('theme_classic_store', function (require) { |
||||
|
'use strict'; |
||||
|
var publicWidget = require('web.public.widget'); |
||||
|
publicWidget.registry.show = publicWidget.Widget.extend({ |
||||
|
selector: '.product_sidebar', |
||||
|
events: { |
||||
|
'click .show_div': '_showDiv', |
||||
|
}, |
||||
|
start: function () { |
||||
|
this._super.apply(this, arguments); |
||||
|
this._setupEventDelegation(); |
||||
|
}, |
||||
|
_setupEventDelegation: function () { |
||||
|
this.$el.on('click', '.fa-angle-down.dropdown-arrow', this._showDiv.bind(this)); |
||||
|
}, |
||||
|
_showDiv: function (ev) { |
||||
|
ev.preventDefault(); |
||||
|
ev.stopPropagation(); |
||||
|
var arrow = this.$(ev.currentTarget); |
||||
|
var div = arrow[0].parentElement.parentElement.nextElementSibling; |
||||
|
if (div.hasAttribute('hidden')) { |
||||
|
div.removeAttribute('hidden'); |
||||
|
} else { |
||||
|
div.setAttribute('hidden', ''); |
||||
|
} |
||||
|
}, |
||||
|
}); |
||||
|
return { |
||||
|
show: publicWidget.registry.show, |
||||
|
}; |
||||
|
}); |
@ -0,0 +1,29 @@ |
|||||
|
odoo.define('theme_classic_store.categories', function(require){ |
||||
|
'use strict'; |
||||
|
var Animation = require('website.content.snippets.animation'); |
||||
|
var ajax = require('web.ajax'); |
||||
|
/** |
||||
|
* Defines an animation class for the categories element in the HTML document. |
||||
|
* Sends an AJAX request to the /classic_product_category URL using the ajax.jsonRpc |
||||
|
* method, and calls the 'call' method on the server-side. If the request is successful, |
||||
|
* clears the current content of the categories element using the empty method on the |
||||
|
* self.$target jQuery object, and appends the returned data to the element using the |
||||
|
* append method. The selector property defines the CSS selector for the element that |
||||
|
* the animation will be applied to. |
||||
|
* |
||||
|
* @module theme_classic_store.price_filter |
||||
|
* @extends Animation.Class |
||||
|
*/ |
||||
|
Animation.registry.categories = Animation.Class.extend({ |
||||
|
selector : '.categories', |
||||
|
start: function(){ |
||||
|
var self = this; |
||||
|
ajax.jsonRpc('/classic_product_category', 'call', {}) |
||||
|
.then(function (data) { |
||||
|
if(data){ |
||||
|
self.$target.empty().append(data); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,76 @@ |
|||||
|
odoo.define('theme_classic_store.trending', function(require){ |
||||
|
'use strict'; |
||||
|
var Animation = require('website.content.snippets.animation'); |
||||
|
var ajax = require('web.ajax'); |
||||
|
/** |
||||
|
* Defines an animation class for the trending element in the HTML document. |
||||
|
* Sends an AJAX request to the /classic_product_trending URL using the ajax.jsonRpc |
||||
|
* method, and calls the 'call' method on the server-side. If the request is successful, |
||||
|
* clears the current content of the trending element using the empty method on the |
||||
|
* self.$target jQuery object, and appends the returned data to the element using the |
||||
|
* append method. Initializes the owl carousel on the .owl-carousel element inside the |
||||
|
* trending element with the specified options. The selector property defines the CSS |
||||
|
* selector for the element that the animation will be applied to. |
||||
|
* |
||||
|
* @module theme_classic_store.price_filter |
||||
|
* @extends Animation.Class |
||||
|
*/ |
||||
|
|
||||
|
Animation.registry.trending = Animation.Class.extend({ |
||||
|
selector : '.trending', |
||||
|
start: function(){ |
||||
|
var self = this; |
||||
|
ajax.jsonRpc('/classic_product_trending', 'call', {}) |
||||
|
.then(function (data) { |
||||
|
if(data){ |
||||
|
self.$target.empty().append(data); |
||||
|
self.product_carousel(); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
product_carousel: function (autoplay=false, items=4, slider_timing=5000) { |
||||
|
var self= this; |
||||
|
$(".owl-carousel").owlCarousel( |
||||
|
{ |
||||
|
// animateOut: 'slideOutDown',
|
||||
|
// animateIn: 'flipInX',
|
||||
|
items: 3, |
||||
|
loop: true, |
||||
|
margin: 30, |
||||
|
stagePadding: 30, |
||||
|
smartSpeed: 450, |
||||
|
autoplay: true, |
||||
|
autoPlaySpeed: 1000, |
||||
|
autoPlayTimeout: 1000, |
||||
|
autoplayHoverPause: true, |
||||
|
onInitialized: self.counter(), |
||||
|
dots: true, |
||||
|
nav: true, |
||||
|
responsiveClass: true, |
||||
|
responsive: { |
||||
|
0: { |
||||
|
items: 1, |
||||
|
nav: true |
||||
|
}, |
||||
|
600: { |
||||
|
items: 2, |
||||
|
nav: false |
||||
|
}, |
||||
|
1000: { |
||||
|
items: 3, |
||||
|
nav: true, |
||||
|
loop: true |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
); |
||||
|
}, |
||||
|
counter: function() { |
||||
|
var buttons = $('.owl-dots button'); |
||||
|
buttons.each(function (index, item) { |
||||
|
$(item).find('span').text(index + 1); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,54 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- This record defines an action window for the "Classic Store Configuration" page. |
||||
|
It sets the name of the page, the model it will use, and the view mode (tree and form). --> |
||||
|
<record id="classic_store_config_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Classic Store Configuration</field> |
||||
|
<field name="type">ir.actions.act_window</field> |
||||
|
<field name="res_model">classic_store.config</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
<!-- This record defines the tree view for the "Classic Store Configuration" page. It sets the name, model, |
||||
|
and arch of the view, which includes a single field for the name. --> |
||||
|
<record id="classic_store_config_tree" model="ir.ui.view"> |
||||
|
<field name="name">classic_store.config.tree</field> |
||||
|
<field name="model">classic_store.config</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree create="0" delete="false"> |
||||
|
<field name="name"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- This record defines the form view for the "Classic Store Configuration" page. |
||||
|
It sets the name, model, and arch of the view, which includes two groups: one for the price filter |
||||
|
with a single field for the max price, and one for trending products with a many2many_tags widget |
||||
|
for the trending product IDs. --> |
||||
|
<record id="classic_store_config_form" model="ir.ui.view"> |
||||
|
<field name="name">classic_store.config.form</field> |
||||
|
<field name="model">classic_store.config</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form create="0" delete="false"> |
||||
|
<sheet> |
||||
|
<field name="name" invisible="1"/> |
||||
|
<group> |
||||
|
<group string="Price Filter"> |
||||
|
<field name="max_price" required="1"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<group> |
||||
|
<group string="Trending Products"> |
||||
|
<field name="trending_product_ids" |
||||
|
widget="many2many_tags"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Menu item for the "Classic Store" configuration page, which appears under the |
||||
|
"Website" global configuration menu. It sets the name, parent, sequence, and action for the menu item. --> |
||||
|
<menuitem id="classic_store_config_menu" name="Classic Store" |
||||
|
parent="website.menu_website_global_configuration" |
||||
|
sequence="15" |
||||
|
action="classic_store_config_action"/> |
||||
|
</odoo> |
@ -0,0 +1,35 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<template id="classic_store_error_404" name="Classic Store 404" |
||||
|
inherit_id="http_routing.404" customize_show="True"> |
||||
|
<!-- It template inherits from "http_routing.404" and customizes it to replace the content of a div element |
||||
|
with a custom error message and image. --> |
||||
|
<xpath expr="//div[@class='container']" position="replace"> |
||||
|
<section class="form"> |
||||
|
<div class="container"> |
||||
|
<div class="error"> |
||||
|
<div class="row"> |
||||
|
<div class="col-6 mx-auto"> |
||||
|
<div class="message"> |
||||
|
<div class="wrapper_img"> |
||||
|
<img src="theme_classic_store/static/src/images/404/404.png"/> |
||||
|
</div> |
||||
|
<div class="oops">Oops</div> |
||||
|
<p> |
||||
|
Something went wrong,we can't find the |
||||
|
page that you are looking for :(But |
||||
|
there is a |
||||
|
lot more for you! |
||||
|
</p> |
||||
|
<a href="/" class="btn btn-primary"> |
||||
|
Go Home |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
</odoo> |
@ -0,0 +1,55 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<template id="s_classic_store_about" name="About Us"> |
||||
|
<!-- This XML code defines a template for the "About Us" page of a website. |
||||
|
Includes sections for a banner and an introduction with text and an image. --> |
||||
|
<section class="banner_about"> |
||||
|
<div class="container"> |
||||
|
<h3>About Us</h3> |
||||
|
</div> |
||||
|
</section> |
||||
|
<section class="about"> |
||||
|
<div class="container"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-6 col-12"> |
||||
|
<div class="about_img"> |
||||
|
<img src="/theme_classic_store/static/src/images/about/about.jpg"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-6 col-12 mt-md-5"> |
||||
|
<div class="about_left"> |
||||
|
<h4>Introduction</h4> |
||||
|
<p> |
||||
|
Lorem ipsum dolor sit amet, consectetur |
||||
|
adipiscing elit. Nunc est justo, aliquam nec |
||||
|
tempor fermentum, commodo et libero. |
||||
|
Quisque et rutrum arcu. Vivamus dictum |
||||
|
tincidunt |
||||
|
magna id euismod. Nam sollicitudin mi quis orci |
||||
|
lobortis feugiat. |
||||
|
</p> |
||||
|
<h4>How Can We Help</h4> |
||||
|
<p> |
||||
|
Lorem ipsum dolor sit amet, consectetur |
||||
|
adipiscing elit. Nunc est justo, aliquam nec |
||||
|
tempor fermentum, commodo et libero. Quisque et |
||||
|
rutrum arcu. Vivamus dictum tincidunt magna id |
||||
|
euismod. Nam sollicitudin mi quis orci lobortis |
||||
|
feugiat. Lorem ipsum dolor sit amet, |
||||
|
consectetur |
||||
|
adipiscing elit. Nunc est justo, aliquam nec |
||||
|
tempor fermentum, commodo et libero. Quisque et |
||||
|
rutrum arcu. Lorem ipsum dolor sit amet, |
||||
|
consectetur adipiscing elit. Nunc est justo, |
||||
|
aliquam nec tempor fermentum, commodo et l |
||||
|
ibero. Quisque et rutrum arcu. Vivamus dictum |
||||
|
tincidunt magna id euismod. Nam sollicitudin mi |
||||
|
quis orci lobortis feugiat. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
</template> |
||||
|
</odoo> |
@ -0,0 +1,43 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<template id="s_classic_store_banner" name="Banner"> |
||||
|
<!-- the template defines a banner section with a card element displaying a message |
||||
|
and a popular categories section with clickable buttons. --> |
||||
|
<section class="banner"> |
||||
|
<div class="container"> |
||||
|
<div class="card"> |
||||
|
<div class="card-body"> |
||||
|
<h5 class="card-title">Buy & Sells Near You</h5> |
||||
|
<p class="card-text">Join the millions who buy and sell |
||||
|
from each other |
||||
|
<br/> |
||||
|
everyday in local communities around the world |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="populor text-center"> |
||||
|
<h4>POPULAR CATEGORIES</h4> |
||||
|
<div class="populor-buttons"> |
||||
|
<a href="" class="btn btn-pop"> |
||||
|
<span class="fa fa-bed"/> |
||||
|
Hotel |
||||
|
</a> |
||||
|
<a href="" class="btn btn-pop"><span |
||||
|
class="fab fa-grav"/>Fitness |
||||
|
</a> |
||||
|
<a href="" class="btn btn-pop"><span |
||||
|
class="fas fa-car-alt"/>Car |
||||
|
</a> |
||||
|
<a href="" class="btn btn-pop"><span |
||||
|
class="fab fa-android"/>Gadgets |
||||
|
</a> |
||||
|
<a href="" class="btn btn-pop"><span |
||||
|
class="fa fa-coffee"/>Cafe |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_structure"/> |
||||
|
</section> |
||||
|
</template> |
||||
|
</odoo> |
@ -0,0 +1,53 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<template id="s_classic_store_categories" name="Categories"> |
||||
|
<!-- The template renders a section for displaying product categories |
||||
|
in an Odoo e-commerce store. It uses a loop to iterate over the main categories and their child |
||||
|
categories to generate the necessary HTML. --> |
||||
|
<section class="categories"> |
||||
|
<div class="container"> |
||||
|
<div class="top_heading2 text-center"> |
||||
|
<h3 class="">All Categories</h3> |
||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipisicing |
||||
|
elit. |
||||
|
Quas, magnam. |
||||
|
</p> |
||||
|
<div class="bottom_line"/> |
||||
|
</div> |
||||
|
<div class="wrapper"> |
||||
|
<div class="row justify-content-center"> |
||||
|
<t t-foreach="product_categories_main" t-as="category"> |
||||
|
<div class="col-lg-3 col-md-6 col-12 p-3"> |
||||
|
<div class="c_wrapper" |
||||
|
style="height: 360px; overflow-x: auto;"> |
||||
|
<div class="categories_single p-1"> |
||||
|
<div class="c_img"> |
||||
|
<img t-attf-src="/web/image?model=product.public.category&field=image_1920&id=#{category.id}" |
||||
|
class="img img-fluid"/> |
||||
|
</div> |
||||
|
<h5> |
||||
|
<t t-esc="category.name"/> |
||||
|
</h5> |
||||
|
</div> |
||||
|
<ul class="categories_list"> |
||||
|
<t t-foreach="category.child_id" |
||||
|
t-as="child"> |
||||
|
<li> |
||||
|
<a t-attf-href="/shop/category/#{slug(child)}"> |
||||
|
<t t-esc="child.name"/> |
||||
|
</a> |
||||
|
<span> |
||||
|
<t t-esc="counter[child]"/> |
||||
|
</span> |
||||
|
</li> |
||||
|
</t> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
</template> |
||||
|
</odoo> |