@ -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. |
|||
*/ |
|||
|
|||
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; |
|||
}); |
@ -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" ?> |
|||
<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> |
|||
|