Browse Source

Sep 15 [FIX] : Bug Fixed 'call_for_price_website'

pull/278/head
AjmalCybro 2 years ago
parent
commit
ca5e6d6349
  1. 6
      call_for_price_website/README.rst
  2. 13
      call_for_price_website/__manifest__.py
  3. 8
      call_for_price_website/doc/RELEASE_NOTES.md
  4. 3
      call_for_price_website/models/__init__.py
  5. 57
      call_for_price_website/models/product_product.py
  6. 32
      call_for_price_website/models/product_template.py
  7. BIN
      call_for_price_website/static/description/assets/screenshots/1.png
  8. BIN
      call_for_price_website/static/description/assets/screenshots/2.png
  9. BIN
      call_for_price_website/static/description/assets/screenshots/3.png
  10. BIN
      call_for_price_website/static/description/assets/screenshots/4.png
  11. BIN
      call_for_price_website/static/description/assets/screenshots/5.png
  12. BIN
      call_for_price_website/static/description/assets/screenshots/6.png
  13. BIN
      call_for_price_website/static/description/assets/screenshots/7.png
  14. BIN
      call_for_price_website/static/description/assets/screenshots/8.png
  15. BIN
      call_for_price_website/static/description/assets/screenshots/Screenshot1.png
  16. BIN
      call_for_price_website/static/description/assets/screenshots/Screenshot2.png
  17. BIN
      call_for_price_website/static/description/assets/screenshots/Screenshot3.png
  18. BIN
      call_for_price_website/static/description/assets/screenshots/Screenshot4.png
  19. BIN
      call_for_price_website/static/description/assets/screenshots/Screenshot5.png
  20. BIN
      call_for_price_website/static/description/assets/screenshots/Screenshot6.png
  21. BIN
      call_for_price_website/static/description/assets/screenshots/Screenshot7.png
  22. BIN
      call_for_price_website/static/description/assets/screenshots/Screenshot8.png
  23. BIN
      call_for_price_website/static/description/assets/screenshots/hero.gif
  24. 35
      call_for_price_website/static/description/index.html
  25. 134
      call_for_price_website/static/src/js/create_call_form.js
  26. 69
      call_for_price_website/static/src/js/variant_mixin.js
  27. 16
      call_for_price_website/views/product_product_views.xml
  28. 14
      call_for_price_website/views/product_template_views.xml
  29. 326
      call_for_price_website/views/shop_hide_call_price_template.xml
  30. 2
      call_for_price_website/views/wishlist_hide_price_template.xml

6
call_for_price_website/README.rst

