@ -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") |
@ -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") |
|
After Width: | Height: | Size: 177 KiB |
After Width: | Height: | Size: 388 KiB |
After Width: | Height: | Size: 171 KiB |
After Width: | Height: | Size: 182 KiB |
After Width: | Height: | Size: 179 KiB |
After Width: | Height: | Size: 142 KiB |
After Width: | Height: | Size: 192 KiB |
After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 101 KiB |
Before Width: | Height: | Size: 307 KiB |
Before Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 143 KiB |
Before Width: | Height: | Size: 274 KiB |
Before Width: | Height: | Size: 213 KiB |
Before Width: | Height: | Size: 298 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 266 KiB After Width: | Height: | Size: 278 KiB |
@ -1,26 +1,122 @@ |
|||||
/** |
/** |
||||
* This file is used to give a success alert after requesting a call for price. |
* 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) { |
||||
odoo.define('call_for_price_website.create', function (require) { |
"use strict"; |
||||
"use strict"; |
|
||||
const rpc = require('web.rpc'); |
const rpc = require('web.rpc'); |
||||
var core = require('web.core'); |
var core = require('web.core'); |
||||
|
var Dialog = require('web.Dialog'); |
||||
|
var publicWidget = require('web.public.widget'); |
||||
|
|
||||
$('#send_btn').on('click', function(){ |
publicWidget.registry.CallForPrice = publicWidget.Widget.extend({ |
||||
var first = $('#first_name').val(); |
selector: '.oe_website_sale', |
||||
var last = $('#last_name').val(); |
events: { |
||||
var product_id = $('#product_id').val(); |
'click #send_btn': 'callForPrice', |
||||
var phone = $('#phone').val(); |
'click #button_call_for_price': 'modalShow', |
||||
var email = $('#email').val(); |
'click #call_modal_close': 'modalHide' |
||||
var message = $('#message').val(); |
}, |
||||
var qty = $('#quantity').val(); |
callForPrice: function() { |
||||
rpc.query({ |
var self = this; |
||||
model: "call.price", |
var first = self.$el.find('#first_name').val(); |
||||
method: "create_form", |
var last = self.$el.find('#last_name').val(); |
||||
args:[first,last,product_id,phone,email,message,qty] |
var product_id = self.$el.find('#product_id').val(); |
||||
}).then(function (result) { |
var phone = self.$el.find('#phone').val(); |
||||
document.getElementById('alert_message').style.display = "block" |
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; |
||||
}); |
}); |
@ -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]); |
||||
|
}; |
||||
|
}); |
@ -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> |
@ -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> |
|
@ -1,176 +1,172 @@ |
|||||
<?xml version="1.0" encoding="UTF-8" ?> |
<?xml version="1.0" encoding="UTF-8" ?> |
||||
<odoo> |
<odoo> |
||||
<!-- This template is used for hiding price from shop grid and list view--> |
<!-- Template for hiding product price when 'price_call' is set --> |
||||
<template id="shop_hide_price" inherit_id="website_sale.products_item"> |
<template id="shop_hide_price_call" inherit_id="website_sale.products_item"> |
||||
<xpath expr="//div[hasclass('product_price')]" position="replace"> |
<xpath expr="//div[hasclass('product_price')]" position="replace"> |
||||
<t t-if="product.price_call"> |
<t t-foreach="product.product_variant_ids" t-as="variant"> |
||||
</t> |
<t t-if="variant.price_call"> |
||||
<t t-else=""> |
<t t-set="has_price_call" t-value="True"/> |
||||
<div class="product_price" itemprop="offers" itemscope="itemscope" itemtype="http://schema.org/Offer"> |
<t t-break="1"/></t> |
||||
<t t-if="'base_price' in template_price_vals"> |
</t> |
||||
<del t-attf-class="text-muted me-1 h6 mb-0" style="white-space: nowrap;"> |
<t t-if="has_price_call"></t> |
||||
<em class="small" t-esc="template_price_vals['base_price']" |
<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}"/> |
t-options="{'widget': 'monetary', 'display_currency': website.currency_id}"/> |
||||
</del> |
</del> |
||||
</t> |
</t> |
||||
<span class="h6 mb-0" |
<span class="h6 mb-0" |
||||
t-if="template_price_vals['price_reduce'] or not website.prevent_zero_price_sale" |
t-if="template_price_vals['price_reduce'] or not website.prevent_zero_price_sale" |
||||
t-esc="template_price_vals['price_reduce']" |
t-esc="template_price_vals['price_reduce']" |
||||
t-options="{'widget': 'monetary', 'display_currency': website.currency_id}"/> |
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 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="price" style="display:none;" t-esc="template_price_vals['price_reduce']"/> |
||||
<span itemprop="priceCurrency" style="display:none;" t-esc="website.currency_id.name"/> |
<span itemprop="priceCurrency" style="display:none;" t-esc="website.currency_id.name"/> |
||||
</div> |
</div> |
||||
</t> |
</t> |
||||
</xpath> |
</xpath> |
||||
</template> |
</template> |
||||
|
<!-- Template for hiding search details --> |
||||
<!-- This template is used for hiding product price and add to cart button from each product and show button for requesting price--> |
<template id="hide_search" inherit_id="website_sale.search"> |
||||
<template id="shop_product_hide_price" inherit_id="website_sale.product"> |
<xpath expr="//t[@t-set='display_detail']" position="replace"> |
||||
<xpath expr="//div[hasclass('js_main_product')]" position="replace"> |
<t t-set="display_detail" t-valuef="false"/> |
||||
<t t-if="product.price_call"> |
</xpath> |
||||
<div class="alert alert-success" id="alert_message" style="display:none"> |
</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. |
Thank you for information, we will get back to you asap. |
||||
</div> |
</div> |
||||
<a role="button" class="btn btn-primary" href="#" data-bs-toggle="modal" |
<a role="button" class="btn btn-primary" href="#call_for_price" |
||||
data-bs-target="#call_for_price"> |
data-bs-toggle="modal" |
||||
|
id="button_call_for_price"> |
||||
Call for Price |
Call for Price |
||||
</a> |
</a> |
||||
<div id="o_wsale_cta_wrapper" class="d-flex flex-wrap align-items-center"> |
</div> |
||||
<t t-set="hasQuantities" t-value="false"/> |
</div> |
||||
<t t-set="hasBuyNow" t-value="false"/> |
</xpath> |
||||
<t t-set="ctaSizeBig" t-value="not hasQuantities or not hasBuyNow"/> |
</template> |
||||
<div id="product_option_block" class="d-flex flex-wrap w-100"/> |
<!-- Template for 'Call for Price' modal --> |
||||
</div> |
<template id="shop_product_hide_price" inherit_id="website_sale.product"> |
||||
</t> |
<xpath expr="//div[@id='o_product_terms_and_share']" position="before"> |
||||
<t t-else=""> |
<div id="call_for_price" class="modal fade"> |
||||
<div class="js_product js_main_product mb-3"> |
<div class="modal-dialog modal-content" style="height:auto"> |
||||
<div> |
<div class="page"> |
||||
<t t-call="website_sale.product_price"/> |
<h3> |
||||
<small t-if="combination_info['base_unit_price']" |
<center>Call For Price</center> |
||||
class="ms-1 text-muted o_base_unit_price_wrapper d-none" |
</h3> |
||||
groups="website_sale.group_show_uom_price"> |
</div> |
||||
<t t-call='website_sale.base_unit_price'/> |
<input type="hidden" name="product_id" id="product_id" t-att-value="product.id"/> |
||||
</small> |
<hr/> |
||||
</div> |
<center> |
||||
<t t-placeholder="select"> |
<table style="width:500px"> |
||||
<input type="hidden" class="product_id" name="product_id" t-att-value="product_variant.id"/> |
<tr style="height:60px"> |
||||
<input type="hidden" class="product_template_id" name="product_template_id" |
<td style="width:100px"> |
||||
t-att-value="product.id"/> |
<label for="first_name" class="control-label">First Name:*</label> |
||||
<input t-if="product.public_categ_ids.ids" type="hidden" class="product_category_id" |
</td> |
||||
name="product_category_id" t-att-value="product.public_categ_ids.ids[0]"/> |
<td> |
||||
<input t-if="product.product_tag_ids.ids" type="hidden" class="product_tag_id" |
<input type="text" class="form-control" name="first_name" |
||||
name="product_tag_id" t-att-value="product.product_tag_ids.ids[0]"/> |
id="first_name" required="required"/> |
||||
<t t-if="combination" t-call="sale.variants"> |
</td> |
||||
<t t-set="ul_class" t-valuef="flex-column"/> |
</tr> |
||||
<t t-set="parent_combination" t-value="None"/> |
<tr style="height:60px"> |
||||
</t> |
<td> |
||||
<t t-else=""> |
<label for="last_name" class="control-label">Last Name:</label> |
||||
<ul class="d-none js_add_cart_variants mb-0" |
</td> |
||||
t-att-data-attribute_exclusions="{'exclusions: []'}"/> |
<td> |
||||
</t> |
<input type="text" class="form-control" name="last_name" |
||||
</t> |
id="last_name"/> |
||||
<p t-if="True" class="css_not_available_msg alert alert-warning">This combination does not exist. |
</td> |
||||
</p> |
</tr> |
||||
<div id="o_wsale_cta_wrapper" class="d-flex flex-wrap align-items-center"> |
<tr style="height:60px"> |
||||
<t t-set="hasQuantities" t-value="false"/> |
<td> |
||||
<t t-set="hasBuyNow" t-value="false"/> |
<label for="email">Email </label> |
||||
<t t-set="ctaSizeBig" t-value="not hasQuantities or not hasBuyNow"/> |
</td> |
||||
|
<td> |
||||
<div id="add_to_cart_wrap" |
<input type="text" class="form-control" name="email" |
||||
t-attf-class="{{'d-none' if combination_info['prevent_zero_price_sale'] else 'd-inline-flex'}} align-items-center mb-2 me-auto"> |
id="email" required="required"/> |
||||
<a role="button" id="add_to_cart" |
</td> |
||||
t-attf-class="btn btn-primary js_check_product a-submit flex-grow-1 #{'btn-lg' if ctaSizeBig else ''}" |
</tr> |
||||
href="#"> |
<tr style="height:60px"> |
||||
<i class="fa fa-shopping-cart me-2"/> |
<td> |
||||
<span style="font-weight: bold">ADD TO CART</span> |
<label for="phone">Contact No.*</label> |
||||
</a> |
</td> |
||||
</div> |
<td> |
||||
<div id="product_option_block" class="d-flex flex-wrap w-100"/> |
<input type="text" class="form-control" id="phone" name="phone"/> |
||||
</div> |
</td> |
||||
<div id="contact_us_wrapper" |
</tr> |
||||
t-attf-class="{{'d-flex' if combination_info['prevent_zero_price_sale'] else 'd-none'}} oe_structure oe_structure_solo #{_div_classes}"> |
<tr style="height:60px"> |
||||
<section class="s_text_block" data-snippet="s_text_block" data-name="Text"> |
<td> |
||||
<div class="container"> |
<label>Quantity</label> |
||||
<a t-att-href="website.contact_us_button_url" |
</td> |
||||
class="btn btn-primary btn_cta">Contact Us |
<td> |
||||
</a> |
<input type="number" class="form-control" name="quantity" id="quantity"/> |
||||
</div> |
</td> |
||||
</section> |
</tr> |
||||
</div> |
<tr style="height:60px"> |
||||
</div> |
<td> |
||||
</t> |
<label>Message</label> |
||||
</xpath> |
</td> |
||||
<xpath expr="//div[@id='o_product_terms_and_share']" position="before"> |
<td> |
||||
<div id="call_for_price" class="modal fade"> |
<input type="text" class="form-control" name="message" id="message"/> |
||||
<div class="modal-dialog modal-content" style="height:60%"> |
</td> |
||||
<div class="page"> |
</tr> |
||||
<h3>Call For Price</h3> |
</table> |
||||
</div> |
<hr/> |
||||
<input type="hidden" name="product_id" id="product_id" t-att-value="product.id"/> |
<button id="send_btn" type="button" data-bs-dismiss="modal" class="btn btn-primary">Send</button> |
||||
<hr/> |
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal" id="call_modal_close"> |
||||
<center> |
Close |
||||
<table style="width:500px"> |
</button> |
||||
<tr style="height:60px"> |
</center> |
||||
<td style="width:100px"> |
</div> |
||||
<label for="first_name" class="control-label">First Name:</label> |
</div> |
||||
</td> |
</xpath> |
||||
<td> |
</template> |
||||
<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> |
|
||||
</odoo> |
</odoo> |
||||
|