Browse Source

Date : [UPDT] Index Updated : 'theme_coffee_shop'

pull/302/head
RisvanaCybro 1 year ago
parent
commit
9ffdb48062
  1. 13
      theme_coffee_shop/README.rst
  2. 5
      theme_coffee_shop/__init__.py
  3. 34
      theme_coffee_shop/__manifest__.py
  4. 5
      theme_coffee_shop/controllers/__init__.py
  5. 192
      theme_coffee_shop/controllers/theme_coffee_shop.py
  6. 11
      theme_coffee_shop/data/website_menu_data.xml
  7. 3
      theme_coffee_shop/doc/RELEASE_NOTES.md
  8. 4
      theme_coffee_shop/models/__init__.py
  9. 14
      theme_coffee_shop/models/theme_utils.py
  10. BIN
      theme_coffee_shop/static/description/banner.png
  11. BIN
      theme_coffee_shop/static/description/images/1.png
  12. BIN
      theme_coffee_shop/static/description/images/2.png
  13. BIN
      theme_coffee_shop/static/description/images/3.png
  14. BIN
      theme_coffee_shop/static/description/images/4.png
  15. BIN
      theme_coffee_shop/static/description/images/5.png
  16. BIN
      theme_coffee_shop/static/description/images/6.png
  17. BIN
      theme_coffee_shop/static/description/images/8.png
  18. BIN
      theme_coffee_shop/static/description/images/9.png
  19. BIN
      theme_coffee_shop/static/description/images/email.png
  20. 0
      theme_coffee_shop/static/description/images/odoo-consultancy.png
  21. 0
      theme_coffee_shop/static/description/images/odoo-integration.png
  22. BIN
      theme_coffee_shop/static/description/images/template-white-theam-36.png
  23. BIN
      theme_coffee_shop/static/description/images/template-white-theam-37.png
  24. BIN
      theme_coffee_shop/static/description/images/template-white-theam-38.jpg
  25. BIN
      theme_coffee_shop/static/description/images/template-white-theam-39.png
  26. BIN
      theme_coffee_shop/static/description/images/template-white-theam-40.jpg
  27. BIN
      theme_coffee_shop/static/description/images/template-white-theam-41.png
  28. BIN
      theme_coffee_shop/static/description/images/template-white-theam-42.png
  29. BIN
      theme_coffee_shop/static/description/images/template-white-theam-43.jpg
  30. BIN
      theme_coffee_shop/static/description/images/template-white-theam-45.png
  31. 0
      theme_coffee_shop/static/description/images/template-white-them-1.jpg
  32. 0
      theme_coffee_shop/static/description/images/template-white-them-12.jpg
  33. 0
      theme_coffee_shop/static/description/images/template-white-them-13.png
  34. 0
      theme_coffee_shop/static/description/images/template-white-them-14.png
  35. 0
      theme_coffee_shop/static/description/images/template-white-them-15.png
  36. 0
      theme_coffee_shop/static/description/images/template-white-them-16.png
  37. 0
      theme_coffee_shop/static/description/images/template-white-them-17.png
  38. 0
      theme_coffee_shop/static/description/images/template-white-them-18.jpg
  39. 0
      theme_coffee_shop/static/description/images/template-white-them-19.png
  40. 0
      theme_coffee_shop/static/description/images/template-white-them-2.png
  41. 0
      theme_coffee_shop/static/description/images/template-white-them-20.png
  42. 0
      theme_coffee_shop/static/description/images/template-white-them-21.png
  43. 0
      theme_coffee_shop/static/description/images/template-white-them-22.png
  44. 0
      theme_coffee_shop/static/description/images/template-white-them-23.png
  45. 0
      theme_coffee_shop/static/description/images/template-white-them-24.jpg
  46. 0
      theme_coffee_shop/static/description/images/template-white-them-25.png
  47. 0
      theme_coffee_shop/static/description/images/template-white-them-26.png
  48. 0
      theme_coffee_shop/static/description/images/template-white-them-27.jpg
  49. 0
      theme_coffee_shop/static/description/images/template-white-them-28.jpg
  50. 0
      theme_coffee_shop/static/description/images/template-white-them-29.jpg
  51. 0
      theme_coffee_shop/static/description/images/template-white-them-3.png
  52. 0
      theme_coffee_shop/static/description/images/template-white-them-30.png
  53. 0
      theme_coffee_shop/static/description/images/template-white-them-31.jpg
  54. 0
      theme_coffee_shop/static/description/images/template-white-them-32.jpg
  55. 0
      theme_coffee_shop/static/description/images/template-white-them-33.png
  56. 0
      theme_coffee_shop/static/description/images/template-white-them-34.jpg
  57. 0
      theme_coffee_shop/static/description/images/template-white-them-35.jpg
  58. 0
      theme_coffee_shop/static/description/images/template-white-them-4.jpg
  59. 0
      theme_coffee_shop/static/description/images/template-white-them-44.png
  60. 0
      theme_coffee_shop/static/description/images/template-white-them-47.png
  61. 0
      theme_coffee_shop/static/description/images/template-white-them-7.png
  62. 1750
      theme_coffee_shop/static/description/index.html
  63. BIN
      theme_coffee_shop/static/description/theme_screenshot.jpeg
  64. 479
      theme_coffee_shop/static/src/css/style.css
  65. 5
      theme_coffee_shop/static/src/images/featureitem1.svg
  66. 10
      theme_coffee_shop/static/src/images/featureitem2.svg
  67. 4
      theme_coffee_shop/static/src/images/featureitem3.svg
  68. 9
      theme_coffee_shop/static/src/images/google 1.svg
  69. 3
      theme_coffee_shop/static/src/images/search.svg
  70. 3
      theme_coffee_shop/static/src/images/shopfilter.svg
  71. 63
      theme_coffee_shop/static/src/js/action.js
  72. 32
      theme_coffee_shop/static/src/js/map_snippet.js
  73. 132
      theme_coffee_shop/views/about_us.xml
  74. 254
      theme_coffee_shop/views/address.xml
  75. 62
      theme_coffee_shop/views/cart.xml
  76. 37
      theme_coffee_shop/views/cart_lines.xml
  77. 85
      theme_coffee_shop/views/cart_popover.xml
  78. 23
      theme_coffee_shop/views/cart_summary.xml
  79. 56
      theme_coffee_shop/views/contact_us.xml
  80. 144
      theme_coffee_shop/views/feature.xml
  81. 48
      theme_coffee_shop/views/footer.xml
  82. 126
      theme_coffee_shop/views/header.xml
  83. 280
      theme_coffee_shop/views/login.xml
  84. 288
      theme_coffee_shop/views/menu_page.xml
  85. 139
      theme_coffee_shop/views/payment.xml
  86. 135
      theme_coffee_shop/views/payment_summary.xml
  87. 260
      theme_coffee_shop/views/product.xml
  88. 86
      theme_coffee_shop/views/shop.xml

13
theme_coffee_shop/README.rst

@ -1,18 +1,27 @@
.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg .. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3 :alt: License: LGPL-3
Theme Coffee Shop Theme Coffee Shop
================= =================
This is a theme for Coffee Shop. This is a theme for Coffee Shop.
Configuration
=============
No configuration
License
-------
General Public License, Version 3 (LGPL v3).
(https://www.gnu.org/licenses/lgpl-3.0-standalone.html)
Company Company
------- -------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ * `Cybrosys Techno Solutions <https://cybrosys.com/>`__
Credits Credits
------- -------
Developer: Ayisha Sumayya K and Abbas P @cybrosys, Contact: odoo@cybrosys.com Developer: (V16) Ayisha Sumayya K, Abbas P, ASWIN A K, Contact: odoo@cybrosys.com
Contacts Contacts
-------- --------

5
theme_coffee_shop/__init__.py

@ -3,7 +3,7 @@
# #
# Cybrosys Technologies Pvt. Ltd. # Cybrosys Technologies Pvt. Ltd.
# #
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) # Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ayisha Sumayya K (odoo@cybrosys.com) # Author: Ayisha Sumayya K (odoo@cybrosys.com)
# #
# You can modify it under the terms of the GNU LESSER # You can modify it under the terms of the GNU LESSER
@ -19,6 +19,5 @@
# If not, see <http://www.gnu.org/licenses/>. # If not, see <http://www.gnu.org/licenses/>.
# #
############################################################################# #############################################################################
from . import models
from . import controllers from . import controllers
from . import models

34
theme_coffee_shop/__manifest__.py