@ -3,7 +3,7 @@
:alt: License: AGPL-3
WEBSITE CALL FOR PRICE
====================
======================
This module helps hide specific products prices from the shop and using 'Call for Price' button customer can sent their details, the user will follow up the details and get the product price.
Configuration
@ -16,7 +16,7 @@ Company
Credits
-------
Developer: Raneesha M K @cybrosys, Contact: odoo@cybrosys.com
Developers: Raneesha M K @cybrosys, Muhsina V @cybrosys, Contact: odoo@cybrosys.com
Contacts
--------
@ -39,4 +39,4 @@ For support and more information, please visit `Our Website <https://cybrosys.co
Further information
===================
HTML Description: `<static/description/index.html>`__
HTML Description: `<static/description/index.html>`__

13
call_for_price_website/__manifest__.py

@ -21,15 +21,15 @@
###############################################################################
{
'name': 'Website Call For Price',
'version': '16.0.1.0.0',
'category': 'Website/Website',
'version': '16.0.1.0.1',
'category': 'Website',
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'images': ['static/description/banner.png'],
'website': 'https://www.cybrosys.com',
'depends': ['base', 'website_sale', 'website_sale_wishlist',
'website_sale_comparison'],
'website_sale_comparison', 'stock'],
'summary': """Helps to hide price of specified product from shop""",
'description': "Hide price and add to cart item button of All page stores"
"and user must ask for a call for price",
@ -38,10 +38,13 @@
'views/wishlist_hide_price_template.xml',
'views/compare_hide_price_template.xml',
'views/call_for_price_views.xml',
'views/product_template_views.xml'],
'views/product_product_views.xml',
],
'assets': {
'web.assets_frontend': [
'/call_for_price_website/static/src/js/create_call_form.js']
'/call_for_price_website/static/src/js/create_call_form.js',
'/call_for_price_website/static/src/js/variant_mixin.js'
]
},
'license': 'AGPL-3',
'installable': True,

8
call_for_price_website/doc/RELEASE_NOTES.md

@ -5,7 +5,7 @@
#### ADD
Initial Commit for Website Call For Price
#### 13.09.2023
#### Version 16.0.1.0.1
#### UPDT
- Updated the "Call for Price" option for the product variant; originally, it was at the product level.

3
call_for_price_website/models/__init__.py

@ -20,4 +20,5 @@
#
###############################################################################
from . import call_price, product_template
from . import call_price
from . import product_product

57
call_for_price_website/models/product_product.py

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Raneesha M K (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, models
class ProductTemplate(models.Model):
"""Inheriting product template model for adding the field price_call into
the combination_info"""
_inherit = 'product.template'
def _get_combination_info(self, combination=False, product_id=False,
add_qty=1, pricelist=False,
parent_combination=False,
only_template=False):
# Call the parent method to get the initial combination_info
combination_info = super(ProductTemplate,
self)._get_combination_info(
combination=combination, product_id=product_id,
add_qty=add_qty, pricelist=pricelist,
parent_combination=parent_combination,
only_template=only_template)
if combination_info.get('product_id'):
product = self.env['product.product'].browse(
combination_info['product_id'])
combination_info['price_call'] = product.price_call
return combination_info
class ProductProduct(models.Model):
"""Inheriting product variants model for adding a field that will hide
price from website"""
_inherit = 'product.product'
price_call = fields.Boolean(string="Call for Price",
help="This will hide the price and cart button"
"from shop and customer can request by "
"calling for price")

32
call_for_price_website/models/product_template.py

@ -1,32 +0,0 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Raneesha M K (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, models
class ProductTemplate(models.Model):
"""Inheriting product variants model for adding a field
that will hide price from website"""
_inherit = 'product.template'
price_call = fields.Boolean(string="Call for Price",
help="This will hide the price and cart button from shop "
"and customer can request by calling for price")

BIN
call_for_price_website/static/description/assets/screenshots/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

BIN
call_for_price_website/static/description/assets/screenshots/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

BIN
call_for_price_website/static/description/assets/screenshots/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

BIN
call_for_price_website/static/description/assets/screenshots/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

BIN
call_for_price_website/static/description/assets/screenshots/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

BIN
call_for_price_website/static/description/assets/screenshots/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

BIN
call_for_price_website/static/description/assets/screenshots/7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

BIN
call_for_price_website/static/description/assets/screenshots/8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

BIN
call_for_price_website/static/description/assets/screenshots/Screenshot1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

BIN
call_for_price_website/static/description/assets/screenshots/Screenshot2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 KiB

BIN
call_for_price_website/static/description/assets/screenshots/Screenshot3.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

BIN
call_for_price_website/static/description/assets/screenshots/Screenshot4.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

BIN
call_for_price_website/static/description/assets/screenshots/Screenshot5.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 KiB

BIN
call_for_price_website/static/description/assets/screenshots/Screenshot6.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

BIN
call_for_price_website/static/description/assets/screenshots/Screenshot7.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 KiB

BIN
call_for_price_website/static/description/assets/screenshots/Screenshot8.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

BIN
call_for_price_website/static/description/assets/screenshots/hero.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 KiB

After

Width:  |  Height:  |  Size: 278 KiB

35
call_for_price_website/static/description/index.html

@ -110,11 +110,13 @@
<div class="row"
style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 py-4">
In some cases, we have to hide the price of a product. These items might
be free, out of stock, or available for
any other reason. This module allows you to hide the price and add to
cart button for specific products; the
call for price option will send a price request to the merchant.
In certain situations, it becomes necessary to conceal the price of a
product or one of its variants. These instances may arise due to
various reasons such as customization, availability issues, or when
the product is offered for free. This module facilitates the hiding of
prices and the addition of a "Add to Cart" button for designated
products. The "Call for Price" option enables customers to send a
price inquiry to the merchant.
</div>
</div>
<!-- END OF OVERVIEW SECTION -->
@ -178,24 +180,25 @@
Enable Call for Price
from the Product Sales tab</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Go to Products -> Sales ->
Go to Product variants -> Sales ->
Enable Call for Price. After enabling this, the price and add to
cart button will hide from the website. </p>
<img src="assets/screenshots/Screenshot1.png" class="img-thumbnail">
<img src="assets/screenshots/1.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Hide product price from list of products</h3>
<img src="assets/screenshots/Screenshot2.png" class="img-thumbnail">
<img src="assets/screenshots/2.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Wishlist page</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Hide the price and add to cart button from wishlist page.</p>
<img src="assets/screenshots/Screenshot3.png" class="img-thumbnail">
Conceal the price and "Add to Cart" button on the wishlist page
for either the product or its specific variant.</p>
<img src="assets/screenshots/3.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
@ -204,7 +207,7 @@
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
If the user needs to compare the products, then they need to
request the price.</p>
<img src="assets/screenshots/Screenshot4.png" class="img-thumbnail">
<img src="assets/screenshots/4.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
@ -214,7 +217,7 @@
Hides the price and add to cart button from product item and
adds button for price request, on clicking a popup will
open.</p>
<img src="assets/screenshots/Screenshot5.png" class="img-thumbnail">
<img src="assets/screenshots/5.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
@ -224,16 +227,16 @@
User need to enter these details inorder to get the price of the
product. The request will send to merchant by clicking send
button.</p>
<img src="assets/screenshots/Screenshot6.png" class="img-thumbnail">
<img src="assets/screenshots/6.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Request Sended</h3>
Request Sent</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
After sending the request a success message will show there, and
merchant can access the request from backend.</p>
<img src="assets/screenshots/Screenshot7.png" class="img-thumbnail">
<img src="assets/screenshots/7.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
@ -242,7 +245,7 @@
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Initially, a draft request is created; after merchant
verification, the sales team contacts the customer.</p>
<img src="assets/screenshots/Screenshot8.png" class="img-thumbnail">
<img src="assets/screenshots/8.png" class="img-thumbnail">
</div>
</div>
</div>

134
call_for_price_website/static/src/js/create_call_form.js

@ -1,26 +1,122 @@
/**
* This file is used to give a success alert after requesting a call for price.
*/
odoo.define('call_for_price_website.create', function (require) {
"use strict";
* This file is used to give a success alert after requesting a call for price.
*/
odoo.define('call_for_price_website.create_call_form', function(require) {
"use strict";
const rpc = require('web.rpc');
var core = require('web.core');
var Dialog = require('web.Dialog');
var publicWidget = require('web.public.widget');
$('#send_btn').on('click', function(){
var first = $('#first_name').val();
var last = $('#last_name').val();
var product_id = $('#product_id').val();
var phone = $('#phone').val();
var email = $('#email').val();
var message = $('#message').val();
var qty = $('#quantity').val();
rpc.query({
model: "call.price",
method: "create_form",
args:[first,last,product_id,phone,email,message,qty]
}).then(function (result) {
document.getElementById('alert_message').style.display = "block"
publicWidget.registry.CallForPrice = publicWidget.Widget.extend({
selector: '.oe_website_sale',
events: {
'click #send_btn': 'callForPrice',
'click #button_call_for_price': 'modalShow',
'click #call_modal_close': 'modalHide'
},
callForPrice: function() {
var self = this;
var first = self.$el.find('#first_name').val();
var last = self.$el.find('#last_name').val();
var product_id = self.$el.find('#product_id').val();
var phone = self.$el.find('#phone').val();
var email = self.$el.find('#email').val();
var message = self.$el.find('#message').val();
var qty = self.$el.find('#quantity').val();
/**
* Validate email address format using a regular expression.
* email - The email address to validate.
* returns - True if the email is valid, false otherwise.
*/
function validateEmail(email) {
// Email validation regex pattern
var emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailPattern.test(email);
}
/**
* Validate phone number format using a regular expression.
* phone - The phone number to validate.
* returns - True if the phone number is valid, false otherwise.
*/
function validatePhoneNumber(phone) {
// Phone number validation regex pattern (without alphabets)
var phonePattern = /^[^A-Za-z]*$/
return phonePattern.test(phone);
}
if (first && phone) {
if (!$.isNumeric(qty)) {
var modal = new Dialog(null, {
title: "Warning",
$content: $('<div>').text("Quantity should be a numeric value."),
buttons: [{
text: "Close",
close: true
}],
});
modal.open();
return;
}
if (!validateEmail(email)) {
var modal = new Dialog(null, {
title: "Warning",
$content: $('<div>').text("Please enter a valid email address."),
buttons: [{
text: "Close",
close: true
}],
});
modal.open();
return;
}
if (!validatePhoneNumber(phone)) {
var modal = new Dialog(null, {
title: "Warning",
$content: $('<div>').text("Please enter a valid phone number."),
buttons: [{
text: "Close",
close: true
}],
});
modal.open();
return;
}
rpc.query({
model: "call.price",
method: "create_form",
args: [first, last, product_id, phone, email, message, qty]
}).then(function(result) {
self.$el.find('#alert_message')[0].style.display = "block"
self.$el.find('#call_for_price')[0].style.display = 'none';
});
} else {
var modal = new Dialog(null, {
title: "Warning",
$content: $('<div>').text("Please enter the required information."),
buttons: [{
text: "Close",
close: true
}],
});
modal.open();
}
},
modalShow: function() {
this.resetFormFields();
this.$el.find('#call_for_price')[0].style.display = 'block';
},
modalHide: function() {
this.$el.find('#call_for_price')[0].style.display = 'none';
},
resetFormFields: function() {
this.$el.find('#first_name').val('');
this.$el.find('#last_name').val('');
this.$el.find('#email').val('');
this.$el.find('#phone').val('');
this.$el.find('#quantity').val('');
this.$el.find('#message').val('');
},
});
return publicWidget.registry.CallForPrice;
});

69
call_for_price_website/static/src/js/variant_mixin.js

@ -0,0 +1,69 @@
/**
* CustomVariantMixin module for Odoo.
* This module extends the VariantMixin functionality from website_sale to handle custom behavior.
*/
odoo.define('call_for_price_website.CustomVariantMixin', function(require) {
'use strict';
// Import the VariantMixin from website_sale module
var VariantMixin = require('website_sale.VariantMixin');
// Store a reference to the original onChangeCombination function
const originalOnChangeCombination = VariantMixin._onChangeCombination;
// Override the onChangeCombination function to implement custom behavior
VariantMixin._onChangeCombination = function(ev, $parent, combination) {
const $pricePerUom = $parent.find(".o_base_unit_price:first .oe_currency_value");
if ($pricePerUom) {
if (combination.is_combination_possible !== false && combination.base_unit_price != 0) {
$pricePerUom.parents(".o_base_unit_price_wrapper").removeClass("d-none");
$pricePerUom.text(this._priceToStr(combination.base_unit_price));
$parent.find(".oe_custom_base_unit:first").text(combination.base_unit_name);
} else {
$pricePerUom.parents(".o_base_unit_price_wrapper").addClass("d-none");
}
}
// Triggers a new JS event with the correct payload, which is then handled
// by the google analytics tracking code.
// Indeed, every time another variant is selected, a new view_item event
// needs to be tracked by google analytics.
if ('product_tracking_info' in combination) {
const $product = $('#product_detail');
$product.data('product-tracking-info', combination['product_tracking_info']);
$product.trigger('view_item_event', combination['product_tracking_info']);
}
const addToCart = $parent.find('#add_to_cart_wrap');
const contactUsButton = $parent.find('#contact_us_wrapper');
const productPrice = $parent.find('.product_price');
const quantity = $parent.find('.css_quantity');
const product_unavailable = $parent.find('#product_unavailable');
const price_call_div = $parent.find('#price_call_hide');
if (combination.prevent_zero_price_sale) {
productPrice.removeClass('d-inline-block').addClass('d-none');
quantity.removeClass('d-inline-flex').addClass('d-none');
addToCart.removeClass('d-inline-flex').addClass('d-none');
contactUsButton.removeClass('d-none').addClass('d-flex');
product_unavailable.removeClass('d-none').addClass('d-flex')
} else if (combination.price_call) {
productPrice.removeClass('d-inline-block').addClass('d-none');
quantity.removeClass('d-inline-flex').addClass('d-none');
addToCart.removeClass('d-inline-flex').addClass('d-none');
contactUsButton.removeClass('d-none').addClass('d-flex');
price_call_div.removeClass('d-none').addClass('d-flex');
this.$el.find('#add_to_cart')[0].style.display = "none";
this.$el.find('#price_of_product')[0].style.display = "none";
this.$el.find('#price_of_product')[0].style.display = "none";
} else {
productPrice.removeClass('d-none').addClass('d-inline-block');
quantity.removeClass('d-none').addClass('d-inline-flex');
addToCart.removeClass('d-none').addClass('d-inline-flex');
contactUsButton.removeClass('d-flex').addClass('d-none');
product_unavailable.removeClass('d-flex').addClass('d-none')
price_call_div.removeClass('d-flex').addClass('d-none')
this.$el.find('#add_to_cart')[0].style.display = "block";
this.$el.find('#price_of_product')[0].style.display = "block";
this.$el.find('#price_of_product')[0].style.display = "block";
}
// Call the original onChangeCombination function
originalOnChangeCombination.apply(this, [ev, $parent, combination]);
};
});

16
call_for_price_website/views/product_product_views.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Inheriting product variant view form to add the 'call for price' field -->
<record id="product_normal_form_view" model="ir.ui.view">
<field name="name">
product.product.view.form.inherit.call.for.price.website
</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='public_categ_ids']" position="after">
<field name="price_call"/>
</xpath>
</field>
</record>
</odoo>

14
call_for_price_website/views/product_template_views.xml

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!--This file is used to add a field on product variants for hiding price-->
<record id="product_template_view_form" model="ir.ui.view">
<field name="name">product.template.view.form.inherit.call.for.price.website</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="website_sale.product_template_only_website_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='public_categ_ids']" position="after">
<field name="price_call"/>
</xpath>
</field>
</record>
</odoo>

326
call_for_price_website/views/shop_hide_call_price_template.xml

@ -1,176 +1,172 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- This template is used for hiding price from shop grid and list view-->
<template id="shop_hide_price" inherit_id="website_sale.products_item">
<xpath expr="//div[hasclass('product_price')]" position="replace">
<t t-if="product.price_call">
</t>
<t t-else="">
<div class="product_price" itemprop="offers" itemscope="itemscope" itemtype="http://schema.org/Offer">
<t t-if="'base_price' in template_price_vals">
<del t-attf-class="text-muted me-1 h6 mb-0" style="white-space: nowrap;">
<em class="small" t-esc="template_price_vals['base_price']"
<!-- Template for hiding product price when 'price_call' is set -->
<template id="shop_hide_price_call" inherit_id="website_sale.products_item">
<xpath expr="//div[hasclass('product_price')]" position="replace">
<t t-foreach="product.product_variant_ids" t-as="variant">
<t t-if="variant.price_call">
<t t-set="has_price_call" t-value="True"/>
<t t-break="1"/></t>
</t>
<t t-if="has_price_call"></t>
<t t-else="">
<div class="product_price" itemprop="offers" itemscope="itemscope" itemtype="http://schema.org/Offer">
<t t-if="'base_price' in template_price_vals">
<del t-attf-class="text-muted me-1 h6 mb-0" style="white-space: nowrap;">
<em class="small" t-esc="template_price_vals['base_price']"
t-options="{'widget': 'monetary', 'display_currency': website.currency_id}"/>
</del>
</t>
<span class="h6 mb-0"
</del>
</t>
<span class="h6 mb-0"
t-if="template_price_vals['price_reduce'] or not website.prevent_zero_price_sale"
t-esc="template_price_vals['price_reduce']"
t-options="{'widget': 'monetary', 'display_currency': website.currency_id}"/>
<span class="h6 mb-0" t-else="" t-field="website.prevent_zero_price_sale_text"/>
<span itemprop="price" style="display:none;" t-esc="template_price_vals['price_reduce']"/>
<span itemprop="priceCurrency" style="display:none;" t-esc="website.currency_id.name"/>
</div>
</t>
</xpath>
</template>
<!-- This template is used for hiding product price and add to cart button from each product and show button for requesting price-->
<template id="shop_product_hide_price" inherit_id="website_sale.product">
<xpath expr="//div[hasclass('js_main_product')]" position="replace">
<t t-if="product.price_call">
<div class="alert alert-success" id="alert_message" style="display:none">
<span class="h6 mb-0" t-else="" t-field="website.prevent_zero_price_sale_text"/>
<span itemprop="price" style="display:none;" t-esc="template_price_vals['price_reduce']"/>
<span itemprop="priceCurrency" style="display:none;" t-esc="website.currency_id.name"/>
</div>
</t>
</xpath>
</template>
<!-- Template for hiding search details -->
<template id="hide_search" inherit_id="website_sale.search">
<xpath expr="//t[@t-set='display_detail']" position="replace">
<t t-set="display_detail" t-valuef="false"/>
</xpath>
</template>
<!-- Template for product price display -->
<template id="product_price" inherit_id="website_sale.product_price">
<xpath expr="//div[@itemprop='offers']" position="replace">
<div itemprop="offers" itemscope="itemscope" itemtype="http://schema.org/Offer" t-attf-class="product_price mt-2 mb-3 {{'d-none' if combination_info['prevent_zero_price_sale'] else 'd-inline-block'}}">
<h3 class="css_editable_mode_hidden" id="price_of_product">
<span class="oe_price" style="white-space: nowrap;" t-esc="combination_info['price']" t-options="{'widget': 'monetary', 'display_currency': website.currency_id}"/>
<span itemprop="price" style="display:none;" t-esc="combination_info['price']"/>
<span itemprop="priceCurrency" style="display:none;" t-esc="website.currency_id.name"/>
<span t-attf-class="text-danger oe_default_price ms-1 h5 {{'' if combination_info['has_discounted_price'] else 'd-none'}}" style="text-decoration: line-through; white-space: nowrap;"
t-esc="combination_info['list_price']" t-options="{'widget': 'monetary', 'display_currency': website.currency_id}"
itemprop="listPrice"
/>
<t t-esc="product_id"/>
<t t-if="is_view_active('website_sale.tax_indication')" t-call="website_sale.tax_indication"/>
<del t-if="product.compare_list_price">
<bdi dir="inherit">
<span t-field="product.compare_list_price"
groups="website_sale.group_product_price_comparison"
t-options='{"widget": "monetary",
"display_currency": product.currency_id,
}'/>
</bdi>
</del>
</h3>
<h3 id="price_of_products" class="css_non_editable_mode_hidden decimal_precision" t-att-data-precision="str(website.currency_id.decimal_places)" style="display:none">
<span t-field="product.list_price"
t-options='{"widget": "monetary",
"display_currency": product.currency_id,
}'/>
<t t-if="is_view_active('website_sale.tax_indication')" t-call="website_sale.tax_indication"/>
<del t-if="product.compare_list_price">
<bdi dir="inherit">
<span t-field="product.compare_list_price"
groups="website_sale.group_product_price_comparison"
t-options='{"widget": "monetary",
"display_currency": product.currency_id,
}'/>
</bdi>
</del>
</h3>
</div>
<div id="product_unavailable" t-attf-class="{{'d-flex' if combination_info['prevent_zero_price_sale'] else 'd-none'}}">
<h3 class="fst-italic" t-field="website.prevent_zero_price_sale_text"/>
</div>
<div id="price_call_hide" style="display:none">
<div>
<div class="alert alert-success" id="alert_message"
style="display:none">
Thank you for information, we will get back to you asap.
</div>
<a role="button" class="btn btn-primary" href="#" data-bs-toggle="modal"
data-bs-target="#call_for_price">
<a role="button" class="btn btn-primary" href="#call_for_price"
data-bs-toggle="modal"
id="button_call_for_price">
Call for Price
</a>
<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="product_option_block" class="d-flex flex-wrap w-100"/>
</div>
</t>
<t t-else="">
<div class="js_product js_main_product mb-3">
<div>
<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>
<p t-if="True" class="css_not_available_msg alert alert-warning">This combination does not exist.
</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'}} align-items-center mb-2 me-auto">
<a role="button" id="add_to_cart"
t-attf-class="btn btn-primary js_check_product a-submit flex-grow-1 #{'btn-lg' if ctaSizeBig else ''}"
href="#">
<i class="fa fa-shopping-cart me-2"/>
<span style="font-weight: bold">ADD TO CART</span>
</a>
</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>
</t>
</xpath>
<xpath expr="//div[@id='o_product_terms_and_share']" position="before">
<div id="call_for_price" class="modal fade">
<div class="modal-dialog modal-content" style="height:60%">
<div class="page">
<h3>Call For Price</h3>
</div>
<input type="hidden" name="product_id" id="product_id" t-att-value="product.id"/>
<hr/>
<center>
<table style="width:500px">
<tr style="height:60px">
<td style="width:100px">
<label for="first_name" class="control-label">First Name:</label>
</td>
<td>
<input type="text" class="form-control" name="first_name"
id="first_name"/>
</td>
</tr>
<tr style="height:60px">
<td>
<label for="last_name" class="control-label">Last Name:</label>
</td>
<td>
<input type="text" class="form-control" name="last_name"
id="last_name"/>
</td>
</tr>
<tr style="height:60px">
<td>
<label for="email">Email</label>
</td>
<td>
<input type="text" class="form-control" name="email"
id="email"/>
</td>
</tr>
<tr style="height:60px">
<td>
<label for="phone">Contact No.</label>
</td>
<td>
<input type="text" class="form-control" id="phone" name="phone"/>
</td>
</tr>
<tr style="height:60px">
<td>
<label>Quantity</label>
</td>
<td>
<input type="text" class="form-control" name="quantity" id="quantity"/>
</td>
</tr>
<tr style="height:60px">
<td>
<label>Message</label>
</td>
<td>
<input type="text" class="form-control" name="message" id="message"/>
</td>
</tr>
</table>
<hr/>
<button id="send_btn" type="button" data-bs-dismiss="modal" class="btn btn-primary">Send</button>
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
Close
</button>
</center>
</div>
</div>
</xpath>
</template>
</div>
</div>
</xpath>
</template>
<!-- Template for 'Call for Price' modal -->
<template id="shop_product_hide_price" inherit_id="website_sale.product">
<xpath expr="//div[@id='o_product_terms_and_share']" position="before">
<div id="call_for_price" class="modal fade">
<div class="modal-dialog modal-content" style="height:auto">
<div class="page">
<h3>
<center>Call For Price</center>
</h3>
</div>
<input type="hidden" name="product_id" id="product_id" t-att-value="product.id"/>
<hr/>
<center>
<table style="width:500px">
<tr style="height:60px">
<td style="width:100px">
<label for="first_name" class="control-label">First Name:*</label>
</td>
<td>
<input type="text" class="form-control" name="first_name"
id="first_name" required="required"/>
</td>
</tr>
<tr style="height:60px">
<td>
<label for="last_name" class="control-label">Last Name:</label>
</td>
<td>
<input type="text" class="form-control" name="last_name"
id="last_name"/>
</td>
</tr>
<tr style="height:60px">
<td>
<label for="email">Email </label>
</td>
<td>
<input type="text" class="form-control" name="email"
id="email" required="required"/>
</td>
</tr>
<tr style="height:60px">
<td>
<label for="phone">Contact No.*</label>
</td>
<td>
<input type="text" class="form-control" id="phone" name="phone"/>
</td>
</tr>
<tr style="height:60px">
<td>
<label>Quantity</label>
</td>
<td>
<input type="number" class="form-control" name="quantity" id="quantity"/>
</td>
</tr>
<tr style="height:60px">
<td>
<label>Message</label>
</td>
<td>
<input type="text" class="form-control" name="message" id="message"/>
</td>
</tr>
</table>
<hr/>
<button id="send_btn" type="button" data-bs-dismiss="modal" class="btn btn-primary">Send</button>
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal" id="call_modal_close">
Close
</button>
</center>
</div>
</div>
</xpath>
</template>
</odoo>

2
call_for_price_website/views/wishlist_hide_price_template.xml

@ -35,4 +35,4 @@
</t>
</xpath>
</template>
</odoo>
</odoo>

Loading…
Cancel
Save