@ -3,8 +3,8 @@
# #
# Cybrosys Technologies Pvt. Ltd. # Cybrosys Technologies Pvt. Ltd.
# #
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) # Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ayisha Sumayya K(odoo@cybrosys.com) # Author: Ayisha Sumayya K (odoo@cybrosys.com)
# #
# You can modify it under the terms of the GNU LESSER # You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. # GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
@ -20,20 +20,27 @@
# #
############################################################################# #############################################################################
{ {
'name': 'Coffee Shop', 'name': 'Theme Coffee Shop',
'description': 'Theme Coffee Shop',
'summary': 'Theme Coffee Shop',
'version': '16.0.1.0.0', 'version': '16.0.1.0.0',
'category': 'Theme',
'summary': 'A Captivating and Practical E-Commerce Theme for Coffee Shops',
'description': 'Theme Coffee Shop brings a captivating and highly '
'practical theme crafted exclusively for e-Commerce'
' websites specializing in coffee shops. With its blend of '
'aesthetic appeal and user-centric design, this theme '
'provides an exceptional browsing and shopping experience '
'for coffee enthusiasts and customers.It encapsulates the'
' essence of a cozy coffee shop, translating it into an '
'engaging online platform for your coffee products and '
'accessories.',
'author': 'Cybrosys Techno Solutions', 'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions', 'company': 'Cybrosys Techno Solutions',
'website': 'https://www.cybrosys.com',
'maintainer': 'Cybrosys Techno Solutions', 'maintainer': 'Cybrosys Techno Solutions',
'category': 'Theme/Creative', 'website': 'https://www.cybrosys.com',
'depends': ['website_sale', 'website_sale_wishlist','auth_oauth', ], 'depends': ['website_sale_wishlist', 'auth_oauth'],
'data': [ 'data': [
'data/menu.xml', 'data/website_menu_data.xml',
'views/header.xml', 'views/header.xml',
'views/login.xml',
'views/footer.xml', 'views/footer.xml',
'views/contact_us.xml', 'views/contact_us.xml',
'views/cart.xml', 'views/cart.xml',
@ -52,14 +59,13 @@
'assets': { 'assets': {
'web.assets_frontend': [ 'web.assets_frontend': [
'theme_coffee_shop/static/src/css/style.css', 'theme_coffee_shop/static/src/css/style.css',
'theme_coffee_shop/static/src/js/action.js', 'theme_coffee_shop/static/src/js/map_snippet.js',
], ],
}, },
'images': ['static/description/banner.png', 'images': ['static/description/banner.png',
'static/description/theme_screenshot.jpeg'], 'static/src/images/thumbnail/theme_coffee.jpeg'],
'license': 'LGPL-3', 'license': 'LGPL-3',
'auto_install': False,
'installable': True, 'installable': True,
'auto_install': False,
'application': False 'application': False
} }

5
theme_coffee_shop/controllers/__init__.py

@ -3,7 +3,7 @@
# #
# Cybrosys Technologies Pvt. Ltd. # Cybrosys Technologies Pvt. Ltd.
# #
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) # Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ayisha Sumayya K (odoo@cybrosys.com) # Author: Ayisha Sumayya K (odoo@cybrosys.com)
# #
# You can modify it under the terms of the GNU LESSER # You can modify it under the terms of the GNU LESSER
@ -19,5 +19,4 @@
# If not, see <http://www.gnu.org/licenses/>. # If not, see <http://www.gnu.org/licenses/>.
# #
############################################################################# #############################################################################
from . import theme_coffee_shop
from . import menu_page

192
theme_coffee_shop/controllers/menu_page.py → theme_coffee_shop/controllers/theme_coffee_shop.py

@ -1,9 +1,10 @@
"""Controller for rendering datas to menu page"""
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################################# #############################################################################
# #
# Cybrosys Technologies Pvt. Ltd. # Cybrosys Technologies Pvt. Ltd.
# #
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) # Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ayisha Sumayya K (odoo@cybrosys.com) # Author: Ayisha Sumayya K (odoo@cybrosys.com)
# #
# You can modify it under the terms of the GNU LESSER # You can modify it under the terms of the GNU LESSER
@ -19,29 +20,28 @@
# If not, see <http://www.gnu.org/licenses/>. # If not, see <http://www.gnu.org/licenses/>.
# #
############################################################################# #############################################################################
from collections import defaultdict from collections import defaultdict
from itertools import product as cartesian_product
from datetime import datetime from datetime import datetime
from itertools import product as cartesian_product
from werkzeug.exceptions import NotFound from werkzeug.exceptions import NotFound
from odoo import http, tools
from odoo import fields, http, tools, _
from odoo.http import request from odoo.http import request
from odoo.osv import expression
from odoo.tools import lazy
from odoo.addons.http_routing.models.ir_http import slug from odoo.addons.http_routing.models.ir_http import slug
from odoo.addons.website.controllers.main import QueryURL from odoo.addons.website.controllers.main import QueryURL
from odoo.addons.website.models.ir_http import sitemap_qs2dom from odoo.addons.website.models.ir_http import sitemap_qs2dom
from odoo.osv import expression
from odoo.tools import lazy
class TableComputeCoffee(object): class TableComputeCoffee(object):
""" Compute data related to coffee shop theme """ """ Compute data related to coffee shop theme """
def __init__(self): def __init__(self):
""" The init for menu page"""
self.table = {} self.table = {}
def _check_place(self, posx, posy, sizex, sizey, ppr): def _check_place(self, posx, posy, sizex, sizey, ppr):
"""Function for check place"""
res = True res = True
for yaxix in range(sizey): for yaxix in range(sizey):
for xaxix in range(sizex): for xaxix in range(sizex):
@ -52,7 +52,7 @@ class TableComputeCoffee(object):
if row.setdefault(posx + xaxix) is not None: if row.setdefault(posx + xaxix) is not None:
res = False res = False
break break
for x in range(ppr): for rec in range(ppr):
self.table[posy + yaxix].setdefault(xaxix, None) self.table[posy + yaxix].setdefault(xaxix, None)
return res return res
@ -67,19 +67,17 @@ class TableComputeCoffee(object):
res = min(max(pdct.website_size_y, 1), ppr) res = min(max(pdct.website_size_y, 1), ppr)
if index >= ppg: if index >= ppg:
rec = res = 1 rec = res = 1
pos = minpos pos = minpos
while not self._check_place(pos % ppr, pos // ppr, rec, res, ppr): while not self._check_place(pos % ppr, pos // ppr, rec, res, ppr):
pos += 1 pos += 1
if index >= ppg and ((pos + 1.0) // ppr) > maxy: if index >= ppg and ((pos + 1.0) // ppr) > maxy:
break break
if rec == 1 and res == 1: if rec == 1 and res == 1:
minpos = pos // ppr minpos = pos // ppr
for sec_y2 in range(res):
for y2 in range(res): for sec_x2 in range(rec):
for x2 in range(rec): self.table[(pos // ppr) + sec_y2][
self.table[(pos // ppr) + y2][(pos % ppr) + x2] = False (pos % ppr) + sec_x2] = False
self.table[pos // ppr][pos % ppr] = { self.table[pos // ppr][pos % ppr] = {
'product': pdct, 'x': rec, 'y': res, 'product': pdct, 'x': rec, 'y': res,
'ribbon': pdct._get_website_ribbon(), 'ribbon': pdct._get_website_ribbon(),
@ -87,30 +85,29 @@ class TableComputeCoffee(object):
if index <= ppg: if index <= ppg:
maxy = max(maxy, res + (pos // ppr)) maxy = max(maxy, res + (pos // ppr))
index += 1 index += 1
rows = sorted(self.table.items()) rows = sorted(self.table.items())
rows = [r[1] for r in rows] rows = [r[1] for r in rows]
for col in range(len(rows)): for col in range(len(rows)):
cols = sorted(rows[col].items()) cols = sorted(rows[col].items())
rec += len(cols) rec += len(cols)
rows[col] = [r[1] for r in cols if r[1]] rows[col] = [res[1] for res in cols if res[1]]
return rows return rows
class ThemeCoffeeMenu(http.Controller): class ThemeCoffeeMenu(http.Controller):
""" controller for rendering datas to menu page """ """ Controller for rendering datas to menu page """
def _get_search_order(self, post): def _get_search_order(self, post):
""" OrderBy will be parsed in orm and so no direct sql injection id is """ OrderBy will be parsed in orm and so no direct sql injection id is
added to be sure that order is a unique sort key added to be sure that order is a unique sort key
""" """
order = post.get('order') or \ order = post.get('order') or request.env[
request.env['website'].get_current_website().shop_default_sort 'website'].get_current_website().shop_default_sort
return 'is_published desc, %s, id desc' % order return 'is_published desc, %s, id desc' % order
def _get_search_domain(self, search, category, attrib_values, def _get_search_domain(self, search, category, attrib_values,
search_in_description=True): search_in_description=True):
"""Function for getting search domain"""
domains = [request.website.sale_product_domain()] domains = [request.website.sale_product_domain()]
if search: if search:
for srch in search.split(" "): for srch in search.split(" "):
@ -122,10 +119,8 @@ class ThemeCoffeeMenu(http.Controller):
subdomains.append([('website_description', 'ilike', srch)]) subdomains.append([('website_description', 'ilike', srch)])
subdomains.append([('description_sale', 'ilike', srch)]) subdomains.append([('description_sale', 'ilike', srch)])
domains.append(expression.OR(subdomains)) domains.append(expression.OR(subdomains))
if category: if category:
domains.append([('public_categ_ids', 'child_of', int(category))]) domains.append([('public_categ_ids', 'child_of', int(category))])
if attrib_values: if attrib_values:
attrib = None attrib = None
ids = [] ids = []
@ -136,28 +131,29 @@ class ThemeCoffeeMenu(http.Controller):
elif value[0] == attrib: elif value[0] == attrib:
ids.append(value[1]) ids.append(value[1])
else: else:
domains.append([('attribute_line_ids.value_ids', 'in', ids)]) domains.append([
('attribute_line_ids.value_ids', 'in', ids)])
attrib = value[0] attrib = value[0]
ids = [value[1]] ids = [value[1]]
if attrib: if attrib:
domains.append([('attribute_line_ids.value_ids', 'in', ids)]) domains.append([('attribute_line_ids.value_ids', 'in', ids)])
return expression.AND(domains) return expression.AND(domains)
def sitemap_shop(env, rule, qs): def sitemap_shop(env, rule, qs):
"""Sitemap for shop"""
if not qs or qs.lower() in '/menu': if not qs or qs.lower() in '/menu':
yield {'loc': '/menu'} yield {'loc': '/menu'}
category = env['product.public.category']
Category = env['product.public.category'] dom = sitemap_qs2dom(qs, '/menu/category', category._rec_name)
dom = sitemap_qs2dom(qs, '/menu/category', Category._rec_name)
dom += env['website'].get_current_website().website_domain() dom += env['website'].get_current_website().website_domain()
for cat in Category.search(dom): for cat in category.search(dom):
loc = '/menu/category/%s' % slug(cat) loc = '/menu/category/%s' % slug(cat)
if not qs or qs.lower() in loc: if not qs or qs.lower() in loc:
yield {'loc': loc} yield {'loc': loc}
def _get_search_options( def _get_search_options(
self, category=None, attrib_values=None, pricelist=None, **post): self, category=None, attrib_values=None, pricelist=None, **post):
"""Function for returning search options"""
return { return {
'displayDescription': True, 'displayDescription': True,
'displayDetail': True, 'displayDetail': True,
@ -170,10 +166,10 @@ class ThemeCoffeeMenu(http.Controller):
'display_currency': pricelist.currency_id, 'display_currency': pricelist.currency_id,
} }
def _shop_lookup_products(self, attrib_set, options, post, search, website): def _shop_lookup_products(self, attrib_set, options,
post, search, website):
""" No limit because attributes are obtained from complete """ No limit because attributes are obtained from complete
product list""" product list"""
product_count, details, fuzzy_search_term = website._search_with_fuzzy( product_count, details, fuzzy_search_term = website._search_with_fuzzy(
"products_only", search, limit=None, "products_only", search, limit=None,
order=self._get_search_order(post), options=options order=self._get_search_order(post), options=options
@ -182,10 +178,10 @@ class ThemeCoffeeMenu(http.Controller):
'results', request.env['product.template'] 'results', request.env['product.template']
).with_context(bin_size=True) ).with_context(bin_size=True)
if attrib_set: if attrib_set:
attribute_values = request.env['product.attribute.value'].browse(attrib_set) attribute_values = request.env[
'product.attribute.value'].browse(attrib_set)
values_per_attribute = defaultdict( values_per_attribute = defaultdict(
lambda: request.env['product.attribute.value']) lambda: request.env['product.attribute.value'])
multi_value_attribute = False multi_value_attribute = False
for value in attribute_values: for value in attribute_values:
values_per_attribute[value.attribute_id] |= value values_per_attribute[value.attribute_id] |= value
@ -195,16 +191,18 @@ class ThemeCoffeeMenu(http.Controller):
def filter_template(template, attribute_values_list): def filter_template(template, attribute_values_list):
"""Transform product.attribute.value to """Transform product.attribute.value to
product.template.attribute.value """ product.template.attribute.value """
attribute_value_to_ptav = dict() attribute_value_to_ptav = {}
for ptav in template.attribute_line_ids.product_template_value_ids: for ptav in \
attribute_value_to_ptav[ptav.product_attribute_value_id] = ptav.id template.attribute_line_ids.product_template_value_ids:
attribute_value_to_ptav[
ptav.product_attribute_value_id] = ptav.id
possible_combinations = False possible_combinations = False
for attribute_values in attribute_values_list: for attribute_values in attribute_values_list:
ptavs = request.env['product.template.attribute.value'].browse( ptav_ids = [attribute_value_to_ptav[val] for val in
[attribute_value_to_ptav[val] attribute_values if
for val in attribute_values val in attribute_value_to_ptav]
if val in attribute_value_to_ptav] ptavs = request.env[
) 'product.template.attribute.value'].browse(ptav_ids)
if len(ptavs) < len(attribute_values): if len(ptavs) < len(attribute_values):
continue continue
if len(ptavs) == len(template.attribute_line_ids): if len(ptavs) == len(template.attribute_line_ids):
@ -212,32 +210,33 @@ class ThemeCoffeeMenu(http.Controller):
return True return True
elif len(ptavs) < len(template.attribute_line_ids): elif len(ptavs) < len(template.attribute_line_ids):
if len(attribute_values_list) == 1: if len(attribute_values_list) == 1:
if any(template._get_possible_combinations( possible_combinations = template._get_possible_combinations(
necessary_values=ptavs)): necessary_values=ptavs)
if any(possible_combinations):
return True return True
if not possible_combinations: if not possible_combinations:
possible_combinations = template._get_possible_combinations() possible_combinations = template._get_possible_combinations()
if any(len(ptavs & combination) == len(ptavs) for combination in possible_combinations:
for combination in possible_combinations): if ptavs.issubset(combination):
return True return True
return False return False
if not multi_value_attribute: if not multi_value_attribute:
possible_attrib_values_list = [attribute_values] possible_attrib_values_list = [attribute_values]
else: else:
possible_attrib_values_list = [ possible_attrib_values_list = [attribute_values] if not \
request.env['product.attribute.value'].browse( multi_value_attribute else \
[v.id for v in values]) for values in cartesian_product( [request.env['product.attribute.value']
*values_per_attribute.values()) .browse([rec.id for rec in values]) for values in
] cartesian_product(*values_per_attribute.values())]
search_result = search_result.filtered( search_result = search_result.filtered(
lambda tmpl: filter_template(tmpl, possible_attrib_values_list) lambda tmpl: filter_template(possible_attrib_values_list)
) )
return fuzzy_search_term, product_count, search_result return fuzzy_search_term, product_count, search_result
def _menu_get_query_url_kwargs(self, category, search, attrib=None, def _menu_get_query_url_kwargs(self, category, search, attrib=None,
order=None, **post): order=None):
"""Function for returning category, search, order and attribute"""
return { return {
'category': category, 'category': category,
'search': search, 'search': search,
@ -245,28 +244,24 @@ class ThemeCoffeeMenu(http.Controller):
'order': order, 'order': order,
} }
def _get_additional_shop_values(self, values):
""" Hook to update values used for rendering website_sale.products template """
return {}
@http.route([ @http.route([
'/menu', '/menu',
'/menu/page/<int:page>', '/menu/page/<int:page>',
'/menu/category/<model("product.public.category"):category>', '/menu/category/<model("product.public.category"):category>',
'/menu/category/<model("product.public.category"):category>/page/<int:page>', '/menu/category/<model("product.public.category"):'
'category>/page/<int:page>',
], type='http', auth="public", website=True, sitemap=sitemap_shop) ], type='http', auth="public", website=True, sitemap=sitemap_shop)
def menu_page(self, page=0, category=None, search='', def menu_page(self, page=0, category=None, search='',
min_price=0.0, max_price=0.0, ppg=False, **post): min_price=0.0, max_price=0.0, ppg=False, **post):
add_qty = int(post.get('add_qty', 1)) """Function for rendering menu page"""
category_id = request.env['product.public.category']
Category = request.env['product.public.category']
if category: if category:
category = Category.search([('id', '=', int(category))], limit=1) category = category_id.search([('id', '=', int(category))],
limit=1)
if not category or not category.can_access_from_current_website(): if not category or not category.can_access_from_current_website():
raise NotFound() raise NotFound()
else: else:
category = Category category = category_id
website = request.env['website'].get_current_website() website = request.env['website'].get_current_website()
if ppg: if ppg:
try: try:
@ -276,37 +271,30 @@ class ThemeCoffeeMenu(http.Controller):
ppg = False ppg = False
if not ppg: if not ppg:
ppg = website.shop_ppg or 20 ppg = website.shop_ppg or 20
ppr = website.shop_ppr or 4 ppr = website.shop_ppr or 4
attrib_list = request.httprequest.args.getlist('attrib') attrib_list = request.httprequest.args.getlist('attrib')
attrib_values = [[int(x) for x in v.split("-")] attrib_values = [[int(rec) for rec in res.split("-")]
for v in attrib_list if v for res in attrib_list if res
] ]
attributes_ids = {v[0] for v in attrib_values} attributes_ids = {res[0] for res in attrib_values}
attrib_set = {v[1] for v in attrib_values} attrib_set = {res[1] for res in attrib_values}
keep = QueryURL('/menu', **self._menu_get_query_url_kwargs(
keep = QueryURL('/menu', **self._menu_get_query_url_kwargs(category category and int(category), search, min_price, max_price, **post))
and int(category), search, min_price, max_price, **post))
now = datetime.timestamp(datetime.now()) now = datetime.timestamp(datetime.now())
pricelist = request.env['product.pricelist'].\ pricelist = request.env['product.pricelist']. \
browse(request.session.get('website_sale_current_pl')) browse(request.session.get('website_sale_current_pl'))
if not pricelist or request.session.\ if not pricelist or request.session. \
get('website_sale_pricelist_time', 0) < now - 60*60: get('website_sale_pricelist_time', 0) < now - 60 * 60:
pricelist = website.get_current_pricelist() pricelist = website.get_current_pricelist()
request.session['website_sale_pricelist_time'] = now request.session['website_sale_pricelist_time'] = now
request.session['website_sale_current_pl'] = pricelist.id request.session['website_sale_current_pl'] = pricelist.id
request.update_context(pricelist=pricelist.id, request.update_context(pricelist=pricelist.id,
partner=request.env.user.partner_id) partner=request.env.user.partner_id)
url = "/menu" url = "/menu"
if search: if search:
post["search"] = search post["search"] = search
if attrib_list: if attrib_list:
post['attrib'] = attrib_list post['attrib'] = attrib_list
options = self._get_search_options( options = self._get_search_options(
category=category, category=category,
attrib_values=attrib_values, attrib_values=attrib_values,
@ -314,37 +302,33 @@ class ThemeCoffeeMenu(http.Controller):
**post **post
) )
fuzzy_search_term, product_count, search_product = \ fuzzy_search_term, product_count, search_product = \
self._shop_lookup_products(attrib_set, options, post, search, website) self._shop_lookup_products(
attrib_set, options, post, search, website)
website_domain = website.website_domain() website_domain = website.website_domain()
categs_domain = [('parent_id', '=', False)] + website_domain categs_domain = [('parent_id', '=', False)] + website_domain
if search: if search:
search_categories = Category.search( search_categories = category_id.search(
[('product_tmpl_ids', 'in', search_product.ids)] + website_domain [('product_tmpl_ids', 'in', search_product.ids)
] + website_domain
).parents_and_self ).parents_and_self
categs_domain.append(('id', 'in', search_categories.ids)) categs_domain.append(('id', 'in', search_categories.ids))
else: else:
search_categories = Category search_categories = category_id
categs = lazy(lambda: Category.search(categs_domain)) categs = lazy(lambda: category_id.search(categs_domain))
if category: if category:
url = "/menu/category/%s" % slug(category) url = "/menu/category/%s" % slug(category)
pager = website.pager(url=url, total=product_count, page=page, pager = website.pager(url=url, total=product_count, page=page,
step=ppg, scope=7, url_args=post) step=ppg, scope=7, url_args=post)
offset = pager['offset'] offset = pager['offset']
products = search_product[offset:offset + ppg] products = search_product[offset:offset + ppg]
product_attribute = request.env['product.attribute']
ProductAttribute = request.env['product.attribute']
if products: if products:
attributes = lazy(lambda: ProductAttribute.search([ attributes = lazy(lambda: product_attribute.search([
('product_tmpl_ids', 'in', search_product.ids), ('product_tmpl_ids', 'in', search_product.ids),
('visibility', '=', 'visible'), ('visibility', '=', 'visible'),
])) ]))
else: else:
attributes = lazy(lambda: ProductAttribute.browse(attributes_ids)) attributes = lazy(lambda: product_attribute.browse(attributes_ids))
layout_mode = request.session.get('website_sale_shop_layout_mode') layout_mode = request.session.get('website_sale_shop_layout_mode')
if not layout_mode: if not layout_mode:
if website.viewref('website_sale.products_list_view').active: if website.viewref('website_sale.products_list_view').active:
@ -352,9 +336,7 @@ class ThemeCoffeeMenu(http.Controller):
else: else:
layout_mode = 'grid' layout_mode = 'grid'
request.session['website_sale_shop_layout_mode'] = layout_mode request.session['website_sale_shop_layout_mode'] = layout_mode
products_prices = lazy(lambda: products._get_sales_prices(pricelist)) products_prices = lazy(lambda: products._get_sales_prices(pricelist))
values = { values = {
'order': post.get('order', ''), 'order': post.get('order', ''),
'category': category, 'category': category,
@ -362,11 +344,12 @@ class ThemeCoffeeMenu(http.Controller):
'attrib_set': attrib_set, 'attrib_set': attrib_set,
'pager': pager, 'pager': pager,
'pricelist': pricelist, 'pricelist': pricelist,
'add_qty': add_qty, 'add_qty': int(post.get('add_qty', 1)),
'products': products, 'products': products,
'search_product': search_product, 'search_product': search_product,
'search_count': product_count, 'search_count': product_count,
'bins': lazy(lambda: TableComputeCoffee().process(products, ppg, ppr)), 'bins': lazy(lambda: TableComputeCoffee().process(
products, ppg, ppr)),
'ppg': ppg, 'ppg': ppg,
'ppr': ppr, 'ppr': ppr,
'categories': categs, 'categories': categs,
@ -381,5 +364,14 @@ class ThemeCoffeeMenu(http.Controller):
} }
if category: if category:
values['main_object'] = category values['main_object'] = category
values.update(self._get_additional_shop_values(values)) # print(values)
return request.render("theme_coffee_shop.coffee_menu", values) return request.render("theme_coffee_shop.coffee_menu", values)
@http.route(
'/get-company/address', type='json', auth="public", website=True)
def get_company_address(self):
user_id = request.env.user
return ' '.join(filter(None, (
user_id.company_id.street, user_id.company_id.city,
user_id.company_id.state_id.display_name,
user_id.company_id.country_id.display_name)))

11
theme_coffee_shop/data/menu.xml → theme_coffee_shop/data/website_menu_data.xml

@ -1,27 +1,26 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<data noupdate="1"> <data noupdate="1">
<!-- Define a menu item for "About us" -->
<record id="menu_about_sub" model="website.menu"> <record id="menu_about_sub" model="website.menu">
<field name="name">About us</field> <field name="name">About us</field>
<field name="url">/about</field> <field name="url">/about</field>
<field name="parent_id" ref="website.main_menu"/> <field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">30</field> <field name="sequence" type="int">30</field>
</record> </record>
<!-- Define a menu item for "Features" -->
<record id="menu_feature" model="website.menu"> <record id="menu_feature" model="website.menu">
<field name="name">Features</field> <field name="name">Features</field>
<field name="url">/feature</field> <field name="url">/feature</field>
<field name="parent_id" ref="website.main_menu"/> <field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">35</field> <field name="sequence" type="int">35</field>
</record> </record>
<!-- Define a menu item for "Menu" -->
<record id="menu_menu" model="website.menu"> <record id="menu_menu" model="website.menu">
<field name="name">Menu</field> <field name="name">Menu</field>
<field name="url">/menu</field> <field name="url">/menu</field>
<field name="parent_id" ref="website.main_menu"/> <field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">15</field> <field name="sequence" type="int">15</field>
</record> </record>
</data> </data>
</odoo> </odoo>

3
theme_coffee_shop/doc/RELEASE_NOTES.md

@ -1,7 +1,6 @@
## Module <theme_coffee_shop> ## Module <theme_coffee_shop>
#### 21.02.2023 #### 22.01.2024
#### Version 16.0.1.0.0 #### Version 16.0.1.0.0
#### ADD #### ADD
- Initial commit for Theme Coffee Shop - Initial commit for Theme Coffee Shop

4
theme_coffee_shop/models/__init__.py

@ -3,7 +3,7 @@
# #
# Cybrosys Technologies Pvt. Ltd. # Cybrosys Technologies Pvt. Ltd.
# #
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) # Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ayisha Sumayya K (odoo@cybrosys.com) # Author: Ayisha Sumayya K (odoo@cybrosys.com)
# #
# You can modify it under the terms of the GNU LESSER # You can modify it under the terms of the GNU LESSER
@ -19,4 +19,4 @@
# If not, see <http://www.gnu.org/licenses/>. # If not, see <http://www.gnu.org/licenses/>.
# #
############################################################################# #############################################################################
from . import main from . import theme_utils

14
theme_coffee_shop/models/main.py → theme_coffee_shop/models/theme_utils.py

@ -1,9 +1,10 @@
""" Class for enable and disable templates when using coffee shop theme """
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################################# #############################################################################
# #
# Cybrosys Technologies Pvt. Ltd. # Cybrosys Technologies Pvt. Ltd.
# #
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) # Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ayisha Sumayya K (odoo@cybrosys.com) # Author: Ayisha Sumayya K (odoo@cybrosys.com)
# #
# You can modify it under the terms of the GNU LESSER # You can modify it under the terms of the GNU LESSER
@ -19,17 +20,16 @@
# If not, see <http://www.gnu.org/licenses/>. # If not, see <http://www.gnu.org/licenses/>.
# #
############################################################################# #############################################################################
from odoo import models, api, fields from odoo import api, models
class ThemeCoffee(models.AbstractModel): class ThemeUtils(models.AbstractModel):
""" class for enable and disable templates when using coffee shop theme """ """ Class for enable and disable templates when using coffee shop theme """
_inherit = 'theme.utils' _inherit = 'theme.utils'
@api.model @api.model
def _theme_coffee_shop_post_copy(self, mod): def _theme_coffee_shop_post_copy(self, mod):
""" enable and disable templates when using coffee shop theme """ """ Enable and disable templates when using coffee shop theme """
self.enable_view("website_sale.products_categories") self.enable_view("website_sale.products_categories")
self.enable_view("website_sale.products_description") self.enable_view("website_sale.products_description")
self.enable_view("website_sale.products_design_card") self.enable_view("website_sale.products_design_card")
@ -37,7 +37,5 @@ class ThemeCoffee(models.AbstractModel):
self.enable_view("website_sale.product_comment") self.enable_view("website_sale.product_comment")
self.enable_view("website_sale.option_collapse_products_categories") self.enable_view("website_sale.option_collapse_products_categories")
self.enable_view("website_sale.product_buy_now") self.enable_view("website_sale.product_buy_now")
self.disable_view("website_sale.products_categories_top") self.disable_view("website_sale.products_categories_top")
self.disable_view("website_sale.products_design_grid") self.disable_view("website_sale.products_design_grid")

BIN
theme_coffee_shop/static/description/banner.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

After

Width:  |  Height:  |  Size: 403 KiB

BIN
theme_coffee_shop/static/description/images/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
theme_coffee_shop/static/description/images/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

BIN
theme_coffee_shop/static/description/images/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
theme_coffee_shop/static/description/images/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

BIN
theme_coffee_shop/static/description/images/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
theme_coffee_shop/static/description/images/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 638 KiB

BIN
theme_coffee_shop/static/description/images/8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 KiB

BIN
theme_coffee_shop/static/description/images/9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

BIN
theme_coffee_shop/static/description/images/email.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

0
theme_coffee_shop/static/description/images/odoo-consultency.png → theme_coffee_shop/static/description/images/odoo-consultancy.png

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

0
theme_coffee_shop/static/description/images/odoo-intergration.png → theme_coffee_shop/static/description/images/odoo-integration.png

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
theme_coffee_shop/static/description/images/template-white-theam-36.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 735 KiB

BIN
theme_coffee_shop/static/description/images/template-white-theam-37.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 576 KiB

BIN
theme_coffee_shop/static/description/images/template-white-theam-38.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 954 KiB

BIN
theme_coffee_shop/static/description/images/template-white-theam-39.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

BIN
theme_coffee_shop/static/description/images/template-white-theam-40.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 972 KiB

BIN
theme_coffee_shop/static/description/images/template-white-theam-41.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

BIN
theme_coffee_shop/static/description/images/template-white-theam-42.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 809 KiB

BIN
theme_coffee_shop/static/description/images/template-white-theam-43.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 922 KiB

BIN
theme_coffee_shop/static/description/images/template-white-theam-45.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-1.jpg → theme_coffee_shop/static/description/images/template-white-them-1.jpg

Before

Width:  |  Height:  |  Size: 990 KiB

After

Width:  |  Height:  |  Size: 990 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-12.jpg → theme_coffee_shop/static/description/images/template-white-them-12.jpg

Before

Width:  |  Height:  |  Size: 930 KiB

After

Width:  |  Height:  |  Size: 930 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-13.png → theme_coffee_shop/static/description/images/template-white-them-13.png

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-14.png → theme_coffee_shop/static/description/images/template-white-them-14.png

Before

Width:  |  Height:  |  Size: 165 KiB

After

Width:  |  Height:  |  Size: 165 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-15.png → theme_coffee_shop/static/description/images/template-white-them-15.png

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

0
theme_coffee_shop/static/description/images/template-white-theam-16.png → theme_coffee_shop/static/description/images/template-white-them-16.png

Before

Width:  |  Height:  |  Size: 269 KiB

After

Width:  |  Height:  |  Size: 269 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-17.png → theme_coffee_shop/static/description/images/template-white-them-17.png

Before

Width:  |  Height:  |  Size: 195 KiB

After

Width:  |  Height:  |  Size: 195 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-18.jpg → theme_coffee_shop/static/description/images/template-white-them-18.jpg

Before

Width:  |  Height:  |  Size: 950 KiB

After

Width:  |  Height:  |  Size: 950 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-19.png → theme_coffee_shop/static/description/images/template-white-them-19.png

Before

Width:  |  Height:  |  Size: 570 KiB

After

Width:  |  Height:  |  Size: 570 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-2.png → theme_coffee_shop/static/description/images/template-white-them-2.png

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 107 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-20.png → theme_coffee_shop/static/description/images/template-white-them-20.png

Before

Width:  |  Height:  |  Size: 245 KiB

After

Width:  |  Height:  |  Size: 245 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-21.png → theme_coffee_shop/static/description/images/template-white-them-21.png

Before

Width:  |  Height:  |  Size: 328 KiB

After

Width:  |  Height:  |  Size: 328 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-22.png → theme_coffee_shop/static/description/images/template-white-them-22.png

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-23.png → theme_coffee_shop/static/description/images/template-white-them-23.png

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-24.jpg → theme_coffee_shop/static/description/images/template-white-them-24.jpg

Before

Width:  |  Height:  |  Size: 890 KiB

After

Width:  |  Height:  |  Size: 890 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-25.png → theme_coffee_shop/static/description/images/template-white-them-25.png

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 84 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-26.png → theme_coffee_shop/static/description/images/template-white-them-26.png

Before

Width:  |  Height:  |  Size: 283 KiB

After

Width:  |  Height:  |  Size: 283 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-27.jpg → theme_coffee_shop/static/description/images/template-white-them-27.jpg

Before

Width:  |  Height:  |  Size: 993 KiB

After

Width:  |  Height:  |  Size: 993 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-28.jpg → theme_coffee_shop/static/description/images/template-white-them-28.jpg

Before

Width:  |  Height:  |  Size: 928 KiB

After

Width:  |  Height:  |  Size: 928 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-29.jpg → theme_coffee_shop/static/description/images/template-white-them-29.jpg

Before

Width:  |  Height:  |  Size: 940 KiB

After

Width:  |  Height:  |  Size: 940 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-3.png → theme_coffee_shop/static/description/images/template-white-them-3.png

Before

Width:  |  Height:  |  Size: 553 KiB

After

Width:  |  Height:  |  Size: 553 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-30.png → theme_coffee_shop/static/description/images/template-white-them-30.png

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-31.jpg → theme_coffee_shop/static/description/images/template-white-them-31.jpg

Before

Width:  |  Height:  |  Size: 975 KiB

After

Width:  |  Height:  |  Size: 975 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-32.jpg → theme_coffee_shop/static/description/images/template-white-them-32.jpg

Before

Width:  |  Height:  |  Size: 999 KiB

After

Width:  |  Height:  |  Size: 999 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-33.png → theme_coffee_shop/static/description/images/template-white-them-33.png

Before

Width:  |  Height:  |  Size: 329 KiB

After

Width:  |  Height:  |  Size: 329 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-34.jpg → theme_coffee_shop/static/description/images/template-white-them-34.jpg

Before

Width:  |  Height:  |  Size: 969 KiB

After

Width:  |  Height:  |  Size: 969 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-35.jpg → theme_coffee_shop/static/description/images/template-white-them-35.jpg

Before

Width:  |  Height:  |  Size: 924 KiB

After

Width:  |  Height:  |  Size: 924 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-4.jpg → theme_coffee_shop/static/description/images/template-white-them-4.jpg

Before

Width:  |  Height:  |  Size: 953 KiB

After

Width:  |  Height:  |  Size: 953 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-44.png → theme_coffee_shop/static/description/images/template-white-them-44.png

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 109 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-47.png → theme_coffee_shop/static/description/images/template-white-them-47.png

Before

Width:  |  Height:  |  Size: 670 KiB

After

Width:  |  Height:  |  Size: 670 KiB

0
theme_coffee_shop/static/description/images/template-white-theam-7.png → theme_coffee_shop/static/description/images/template-white-them-7.png

Before

Width:  |  Height:  |  Size: 269 KiB

After

Width:  |  Height:  |  Size: 269 KiB

1750
theme_coffee_shop/static/description/index.html

File diff suppressed because it is too large

BIN
theme_coffee_shop/static/description/theme_screenshot.jpeg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 658 KiB

479
theme_coffee_shop/static/src/css/style.css

File diff suppressed because it is too large

5
theme_coffee_shop/static/src/images/featureitem1.svg

@ -1,5 +0,0 @@
<svg width="67" height="75" viewBox="0 0 67 75" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M61.2122 71.8909V71.8906V21.8344C61.2122 21.1071 60.6222 20.5171 59.8949 20.5171H53.3084V4.70973C53.3084 4.11935 52.9159 3.60134 52.3476 3.44127C51.9579 3.33182 42.6972 0.757812 33.5495 0.757812C24.4018 0.757812 15.1407 3.33182 14.7507 3.44127C14.1821 3.60134 13.7899 4.11935 13.7899 4.70973V20.5171H7.20372C6.47644 20.5171 5.88641 21.1071 5.88641 21.8344V71.8909H0.617188V74.5256H7.20372H59.8949H66.4814V71.8909H61.2122ZM16.4249 21.8344V5.72721C19.0156 5.07765 26.4278 3.39243 33.5495 3.39243C40.6712 3.39243 48.0834 5.07765 50.6741 5.72721V21.8344V36.3244H16.4249V21.8344ZM40.1357 56.0833V63.9867V70.5733H26.963V54.766H40.1357V56.0833ZM58.5776 71.8909H42.7699V71.8906V65.3041H48.0392C48.7664 65.3041 49.3565 64.714 49.3565 63.9867V56.0833C49.3565 55.356 48.7664 54.766 48.0392 54.766H42.7699V53.4487C42.7699 52.7214 42.1799 52.1313 41.4526 52.1313H25.6457C24.9184 52.1313 24.3284 52.7214 24.3284 53.4487V71.8906H8.52103V23.1517H13.7903V37.6417C13.7903 38.369 14.3803 38.959 15.1076 38.959H51.9914C52.7187 38.959 53.3087 38.369 53.3087 37.6417V23.1517H58.578V71.8909H58.5776ZM42.7703 62.6698V57.4006H46.7222V62.6698H42.7703Z" fill="#282828"/>
<path d="M38.8174 40.2759H28.2793V42.9105H38.8174V40.2759Z" fill="#282828"/>
<path d="M40.4625 12.5641C37.1729 9.70558 31.3953 10.9459 27.5835 15.3324C23.7721 19.7175 23.3464 25.612 26.6352 28.4709C27.8199 29.4998 29.329 30.0306 31.0082 30.0306C31.6791 30.0306 32.3775 29.9458 33.0927 29.7746C35.4389 29.2131 37.7191 27.7664 39.5138 25.7026C41.3085 23.6384 42.4229 21.1788 42.6525 18.7773C42.8981 16.2115 42.1202 14.0047 40.4625 12.5641ZM40.0304 18.5264C39.8521 20.3859 38.9626 22.3207 37.5252 23.9742C36.0884 25.6273 34.2963 26.7771 32.4791 27.2127C30.8228 27.6088 29.3622 27.3504 28.3639 26.4819C26.2088 24.6084 26.7621 20.2939 29.5729 17.0604C31.4652 14.8825 33.9865 13.6507 36.0892 13.6507C36.8079 13.6507 37.4721 13.8033 38.0514 14.1024C36.4906 15.2012 34.0285 17.1417 32.1932 19.5702C31.7547 20.151 31.8698 20.977 32.4499 21.4155C32.688 21.5948 32.9665 21.6818 33.2431 21.6818C33.6424 21.6818 34.0364 21.5018 34.2952 21.1588C35.9897 18.916 38.3758 17.0853 39.7666 16.1206C40.0165 16.8201 40.1159 17.629 40.0304 18.5264Z" fill="#282828"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

10
theme_coffee_shop/static/src/images/featureitem2.svg

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.8 KiB

4
theme_coffee_shop/static/src/images/featureitem3.svg

@ -1,4 +0,0 @@
<svg width="55" height="81" viewBox="0 0 55 81" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M46.7583 35.1761L46.9047 35.0296L53.5444 28.39C54.2207 27.7137 54.2207 26.6199 53.5444 25.9436L46.9047 19.304L46.7583 19.1576V18.9504V9.55353C46.7583 8.59365 45.9838 7.81919 45.024 7.81919H35.627H35.4199L35.2735 7.67274L28.6338 1.0331C27.9576 0.356806 26.8638 0.356807 26.1875 1.0331L26.1871 1.03352L19.5316 7.67316L19.3852 7.81919H19.1785H9.78156C8.82168 7.81919 8.04721 8.59365 8.04721 9.55353V18.9504V19.1576L7.90077 19.304L1.26112 25.9436C0.584834 26.6199 0.584833 27.7137 1.26112 28.39L7.90077 35.0296L8.04721 35.1761V35.3832V44.7801C8.04721 45.74 8.82168 46.5144 9.78156 46.5144H16.136H16.95L16.5819 47.2405L4.33034 71.4113C4.05703 72.1714 4.13065 72.8705 4.42796 73.3251C4.70941 73.7554 5.25811 74.068 6.18355 73.9351L12.6879 72.764L13.0596 72.6971L13.2256 73.0363L16.137 78.9858C16.1377 78.9872 16.1384 78.9886 16.1391 78.9899C16.8371 80.3407 18.7218 80.1628 19.23 79.0398L19.2346 79.0297L19.2397 79.0198L26.941 63.8389L27.3869 62.96L27.8328 63.8389L35.5306 79.0128C35.9174 79.7161 36.522 80.0285 37.0883 80.0256C37.6535 80.0227 38.255 79.705 38.6359 78.9874L41.5482 73.0363L41.7138 72.6979L42.0847 72.7638L41.9973 73.2561L42.0848 72.7638L42.085 72.7638L42.0859 72.764L42.0896 72.7646L42.1041 72.7672L42.1609 72.7773L42.3763 72.8155L43.1462 72.9519C43.7839 73.0648 44.6354 73.2153 45.4909 73.3658C46.3465 73.5163 47.2055 73.6667 47.8584 73.7795C48.185 73.8359 48.4592 73.8828 48.6553 73.9155C48.7535 73.9318 48.8308 73.9444 48.8848 73.9528C48.8982 73.9549 48.9097 73.9567 48.9194 73.9581C48.9293 73.9596 48.9373 73.9608 48.9436 73.9616L46.7583 35.1761ZM46.7583 35.1761V35.3832V44.7801C46.7583 45.7331 45.9749 46.5144 44.9923 46.5144H38.6379H37.8238L38.1919 47.2405L50.3302 71.1844L50.3463 71.216L50.3666 71.2451C50.4547 71.3709 50.569 71.6301 50.6384 71.9657C50.7067 72.2955 50.7218 72.6521 50.6539 72.9663C50.5873 73.275 50.4463 73.5238 50.2126 73.6937C49.9777 73.8644 49.5891 73.9989 48.9449 73.9618L46.7583 35.1761ZM17.3034 73.4447L17.7446 74.3435L18.1981 73.4508L27.801 54.5461L28.1588 53.8417L27.3691 53.8198C26.9245 53.8075 26.492 53.6208 26.1875 53.3164L20.8473 47.9761L20.3597 47.4886L20.0478 48.1035L9.44656 69.0049L8.99116 69.9028L9.98174 69.7231L13.7172 69.0453C14.213 68.9978 14.5595 69.0452 14.8313 69.1763C15.0996 69.3057 15.3561 69.5461 15.6141 70.0028L17.3034 73.4447ZM44.8238 69.7231L45.8139 69.9027L45.359 69.0051L35.2966 49.1495L34.8508 48.2699L34.4047 49.1493L29.4606 58.8949L29.3459 59.1209L29.4605 59.3471L36.6072 73.4504L37.0604 74.3446L37.5021 73.4447L39.1976 69.9903C39.1976 69.9903 39.1976 69.9902 39.1976 69.9902C39.5423 69.2887 40.3048 68.9066 41.0691 69.0418C41.0695 69.0419 41.0698 69.0419 41.0701 69.042L44.8238 69.7231ZM42.7896 43.0457H43.2896V42.5457V34.4641C43.2896 34.0024 43.464 33.5657 43.7861 33.2554L43.7862 33.2555L43.7929 33.2488L49.5134 27.5283L49.867 27.1747L49.5134 26.8212L43.7964 21.1042C43.4723 20.766 43.2896 20.3199 43.2896 19.8695V11.7879V11.2879H42.7896H34.7079C34.2369 11.2879 33.794 11.1018 33.4769 10.7846L27.7563 5.06406L27.4032 4.711L27.0497 5.06357L21.3324 10.765C20.9942 11.0892 20.548 11.272 20.0976 11.272H12.0159H11.5159V11.772V19.8537C11.5159 20.3248 11.3298 20.7676 11.0126 21.0848L5.29209 26.8053L4.93854 27.1589L5.29209 27.5124L11.0091 33.2295C11.3332 33.5676 11.5159 34.0138 11.5159 34.4641V42.5457V43.0457H12.0159H20.0976C20.5686 43.0457 21.0115 43.2318 21.3286 43.549L21.3291 43.5495L27.0497 49.2542L27.4028 49.6063L27.7558 49.2542L33.473 43.5528C33.8112 43.2286 34.2575 43.0457 34.7079 43.0457H42.7896Z" fill="#282828" stroke="white"/>
<path d="M15.6543 27.1746C15.6543 20.7001 20.9291 15.4253 27.4036 15.4253C33.878 15.4253 39.1528 20.7001 39.1528 27.1746C39.1528 33.649 33.878 38.9238 27.4036 38.9238C20.9291 38.9238 15.6543 33.649 15.6543 27.1746ZM19.123 27.1746C19.123 31.7451 22.833 35.4551 27.4036 35.4551C31.9741 35.4551 35.6842 31.7451 35.6842 27.1746C35.6842 22.604 31.9741 18.894 27.4036 18.894C22.833 18.894 19.123 22.604 19.123 27.1746Z" fill="#282828" stroke="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.0 KiB

9
theme_coffee_shop/static/src/images/google 1.svg

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 26 KiB

3
theme_coffee_shop/static/src/images/search.svg

@ -1,3 +0,0 @@
<svg width="21" height="22" viewBox="0 0 21 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.9096 19.2841L19.9101 19.2845C20.0418 19.415 20.1315 19.5819 20.1679 19.7637C20.2042 19.9455 20.1856 20.134 20.1142 20.3052L20.1138 20.3063C20.0552 20.4491 19.9622 20.5751 19.8431 20.6732C19.7239 20.7713 19.5823 20.8383 19.4309 20.8683C19.2795 20.8984 19.1231 20.8904 18.9755 20.8452C18.8279 20.8 18.6939 20.719 18.5853 20.6093L18.5848 20.6089L14.7467 16.7596L14.6213 16.6339L14.4816 16.7435C12.9346 17.9578 11.0243 18.6166 9.05767 18.6142H9.05742C7.30559 18.6142 5.59309 18.0947 4.1365 17.1215C2.67991 16.1483 1.54463 14.765 0.874233 13.1466C0.203838 11.5282 0.0284319 9.74735 0.370196 8.02927C0.711961 6.31118 1.55555 4.73302 2.79428 3.49435C4.03301 2.25568 5.61125 1.41213 7.32942 1.07038C9.0476 0.728635 10.8285 0.904033 12.447 1.5744C14.0655 2.24476 15.4488 3.37998 16.4221 4.83651C17.3954 6.29303 17.9148 8.00543 17.9148 9.75718V9.75743C17.9173 11.7239 17.2584 13.6342 16.0441 15.1811L15.9345 15.3208L16.0602 15.4462L19.9096 19.2841ZM2.59667 7.08117C2.24524 7.92957 2.06436 8.83888 2.06436 9.75718C2.06436 11.6118 2.80113 13.3904 4.11258 14.7018C5.42404 16.0132 7.20275 16.7499 9.05742 16.7499C10.9121 16.7499 12.6908 16.0132 14.0023 14.7018C15.3137 13.3904 16.0505 11.6118 16.0505 9.75718C16.0505 8.83888 15.8696 7.92957 15.5182 7.08117C15.1667 6.23277 14.6516 5.4619 14.0023 4.81256C13.3529 4.16323 12.582 3.64815 11.7335 3.29673C10.8851 2.94532 9.97576 2.76444 9.05742 2.76444C8.13908 2.76444 7.22973 2.94532 6.3813 3.29673C5.53286 3.64815 4.76195 4.16323 4.11258 4.81256C3.46322 5.4619 2.94811 6.23277 2.59667 7.08117Z" fill="#282828" stroke="white" stroke-width="0.4"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

3
theme_coffee_shop/static/src/images/shopfilter.svg

@ -1,3 +0,0 @@
<svg width="30" height="27" viewBox="0 0 30 27" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22.6667 26.0335L29 19.7002M0.5 0.700195H21.0833H0.5ZM0.5 7.03353H14.75H0.5ZM0.5 13.3669H14.75H0.5ZM22.6667 7.03353V26.0335V7.03353ZM22.6667 26.0335L16.3333 19.7002L22.6667 26.0335Z" stroke="black" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 359 B

63
theme_coffee_shop/static/src/js/action.js

@ -1,63 +0,0 @@
odoo.define("theme_coffee_shop.theme_coffee_shop_template", function (require) {
"use strict";
var ajax = require('web.ajax');
const navicon = document.getElementById('nav-icon');
const navitem = document.getElementById('nav-item');
if(navicon){
navicon.addEventListener("click",function(e){
e.preventDefault();
navitem.classList.toggle('active');
})
}
function functionLike(r) {
r.classList.toggle("fa-solid");
}
function fliterclick() {
var x = document.querySelector(".pr-categories");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
/* Toggle between adding and removing the "active" class,
to highlight the button that controls the panel */
this.classList.toggle("active");
/* Toggle between hiding and showing the active panel */
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
const loginPage=document.querySelectorAll("#login-btn");
loginPage.forEach(login=>{
login.addEventListener('click',e=>{
e.preventDefault();
document.querySelector('.login-form-container').classList.toggle('show');
})
})
document.querySelector(".login-close").onclick=()=>{
document.querySelector('.login-form-container').classList.toggle('show');
}
});

32
theme_coffee_shop/static/src/js/map_snippet.js

@ -0,0 +1,32 @@
/** @odoo-module **/
import publicWidget from 'web.public.widget';
import {generateGMapLink, generateGMapIframe} from 'website.utils';
publicWidget.registry.Map_1 = publicWidget.Widget.extend({
selector: '.s_map.s_map_1',
/**
* @override
*/
async start() {
console.log("kkkkk")
const address = await this._rpc({
route: "/get-company/address",
});
const existingIframe = this.el.querySelector('.s_map.s_map_1 iframe');
if (existingIframe) {
existingIframe.remove();
}
if (address) {
const iframeEl = generateGMapIframe();
iframeEl.setAttribute('src', generateGMapLink({mapType: 'm', mapZoom: "12", name: 'Map', snippet: 's_map', mapAddress: address}));
this.el.querySelector('.s_map_color_filter_1').before(iframeEl);
}
},
});
export default publicWidget.registry.Map_1;

132
theme_coffee_shop/views/about_us.xml

@ -1,31 +1,135 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- This XML defines a new page named "About" for the coffee shop theme -->
<record id="coffee_about_us" model="website.page"> <record id="coffee_about_us" model="website.page">
<field name="name">About</field> <field name="name">About</field>
<field name="type">qweb</field> <field name="type">qweb</field>
<field name="key">theme_coffee_shop.coffee_about_us</field> <field name="key">theme_coffee_shop.coffee_about_us</field>
<field name="url">/about</field> <field name="url">/about</field>
<field name="is_published">True</field> <field name="is_published">True</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<t name="About" t-name="theme_coffee_shop.coffee_about_us"> <t name="About" t-name="theme_coffee_shop.coffee_about_us">
<t t-call="website.layout"> <t t-call="website.layout">
<div id="wrap"> <div id="wrap" class="oe_structure oe_empty">
<section id="banner" class="banner-imgAbout"> <section id="banner" class="banner-imgAbout">
<div class="container wrapper"> <div class="container wrapper">
<div class="banner-content"> <div class="banner-content">
<div class="banner-text"> <div class="banner-text">
<p class="banner-head">More than</p> <p class="banner-head">More than</p>
<p class="banner-head">Just Coffee</p> <p class="banner-head">Just Coffee</p>
</div>
</div> </div>
</div> </div>
</div> </section>
</section> <section class="s_company_team pt48 pb48">
<div class="oe_structure"/> <div class="container">
</div> <div class="row s_nb_column_fixed">
<div class="col-lg-6 pt24 pb24">
<div class="row s_col_no_resize s_col_no_bgcolor">
<div class="col-lg-4 pb16 o_not_editable" contenteditable="false">
<img alt="" src="/web/image/website.s_company_team_image_1"
class="img-fluid rounded-circle mx-auto o_editable_media"
contenteditable="true"/>
</div>
<div class="col-lg-8">
<h4>Tony Fred, CEO</h4>
<p>
Founder and chief visionary, Tony is the driving force behind the
company. He loves
to keep his hands full by participating in the development of the
software,
marketing, and customer experience strategies.
</p>
</div>
</div>
</div>
<div class="col-lg-6 pt24 pb24">
<div class="row s_col_no_resize s_col_no_bgcolor">
<div class="col-lg-4 pb16 o_not_editable" contenteditable="false">
<img alt="" src="/web/image/website.s_company_team_image_2"
class="img-fluid rounded-circle mx-auto o_editable_media"
contenteditable="true"/>
</div>
<div class="col-lg-8">
<h4>Mich Stark, COO</h4>
<p>Mich loves taking on challenges. With his multi-year experience as
Commercial Director in the software industry, Mich has helped the
company to get where it is today. Mich is among the best minds.
</p>
</div>
</div>
</div>
<div class="col-lg-6 pt24 pb24">
<div class="row s_col_no_resize s_col_no_bgcolor">
<div class="col-lg-4 pb16 o_not_editable" contenteditable="false">
<img alt="" src="/web/image/website.s_company_team_image_3"
class="img-fluid rounded-circle mx-auto o_editable_media"
contenteditable="true"/>
</div>
<div class="col-lg-8">
<h4>Aline Turner, CTO</h4>
<p>Aline is one of the iconic people in life who can say they love what
they do. She mentors 100+ in-house developers and looks after the
community of thousands of developers.
</p>
</div>
</div>
</div>
<div class="col-lg-6 pt24 pb24">
<div class="row s_col_no_resize s_col_no_bgcolor">
<div class="col-lg-4 pb16 o_not_editable" contenteditable="false">
<img alt="" src="/web/image/website.s_company_team_image_4"
class="img-fluid rounded-circle mx-auto o_editable_media"
contenteditable="true"/>
</div>
<div class="col-lg-8">
<h4>Iris Joe, CFO</h4>
<p>Iris, with her international experience, helps us easily understand
the numbers and improves them. She is determined to drive success
and delivers her professional acumen to bring the company to the
next level.
</p>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="s_references pt48 pb32">
<div class="container">
<h2 style="text-align: center;">Our References</h2>
<p style="text-align: center;">We are in good company.</p>
<div class="row">
<div class="col-lg-2 pt16 pb16">
<img src="/web/image/website.s_reference_demo_image_1"
class="img img-fluid mx-auto" alt=""/>
</div>
<div class="col-lg-2 pt16 pb16">
<img src="/web/image/website.s_reference_demo_image_2"
class="img img-fluid mx-auto" alt=""/>
</div>
<div class="col-lg-2 pt16 pb16">
<img src="/web/image/website.s_reference_demo_image_3"
class="img img-fluid mx-auto" alt=""/>
</div>
<div class="col-lg-2 pt16 pb16">
<img src="/web/image/website.s_reference_demo_image_4"
class="img img-fluid mx-auto" alt=""/>
</div>
<div class="col-lg-2 pt16 pb16">
<img src="/web/image/website.s_reference_demo_image_5"
class="img img-fluid mx-auto" alt=""/>
</div>
<div class="col-lg-2 pt16 pb16">
<img src="/web/image/website.s_reference_default_image_6"
class="img img-fluid mx-auto" alt=""/>
</div>
</div>
</div>
</section>
</div>
</t> </t>
</t> </t>
</field> </field>
</record> </record>
</odoo> </odoo>

254
theme_coffee_shop/views/address.xml

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- This XML template modifies the payment address section of the website's checkout process -->
<template id="coffee_shop_payment_address" <template id="coffee_shop_payment_address"
inherit_id="website_sale.address" inherit_id="website_sale.address"
name="Coffee Payment Address"> name="Coffee Payment Address">
@ -12,19 +13,17 @@
<p class="banner-head">Pick your</p> <p class="banner-head">Pick your</p>
<p class="banner-head">favourites</p> <p class="banner-head">favourites</p>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<section id="my-cart" class="container wrapper"> <section id="my-cart-checkout" class="container wrapper">
<span class="cart-heading">Checkout</span> <span class="cart-heading">Checkout</span>
</section> </section>
<div class="border"> <div class="border"/>
</div>
<div id="wrap"> <div id="wrap">
<div class="container oe_website_sale py-2"> <div class="container oe_website_sale py-2">
<div class="row"> <div class="row">
<div class="col-12" style="display:none;"> <div class="col-12 d-none">
<t t-call="website_sale.wizard_checkout"> <t t-call="website_sale.wizard_checkout">
<t t-set="step" t-value="20"/> <t t-set="step" t-value="20"/>
</t> </t>
@ -35,45 +34,61 @@
<div> <div>
<t t-call="website_sale.cart_summary"> <t t-call="website_sale.cart_summary">
<t t-set="hide_promotions">True</t> <t t-set="hide_promotions">True</t>
<t t-set="redirect" t-valuef="/shop/address"/> <t t-set="redirect"
t-valuef="/shop/address"/>
</t> </t>
</div> </div>
<img src="/theme_coffee_shop/static/src/images/payment-method_69e7ec.svg" class="img-pay" alt=""/> <img src="/theme_coffee_shop/static/src/images/payment-method_69e7ec.svg"
class="img-pay" alt=""/>
</div> </div>
<div class="col-12 col-xl order-xl-1 oe_cart"> <div class="col-12 col-xl order-xl-1 oe_cart sign_in">
<t t-if="mode == ('new', 'billing')"> <t t-if="mode == ('new', 'billing')">
<h2 class="o_page_header mt8"> <h2 class="o_page_header mt8">
<span t-if="account_on_checkout != 'mandatory'"> <span t-if="account_on_checkout != 'mandatory'">
Fill in your address</span> Fill in your address
<small class="text-muted" </span>
t-if="account_on_checkout == 'optional'">or</small> <small class="text-muted"
<a t-if="account_on_checkout != 'disabled'" t-if="account_on_checkout == 'optional'">
role="button" or
href='/web/login?redirect=/shop/checkout' </small>
style="margin-top: -11px">Sign in <a t-if="account_on_checkout != 'disabled'"
</a> role="button"
</h2> href='/web/login?redirect=/shop/checkout'>
</t> Sign in
<t t-if="mode == ('edit', 'billing')"> </a>
<h2 class="o_page_header mt8">Your Address</h2> </h2>
</t> </t>
<t t-if="mode[1] == 'shipping'"> <t t-if="mode == ('edit', 'billing')">
<h2 class="o_page_header mt8" style="display:none;">Shipping Address</h2> <h2 class="o_page_header mt8">Your Address
</t> </h2>
<t t-if="partner_id == website_sale_order.partner_shipping_id.id == website_sale_order.partner_invoice_id.id"> </t>
<div class="alert alert-warning" <t t-if="mode[1] == 'shipping'">
role="alert" t-if="not only_services"> <h2 class="o_page_header mt8 d-none">
<h4 class="alert-heading">Be aware!</h4> Shipping Address
<p groups="account.group_delivery_invoice_address"> </h2>
You are editing your <b>billing </t>
and shipping</b> addresses at the same time!<br/> <t t-if="partner_id == website_sale_order.partner_shipping_id.id == website_sale_order.partner_invoice_id.id">
If you want to modify your shipping address, create a <a href='/shop/address'>new address</a>. <div class="alert alert-warning"
</p> role="alert" t-if="not only_services">
</div> <h4 class="alert-heading">Be aware!
</t> </h4>
<t t-if="error" t-foreach="error.get('error_message', [])" t-as="err"> <p groups="account.group_delivery_invoice_address">
<h5 class="text-danger" t-esc="err"/> You are editing your <b>billing
</t> and shipping
</b> addresses at the same time!
<br/>
If you want to modify your shipping
address, create a <a
href='/shop/address'>new
address</a>.
</p>
</div>
</t>
<t t-if="error"
t-foreach="error.get('error_message', [])"
t-as="err">
<h5 class="text-danger" t-esc="err"/>
</t>
<div> <div>
<form t-if="account_on_checkout != 'mandatory' or not is_public_user" <form t-if="account_on_checkout != 'mandatory' or not is_public_user"
action="/shop/address" method="post" action="/shop/address" method="post"
@ -82,7 +97,8 @@
<div class="mb-3"> <div class="mb-3">
<input type="text" name="name" <input type="text" name="name"
t-attf-class="forms-input form-control #{error.get('name') and 'is-invalid' or ''}" t-attf-class="forms-input form-control #{error.get('name') and 'is-invalid' or ''}"
t-att-value="'name' in checkout and checkout['name']" placeholder='Name'/> t-att-value="'name' in checkout and checkout['name']"
placeholder='Name'/>
</div> </div>
<div class="w-100"/> <div class="w-100"/>
<div t-attf-class="mb-3 #{error.get('email') and 'o_has_error' or ''} col-lg-6" <div t-attf-class="mb-3 #{error.get('email') and 'o_has_error' or ''} col-lg-6"
@ -90,34 +106,73 @@
<input type="email" <input type="email"
name="email" name="email"
t-attf-class="forms-input form-control #{error.get('email') and 'is-invalid' or ''}" t-attf-class="forms-input form-control #{error.get('email') and 'is-invalid' or ''}"
t-att-value="'email' in checkout and checkout['email']" placeholder='Email'/> t-att-value="'email' in checkout and checkout['email']"
placeholder='Email'/>
</div> </div>
<div t-attf-class="mb-3 #{error.get('phone') and 'o_has_error' or ''} col-lg-6" <div t-attf-class="mb-3 #{error.get('phone') and 'o_has_error' or ''} col-lg-6"
id="div_phone"> id="div_phone">
<input type="tel" name="phone" <input type="tel" name="phone"
t-attf-class="forms-input form-control #{error.get('phone') and 'is-invalid' or ''}" t-attf-class="forms-input form-control #{error.get('phone') and 'is-invalid' or ''}"
t-att-value="'phone' in checkout and checkout['phone']" placeholder='Phone'/> t-att-value="'phone' in checkout and checkout['phone']"
placeholder='Phone'/>
</div> </div>
<t t-if="website._display_partner_b2b_fields()"> <t t-if="website._display_partner_b2b_fields()">
<div class="w-100"/> <div class="w-100"/>
<t t-set='vat_warning' t-value="'vat' in checkout and checkout['vat'] and not can_edit_vat" /> <t t-set='vat_warning'
t-value="'vat' in checkout and checkout['vat'] and not can_edit_vat"/>
<t t-if="mode == ('new', 'billing') or (mode == ('edit', 'billing') and (can_edit_vat or 'vat' in checkout and checkout['vat']))"> <t t-if="mode == ('new', 'billing') or (mode == ('edit', 'billing') and (can_edit_vat or 'vat' in checkout and checkout['vat']))">
<div t-attf-class="mb-3 #{error.get('company_name') and 'o_has_error' or ''} col-lg-6 mb-0"> <div t-attf-class="mb-3 #{error.get('company_name') and 'o_has_error' or ''} col-lg-6 mb-0">
<input type="text" name="company_name" <input type="text"
t-attf-class="forms-input form-control #{error.get('company_name') and 'is-invalid' or ''}" name="company_name"
t-att-value="'commercial_company_name' in checkout and checkout['commercial_company_name'] or 'company_name' in checkout and checkout['company_name']" t-attf-class="forms-input form-control #{error.get('company_name') and 'is-invalid' or ''}"
t-att-readonly="'1' if vat_warning else None" placeholder='Company Name'/> t-att-value="'commercial_company_name' in checkout and checkout['commercial_company_name'] or 'company_name' in checkout and checkout['company_name']"
<small t-if="vat_warning" class="form-text text-muted d-block d-lg-none">Changing company name is not allowed once document(s) have been issued for your account. Please contact us directly for this operation.</small> t-att-readonly="'1' if vat_warning else None"
placeholder='Company Name'/>
<small t-if="vat_warning"
class="form-text text-muted d-block d-lg-none">
Changing company
name is not allowed
once document(s)
have been issued
for
your account.
Please
contact us directly
for this operation.
</small>
</div> </div>
<div t-attf-class="mb-3 #{error.get('vat') and 'o_has_error' or ''} col-lg-6 div_vat mb-0"> <div t-attf-class="mb-3 #{error.get('vat') and 'o_has_error' or ''} col-lg-6 div_vat mb-0">
<input type="text" name="vat" t-attf-class="forms-input form-control #{error.get('vat') and 'is-invalid' or ''}" <input type="text"
name="vat"
t-attf-class="forms-input form-control #{error.get('vat') and 'is-invalid' or ''}"
t-att-value="'vat' in checkout and checkout['vat']" t-att-value="'vat' in checkout and checkout['vat']"
t-att-readonly="'1' if vat_warning else None" t-att-readonly="'1' if vat_warning else None"
placeholder="TIN / VAT"/> placeholder="TIN / VAT"/>
<small t-if="vat_warning" class="form-text text-muted d-block d-lg-none">Changing VAT number is not allowed once document(s) have been issued for your account. Please contact us directly for this operation.</small> <small t-if="vat_warning"
class="form-text text-muted d-block d-lg-none">
Changing VAT number
is not allowed once
document(s) have
been issued for
your
account. Please
contact us directly
for this operation.
</small>
</div> </div>
<div t-if="vat_warning" class="col-12 d-none d-lg-block mb-1"> <div t-if="vat_warning"
<small class="form-text text-muted">Changing company name or VAT number is not allowed once document(s) have been issued for your account. Please contact us directly for this operation.</small> class="col-12 d-none d-lg-block mb-1">
<small class="form-text text-muted">
Changing company
name or VAT number
is not allowed once
document(s) have
been issued for
your
account. Please
contact us directly
for this operation.
</small>
</div> </div>
</t> </t>
</t> </t>
@ -126,35 +181,41 @@
<input type="text" <input type="text"
name="street" name="street"
t-attf-class="forms-input form-control #{error.get('street') and 'is-invalid' or ''}" t-attf-class="forms-input form-control #{error.get('street') and 'is-invalid' or ''}"
t-att-value="'street' in checkout and checkout['street']" placeholder='Street and Number'/> t-att-value="'street' in checkout and checkout['street']"
placeholder='Street and Number'/>
</div> </div>
<div t-attf-class="mb-3 #{error.get('street2') and 'o_has_error' or ''} col-lg-12 div_street2"> <div t-attf-class="mb-3 #{error.get('street2') and 'o_has_error' or ''} col-lg-12 div_street2">
<input type="text" <input type="text"
name="street2" name="street2"
t-attf-class="forms-input form-control #{error.get('street2') and 'is-invalid' or ''}" t-attf-class="forms-input form-control #{error.get('street2') and 'is-invalid' or ''}"
t-att-value="'street2' in checkout and checkout['street2']" placeholder='Street 2'/> t-att-value="'street2' in checkout and checkout['street2']"
placeholder='Street 2'/>
</div> </div>
<div class="w-100"/> <div class="w-100"/>
<t t-set='zip_city' t-value='country and [x for x in country.get_address_fields() if x in ["zip", "city"]] or ["city", "zip"]'/> <t t-set='zip_city'
t-value='country and [x for x in country.get_address_fields() if x in ["zip", "city"]] or ["city", "zip"]'/>
<t t-if="'zip' in zip_city and zip_city.index('zip') &lt; zip_city.index('city')"> <t t-if="'zip' in zip_city and zip_city.index('zip') &lt; zip_city.index('city')">
<div t-attf-class="mb-3 #{error.get('zip') and 'o_has_error' or ''} col-md-4 div_zip"> <div t-attf-class="mb-3 #{error.get('zip') and 'o_has_error' or ''} col-md-4 div_zip">
<input type="text" <input type="text"
name="zip" name="zip"
t-attf-class="forms-input form-control #{error.get('zip') and 'is-invalid' or ''}" t-attf-class="forms-input form-control #{error.get('zip') and 'is-invalid' or ''}"
t-att-value="'zip' in checkout and checkout['zip']" placeholder='Zip Code'/> t-att-value="'zip' in checkout and checkout['zip']"
placeholder='Zip Code'/>
</div> </div>
</t> </t>
<div t-attf-class="mb-3 #{error.get('city') and 'o_has_error' or ''} col-md-8 div_city"> <div t-attf-class="mb-3 #{error.get('city') and 'o_has_error' or ''} col-md-8 div_city">
<input type="text" name="city" <input type="text" name="city"
t-attf-class="forms-input form-control #{error.get('city') and 'is-invalid' or ''}" t-attf-class="forms-input form-control #{error.get('city') and 'is-invalid' or ''}"
t-att-value="'city' in checkout and checkout['city']" placeholder='City'/> t-att-value="'city' in checkout and checkout['city']"
placeholder='City'/>
</div> </div>
<t t-if="'zip' in zip_city and zip_city.index('zip') &gt; zip_city.index('city')"> <t t-if="'zip' in zip_city and zip_city.index('zip') &gt; zip_city.index('city')">
<div t-attf-class="mb-3 #{error.get('zip') and 'o_has_error' or ''} col-md-4 div_zip"> <div t-attf-class="mb-3 #{error.get('zip') and 'o_has_error' or ''} col-md-4 div_zip">
<input type="text" <input type="text"
name="zip" name="zip"
t-attf-class="forms-input form-control #{error.get('zip') and 'is-invalid' or ''}" t-attf-class="forms-input form-control #{error.get('zip') and 'is-invalid' or ''}"
t-att-value="'zip' in checkout and checkout['zip']" placeholder='Zip Code'/> t-att-value="'zip' in checkout and checkout['zip']"
placeholder='Zip Code'/>
</div> </div>
</t> </t>
<div class="w-100"/> <div class="w-100"/>
@ -163,9 +224,13 @@
name="country_id" name="country_id"
t-attf-class="forms-input form-select #{error.get('country_id') and 'is-invalid' or ''}" t-attf-class="forms-input form-select #{error.get('country_id') and 'is-invalid' or ''}"
t-att-mode="mode[1]"> t-att-mode="mode[1]">
<option value="">Country...</option> <option value="">
<t t-foreach="countries" t-as="c"> Country...
<option t-att-value="c.id" t-att-selected="c.id == (country and country.id or -1)"> </option>
<t t-foreach="countries"
t-as="c">
<option t-att-value="c.id"
t-att-selected="c.id == (country and country.id or -1)">
<t t-esc="c.name"/> <t t-esc="c.name"/>
</option> </option>
</t> </t>
@ -176,8 +241,11 @@
<select name="state_id" <select name="state_id"
t-attf-class="forms-input form-select #{error.get('state_id') and 'is-invalid' or ''}" t-attf-class="forms-input form-select #{error.get('state_id') and 'is-invalid' or ''}"
data-init="1"> data-init="1">
<option value="">State / Province...</option> <option value="">State /
<t t-foreach="country_states" t-as="s"> Province...
</option>
<t t-foreach="country_states"
t-as="s">
<option t-att-value="s.id" <option t-att-value="s.id"
t-att-selected="s.id == ('state_id' in checkout and country and checkout['state_id'] != '' and int(checkout['state_id']))"> t-att-selected="s.id == ('state_id' in checkout and country and checkout['state_id'] != '' and int(checkout['state_id']))">
<t t-esc="s.name"/> <t t-esc="s.name"/>
@ -190,33 +258,52 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input type="checkbox" id='shipping_use_same' class="mr8" <input type="checkbox"
name='use_same' value="1" checked='checked'/>Ship to the same address id='shipping_use_same'
<span class='ship_to_other text-muted' class="mr8"
style="display: none"> name='use_same'
&amp;nbsp;(<i>Your shipping address will be requested later)</i> value="1"
checked='checked'/>
Ship to the same
address
<span class='ship_to_other text-muted d-none'>
&amp;nbsp;(
<i>Your
shipping
address
will
be
requested
later)
</i>
</span> </span>
</label> </label>
</div> </div>
</div> </div>
</t> </t>
</div> </div>
<input type="hidden" name="csrf_token"
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/> t-att-value="request.csrf_token()"/>
<input type="hidden" name="submitted" value="1"/> <input type="hidden" name="submitted"
<input type="hidden" name="partner_id" t-att-value="partner_id or '0'"/> value="1"/>
<input type="hidden" name="callback" t-att-value="callback"/> <input type="hidden" name="partner_id"
<!-- Example --> t-att-value="partner_id or '0'"/>
<input type="hidden" name="field_required" t-att-value="'phone,name'"/> <input type="hidden" name="callback"
t-att-value="callback"/>
<input type="hidden"
name="field_required"
t-att-value="'phone,name'"/>
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<a role="button" t-att-href="mode == ('new', 'billing') and '/shop/cart' or '/shop/checkout'" <a role="button"
t-att-href="mode == ('new', 'billing') and '/shop/cart' or '/shop/checkout'"
class="btn btn-secondary mb32 form-btn catform-btn btn"> class="btn btn-secondary mb32 form-btn catform-btn btn">
<i class="fa fa-chevron-left"/><span>Back</span> <i class="fa fa-chevron-left"/>
<span>Back</span>
</a> </a>
<a role="button" href="#" <a role="button" href="#"
class="btn btn-primary mb32 a-submit a-submit-disable a-submit-loading form-btn catform-btn btn"> class="btn btn-primary mb32 a-submit a-submit-disable a-submit-loading form-btn catform-btn btn">
<span>Next</span><i class="fa fa-chevron-right"/> <span>Next</span>
<i class="fa fa-chevron-right"/>
</a> </a>
</div> </div>
</form> </form>
@ -225,9 +312,8 @@
</div> </div>
</div> </div>
</div> </div>
<div class="border"> <div class="border"/>
</div>
</t> </t>
</xpath> </xpath>
</template> </template>
</odoo> </odoo>

62
theme_coffee_shop/views/cart.xml

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<template id="boec_cart" name="Boec Cart" inherit_id="website_sale.cart"> <!-- This XML template customizes the appearance and functionality of the shopping cart page -->
<template id="coffee_shop_cart" name="Coffee Shop Cart"
inherit_id="website_sale.cart">
<xpath expr="//div[@id='wrap']" position="replace"> <xpath expr="//div[@id='wrap']" position="replace">
<section id="banner" class="banner-imgcart"> <section id="banner" class="banner-imgcart">
<div class="container wrapper "> <div class="container wrapper ">
@ -9,42 +11,58 @@
<p class="banner-head">Pick your</p> <p class="banner-head">Pick your</p>
<p class="banner-head">favourites</p> <p class="banner-head">favourites</p>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<section id="my-cart" class="container wrapper" style="padding-bottom: 20px"> <section id="my-cart" class="container wrapper">
<span class="cart-heading">My Cart</span> <span class="cart-heading">My Cart</span>
</section> </section>
<div class="border"> <div class="border"/>
</div>
<section id="carts" class="container wrapper"> <section id="carts" class="container wrapper">
<div class="container oe_website_sale py-2"> <div class="container oe_website_sale py-2">
<div class="row"> <div class="row">
<div class="col-12" style="display:none;"> <div class="col-12 d-none">
<t t-call="website_sale.wizard_checkout"> <t t-call="website_sale.wizard_checkout">
<t t-set="step" t-value="10" /> <t t-set="step" t-value="10"/>
</t> </t>
</div> </div>
<div class=" oe_cart"> <div class=" oe_cart">
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<div t-if="abandoned_proceed or access_token" class="mt8 mb8 alert alert-info" role="alert"> <!-- abandoned cart choices --> <div t-if="abandoned_proceed or access_token"
class="mt8 mb8 alert alert-info"
role="alert"> <!-- Abandoned cart choices -->
<t t-if="abandoned_proceed"> <t t-if="abandoned_proceed">
<p>Your previous cart has already been completed.</p> <p>Your previous cart has already
<p t-if="website_sale_order">Please proceed your current cart.</p> been completed.
</p>
<p t-if="website_sale_order">Please
proceed your current cart.
</p>
</t> </t>
<t t-if="access_token"> <t t-if="access_token">
<p>This is your current cart.</p> <p>This is your current cart.</p>
<p> <p>
<strong> <strong>
<a t-attf-href="/shop/cart/?access_token=#{access_token}&amp;revive=squash">Click here</a> <a t-attf-href="/shop/cart/?access_token=#{access_token}&amp;revive=squash">
</strong> if you want to restore your previous cart. Your current cart will be replaced with your previous cart. Click here
</a>
</strong>
if you want to restore your
previous cart. Your current
cart
will be replaced with your
previous cart.
</p> </p>
<p> <p>
<strong> <strong>
<a t-attf-href="/shop/cart/?access_token=#{access_token}&amp;revive=merge">Click here</a> <a t-attf-href="/shop/cart/?access_token=#{access_token}&amp;revive=merge">
</strong> if you want to merge your previous cart into current cart. Click here
</a>
</strong>
if you want to merge your
previous cart into current
cart.
</p> </p>
</t> </t>
</div> </div>
@ -55,12 +73,11 @@
</div> </div>
</div> </div>
</section> </section>
<div class="border"> <div class="border"/>
</div>
<section id="cart-sum" class="container wrapper"> <section id="cart-sum" class="container wrapper">
<div class="cart-left"> <div class="cart-left">
<div class="continue-shopping"> <div class="continue-shopping">
<a role="button" href="/shop" > <a role="button" href="/shop">
<img src="/theme_coffee_shop/static/src/images/Arrow 2.svg" <img src="/theme_coffee_shop/static/src/images/Arrow 2.svg"
alt=""/> alt=""/>
</a> </a>
@ -69,14 +86,15 @@
<div class="shop-details"> <div class="shop-details">
<p>Congrats you’re eligible for free shipping</p> <p>Congrats you’re eligible for free shipping</p>
<p>100% Secure &amp; Encrypt</p> <p>100% Secure &amp; Encrypt</p>
<img src="/theme_coffee_shop/static/src/images/payment-method_69e7ec.svg" alt=""/> <img src="/theme_coffee_shop/static/src/images/payment-method_69e7ec.svg"
alt=""/>
</div> </div>
</div> </div>
<div class="cart-right" style="width: 35%;"> <div class="cart-right width_35">
<t t-call="website_sale.short_cart_summary"/> <t t-call="website_sale.short_cart_summary"/>
<div class="check-btn"> <div class="check-btn">
<a role="button" href="/shop/checkout?express=1" class="btn-ckeckout"> <a role="button" href="/shop/checkout?express=1"
class="btn-ckeckout">
Process Checkout Process Checkout
</a> </a>
</div> </div>
@ -84,4 +102,4 @@
</section> </section>
</xpath> </xpath>
</template> </template>
</odoo> </odoo>

37
theme_coffee_shop/views/cart_lines.xml

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- This XML template customizes the appearance and functionality of cart lines in the shopping cart page -->
<template id="coffee_cart_lines" inherit_id="website_sale.cart_lines" <template id="coffee_cart_lines" inherit_id="website_sale.cart_lines"
name="Coffee Cart Lines"> name="Coffee Cart Lines">
<xpath expr="//table[@id='cart_products']" position="replace"> <xpath expr="//table[@id='cart_products']" position="replace">
@ -11,7 +12,7 @@
<thead> <thead>
<tr> <tr>
<th class="td-img">Product</th> <th class="td-img">Product</th>
<th></th> <th/>
<th class="text-center td-qty"> <th class="text-center td-qty">
<t t-if="show_qty"> <t t-if="show_qty">
Quantity Quantity
@ -19,10 +20,9 @@
</th> </th>
<th class="text-center td-price">Price</th> <th class="text-center td-price">Price</th>
<th class="text-center td-price">Total</th> <th class="text-center td-price">Total</th>
<th class="text-center td-action"></th> <th class="text-center td-action"/>
</tr>
<tr style="height: 30px;">
</tr> </tr>
<tr class="height_30"/>
</thead> </thead>
<tbody> <tbody>
<t t-foreach="website_sale_order.website_order_line" <t t-foreach="website_sale_order.website_order_line"
@ -46,15 +46,17 @@
</td> </td>
<td class='td-product_name cstm_tbl'> <td class='td-product_name cstm_tbl'>
<div> <div>
<t t-call="website_sale.cart_line_product_link"> <t t-call="website_sale.cart_line_product_link">
<p class="item-name"><strong t-field="line.name_short"/></p> <p class="item-name">
</t> <strong t-field="line.name_short"/>
</p>
</t>
</div> </div>
<p class="item-about"> <p class="item-about">
<t t-esc="line.product_id.categ_id.name"/> <t t-esc="line.product_id.categ_id.name"/>
</p> </p>
<div class="product-indicate"> <div class="product-indicate">
<div class="indicate-content"></div> <div class="indicate-content"/>
</div> </div>
</td> </td>
</t> </t>
@ -68,7 +70,7 @@
class="btn btn-link js_add_cart_json d-none d-md-inline-block border_link" class="btn btn-link js_add_cart_json d-none d-md-inline-block border_link"
aria-label="Remove one" aria-label="Remove one"
title="Remove one"> title="Remove one">
<i class="fa fa-minus"></i> <i class="fa fa-minus"/>
</a> </a>
<input type="text" <input type="text"
class="js_quantity form-control quantity" class="js_quantity form-control quantity"
@ -89,7 +91,7 @@
class="btn btn-link float_left js_add_cart_json d-none d-md-inline-block border_link" class="btn btn-link float_left js_add_cart_json d-none d-md-inline-block border_link"
aria-label="Add one" aria-label="Add one"
title="Add one"> title="Add one">
<i class="fa fa-plus"></i> <i class="fa fa-plus"/>
</a> </a>
</div> </div>
</div> </div>
@ -117,17 +119,16 @@
name="price"> name="price">
<t groups="account.group_show_line_subtotals_tax_excluded"> <t groups="account.group_show_line_subtotals_tax_excluded">
<span t-field="line.price_reduce_taxexcl" <span t-field="line.price_reduce_taxexcl"
style="white-space: nowrap;" class="text-nowrap"
t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"/> t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"/>
</t> </t>
<t groups="account.group_show_line_subtotals_tax_included"> <t groups="account.group_show_line_subtotals_tax_included">
<span t-field="line.price_reduce_taxinc" <span t-field="line.price_reduce_taxinc"
style="white-space: nowrap;" class="text-nowrap"
t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"/> t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"/>
</t> </t>
<t t-if="line.discount"> <t t-if="line.discount">
<del t-attf-class="#{'text-danger mr8'}" <del t-attf-class="#{'text-danger mr8'} text-nowrap"
style="white-space: nowrap;"
t-esc="line.price_unit" t-esc="line.price_unit"
t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"/> t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"/>
</t> </t>
@ -148,10 +149,10 @@
<a href='#' aria-label="Remove from cart" <a href='#' aria-label="Remove from cart"
title="Remove from cart" title="Remove from cart"
class='js_delete_product no-decoration'> class='js_delete_product no-decoration'>
<div class="col remove"> <div class="col remove">
<div class="close-circle"> <div class="close-circle">
<i class="fa fa-times" <i class="fa fa-times"
aria-hidden="false"></i> aria-hidden="false"/>
</div> </div>
</div> </div>
</a> </a>
@ -162,4 +163,4 @@
</table> </table>
</xpath> </xpath>
</template> </template>
</odoo> </odoo>

85
theme_coffee_shop/views/cart_popover.xml

@ -1,52 +1,49 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- This XML template customizes the appearance and functionality of the cart popover in the website -->
<template id="coffee_cart_popover" inherit_id="website_sale.cart_popover" <template id="coffee_cart_popover" inherit_id="website_sale.cart_popover"
name="Coffee Cart Popover"> name="Coffee Cart Popover">
<xpath expr="." position="replace"> <xpath expr="." position="replace">
<div> <div>
<div class="items-cart"> <div class="items-cart">
<t t-foreach="website_sale_order.website_order_line" t-as="order_line"> <t t-foreach="website_sale_order.website_order_line"
<div class="item"> t-as="order_line">
<div class="item-img"> <div class="item">
<img t-attf-src="data:image/png;base64,{{order_line.product_id.image_1920}}" <div class="item-img">
alt=""/> <img t-attf-src="data:image/png;base64,{{order_line.product_id.image_1920}}"
alt=""/>
</div>
<div class="item-desc">
<p class="item-cartname">
<t t-esc="order_line.product_id.name"/>
</p>
<p class="item-cartabout">
<t t-esc="order_line.product_id.categ_id.name"/>
</p>
<p class="item-rate">
<t t-esc="order_line.price_unit"/>
</p>
</div>
</div> </div>
<div class="item-desc"> </t>
<p class="item-cartname"> </div>
<t t-esc="order_line.product_id.name"/> <div class="cart-border"/>
</p> <div class="row list-row cart-box-total">
<p class="item-cartabout"> <p class="list">Subtotal:</p>
<t t-esc="order_line.product_id.categ_id.name"/> <p class="amount">
</p> <t t-esc="website_sale_order.amount_total"/>
<p class="item-rate"> </p>
<t t-esc="order_line.price_unit"/> </div>
</p> <div class="cart-buttons">
</div> <a href="/shop/cart"
t-attf-class="nav-link">
</div> <button class="cartview">View Cart</button>
</t> </a>
</div> <a href="/shop/payment">
<div class="cart-border"> <button class="cartcheckout">checkout</button>
</div> </a>
<div class="row list-row cart-box-total"> </div>
<p class="list">Subtotal:</p>
<p class="amount">
<t t-esc="website_sale_order.amount_total"/>
</p>
</div>
<div class="cart-buttons">
<a href="/shop/cart"
t-attf-class="nav-link">
<button class="cartview">View Cart</button>
</a>
<a href="/shop/payment">
<button class="cartcheckout">checkout</button>
</a>
</div> </div>
</div>
</xpath> </xpath>
</template> </template>
</odoo> </odoo>

23
theme_coffee_shop/views/cart_summary.xml

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- This XML template customizes the appearance of the short cart summary in the website -->
<template id="coffee_short_cart_summary" <template id="coffee_short_cart_summary"
inherit_id="website_sale.short_cart_summary" inherit_id="website_sale.short_cart_summary"
name="Coffee Cart Summary"> name="Coffee Cart Summary">
@ -14,33 +15,30 @@
</div> </div>
</xpath> </xpath>
</template> </template>
<template id="coffee_shop_total" inherit_id="website_sale.total" <template id="coffee_shop_total" inherit_id="website_sale.total"
name="Coffee Total"> name="Coffee Total">
<xpath expr="." position="replace"> <xpath expr="." position="replace">
<div id="cart_total" style="margin-top: 40px;" t-att-class="extra_class or ''" <div id="cart_total" t-att-class="extra_class or ''"
t-if="website_sale_order and website_sale_order.website_order_line"> t-if="website_sale_order and website_sale_order.website_order_line">
<table class="table mb-0"> <table class="table mb-0">
<tr id="order_total_untaxed"> <tr id="order_total_untaxed">
<td class="list border-0">Subtotal:</td> <td class="list border-0">Subtotal:</td>
<td class="amount text-xl-end border-0"> <td class="amount text-xl-end border-0">
<span t-field="website_sale_order.amount_untaxed" <span t-field="website_sale_order.amount_untaxed"
class="monetary_field" class="monetary_field text-nowrap"
style="white-space: nowrap;"
t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"/> t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"/>
</td> </td>
</tr> </tr>
<tr></tr> <tr/>
<tr id="order_total_taxes"> <tr id="order_total_taxes">
<td class="list border-0">Sales tax:</td> <td class="list border-0">Sales tax:</td>
<td class="amount text-xl-end border-0"> <td class="amount text-xl-end border-0">
<span t-field="website_sale_order.amount_tax" <span t-field="website_sale_order.amount_tax"
class="monetary_field" class="monetary_field text-nowrap"
style="white-space: nowrap;"
t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"/> t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"/>
</td> </td>
</tr> </tr>
<tr></tr> <tr/>
<tr id="order_total"> <tr id="order_total">
<td class="list border-bottom-0">Grand Total:</td> <td class="list border-bottom-0">Grand Total:</td>
<td class="amount text-xl-end border-bottom-0"> <td class="amount text-xl-end border-bottom-0">
@ -49,7 +47,7 @@
t-options='{"widget": "monetary", "display_currency": website_sale_order.pricelist_id.currency_id}'/> t-options='{"widget": "monetary", "display_currency": website_sale_order.pricelist_id.currency_id}'/>
</td> </td>
</tr> </tr>
<tr></tr> <tr/>
<tr t-if="not hide_promotions"> <tr t-if="not hide_promotions">
<td class="list border-0">Coupon code:</td> <td class="list border-0">Coupon code:</td>
<td colspan="3" <td colspan="3"
@ -58,7 +56,9 @@
<t t-set='force_coupon' <t t-set='force_coupon'
t-value="website_sale_order.pricelist_id.code or request.params.get('code_not_available')"/> t-value="website_sale_order.pricelist_id.code or request.params.get('code_not_available')"/>
<t t-if="not force_coupon"> <t t-if="not force_coupon">
<a href="#" class="show_coupon coupon">I have a promo code </a> <a href="#" class="show_coupon coupon">I
have a promo code
</a>
</t> </t>
<div t-attf-class="coupon_form #{not force_coupon and 'd-none'}"> <div t-attf-class="coupon_form #{not force_coupon and 'd-none'}">
<t t-call="website_sale.coupon_form"/> <t t-call="website_sale.coupon_form"/>
@ -70,5 +70,4 @@
</div> </div>
</xpath> </xpath>
</template> </template>
</odoo>
</odoo>

56
theme_coffee_shop/views/contact_us.xml

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- This XML template customizes the appearance of the Contact Us page in the website -->
<template id="coffee_shop_contact_us" name="Coffee Shop Contact Us" <template id="coffee_shop_contact_us" name="Coffee Shop Contact Us"
inherit_id="website.contactus"> inherit_id="website.contactus">
<xpath expr="//div[@id='wrap']" position="replace"> <xpath expr="//div[@id='wrap']" position="replace">
<div id="wrap" class="oe_structure oe_empty">
<section id="banner" class="banner-imgContact"> <section id="banner" class="banner-imgContact">
<div class="container wrapper "> <div class="container wrapper ">
<div class="banner-content"> <div class="banner-content">
@ -43,8 +45,7 @@
data-type="char" data-type="char"
data-name="Field"> data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor"> <div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" <label class="col-form-label width_200 col-sm-auto s_website_form_label"
style="width: 200px"
for="contact1"> for="contact1">
<span class="s_website_form_label_content"> <span class="s_website_form_label_content">
Name Name
@ -67,8 +68,7 @@
data-type="char" data-type="char"
data-name="Field"> data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor"> <div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" <label class="col-form-label width_200 col-sm-auto s_website_form_label"
style="width: 200px"
for="contact2"> for="contact2">
<span class="s_website_form_label_content"> <span class="s_website_form_label_content">
Phone Phone
@ -88,8 +88,7 @@
data-type="email" data-type="email"
data-name="Field"> data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor"> <div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" <label class="col-form-label width_200 col-sm-auto s_website_form_label"
style="width: 200px"
for="contact3"> for="contact3">
<span class="s_website_form_label_content"> <span class="s_website_form_label_content">
Email Email
@ -112,8 +111,7 @@
data-type="char" data-type="char"
data-name="Field"> data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor"> <div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" <label class="col-form-label width_200 col-sm-auto s_website_form_label"
style="width: 200px"
for="contact4"> for="contact4">
<span class="s_website_form_label_content"> <span class="s_website_form_label_content">
Company Company
@ -132,8 +130,7 @@
data-type="char" data-type="char"
data-name="Field"> data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor"> <div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" <label class="col-form-label width_200 col-sm-auto s_website_form_label"
style="width: 200px"
for="contact5"> for="contact5">
<span class="s_website_form_label_content"> <span class="s_website_form_label_content">
Subject Subject
@ -155,26 +152,27 @@
data-type="text" data-type="text"
data-name="Field"> data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor"> <div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" <label class="col-form-label width_200 col-sm-auto s_website_form_label"
style="width: 200px"
for="contact6"> for="contact6">
<span class="s_website_form_label_content"> <span class="s_website_form_label_content">
Question Question
</span> </span>
<span class="s_website_form_mark">
*
</span>
</label> </label>
<div class="col-sm"> <div class="col-sm">
<textarea <textarea
id="contact6" id="contact6"
class="form-control s_website_form_input forms-input" class="form-control s_website_form_input forms-input"
name="description" name="description"
required=""></textarea> required=""/>
</div> </div>
</div> </div>
</div> </div>
<div class="mb-0 py-2 col-12 s_website_form_field s_website_form_dnone"> <div class="mb-0 py-2 col-12 s_website_form_field s_website_form_dnone">
<div class="row s_col_no_resize s_col_no_bgcolor"> <div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" <label class="col-form-label width_200 col-sm-auto s_website_form_label"
style="width: 200px"
for="contact7"> for="contact7">
<span class="s_website_form_label_content"> <span class="s_website_form_label_content">
Email Email
@ -196,10 +194,11 @@
personal personal
information to third parties. information to third parties.
</p> </p>
<a class="send-btn btn btn-primary btn-lg s_website_form_send" href="#" <a class="send-btn btn btn-primary btn-lg s_website_form_send"
href="#"
role="button">Send role="button">Send
</a> </a>
<span id="s_website_form_result"></span> <span id="s_website_form_result"/>
</div> </div>
</div> </div>
</form> </form>
@ -208,15 +207,20 @@
</div> </div>
</div> </div>
</section> </section>
<section id="map" class="container wrapper"> <!-- <t t-snippet="website.s_map" string="Smap"/>-->
<div class="map-container"> <section class="s_map s_map_1 pb56 pt56">
<iframe title="Calicut" loading="lazy" width="100%" <div class="map_container o_not_editable">
height="350" id="gmap_canvas" <div class="css_non_editable_mode_hidden">
src="https://maps.google.com/maps?q=Cybrosys%20Technologies%20Pvt.%20Ltd.%20Neospace%2C%20Kinfra%20Techno%20Park%2C%20Kakkancherry&amp;t=&amp;z=7&amp;ie=UTF8&amp;iwloc=&amp;output=embed" <div class="missing_option_warning alert alert-info rounded-0 fade show d-none d-print-none">
frameborder="0" scrolling="no" marginheight="0" An address must be specified for a map to be embedded
marginwidth="0"/> </div>
</div> </div>
</section> <!-- GMap iframe will be injected in JS -->
<div class="s_map_color_filter_1"/>
</div>
</section>
</div>
</xpath> </xpath>
</template> </template>
</odoo> </odoo>

144
theme_coffee_shop/views/feature.xml

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- This XML record defines a custom QWeb view for the "Feature" section of the website -->
<record id="coffee_feature" model="ir.ui.view"> <record id="coffee_feature" model="ir.ui.view">
<field name="name">Feature</field> <field name="name">Feature</field>
<field name="type">qweb</field> <field name="type">qweb</field>
@ -8,30 +8,142 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<t name="Feature" t-name="theme_coffee_shop.feature"> <t name="Feature" t-name="theme_coffee_shop.feature">
<t t-call="website.layout"> <t t-call="website.layout">
<div id="wrap"> <div id="wrap" class="oe_structure oe_empty">
<section id="banner" class="banner-imgFeature"> <section id="banner" class="banner-imgFeature" data-vcss="001" data-snippet="s_title">
<div class="container wrapper "> <div class="container wrapper ">
<div class="banner-content"> <div class="banner-content">
<div class="banner-text"> <div class="banner-text">
<p class="banner-head">Our aewsome</p> <p class="banner-head">Our awesome</p>
<p class="banner-head">Premium Features</p> <p class="banner-head">Premium
Features
</p>
</div>
</div> </div>
</div> </div>
</div> </section>
</section> <section class="s_process_steps pt24 pb24 s_process_steps_connector_line" data-vcss="001">
<div class="oe_structure"/> <svg class="s_process_step_svg_defs position-absolute">
</div> <defs>
<marker class="s_process_steps_arrow_head" markerWidth="15" markerHeight="10"
refX="6" refY="6" orient="auto">
<path d="M 2,2 L10,6 L2,10 L6,6 L2,2" vector-effect="non-scaling-size"/>
</marker>
</defs>
</svg>
<div class="container">
<div class="row g-0">
<div class="col-lg-3 s_process_step pt24 pb24">
<svg class="s_process_step_connector" viewBox="0 0 100 20"
preserveAspectRatio="none">
<path d="M 0 10 L 100 10" vector-effect="non-scaling-stroke"/>
</svg>
<div class="s_process_step_icon">
<i class="fa fa-shopping-basket fa-2x mx-auto rounded-circle bg-o-color-1"/>
</div>
<div class="s_process_step_content">
<h2>Add to cart</h2>
<p>Let your customers follow<br/>and understand your process.
</p>
</div>
</div>
<div class="col-lg-3 s_process_step pt24 pb24">
<svg class="s_process_step_connector" viewBox="0 0 100 20"
preserveAspectRatio="none">
<path d="M 0 10 L 100 10" vector-effect="non-scaling-stroke"/>
</svg>
<div class="s_process_step_icon">
<i class="fa fa-unlock-alt fa-2x mx-auto rounded-circle bg-o-color-5"/>
</div>
<div class="s_process_step_content">
<h2>Sign in</h2>
<p>Click on the icon to adapt it<br/>to your purpose.
</p>
</div>
</div>
<div class="col-lg-3 s_process_step pt24 pb24">
<svg class="s_process_step_connector" viewBox="0 0 100 20"
preserveAspectRatio="none">
<path d="M 0 10 L 100 10" vector-effect="non-scaling-stroke"/>
</svg>
<div class="s_process_step_icon">
<i class="fa fa-paypal fa-2x mx-auto rounded-circle bg-o-color-2"/>
</div>
<div class="s_process_step_content">
<h2>Pay</h2>
<p>Duplicate blocks<br/>to add more steps.
</p>
</div>
</div>
<div class="col-lg-3 s_process_step pt24 pb24">
<svg class="s_process_step_connector" viewBox="0 0 100 20"
preserveAspectRatio="none">
<path d="M 0 10 L 100 10" vector-effect="non-scaling-stroke"/>
</svg>
<div class="s_process_step_icon">
<i class="fa fa-plane fa-2x mx-auto rounded-circle bg-o-color-3"/>
</div>
<div class="s_process_step_content">
<h2>Get Delivered</h2>
<p>Select and delete blocks<br/>to remove some steps.
</p>
</div>
</div>
</div>
</div>
</section>
<section class="s_text_image pt32 pb32">
<div class="container">
<div class="row align-items-center">
<div class="col-lg-6 pt16 pb16">
<img src="/web/image/website.s_image_text_default_image"
class="img img-fluid mx-auto" alt=""/>
</div>
<div class="col-lg-6 pt16 pb16">
<h2>Section Subtitle</h2>
<p>Write one or two paragraphs describing your product or services. To be
successful your content needs to be useful to your readers.
</p>
<p>Start with the customer – find out what they want and give it to them.</p>
<p>
<a href="#" class="btn btn-secondary">Discover more</a>
</p>
</div>
</div>
</div>
</section>
<section class="s_features pt32 pb32">
<div class="container">
<div class="row">
<div class="col-lg-4 pt32 pb32 text-center">
<i class="fa fa-3x fa-gear rounded bg-o-color-1 m-3"/>
<h3>First Feature</h3>
<p>Tell what's the value for the<br/>customer for this feature.
</p>
</div>
<div class="col-lg-4 pt32 pb32 text-center">
<i class="fa fa-3x fa-photo rounded bg-o-color-5 m-3"/>
<h3>Second Feature</h3>
<p>Write what the customer would like to know,<br/>not what you want to show.
</p>
</div>
<div class="col-lg-4 pt32 pb32 text-center">
<i class="fa fa-3x fa-leaf rounded bg-o-color-2 m-3"/>
<h3>Third Feature</h3>
<p>A small explanation of this great<br/>feature, in clear words.
</p>
</div>
</div>
</div>
</section>
</div>
</t> </t>
</t> </t>
</field> </field>
</record> </record>
<record id="feature" model="website.page">
<record id="feature" model="website.page">
<field name="is_published">True</field> <field name="is_published">True</field>
<field name="url">/feature</field> <field name="url">/feature</field>
<field name="view_id" ref="coffee_feature"/> <field name="view_id" ref="coffee_feature"/>
<field name="track">True</field> <field name="track">True</field>
</record> </record>
</odoo> </odoo>

48
theme_coffee_shop/views/footer.xml

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- Footer-->
<template id="theme_coffee_shop_footer" inherit_id="website.layout" <template id="theme_coffee_shop_footer" inherit_id="website.layout"
name="Coffee Shop Footer"> name="Coffee Shop Footer">
<xpath expr="//div[@id='footer']" position="replace"> <xpath expr="//div[@id='footer']" position="replace">
@ -19,57 +20,42 @@
</div> </div>
<p class="footer-para">Lorem ipsum dolor sit amet, <p class="footer-para">Lorem ipsum dolor sit amet,
consectetur consectetur
adipiscing elit, sed do eiusmod tempor fiter adipiscing elit, sed do eiusmod tempor fiter
incididunt ut labore et dolore magna aliqua. incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip exercitation ullamco laboris nisi ut aliquip
ea commodo consequat. ea commodo consequat.
</p> </p>
</div> </div>
<div class="col foot "> <div class="col foot ">
<p class="footer-heading">Location</p> <p class="footer-heading">Location</p>
<div class="address"> <div class="address">
<p class="footer-subhead">New York</p> <p class="footer-subhead">New York</p>
<p class="foot-address">1 444 123 4559Raymond <p class="foot-address">1 444 123 4559<br/>
Raymond Boulevard 224, New York<br/>
Boulevard 224,New York Info@Expresso.com<br/>
Info@Expresso.com
213 548 698 213 548 698
</p> </p>
</div> </div>
<div class="address"> <div class="address">
<p class="footer-subhead">Florida</p> <p class="footer-subhead">Florida</p>
<p class="foot-address"> <p class="foot-address">
2606 Saints AlleyTampa, 2606 Saints AlleyTampa, <br/>
FL 33602 FL 33602<br/>
Info@Expresso.com Info@Expresso.com<br/>
213 548 698 213 548 698
</p> </p>
</div> </div>
</div> </div>
<div class="col foot"> <div class="col foot">
<p class="footer-heading">Home</p> <p class="footer-heading">Home</p>
<div class="link"> <div class="link">
<a class="foot-links" href="#">Menu</a> <a class="foot-links" href="/menu">Menu</a>
<a class="foot-links" href="#">Shop</a> <a class="foot-links" href="/shop">Shop</a>
<a class="foot-links" href="#">About</a> <a class="foot-links" href="/about">About</a>
<a class="foot-links" href="#">Contact</a> <a class="foot-links" href="/contactus">Contact</a>
<a class="foot-links" href="#">Login</a> <a class="foot-links" href="/web/login">Login</a>
</div> </div>
</div> </div>
<div class="col foot"> <div class="col foot">
<p class="footer-heading">Get in touch</p> <p class="footer-heading">Get in touch</p>
@ -102,18 +88,12 @@
</a> </a>
<p class="foot-address">Twitter</p> <p class="foot-address">Twitter</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<p class="foot-end">© Cybrosys technologies 2022</p> <p class="foot-end">© Cybrosys technologies 2023</p>
</div> </div>
</footer> </footer>
</xpath> </xpath>
</template> </template>
</odoo> </odoo>

126
theme_coffee_shop/views/header.xml

@ -1,123 +1,75 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- Navbar-->
<template id="header_coffee_shop" <template id="header_coffee_shop"
inherit_id="website.template_header_default" inherit_id="website.template_header_default"
name="Template Header Theme" active="True"> name="Template Header Theme" active="True">
<xpath expr="//t[@t-call='website.navbar']" position="replace"> <xpath expr="//t[@t-call='website.navbar']" position="replace">
<t t-call="website.navbar"> <t t-call="website.navbar">
<div id="top_menu_container" <div id="top_menu_container"
class="container justify-content-start justify-content-lg-between"> class="container justify-content-start justify-content-lg-between">
<div class="logo"> <div class="logo">
<img src="/theme_coffee_shop/static/src/images/logo.png" <img src="/theme_coffee_shop/static/src/images/logo.png"
alt=""/> alt=""/>
</div> </div>
<div id="top_menu_collapse"
<div id="top_menu_collapse" class="collapse navbar-collapse order-last order-lg-0"> class="collapse navbar-collapse order-last order-lg-0">
<t t-call="website.navbar_nav"> <t t-call="website.navbar_nav">
<t t-set="_nav_class" t-valuef="flex-grow"/> <t t-set="_nav_class" t-valuef="flex-grow"/>
<!-- Menu --> <!-- Menu -->
<t t-foreach="website.menu_id.child_id" t-as="submenu"> <t t-foreach="website.menu_id.child_id"
<t t-call="website.submenu"> t-as="submenu">
<t t-set="item_class" t-valuef="nav-item"/> <t t-call="website.submenu">
<t t-set="link_class" t-valuef="nav-link"/> <t t-set="item_class" t-valuef="nav-item"/>
</t> <t t-set="link_class" t-valuef="nav-link"/>
</t> </t>
<!-- Cart--> </t>
<t t-call="website_sale.header_cart_link"> <!-- Cart -->
<t t-set="_icon" t-value="True"/> <t t-call="website_sale.header_cart_link">
<t t-set="_item_class" t-value="'mx-lg-3 '"/> <t t-set="_icon" t-value="True"/>
<t t-set="_link_class" t-value="'nav-link'"/> <t t-set="_item_class" t-value="'mx-lg-3 '"/>
</t> <t t-set="_link_class" t-value="'nav-link'"/>
<!-- Wishlist--> </t>
<t t-call="website_sale_wishlist.header_wishlist_link"> <!-- Wishlist -->
<t t-set="_icon" t-value="True"/> <t t-call="website_sale_wishlist.header_wishlist_link">
<t t-set="_item_class" t-value="'mx-lg-3'"/> <t t-set="_icon" t-value="True"/>
<t t-set="_link_class" t-value="'nav-link'"/> <t t-set="_item_class" t-value="'mx-lg-3'"/>
</t> <t t-set="_link_class" t-value="'nav-link'"/>
</t>
<!-- Sign In --> <!-- Sign In -->
<t t-call="portal.placeholder_user_sign_in"> <t t-call="portal.placeholder_user_sign_in">
<t t-set="_item_class" t-valuef="nav-item ms-lg-auto"/> <t t-set="_item_class"
<t t-set="_link_class" t-valuef="nav-link fw-bold"/> t-valuef="nav-item ms-lg-auto"/>
</t> <t t-set="_link_class"
t-valuef="nav-link fw-bold"/>
</t>
<!-- User Dropdown --> <!-- User Dropdown -->
<t t-call="portal.user_dropdown"> <t t-call="portal.user_dropdown">
<t t-set="_user_name" t-value="true"/> <t t-set="_user_name" t-value="true"/>
<t t-set="_item_class" t-valuef="dropdown ms-lg-auto "/> <t t-set="_item_class"
<t t-set="_link_class" t-valuef="nav-link fw-bold"/> t-valuef="dropdown ms-lg-auto "/>
<t t-set="_link_class"
t-valuef="nav-link fw-bold"/>
</t> </t>
</t> </t>
</div> </div>
<!-- Navbar Toggler --> <!-- Navbar Toggler -->
<t t-call="website.navbar_toggler"> <t t-call="website.navbar_toggler">
<t t-set="_toggler_class" t-valuef="ms-auto"/> <t t-set="_toggler_class" t-valuef="ms-auto"/>
</t> </t>
</div> </div>
</t> </t>
</xpath> </xpath>
</template> </template>
<!-- TEMPLATE FOR WISHLIST AND CART IN HEADER-->
<!-- TEMPLATE FOR CART IN HEADER-->
<template id="coffee_header_cart_link" name=" Coffee Header Cart Link"
inherit_id="website_sale.header_cart_link">
<xpath expr="//t" position="replace">
<t t-nocache="The number of products is dynamic, this rendering cannot be cached."
t-nocache-_icon="_icon"
t-nocache-_text="_text"
t-nocache-_item_class="_item_class"
t-nocache-_link_class="_link_class">
<t t-set="website_sale_cart_quantity" t-value="request.session['website_sale_cart_quantity'] if 'website_sale_cart_quantity' in request.session else website.sale_get_order().cart_quantity or 0"/>
<t t-set="show_cart" t-value="true"/>
<li t-attf-class="#{_item_class} divider d-none"/>
<li t-attf-class="o_wsale_my_cart align-self-md-start #{not show_cart and 'd-none'} #{_item_class}">
<a href="/shop/cart" t-attf-class="#{_link_class}">
<img class="cart-icon"
src="/theme_coffee_shop/static/src/images/cart.png"
alt=""/>
<span t-if="_text">Cart items</span>
<sup class="my_cart_quantity badge text-bg-primary d-none" t-esc="website_sale_cart_quantity" t-att-data-order-id="request.session.get('sale_order_id', '')"/>
<div class="notify"/>
</a>
</li>
</t>
</xpath>
</template>
<!-- TEMPLATE FOR WISHLIST IN HEADER-->
<template id="coffee_header_wishlist_link" <template id="coffee_header_wishlist_link"
name=" Coffee Header Wishlist Link" name=" Coffee Header Wishlist Link"
inherit_id="website_sale_wishlist.header_wishlist_link"> inherit_id="website_sale_wishlist.template_header_default">
<xpath expr="//t" position="replace"> <xpath expr="//t[@t-call='website_sale.header_cart_link']"
<t t-nocache="The wishlist may vary and depends on the user." position="replace">
t-nocache-_icon="_icon" </xpath>
t-nocache-_item_class="_item_class" <xpath expr="//t[@t-call='website_sale_wishlist.header_wishlist_link']"
t-nocache-_link_class="_link_class" position="replace">
t-nocache-_text="_text">
<t t-set="wishcount"
t-value="len(request.env['product.wishlist'].current())"/>
<t t-set="show_wishes" t-value="True"/>
<li t-attf-class="o_wsale_my_wish #{not show_wishes and 'd-none'} #{_item_class}">
<a href="/shop/wishlist" t-attf-class="#{_link_class}">
<img src="/theme_coffee_shop/static/src/images/wishlist.png"
alt=""/>
<span t-if="_text">Wishlist</span>
<div class="notify"/>
</a>
</li>
</t>
</xpath> </xpath>
</template> </template>
</odoo> </odoo>

280
theme_coffee_shop/views/login.xml

@ -1,280 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- SIGN IN FIELDS-->
<template id="coffee_auth_fields" inherit_id="auth_signup.fields" name="Auth Signup/ResetPassword form fields">
<xpath expr="//t" position="replace">
<div class="form-group">
<input type="text" name="login" t-att-value="login"
id="login" class="login-input form-control form-control-sm"
placeholder="Email" autofocus="autofocus"
autocapitalize="off" required="required"
t-att-readonly="'readonly' if only_passwords else None"
style="margin-bottom: 15px;"/>
</div>
<div class="form-group">
<input type="text" name="name" t-att-value="name"
id="name" class="login-input" placeholder="Your Name"
style="margin-bottom: 15px;"
required="required" t-att-readonly="'readonly' if only_passwords else None"
t-att-autofocus="'autofocus' if login and not only_passwords else None" />
</div>
<div class="form-group">
<input type="password" name="password" id="password"
class="login-input" placeholder="Password"
style="margin-bottom: 15px;"
required="required" t-att-autofocus="'autofocus' if only_passwords else None"/>
</div>
<div class="form-group">
<input type="password" name="confirm_password" id="confirm_password"
class="login-input" placeholder="Confirm Password"
style="margin-bottom: 15px;" required="required"/>
</div>
</xpath>
</template>
<!-- SIGN UP-->
<template id="coffee_signup" name="Sign up login" inherit_id="auth_signup.signup">
<xpath expr="//t[@t-call='web.login_layout']" position="replace">
<t t-call="web.login_layout">
<section class="login-form-container show">
<form style="width: 505px;height: auto;" role="form" method="post" t-if="not message">
<input type="hidden" name="csrf_token"
t-att-value="request.csrf_token()"/>
<i class="fa-solid fa-xmark login-close">X</i>
<div class="form-content">
<h3 class="login-form-head">Create New Account
</h3>
<div class="form-group">
<div class="o_login_auth">
<t t-call="auth_oauth.providers"/>
</div>
</div>
<div class="form-group">
<input type="text" name="login" t-att-value="login"
id="login" class="login-input form-control form-control-sm"
placeholder="Email" autofocus="autofocus"
autocapitalize="off" required="required"
t-att-readonly="'readonly' if only_passwords else None"
style="margin-bottom: 15px;"/>
</div>
<div class="form-group">
<input type="text" name="name" t-att-value="name"
id="name" class="login-input" placeholder="Your Name"
style="margin-bottom: 15px;"
required="required" t-att-readonly="'readonly' if only_passwords else None"
t-att-autofocus="'autofocus' if login and not only_passwords else None" />
</div>
<div class="form-group">
<input type="password" name="password" id="password"
class="login-input" placeholder="Password"
style="margin-bottom: 15px;"
required="required" t-att-autofocus="'autofocus' if only_passwords else None"/>
</div>
<div class="form-group">
<input type="password" name="confirm_password" id="confirm_password"
class="login-input" placeholder="Confirm Password"
style="margin-bottom: 15px;" required="required"/>
</div>
<t t-set="only_passwords" t-value="bool(token and not invalid_token)"/>
<input type="hidden" name="redirect" t-att-value="redirect"/>
<input type="hidden" name="token" t-att-value="token"/>
<button type="submit" class="login-google"> Sign up</button>
<p class="register">
<a t-attf-href="/web/login?{{ keep_query() }}" class="frgt-text" role="button">Already have an account?</a>
</p>
</div>
</form>
</section>
</t>
</xpath>
</template>
<!-- RESET PASSWORD-->
<template id="coffee_reset" inherit_id="auth_signup.reset_password" name="Reset password">
<xpath expr="//t[@t-call='web.login_layout']" position="replace">
<t t-call="web.login_layout">
<section class="login-form-container show">
<form style="width: 445px;height: auto;"
role="form" method="post" t-if="not message" >
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<i class="fa-solid fa-xmark login-close">X</i>
<div class="form-content">
<h3 class="login-form-head">Reset Password
</h3>
<t t-if="token and not invalid_token">
<t t-call="auth_signup.fields">
<t t-set="only_passwords" t-value="1"/>
</t>
</t>
<t t-if="not token">
<div class="form-group">
<input type="text" name="login" t-att-value="login"
id="login" class="login-input" placeholder="Your Email"
style="margin-bottom: 15px;" autofocus="autofocus"
required="required" autocapitalize="off"/>
</div>
</t>
<input type="hidden" name="redirect" t-att-value="redirect"/>
<input type="hidden" name="token" t-att-value="token"/>
<button type="submit" class="login-google" style="margin-bottom: 15px;">Reset Password</button>
<p class="register">
<a t-if="not token" t-attf-href="/web/login?{{ keep_query() }}" class="frgt-text">Back to Login</a>
<a t-if="invalid_token" href="/web/login" class="frgt-text">Back to Login</a>
</p>
</div>
</form>
</section>
</t>
</xpath>
</template>
<!-- TEMPLATE FOR LOGIN-->
<template id="coffee_user_sign_in" name="User Sign In" inherit_id="portal.user_sign_in">
<xpath expr="." position="replace">
<li t-nocache="Profile session and user group can change unrelated to parent caches."
t-nocache-_item_class="_item_class"
t-nocache-_link_class="_link_class"
groups="base.group_public" t-attf-class="#{_item_class} o_no_autohide_item">
<a t-attf-href="/web/login" t-attf-class="#{_link_class}">
<span> Log in</span>
<span t-if="request.session.profile_session" class="text-danger fa fa-circle"/>
</a>
</li>
</xpath>
</template>
<!-- PROFILE-->
<template id="user_dropdown" name="Portal User Dropdown" inherit_id="portal.user_dropdown">
<xpath expr="//t" position="replace">
<t t-nocache="Each user is different regardless of the page visited."
t-nocache-_avatar="_avatar"
t-nocache-_icon="_icon"
t-nocache-_icon_class="_icon_class"
t-nocache-_user_name="_user_name"
t-nocache-_user_name_class="_user_name_class"
t-nocache-_item_class="_item_class"
t-nocache-_link_class="_link_class"
t-nocache-_dropdown_menu_class="_dropdown_menu_class">
<t t-set="is_connected" t-value="not user_id._is_public()"/>
<li t-if="is_connected" t-attf-class="#{_item_class} o_no_autohide_item">
<a href="#" role="button" data-bs-toggle="dropdown" t-attf-class="dropdown-toggle #{_link_class}">
<t t-if="_avatar">
<t t-set="avatar_source" t-value="image_data_uri(user_id.avatar_256)"/>
<img t-att-src="avatar_source" t-attf-class="rounded-circle o_object_fit_cover #{_avatar_class}" width="24" height="24" alt="" loading="eager"/>
</t>
<i t-if="_icon" t-attf-class="fa fa-1x fa-fw fa-user-circle-o #{_icon_class}"/>
<span t-if="_user_name" t-attf-class="#{_user_name_class}" t-esc="user_id.name[:23] + '...' if user_id.name and len(user_id.name) &gt; 25 else user_id.name"/>
</a>
<div t-attf-class=" dropdown-menu js_usermenu #{_dropdown_menu_class}" role="menu">
<a groups="base.group_user" href="/web" role="menuitem" class="dropdown-item ps-3 my_coffee" id="o_backend_user_dropdown_link">
Apps
</a>
<a href="/my/home" role="menuitem" class="dropdown-item ps-3 my_coffee ">
My Account
</a>
<a t-attf-href="/web/session/logout?redirect=/" role="menuitem" id="o_logout" class="dropdown-item ps-3 my_coffee">
Logout
</a>
</div>
</li>
</t>
</xpath>
</template>
<!-- LOGIN-->
<template id="coffee_login" inherit_id="web.login" name="Coffee login">
<xpath expr="//t[@t-call='web.login_layout']" position="replace">
<t t-call="web.login_layout">
<section class="login-form-container show">
<form action="" style="width: 505px;height: auto;"
role="form" t-attf-action="/web/login" method="post"
onsubmit="this.action = '/web/login' + location.hash">
<input type="hidden" name="csrf_token"
t-att-value="request.csrf_token()"/>
<i class="fa-solid fa-xmark login-close">X</i>
<div class="form-content">
<h3 class="login-form-head">Welcome to expresoo</h3>
<div class="form-group">
<div class="o_login_auth">
<t t-call="auth_oauth.providers"></t>
</div>
<input type="text"
class="login-input"
placeholder="Email"
name="login"
t-att-value="login"
id="login"
required="required"
autofocus="autofocus"
autocapitalize="off"
style="margin-bottom: 15px;"/>
</div>
<div class="form-group">
<input type="password"
class="login-input"
placeholder="Password"
name="password"
id="password"
required="required"
autocomplete="current-password"
t-att-autofocus="'autofocus' if login else None"
maxlength="4096"/>
</div>
<div class="password-settings">
<a t-if="signup_enabled" t-attf-href="/web/signup?{{ keep_query() }}" class="frgt-text">Create an account</a>
<a t-if="reset_password_enabled" t-attf-href="/web/reset_password?{{ keep_query() }}" class="frgt-text">Forgot password?</a>
</div>
<button type="submit" class="login-google">Login</button>
<br></br>
<t t-if="debug">
<button type="submit" name="redirect" style="padding-top: 10px;" value="/web/become" class="btn btn-link btn-sm frgt-text">Log in as superuser</button>
</t>
</div>
<input type="hidden" name="redirect" t-att-value="redirect"/>
</form>
</section>
</t>
</xpath>
</template>
<!--REMOVE 'OR' FROM LOGIN PAGE-->
<template id="remove_or" inherit_id="auth_oauth.providers">
<xpath expr="//t" position="replace">
<t t-if="len(providers) &gt; 0">
<em t-attf-class="d-block d-none text-center text-muted small my-#{len(providers) if len(providers) &lt; 3 else 3}">- or -</em>
<div class="o_auth_oauth_providers list-group mt-1 mb-1 text-start">
<a t-foreach="providers" t-as="p" class="list-group-item list-group-item-action py-2 my_superlogin" t-att-href="p['auth_link']">
<i t-att-class="p['css_class']"/>
<t t-esc="p['body']"/>
</a>
</div>
<p class="login-or">Or sign in with Email</p>
</t>
</xpath>
</template>
</odoo>

288
theme_coffee_shop/views/menu_page.xml

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- This XML record defines a custom website page for the "Menu" section -->
<record id="coffee_menu" model="website.page"> <record id="coffee_menu" model="website.page">
<field name="name">Menu</field> <field name="name">Menu</field>
<field name="type">qweb</field> <field name="type">qweb</field>
@ -10,151 +10,185 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<t name="Menu" t-name="theme_coffee_shop.coffee_menu"> <t name="Menu" t-name="theme_coffee_shop.coffee_menu">
<t t-call="website.layout"> <t t-call="website.layout">
<t t-set="opt_wsale_categories_top" t-value="is_view_active('website_sale.products_categories_top')"/> <t t-set="opt_wsale_categories_top"
t-value="is_view_active('website_sale.products_categories_top')"/>
<div id="wrap"> <div id="wrap">
<section id="banner" class="banner-img"> <section id="banner" class="banner-img">
<div class="container wrapper "> <div class="container wrapper ">
<div class="banner-content"> <div class="banner-content">
<div class="banner-text"> <div class="banner-text">
<p class="banner-head">Better Beans</p> <p class="banner-head">Better Beans</p>
<p class="banner-head">Better Coffee</p> <p class="banner-head">Better Coffee
</div> </p>
</div> </div>
</div>
</section>
<div class="oe_structure oe_empty oe_structure_not_nearest"/>
<div class="container oe_website_sale pt-2">
<div class="row o_wsale_products_main_row align-items-start flex-nowrap">
<div id="products_grid">
<t t-call="theme_coffee_shop.coffee_products_breadcrumb">
<t t-set="_classes" t-valuef="d-none d-lg-flex w-100 p-0 small"/>
</t>
<div class="products_header btn-toolbar flex-nowrap align-items-center justify-content-between mb-3">
<t t-call="theme_coffee_shop.coffee_menu_category"/>
<div t-if="category" class="d-flex align-items-center d-lg-none me-auto">
<t t-if="not category.parent_id" t-set="backUrl" t-valuef="/menu"/>
<t t-else="" t-set="backUrl" t-value="keep('/menu/category/' + slug(category.parent_id), category=0)"/>
<a t-attf-class="btn btn-{{navClass}} me-2" t-att-href="category.parent_id and keep('/menu/category/' + slug(category.parent_id), category=0) or '/menu'">
<i class="fa fa-angle-left"/>
</a>
<h4 t-out="category.name" class="mb-0 me-auto"/>
</div> </div>
<button t-if="opt_wsale_categories"
t-attf-class="btn btn-{{navClass}} position-relative ms-3 {{not opt_wsale_attributes_top and 'd-lg-none'}}"
data-bs-toggle="offcanvas"
data-bs-target="#o_wsale_offcanvas">
<i class="fa fa-sliders"/>
<span t-if="isFilteringByPrice or attrib_set" t-attf-class="position-absolute top-0 start-100 translate-middle badge border border-{{navClass}} rounded-circle bg-danger p-1"><span class="visually-hidden">filters active</span></span>
</button>
</div>
<div t-if="original_search and products" class="alert alert-warning mt8">
No results found for '<span t-esc="original_search"/>'. Showing results for '<span t-esc="search"/>'.
</div> </div>
</section>
<t t-if="category"> <div class="oe_structure oe_empty oe_structure_not_nearest"/>
<t t-set='editor_msg'>Drag building blocks here to customize the header for "<t t-esc='category.name'/>" category.</t> <div class="container oe_website_sale pt-2">
<div class="mb16" id="category_header" t-att-data-editor-message="editor_msg" t-field="category.website_description"/> <div class="row o_wsale_products_main_row align-items-start flex-nowrap">
</t> <div id="products_grid">
<t t-call="theme_coffee_shop.coffee_products_breadcrumb">
<div t-cache="pricelist,products" t-if="products" class="o_wsale_products_grid_table_wrapper pt-3 pt-lg-0"> <t t-set="_classes"
<table class="table table-borderless h-100 m-0" t-att-data-ppg="ppg" t-att-data-ppr="ppr" t-att-data-default-sort="website.shop_default_sort" t-att-data-name="grid_block_name"> t-valuef="d-none d-lg-flex w-100 p-0 small"/>
<colgroup t-ignore="true"> </t>
<col t-foreach="ppr" t-as="p"/> <div class="products_header btn-toolbar flex-nowrap align-items-center justify-content-between mb-3">
</colgroup> <t t-call="theme_coffee_shop.coffee_menu_category"/>
<tbody>
<tr t-foreach="bins" t-as="tr_product"> <div t-if="category"
<t t-foreach="tr_product" t-as="td_product"> class="d-flex align-items-center d-lg-none me-auto">
<t t-if="td_product"> <t t-if="not category.parent_id"
<td t-att-colspan="td_product['x'] != 1 and td_product['x']" t-set="backUrl"
t-att-rowspan="td_product['y'] != 1 and td_product['y']" t-valuef="/menu"/>
t-attf-class="oe_product" <t t-else="" t-set="backUrl"
t-att-data-ribbon-id="td_product['ribbon'].id" t-value="keep('/menu/category/' + slug(category.parent_id), category=0)"/>
t-att-data-name="product_block_name">
<div t-attf-class="o_wsale_product_grid_wrapper position-relative h-100 o_wsale_product_grid_wrapper_#{td_product['x']}_#{td_product['y']}"> <a t-attf-class="btn btn-{{navClass}} me-2"
<t t-call="website_sale.products_item"> t-att-href="category.parent_id and keep('/menu/category/' + slug(category.parent_id), category=0) or '/menu'">
<t t-set="product" t-value="td_product['product']"/> <i class="fa fa-angle-left"/>
</t> </a>
</div> <h4 t-out="category.name"
</td> class="mb-0 me-auto"/>
</div>
<button t-if="opt_wsale_categories"
t-attf-class="btn btn-{{navClass}} position-relative ms-3 {{not opt_wsale_attributes_top and 'd-lg-none'}}"
data-bs-toggle="offcanvas"
data-bs-target="#o_wsale_offcanvas">
<i class="fa fa-sliders"/>
<span t-if="isFilteringByPrice or attrib_set"
t-attf-class="position-absolute top-0 start-100 translate-middle badge border border-{{navClass}} rounded-circle bg-danger p-1">
<span class="visually-hidden">
filters active
</span>
</span>
</button>
</div>
<div t-if="original_search and products"
class="alert alert-warning mt8">
No results found for '<span
t-esc="original_search"/>'. Showing
results for '<span t-esc="search"/>'.
</div>
<t t-if="category">
<t t-set='editor_msg'>Drag building
blocks here to customize the header
for "<t t-esc='category.name'/>"
category.
</t>
<div class="mb16" id="category_header"
t-att-data-editor-message="editor_msg"
t-field="category.website_description"/>
</t>
<div t-cache="pricelist,products"
t-if="products"
class="o_wsale_products_grid_table_wrapper pt-3 pt-lg-0">
<table class="table table-borderless h-100 m-0"
t-att-data-ppg="ppg"
t-att-data-ppr="ppr"
t-att-data-default-sort="website.shop_default_sort"
t-att-data-name="grid_block_name">
<colgroup t-ignore="true">
<col t-foreach="ppr" t-as="p"/>
</colgroup>
<tbody>
<tr t-foreach="bins"
t-as="tr_product">
<t t-foreach="tr_product"
t-as="td_product">
<t t-if="td_product">
<td t-att-colspan="td_product['x'] != 1 and td_product['x']"
t-att-rowspan="td_product['y'] != 1 and td_product['y']"
t-attf-class="oe_product"
t-att-data-ribbon-id="td_product['ribbon'].id"
t-att-data-name="product_block_name">
<div t-attf-class="o_wsale_product_grid_wrapper position-relative h-100 o_wsale_product_grid_wrapper_#{td_product['x']}_#{td_product['y']}">
<t t-call="website_sale.products_item">
<t t-set="product"
t-value="td_product['product']"/>
</t>
</div>
</td>
</t>
<td t-else=""/>
</t>
</tr>
</tbody>
</table>
</div>
<div t-else=""
class="text-center text-muted mt128 mb256">
<t t-if="not search">
<h3 class="mt8">No product defined
</h3>
<p t-if="category">No product
defined in category "
<strong
t-esc="category.display_name"/>
".
</p>
</t>
<t t-else="">
<h3 class="mt8">No results</h3>
<p>No results for "<strong
t-esc='search'/>"
<t t-if="category">in category
"
<strong t-esc="category.display_name"/>
"
</t> </t>
<td t-else=""/> .
</t> </p>
</tr> </t>
</tbody> <p t-ignore="true"
</table> groups="sales_team.group_sale_manager">
</div> Click <i>'New'</i> in the top-right
<div t-else="" class="text-center text-muted mt128 mb256"> corner to create your first
<t t-if="not search"> product.
<h3 class="mt8">No product defined</h3> </p>
<p t-if="category">No product defined in category "<strong t-esc="category.display_name"/>".</p> </div>
</t> <div class="products_pager d-flex justify-content-center pt-5 pb-3">
<t t-else=""> <t t-call="website.pager"/>
<h3 class="mt8">No results</h3> </div>
<p>No results for "<strong t-esc='search'/>"<t t-if="category"> in category "<strong t-esc="category.display_name"/>"</t>.</p> </div>
</t>
<p t-ignore="true" groups="sales_team.group_sale_manager">Click <i>'New'</i> in the top-right corner to create your first product.</p>
</div>
<div class="products_pager d-flex justify-content-center pt-5 pb-3">
<t t-call="website.pager"/>
</div> </div>
<t t-call="website_sale.o_wsale_offcanvas"/>
</div> </div>
<div class="oe_structure oe_empty oe_structure_not_nearest"/>
</div> </div>
<t t-call="website_sale.o_wsale_offcanvas"/>
</div>
<div class="oe_structure oe_empty oe_structure_not_nearest"/>
</div>
</t> </t>
</t> </t>
</field> </field>
</record> </record>
<!-- This XML template defines the display of menu categories in the "Menu" section -->
<template id="coffee_menu_category" name="Coffee Menu Categories">
<template id="coffee_menu_category" name=" Coffee Menu Categories ">
<t t-if="category.id"> <t t-if="category.id">
<t t-set="entries" t-value="not search and category.child_id or category.child_id.filtered(lambda c: category.id in search_categories_ids)"/> <t t-set="entries"
t-value="not search and category.child_id or category.child_id.filtered(lambda c: category.id in search_categories_ids)"/>
<t t-if="not entries">
<t t-set="parent" t-value="category.parent_id"/>
<t t-set="entries" t-value="not search and parent.child_id or parent.child_id.filtered(lambda c: parent.id in search_categories_ids)"/>
</t>
</t> </t>
<t t-else=""> <t t-else="">
<t t-set="entries" t-value="categories"/> <t t-set="entries" t-value="categories"/>
</t> </t>
<div t-if="entries"
<div t-if="entries" class="o_wsale_filmstip_container d-flex align-items-stretch mb-2 overflow-hidden"> class="o_wsale_filmstip_container d-flex align-items-stretch mb-2 overflow-hidden">
<div class="o_wsale_filmstip_wrapper pb-1 mb-2 overflow-auto"> <div class="o_wsale_filmstip_wrapper pb-1 mb-2 overflow-auto">
<ul class="o_wsale_filmstip d-flex align-items-stretch mb-0 list-unstyled overflow-visible"> <ul class="o_wsale_filmstip d-flex align-items-stretch mb-0 list-unstyled overflow-visible">
<t t-foreach="entries" t-as="c" t-if="c.image_128" t-set="atLeastOneImage" t-value="True"/> <t t-foreach="entries" t-as="c" t-if="c.image_128"
<t t-if="category.parent_id" t-set="backUrl" t-value="keep('/menu/category/' + slug(category.parent_id), category=0)"/> t-set="atLeastOneImage" t-value="True"/>
<t t-else="" t-set="backUrl" t-value="'/menu'"/> <t t-foreach="entries" t-as="c">
<a t-attf-class="d-flex {{'pe-3' if not c_last else ''}} btn filter-box"
<a t-foreach="entries" t-as="c" t-att-href="keep('/menu/category/' + slug(c), category=0)">
t-attf-class="d-flex {{'pe-3' if not c_last else ''}} btn filter-box" <div t-attf-class="btn btn-{{navClass}} d-flex align-items-center {{'ps-2 pe-3' if c.image_128 else 'px-4'}} fs-6 fw-normal filter-text">
t-att-href="keep('/menu/category/' + slug(c), category=0)"> <span t-field="c.name"/>
<input type="radio" t-attf-name="wsale_categories_top_radios_{{parentCategoryId}}" class="btn-check pe-none" t-att-id="c.id" t-att-value="c.id" t-att-checked="'true' if c.id == category.id else None"/> </div>
</a>
<div t-attf-class=" btn btn-{{navClass}} d-flex align-items-center {{'ps-2 pe-3' if c.image_128 else 'px-4'}} fs-6 fw-normal filter-tex" t-att-for="c.id"> </t>
<span t-field="c.name"/>
</div>
</a>
</ul> </ul>
</div> </div>
</div> </div>
</template> </template>
<!-- This XML template defines the breadcrumb for product categories in the "Menu" section -->
<template id="coffee_products_breadcrumb" name=" Coffee Products Breadcrumb"> <template id="coffee_products_breadcrumb"
name=" Coffee Products Breadcrumb">
<ol t-if="category" t-attf-class="breadcrumb #{_classes}"> <ol t-if="category" t-attf-class="breadcrumb #{_classes}">
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a t-attf-href="/menu">Products</a> <a t-attf-href="/menu">Products</a>
@ -164,10 +198,10 @@
<span class="d-inline-block" t-field="cat.name"/> <span class="d-inline-block" t-field="cat.name"/>
</li> </li>
<li t-else="" class="breadcrumb-item"> <li t-else="" class="breadcrumb-item">
<a t-att-href="keep('/menu/category/%s' % slug(cat), category=0)" t-field="cat.name"/> <a t-att-href="keep('/menu/category/%s' % slug(cat), category=0)"
t-field="cat.name"/>
</li> </li>
</t> </t>
</ol> </ol>
</template> </template>
</odoo>
</odoo>

139
theme_coffee_shop/views/payment.xml

@ -1,76 +1,93 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- This XML template inherits from the existing "website_sale.payment" template -->
<template id="coffee_shop_payment" inherit_id="website_sale.payment" <template id="coffee_shop_payment" inherit_id="website_sale.payment"
name="Coffee Payment"> name="Coffee Payment">
<xpath expr="." position="replace"> <xpath expr="." position="replace">
<t t-call="website.layout"> <t t-call="website.layout">
<t t-set="additional_title">Shop - Select Payment Provider</t> <t t-set="additional_title">Shop - Select Payment Provider</t>
<t t-set="no_footer" t-value="1"/> <t t-set="no_footer" t-value="1"/>
<div id="wrap">
<div id="wrap"> <div class="container oe_website_sale py-2">
<div class="container oe_website_sale py-2"> <div class="row">
<div class="row"> <div class='col-12'>
<div class='col-12'> <t t-call="website_sale.wizard_checkout">
<t t-call="website_sale.wizard_checkout"> <t t-set="step" t-value="40"/>
<t t-set="step" t-value="40" /> </t>
</t>
</div>
<div class="col-12" t-if="errors">
<t t-foreach="errors" t-as="error">
<div class="alert alert-danger" t-if="error" role="alert">
<h4>
<t t-esc="error[0]" />
</h4>
<t t-esc="error[1]" />
</div>
</t>
</div>
<div class="col-12 col-xl-auto order-xl-2">
<t t-call="website_sale.cart_summary"/>
</div>
<div class="col-12 col-xl order-xl-1 oe_cart">
<div id='address_on_payment'>
<t t-call="website_sale.address_on_payment"/>
</div> </div>
<div class="col-12" t-if="errors">
<div class="oe_structure clearfix mt-3" id="oe_structure_website_sale_payment_1"/> <t t-foreach="errors" t-as="error">
<div class="alert alert-danger"
<t t-if="website_sale_order.amount_total"> t-if="error" role="alert">
<div t-if="providers or tokens" id="payment_method" class="mt-3"> <h4>
<h3 class="mb24">Pay with </h3> <t t-esc="error[0]"/>
<t t-call="payment.checkout"> </h4>
<t t-set="footer_template_id" t-value="'website_sale.payment_footer'"/> <t t-esc="error[1]"/>
<t t-set="submit_button_label" class="btn-color">Pay Now</t> </div>
</t> </t>
</div> </div>
<div t-else="" class="alert alert-warning"> <div class="col-12 col-xl-auto order-xl-2">
<strong>No suitable payment option could be found.</strong><br/> <t t-call="website_sale.cart_summary"/>
If you believe that it is an error, please contact the website administrator. </div>
<div class="col-12 col-xl order-xl-1 oe_cart">
<div id='address_on_payment'>
<t t-call="website_sale.address_on_payment"/>
</div> </div>
</t> <div class="oe_structure clearfix mt-3"
id="oe_structure_website_sale_payment_1"/>
<div t-if="not providers" class="mt-2"> <t t-if="website_sale_order.amount_total">
<div t-if="providers or tokens"
id="payment_method" class="mt-3">
<h3 class="mb24">Pay with</h3>
<t t-call="payment.checkout">
<t t-set="footer_template_id"
t-value="'website_sale.payment_footer'"/>
<t t-set="submit_button_label"
class="btn-color">Pay Now
</t>
</t>
</div>
<div t-else="" class="alert alert-warning">
<strong>No suitable payment option
could be found.
</strong>
<br/>
If you believe that it is an error,
please contact the website
administrator.
</div>
</t>
<div t-if="not providers" class="mt-2">
<a role="button" groups="base.group_system" <a role="button" groups="base.group_system"
t-attf-href="/web#action=#{payment_action_id}"> t-attf-href="/web#action=#{payment_action_id}">
<i class="fa fa-arrow-right"></i> Add payment providers <i class="fa fa-arrow-right"/>
</a> Add payment providers
</div> </a>
<div class="js_payment mt-3" t-if="not website_sale_order.amount_total" id="payment_method" name="o_website_sale_free_cart"> </div>
<form target="_self" action="/shop/payment/validate" method="post"> <div class="js_payment mt-3"
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()" /> t-if="not website_sale_order.amount_total"
<t t-call="website_sale.payment_footer" class="btn-color"> id="payment_method"
<t t-set="submit_button_label" class="btn-color">Confirm Order</t> name="o_website_sale_free_cart">
</t> <form target="_self"
</form> action="/shop/payment/validate"
method="post">
<input type="hidden" name="csrf_token"
t-att-value="request.csrf_token()"/>
<t t-call="website_sale.payment_footer"
class="btn-color">
<t t-set="submit_button_label"
class="btn-color">Confirm Order
</t>
</t>
</form>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="oe_structure"
id="oe_structure_website_sale_payment_2"/>
</div> </div>
<div class="oe_structure" id="oe_structure_website_sale_payment_2"/> </t>
</div>
</t>
</xpath> </xpath>
</template> </template>
</odoo>
</odoo>

135
theme_coffee_shop/views/payment_summary.xml

@ -1,67 +1,90 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<template id="coffee_shop_payment_summary" inherit_id="website_sale.cart_summary" <!-- Template for cart summary-->
<template id="coffee_shop_payment_summary"
inherit_id="website_sale.cart_summary"
name="Coffee Payment Total"> name="Coffee Payment Total">
<xpath expr="." position="replace"> <xpath expr="." position="replace">
<div class="card tbl-tbl"> <div class="card tbl-tbl">
<div class="card-body"> <div class="card-body">
<div class="toggle_summary d-xl-none"> <div class="toggle_summary d-xl-none">
<b>Your order: </b> <span id="amount_total_summary" class="monetary_field" t-field="website_sale_order.amount_total" t-options='{"widget": "monetary", "display_currency": website_sale_order.pricelist_id.currency_id}'/> <b>Your order:</b>
<span class='fa fa-chevron-down fa-border float-end' role="img" aria-label="Details" title="Details"></span> <span id="amount_total_summary" class="monetary_field"
</div> t-field="website_sale_order.amount_total"
<div t-if="not website_sale_order or not website_sale_order.website_order_line" class="alert alert-info"> t-options='{"widget": "monetary", "display_currency": website_sale_order.pricelist_id.currency_id}'/>
Your cart is empty! <span class='fa fa-chevron-down fa-border float-end'
</div> role="img" aria-label="Details" title="Details"/>
<div class="toggle_summary_div d-none d-xl-block"> </div>
<table class="table table-striped table-sm" id="cart_products" t-if="website_sale_order and website_sale_order.website_order_line"> <div t-if="not website_sale_order or not website_sale_order.website_order_line"
<thead> class="alert alert-info">
<h3>Order Summary</h3> Your cart is empty!
</thead> </div>
<tbody> <div class="toggle_summary_div d-none d-xl-block">
<tr t-foreach="website_sale_order.website_order_line" t-as="line" class="d-none"> <table class="table table-striped table-sm"
<td colspan="2" t-if="not line.product_id.product_tmpl_id"/> id="cart_products"
<t t-else=""> t-if="website_sale_order and website_sale_order.website_order_line">
<td class='td-img text-center'> <thead>
<span t-if="line._is_not_sellable_line() and line.product_id.image_128"> <h3>Order Summary</h3>
<img t-att-src="image_data_uri(line.product_id.image_128)" class="img o_image_64_max rounded" t-att-alt="line.name_short"/> </thead>
</span> <tbody>
<span t-else="" <tr t-foreach="website_sale_order.website_order_line"
t-field="line.product_id.image_128" t-as="line" class="d-none">
t-options="{'widget': 'image', 'qweb_img_responsive': False, 'class': 'rounded o_image_64_max'}" <td colspan="2"
/> t-if="not line.product_id.product_tmpl_id"/>
<t t-else="">
<td class='td-img text-center'>
<span t-if="line._is_not_sellable_line() and line.product_id.image_128">
<img t-att-src="image_data_uri(line.product_id.image_128)"
class="img o_image_64_max rounded"
t-att-alt="line.name_short"/>
</span>
<span t-else=""
t-field="line.product_id.image_128"
t-options="{'widget': 'image', 'qweb_img_responsive': False, 'class': 'rounded o_image_64_max'}"
/>
</td>
<td class='td-product_name'>
<div>
<strong t-field="line.name_short"/>
</div>
</td>
</t>
<td class='td-qty'>
<div t-esc="line.product_uom_qty"/>
<t t-if='line._get_shop_warning(clear=False)'>
<i class='fa fa-warning text-warning'
t-att-title="line._get_shop_warning()"
role="img"
aria-label="Warning"/>
</t>
</td> </td>
<td class='td-product_name'> <td class="text-center td-price text-nowrap">
<div> <span t-field="line.price_reduce_taxexcl"
<strong t-field="line.name_short" /> t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"
</div> groups="account.group_show_line_subtotals_tax_excluded"/>
<span t-field="line.price_reduce_taxinc"
t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"
groups="account.group_show_line_subtotals_tax_included"/>
</td> </td>
</t> </tr>
<td class='td-qty'> </tbody>
<div t-esc="line.product_uom_qty" /> </table>
<t t-if='line._get_shop_warning(clear=False)'> <t t-if='website_sale_order'>
<i class='fa fa-warning text-warning' t-att-title="line._get_shop_warning()" role="img" aria-label="Warning"/> <t t-set='warning'
</t> t-value='website_sale_order._get_shop_warning(clear=False)'/>
</td> <div t-if='warning' class="alert alert-warning"
<td class="text-center td-price"> role="alert">
<span t-field="line.price_reduce_taxexcl" style="white-space: nowrap;" t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}" groups="account.group_show_line_subtotals_tax_excluded" /> <strong>Warning!</strong>
<span t-field="line.price_reduce_taxinc" style="white-space: nowrap;" t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}" groups="account.group_show_line_subtotals_tax_included" /> <t t-esc='website_sale_order._get_shop_warning()'/>
</td> </div>
</tr> </t>
</tbody> <t t-call="website_sale.total">
</table> <t t-set='redirect'
<t t-if='website_sale_order'> t-value="redirect or '/shop/payment'"/>
<t t-set='warning' t-value='website_sale_order._get_shop_warning(clear=False)' /> </t>
<div t-if='warning' class="alert alert-warning" role="alert"> </div>
<strong>Warning!</strong> <t t-esc='website_sale_order._get_shop_warning()'/>
</div>
</t>
<t t-call="website_sale.total">
<t t-set='redirect' t-value="redirect or '/shop/payment'"></t>
</t>
</div> </div>
</div> </div>
</div>
</xpath> </xpath>
</template> </template>
</odoo> </odoo>

260
theme_coffee_shop/views/product.xml

@ -1,117 +1,173 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- Template for product page-->
<template id="coffee_product_page" inherit_id="website_sale.product"> <template id="coffee_product_page" inherit_id="website_sale.product">
<xpath expr="//div[@id='product_detail_main']" position="replace"> <xpath expr="//div[@id='product_detail_main']" position="replace">
<div class="row" id="product_detail_main" data-name="Product Page" <div class="row" id="product_detail_main" data-name="Product Page"
t-att-data-image_width="website.product_page_image_width" t-att-data-image_width="website.product_page_image_width"
t-att-data-image_layout="website.product_page_image_layout"> t-att-data-image_layout="website.product_page_image_layout">
<t t-set="image_cols" t-value="website._get_product_page_proportions()"/> <t t-set="image_cols"
<div t-attf-class="col-lg-#{image_cols[0]} mt-lg-4 o_wsale_product_images position-relative" t-if="website.product_page_image_width != 'none'"> t-value="website._get_product_page_proportions()"/>
<t t-call="website_sale.shop_product_images"/> <div t-attf-class="col-lg-#{image_cols[0]} mt-lg-4 o_wsale_product_images position-relative"
t-if="website.product_page_image_width != 'none'">
<t t-call="website_sale.shop_product_images"/>
</div>
<div t-attf-class="col-lg-#{image_cols[1]} mt-md-4"
id="product_details">
<div class="pr-descr">
<t t-set="base_url" t-value="product.get_base_url()"/>
<h1 itemprop="name" t-field="product.name"
class="pr-title">Product Name
</h1>
<div class="pr-price">
<b>
<t t-call="website_sale.product_price"/>
</b>
<small t-if="combination_info['base_unit_price']"
class="ms-1 text-muted o_base_unit_price_wrapper d-none"
groups="website_sale.group_show_uom_price">
<t t-call='website_sale.base_unit_price'/>
</small>
</div>
</div> </div>
<span itemprop="url" class="d-none"
<div t-attf-class="col-lg-#{image_cols[1]} mt-md-4" id="product_details"> t-esc="base_url + product.website_url"/>
<div class="pr-descr"> <span itemprop="image" class="d-none"
<t t-set="base_url" t-value="product.get_base_url()"/> t-esc="base_url + website.image_url(product, 'image_1920')"/>
<h1 itemprop="name" t-field="product.name" class="pr-title">Product Name</h1> <t t-if="is_view_active('website_sale.product_comment')">
<div class="pr-price"> <a href="#o_product_page_reviews"
<b><t t-call="website_sale.product_price"/></b> class="o_product_page_reviews_link text-decoration-none">
<small t-if="combination_info['base_unit_price']" <t t-call="portal_rating.rating_widget_stars_static">
class="ms-1 text-muted o_base_unit_price_wrapper d-none" groups="website_sale.group_show_uom_price"> <t t-set="rating_avg"
<t t-call='website_sale.base_unit_price'/> t-value="product.rating_avg"/>
</small> <t t-set="trans_text_plural">%s reviews</t>
</div> <t t-set="trans_text_singular">%s review</t>
<t t-set="rating_count"
t-value="(trans_text_plural if product.rating_count > 1 else trans_text_singular) % product.rating_count"/>
</t>
</a>
</t>
<p t-field="product.description_sale"
class="text-muted my-2"
placeholder="A short description that will also appear on documents."/>
<form t-if="product._is_add_to_cart_possible()"
action="/shop/cart/update" method="POST">
<input type="hidden" name="csrf_token"
t-att-value="request.csrf_token()"/>
<div class="js_product js_main_product mb-3">
<div class="d-none">
<t t-call="website_sale.product_price"/>
<small t-if="combination_info['base_unit_price']"
class="ms-1 text-muted o_base_unit_price_wrapper d-none"
groups="website_sale.group_show_uom_price">
<t t-call='website_sale.base_unit_price'/>
</small>
</div> </div>
<span itemprop="url" style="display:none;" t-esc="base_url + product.website_url"/> <t t-placeholder="select">
<span itemprop="image" style="display:none;" t-esc="base_url + website.image_url(product, 'image_1920')" /> <input type="hidden" class="product_id"
<t t-if="is_view_active('website_sale.product_comment')"> name="product_id"
<a href="#o_product_page_reviews" class="o_product_page_reviews_link text-decoration-none"> t-att-value="product_variant.id"/>
<t t-call="portal_rating.rating_widget_stars_static"> <input type="hidden"
<t t-set="rating_avg" t-value="product.rating_avg"/> class="product_template_id"
<t t-set="trans_text_plural">%s reviews</t> name="product_template_id"
<t t-set="trans_text_singular">%s review</t> t-att-value="product.id"/>
<t t-set="rating_count" t-value="(trans_text_plural if product.rating_count > 1 else trans_text_singular) % product.rating_count"/> <input t-if="product.public_categ_ids.ids"
type="hidden"
class="product_category_id"
name="product_category_id"
t-att-value="product.public_categ_ids.ids[0]"/>
<input t-if="product.product_tag_ids.ids"
type="hidden" class="product_tag_id"
name="product_tag_id"
t-att-value="product.product_tag_ids.ids[0]"/>
<t t-if="combination" t-call="sale.variants">
<t t-set="ul_class"
t-valuef="flex-column"/>
<t t-set="parent_combination"
t-value="None"/>
</t> </t>
</a> <t t-else="">
</t> <ul class="d-none js_add_cart_variants mb-0"
<p t-field="product.description_sale" class="text-muted my-2" placeholder="A short description that will also appear on documents." /> t-att-data-attribute_exclusions="{'exclusions: []'}"/>
<form t-if="product._is_add_to_cart_possible()" action="/shop/cart/update" method="POST">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()" />
<div class="js_product js_main_product mb-3">
<div class="d-none">
<t t-call="website_sale.product_price"/>
<small t-if="combination_info['base_unit_price']"
class="ms-1 text-muted o_base_unit_price_wrapper d-none" groups="website_sale.group_show_uom_price">
<t t-call='website_sale.base_unit_price'/>
</small>
</div>
<t t-placeholder="select">
<input type="hidden" class="product_id" name="product_id" t-att-value="product_variant.id" />
<input type="hidden" class="product_template_id" name="product_template_id" t-att-value="product.id" />
<input t-if="product.public_categ_ids.ids" type="hidden" class="product_category_id" name="product_category_id" t-att-value="product.public_categ_ids.ids[0]" />
<input t-if="product.product_tag_ids.ids" type="hidden" class="product_tag_id" name="product_tag_id" t-att-value="product.product_tag_ids.ids[0]" />
<t t-if="combination" t-call="sale.variants">
<t t-set="ul_class" t-valuef="flex-column" />
<t t-set="parent_combination" t-value="None" />
</t>
<t t-else="">
<ul class="d-none js_add_cart_variants mb-0" t-att-data-attribute_exclusions="{'exclusions: []'}"/>
</t>
</t> </t>
<p t-if="True" class="css_not_available_msg alert alert-warning">This combination does not exist.</p> </t>
<div id="o_wsale_cta_wrapper" class="d-flex flex-wrap align-items-center"> <p t-if="True"
<t t-set="hasQuantities" t-value="false"/> class="css_not_available_msg alert alert-warning">
<t t-set="hasBuyNow" t-value="false"/> This combination does not exist.
<t t-set="ctaSizeBig" t-value="not hasQuantities or not hasBuyNow"/> </p>
<div id="o_wsale_cta_wrapper"
class="d-flex flex-wrap align-items-center">
<t t-set="hasQuantities" t-value="false"/>
<t t-set="hasBuyNow" t-value="false"/>
<t t-set="ctaSizeBig"
t-value="not hasQuantities or not hasBuyNow"/>
<div id="add_to_cart_wrap" t-attf-class="{{'d-none' if combination_info['prevent_zero_price_sale'] else 'd-inline-flex'}} mb-2"> <div id="add_to_cart_wrap"
<a role="button" id="add_to_cart" t-attf-class="btn js_check_product a-submit flex-grow-1 #{'btn-lg' if ctaSizeBig else ''} add_to" href="#"> t-attf-class="{{'d-none' if combination_info['prevent_zero_price_sale'] else 'd-inline-flex'}} mb-2">
<span style="font-weight: bold">ADD TO CART</span> <a role="button" id="add_to_cart"
</a> t-attf-class="btn js_check_product a-submit flex-grow-1 #{'btn-lg' if ctaSizeBig else ''} add_to"
</div> href="#">
<div id="product_option_block" class="d-flex flex-wrap w-100"/> <span class="bold">ADD TO CART</span>
</div> </a>
<div id="contact_us_wrapper"
t-attf-class="{{'d-flex' if combination_info['prevent_zero_price_sale'] else 'd-none'}} oe_structure oe_structure_solo #{_div_classes}">
<section class="s_text_block" data-snippet="s_text_block" data-name="Text">
<div class="container">
<a t-att-href="website.contact_us_button_url"
class="btn btn-primary btn_cta">Contact Us
</a>
</div>
</section>
</div> </div>
<div id="product_option_block"
class="d-flex flex-wrap w-100"/>
</div>
<div id="contact_us_wrapper"
t-attf-class="{{'d-flex' if combination_info['prevent_zero_price_sale'] else 'd-none'}} oe_structure oe_structure_solo #{_div_classes}">
<section class="s_text_block"
data-snippet="s_text_block"
data-name="Text">
<div class="container">
<a t-att-href="website.contact_us_button_url"
class="btn btn-primary btn_cta">
Contact Us
</a>
</div>
</section>
</div> </div>
</form>
<p t-elif="not product.active" class="alert alert-warning">This product is no longer available.</p>
<p t-else="" class="alert alert-warning">This product has no valid combination.</p>
<div id="product_attributes_simple">
<t t-set="single_value_attributes" t-value="product.valid_product_template_attribute_line_ids._prepare_single_value_for_display()"/>
<table t-attf-class="table table-sm text-muted {{'' if single_value_attributes else 'd-none'}}">
<t t-foreach="single_value_attributes" t-as="attribute">
<tr>
<td>
<span t-field="attribute.name"/>:
<t t-foreach="single_value_attributes[attribute]" t-as="ptal">
<span t-field="ptal.product_template_value_ids._only_active().name"/><t t-if="not ptal_last">, </t>
</t>
</td>
</tr>
</t>
</table>
</div>
<div id="o_product_terms_and_share" class="d-flex justify-content-between flex-column flex-md-row align-items-md-end mb-3">
</div> </div>
</form>
<p t-elif="not product.active" class="alert alert-warning">
This product is no longer available.
</p>
<p t-else="" class="alert alert-warning">This product has
no valid combination.
</p>
<div id="product_attributes_simple">
<t t-set="single_value_attributes"
t-value="product.valid_product_template_attribute_line_ids._prepare_single_value_for_display()"/>
<table t-attf-class="table table-sm text-muted {{'' if single_value_attributes else 'd-none'}}">
<t t-foreach="single_value_attributes"
t-as="attribute">
<tr>
<td>
<span t-field="attribute.name"/>:
<t t-foreach="single_value_attributes[attribute]"
t-as="ptal">
<span t-field="ptal.product_template_value_ids._only_active().name"/>
<t t-if="not ptal_last">,</t>
</t>
</td>
</tr>
</t>
</table>
</div>
<div id="o_product_terms_and_share"
class="d-flex justify-content-between flex-column flex-md-row align-items-md-end mb-3">
</div> </div>
</div> </div>
</xpath> </div>
</template>
<template id="alternative_products_coffee" name="Alternative Products Coffee" inherit_id="website_sale.alternative_products" active="True">
<xpath expr="//section[hasclass('s_dynamic_snippet_products')]" position="attributes">
<attribute name="data-template-key">website_sale.dynamic_filter_template_product_product_borderless_2</attribute>
</xpath> </xpath>
</template> </template>
<template id="alternative_products_coffee"
</odoo> name="Alternative Products Coffee"
inherit_id="website_sale.alternative_products" active="True">
<xpath expr="//section[hasclass('s_dynamic_snippet_products')]"
position="attributes">
<attribute name="data-template-key">
website_sale.dynamic_filter_template_product_product_borderless_2
</attribute>
</xpath>
</template>
</odoo>

86
theme_coffee_shop/views/shop.xml

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- Template for customizing the appearance of product listings -->
<template id="coffee_shop_products" inherit_id="website_sale.products" <template id="coffee_shop_products" inherit_id="website_sale.products"
name="Coffee Shop Products" active="True"> name="Coffee Shop Products" active="True">
<xpath expr="//div[@id='wrap']" position="before"> <xpath expr="//div[@id='wrap']" position="before">
@ -14,67 +15,74 @@
</div> </div>
</section> </section>
</xpath> </xpath>
<xpath expr="//t[@t-call='website_sale.search']" position="replace"/> <xpath expr="//t[@t-call='website_sale.search']" position="replace"/>
<xpath expr="//div[hasclass('products_header')]" position="attributes"> <xpath expr="//div[hasclass('products_header')]" position="attributes">
<attribute name="class" add="pricelist_right" remove="align-items-center justify-content-between" separator=" "/> <attribute name="class" add="pricelist_right"
remove="align-items-center justify-content-between"
separator=" "/>
</xpath> </xpath>
</template> </template>
<!-- Template for customizing individual product items -->
<template id="products_item_coffee" name="Products item Coffee" inherit_id="website_sale.products_item"> <template id="products_item_coffee" name="Products item Coffee"
<xpath expr="//div[hasclass('o_wsale_product_information_text')]" position="after"> inherit_id="website_sale.products_item">
<xpath expr="//div[hasclass('o_wsale_product_information_text')]"
position="after">
<div id="rating_coffee"> <div id="rating_coffee">
<t t-if="is_view_active('website_sale.product_comment')"> <t t-if="is_view_active('website_sale.product_comment')">
<t t-if="product.rating_avg > 1"> <t t-if="product.rating_avg > 1">
<i class="fa fa-star star" role="img"></i> <i class="fa fa-star star" role="img"/>
</t>
<t t-else="">
<i class="fa fa-star-o star" role="img"></i>
</t>
<small class="text-muted ms-1">
<t t-esc="product.rating_avg"/>
(<t t-esc="product.rating_count"/> Review)
</small>
</t> </t>
</div> <t t-else="">
<i class="fa fa-star-o star" role="img"/>
</t>
<small class="text-muted ms-1">
<t t-esc="product.rating_avg"/>
(
<t t-esc="product.rating_count"/>
Review)
</small>
</t>
</div>
</xpath> </xpath>
</template> </template>
<!-- Template for customizing the product search section -->
<template id="coffee_categ_list" inherit_id="website_sale.products_categories_list" name="coffee categ list"> <template id="coffee_search"
inherit_id="website_sale.products_categories_list"
name="coffee search">
<xpath expr="//input[@t-att-id='all_products']" position="attributes"> <xpath expr="//input[@t-att-id='all_products']" position="attributes">
<attribute name="class" add="d-none" separator=" "></attribute> <attribute name="class" add="d-none" separator=" "/>
</xpath> </xpath>
</template>
<template id="coffee_search" inherit_id="website_sale.products_categories_list" name="coffee search">
<xpath expr="//h6" position="before"> <xpath expr="//h6" position="before">
<div style="margin-bottom: 14px;"> <div class="coffe_search">
<t t-call="website_sale.search"> <t t-call="website_sale.search">
<t t-set="search" t-value="original_search or search"/> <t t-set="search" t-value="original_search or search"/>
<t t-set="_form_classes" t-valuef="d-lg-inline {{'d-inline' if not category else 'd-none'}}"/> <t t-set="_form_classes"
</t> t-valuef="d-lg-inline {{'d-inline' if not category else 'd-none'}}"/>
</t>
</div> </div>
</xpath> </xpath>
</template> </template>
<!-- Template for customizing category links -->
<template id="coffee_category" inherit_id="website_sale.categorie_link" name="Coffee Category"> <template id="coffee_category" inherit_id="website_sale.categorie_link"
name="Coffee Category">
<xpath expr="//input[@type='radio']" position="attributes"> <xpath expr="//input[@type='radio']" position="attributes">
<attribute name="class" add="d-none" separator=" "/> <attribute name="class" add="d-none" separator=" "/>
</xpath> </xpath>
</template> </template>
<!-- Template for customizing the "Add to Cart" button -->
<template id="coffee_buy" inherit_id="website_sale.products_add_to_cart" name="Coffee Buy"> <template id="coffee_buy" inherit_id="website_sale.products_add_to_cart"
name="Coffee Buy">
<xpath expr="//a" position="attributes"> <xpath expr="//a" position="attributes">
<attribute name="class" add="add_buy" separator=" "/> <attribute name="class" add="add_buy" separator=" "/>
</xpath> </xpath>
</template> </template>
<!-- Template for customizing the wishlist button -->
<template id="coffee_wishlist" inherit_id="website_sale_wishlist.add_to_wishlist"> <template id="coffee_wishlist"
<xpath expr="//button[hasclass('o_add_wishlist')]" position="attributes"> inherit_id="website_sale_wishlist.add_to_wishlist">
<attribute name="class" add="btn-primary" remove="btn-outline-primary" separator=" "/> <xpath expr="//button[hasclass('o_add_wishlist')]"
position="attributes">
<attribute name="class" add="btn-primary"
remove="btn-outline-primary" separator=" "/>
</xpath> </xpath>
</template> </template>
</odoo>
</odoo>

Loading…
Cancel
Save