[IMP] website_sale, payment: create payment button widget
Before this commit, the payment button was part of the checkout/manage form widgets, which caused conflicts when other modules needed to enable/disable the button depending on custom conditions. After this commit, the payment button logic is extracted in a separate widget that handles its enabling after checking if all conditions are satisfied. Other modules can extend the widget and override `isButtonReady` to add custom logic. task-3568861 closes odoo/odoo#142265 X-original-commit: 496c22f67b840a72758640576546ba16b177aafc Related: odoo/enterprise#50783 Signed-off-by: Antoine Vandevenne (anv) <anv@odoo.com>
This commit is contained in:
committed by
Antoine Vandevenne (anv)
parent
71a61fb8d9
commit
671640cf59
@@ -0,0 +1,81 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import publicWidget from '@web/legacy/js/public/public_widget';
|
||||
import { Component } from "@odoo/owl";
|
||||
|
||||
publicWidget.registry.PaymentButton = publicWidget.Widget.extend({
|
||||
selector: 'button[name="o_payment_submit_button"]',
|
||||
|
||||
async start() {
|
||||
await this._super(...arguments);
|
||||
this.paymentButton = this.el;
|
||||
this.iconClass = this.paymentButton.dataset.iconClass;
|
||||
this._enable();
|
||||
Component.env.bus.addEventListener('enablePaymentButton', this._enable.bind(this));
|
||||
Component.env.bus.addEventListener('disablePaymentButton',this._disable.bind(this));
|
||||
Component.env.bus.addEventListener('hidePaymentButton', this._hide.bind(this));
|
||||
Component.env.bus.addEventListener('showPaymentButton', this._show.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the payment button can be enabled and do it if so.
|
||||
*
|
||||
* @private
|
||||
* @return {void}
|
||||
*/
|
||||
_enable() {
|
||||
if (this._canSubmit()) {
|
||||
this.paymentButton.disabled = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether the payment form can be submitted, i.e. whether exactly one payment option is
|
||||
* selected.
|
||||
*
|
||||
* For a module to add a condition on the submission of the form, it must override this method
|
||||
* and return whether both this method's condition and the override method's condition are met.
|
||||
*
|
||||
* @private
|
||||
* @return {boolean} Whether the form can be submitted.
|
||||
*/
|
||||
_canSubmit() {
|
||||
const paymentForm = document.querySelector('#o_payment_form');
|
||||
if (!paymentForm) { // Payment form is not present.
|
||||
return true; // Ignore the check.
|
||||
}
|
||||
return document.querySelectorAll('input[name="o_payment_radio"]:checked').length === 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Disable the payment button.
|
||||
*
|
||||
* @private
|
||||
* @return {void}
|
||||
*/
|
||||
_disable() {
|
||||
this.paymentButton.disabled = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide the payment button.
|
||||
*
|
||||
* @private
|
||||
* @return {void}
|
||||
*/
|
||||
_hide() {
|
||||
this.paymentButton.classList.add('d-none');
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the payment button.
|
||||
*
|
||||
* @private
|
||||
* @return {void}
|
||||
*/
|
||||
_show() {
|
||||
this.paymentButton.classList.remove('d-none');
|
||||
},
|
||||
|
||||
});
|
||||
export default publicWidget.registry.PaymentButton;
|
||||
@@ -1,5 +1,6 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { Component } from '@odoo/owl';
|
||||
import publicWidget from '@web/legacy/js/public/public_widget';
|
||||
import { browser } from '@web/core/browser/browser';
|
||||
import { ConfirmationDialog } from '@web/core/confirmation_dialog/confirmation_dialog';
|
||||
@@ -168,9 +169,7 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
|
||||
* @return {void}
|
||||
*/
|
||||
_enableButton(unblockUI = true) {
|
||||
if (this._canSubmit()) {
|
||||
this._getSubmitButton().removeAttribute('disabled');
|
||||
}
|
||||
Component.env.bus.trigger('enablePaymentButton');
|
||||
if (unblockUI) {
|
||||
this.call('ui', 'unblock');
|
||||
}
|
||||
@@ -184,7 +183,7 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
|
||||
* @return {void}
|
||||
*/
|
||||
_disableButton(blockUI = false) {
|
||||
this._getSubmitButton().setAttribute('disabled', true);
|
||||
Component.env.bus.trigger('disablePaymentButton');
|
||||
if (blockUI) {
|
||||
this.call('ui', 'block');
|
||||
}
|
||||
@@ -202,7 +201,7 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
|
||||
tokenizeContainer?.classList.remove('d-none');
|
||||
|
||||
// Show the submit button.
|
||||
this._getSubmitButton().classList.remove('d-none');
|
||||
Component.env.bus.trigger('showPaymentButton');
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -221,7 +220,7 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
|
||||
tokenizeContainer?.classList.add('d-none');
|
||||
|
||||
// Hide the submit button.
|
||||
this._getSubmitButton().classList.add('d-none');
|
||||
Component.env.bus.trigger('hidePaymentButton');
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -313,20 +312,6 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
|
||||
|
||||
// #=== PAYMENT FLOW ===#
|
||||
|
||||
/**
|
||||
* Check whether the payment form can be submitted, i.e. whether exactly one payment option is
|
||||
* selected.
|
||||
*
|
||||
* For a module to add a condition on the submission of the form, it must override this method
|
||||
* and return whether both this method's condition and the override method's condition are met.
|
||||
*
|
||||
* @private
|
||||
* @return {boolean} Whether the form can be submitted.
|
||||
*/
|
||||
_canSubmit() {
|
||||
return this.el.querySelectorAll('input[name="o_payment_radio"]:checked').length === 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the payment flow for the selected payment option.
|
||||
*
|
||||
@@ -535,19 +520,6 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
|
||||
return inlineFormContainer?.querySelector('[name="o_payment_inline_form"]');
|
||||
},
|
||||
|
||||
/**
|
||||
* Find and return the submit button.
|
||||
*
|
||||
* The button is searched in the whole document, rather than only in the current form, to allow
|
||||
* modules to place it outside the payment form (e.g., eCommerce).
|
||||
*
|
||||
* @private
|
||||
* @return {Element} The submit button.
|
||||
*/
|
||||
_getSubmitButton() {
|
||||
return document.querySelector('[name="o_payment_submit_button"]');
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine and return the payment flow of the selected payment option.
|
||||
*
|
||||
|
||||
@@ -61,7 +61,10 @@
|
||||
'website_sale/static/src/scss/website_sale_delivery.scss',
|
||||
'website/static/lib/multirange/multirange_custom.scss',
|
||||
'sale/static/src/scss/sale_portal.scss',
|
||||
'website_sale/static/src/js/payment_button.js',
|
||||
'website_sale/static/src/js/payment_form.js',
|
||||
'website_sale/static/src/js/sale_variant_mixin.js',
|
||||
'website_sale/static/src/js/terms_and_conditions_checkbox.js',
|
||||
'website_sale/static/src/js/variant_mixin.js',
|
||||
'website_sale/static/src/js/website_sale.js',
|
||||
'website_sale/static/src/xml/website_sale.xml',
|
||||
@@ -69,7 +72,6 @@
|
||||
'website_sale/static/src/js/website_sale_price_range_option.js',
|
||||
'website_sale/static/src/js/website_sale_utils.js',
|
||||
'website_sale/static/src/xml/website_sale_utils.xml',
|
||||
'website_sale/static/src/js/website_sale_payment.js',
|
||||
'website_sale/static/src/js/website_sale_recently_viewed.js',
|
||||
'website_sale/static/src/js/website_sale_tracking.js',
|
||||
'website/static/lib/multirange/multirange_custom.js',
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import paymentButton from '@payment/js/payment_button';
|
||||
|
||||
paymentButton.include({
|
||||
|
||||
/**
|
||||
* Verify that the payment button is ready to be enabled.
|
||||
*
|
||||
* The conditions are that:
|
||||
* - a delivery carrier is selected and ready (the price is computed) if deliveries are enabled;
|
||||
* - the "Terms and Conditions" checkbox is ticked if it is present.
|
||||
*
|
||||
* @override from @payment/js/payment_button
|
||||
* @return {boolean}
|
||||
*/
|
||||
_canSubmit() {
|
||||
return this._super(...arguments) && this._isCarrierReady() && this._isTCCheckboxReady();
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the delivery carrier is selected and if its price is computed.
|
||||
*
|
||||
* @private
|
||||
* @return {boolean}
|
||||
*/
|
||||
_isCarrierReady() {
|
||||
const carriers = document.querySelectorAll('.o_delivery_carrier_select');
|
||||
if (carriers.length === 0) { // No carrier is available.
|
||||
return true; // Ignore the check.
|
||||
}
|
||||
|
||||
const checkedCarriers = document.querySelectorAll('input[name="delivery_type"]:checked');
|
||||
if (checkedCarriers.length === 0) { // No carrier is selected.
|
||||
return false; // Nothing else to check.
|
||||
}
|
||||
const carriersContainer = checkedCarriers[0].closest('.o_delivery_carrier_select');
|
||||
const isPickUpPointRequired = carriersContainer.querySelector('.o_show_pickup_locations');
|
||||
if (isPickUpPointRequired) {
|
||||
const address = carriersContainer.querySelector(
|
||||
'.o_order_location_address'
|
||||
).innerText;
|
||||
const isPickUp = carriersContainer.lastChild.previousSibling.children;
|
||||
if (
|
||||
isPickUp.length > 1 && (address === '' || isPickUp[0].classList.contains('d-none'))
|
||||
) { // A pickup point is required but not selected
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the "Terms and Conditions" checkbox is ticked, if present.
|
||||
*
|
||||
* @private
|
||||
* @return {boolean}
|
||||
*/
|
||||
_isTCCheckboxReady() {
|
||||
const checkbox = document.querySelector('#website_sale_tc_checkbox');
|
||||
if (!checkbox) { // The checkbox is not present.
|
||||
return true; // Ignore the check.
|
||||
}
|
||||
|
||||
return checkbox.checked;
|
||||
},
|
||||
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import PaymentForm from '@payment/js/payment_form';
|
||||
|
||||
PaymentForm.include({
|
||||
|
||||
/**
|
||||
* Create an event listener for the payment button located outside the payment form.
|
||||
* @override
|
||||
*/
|
||||
async start() {
|
||||
const submitButton = document.querySelector('[name="o_payment_submit_button"]');
|
||||
submitButton.addEventListener('click', ev => this._submitForm(ev));
|
||||
return await this._super(...arguments);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { Component } from '@odoo/owl';
|
||||
import publicWidget from '@web/legacy/js/public/public_widget';
|
||||
|
||||
publicWidget.registry.TermsAndConditionsCheckbox = publicWidget.Widget.extend({
|
||||
selector: 'div[name="website_sale_terms_and_conditions_checkbox"]',
|
||||
events: {
|
||||
'change #website_sale_tc_checkbox': '_onClickTCCheckbox',
|
||||
},
|
||||
|
||||
async start() {
|
||||
this.checkbox = this.el.querySelector('#website_sale_tc_checkbox');
|
||||
return this._super(...arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable/disabled the payment button when the "Terms and Conditions" checkbox is
|
||||
* checked/unchecked.
|
||||
*
|
||||
* @private
|
||||
* @return {void}
|
||||
*/
|
||||
_onClickTCCheckbox() {
|
||||
if (this.checkbox.checked) {
|
||||
Component.env.bus.trigger('enablePaymentButton');
|
||||
} else {
|
||||
Component.env.bus.trigger('disablePaymentButton');
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
export default publicWidget.registry.TermsAndConditionsCheckbox;
|
||||
@@ -192,9 +192,14 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Disable the payment button.
|
||||
*
|
||||
* @private
|
||||
* @return {void}
|
||||
*/
|
||||
_disablePayButton: function (){
|
||||
var payButton = document.querySelector('button[name="o_payment_submit_button"]');
|
||||
payButton? payButton.disabled = true : null;
|
||||
Component.env.bus.trigger('disablePaymentButton');
|
||||
},
|
||||
|
||||
_disablePayButtonNoPickupPoint : function (ev){
|
||||
@@ -247,57 +252,16 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
|
||||
this._enableButton(result.status);
|
||||
},
|
||||
/**
|
||||
* Check if the submit button can be enabled.
|
||||
* If it is the case, trigger the `_enableButton` from payment
|
||||
* Enable the payment button if the rate_shipment request succeeded.
|
||||
*
|
||||
* @private
|
||||
* @param {boolean} status - The status of the rate_shipment request.
|
||||
* @return {void}
|
||||
*/
|
||||
_enableButton: function(status){
|
||||
if (!this._isPayable(status)) {
|
||||
return;
|
||||
_enableButton(status){
|
||||
if (status) {
|
||||
Component.env.bus.trigger('enablePaymentButton');
|
||||
}
|
||||
Component.env.bus.trigger('enableButton');
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @param {boolean} status : the status of the rate_shipment request
|
||||
* @return {boolean}
|
||||
*/
|
||||
// FYI we don't cover the case where the payement method is not selected because it already throws an error
|
||||
_isPayable: function(status=false){
|
||||
// abort if no paybutton
|
||||
var payButton = document.querySelector('button[name="o_payment_submit_button"]');
|
||||
if (!payButton) {
|
||||
return false;
|
||||
}
|
||||
// abort if the rating failed
|
||||
if (!status){
|
||||
return false;
|
||||
}
|
||||
const carriers = Array.from(document.querySelectorAll('.o_delivery_carrier_select'))
|
||||
let carrierChecked = null;
|
||||
carriers.forEach((carrier) => {
|
||||
if (carrier.querySelector('input').checked){
|
||||
carrierChecked = carrier;
|
||||
}
|
||||
})
|
||||
//abort if no carrier is selected
|
||||
if (!carrierChecked){
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the carrier does not need a pickup point
|
||||
const isPickUpPointNeeded = carrierChecked.querySelector('.o_show_pickup_locations')
|
||||
if (!isPickUpPointNeeded){
|
||||
return true;
|
||||
}
|
||||
|
||||
const address = carrierChecked.querySelector('.o_order_location_address').innerText
|
||||
const isPickUp = carrierChecked.lastChild.previousSibling.children;
|
||||
if (isPickUp.length > 1 && (address == "" || isPickUp[0].classList.contains("d-none"))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
_isPickupLocationSelected: function (ev) {
|
||||
@@ -381,11 +345,14 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
|
||||
* @param {Event} ev
|
||||
*/
|
||||
_onCarrierClick: async function (ev) {
|
||||
this._disablePayButton();
|
||||
const radio = ev.currentTarget.closest('.o_delivery_carrier_select').querySelector('input[type="radio"]');
|
||||
if (radio.checked && !this._shouldDisplayPickupLocations(ev)) {
|
||||
const radio = ev.currentTarget.closest('.o_delivery_carrier_select').querySelector(
|
||||
'input[type="radio"]'
|
||||
);
|
||||
if (radio.checked) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._disablePayButton();
|
||||
this._showLoading(radio);
|
||||
radio.checked = true;
|
||||
await this._onClickShowLocations(ev);
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { debounce } from '@web/core/utils/timing';
|
||||
import publicWidget from '@web/legacy/js/public/public_widget';
|
||||
|
||||
import PaymentForm from '@payment/js/payment_form';
|
||||
|
||||
const websiteSalePaymentMixin = {
|
||||
|
||||
// #=== WIDGET LIFECYCLE ===#
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init() {
|
||||
this._onClickTCCheckbox = debounce(this._onClickTCCheckbox, 100, true);
|
||||
this._super(...arguments);
|
||||
},
|
||||
|
||||
prepareInputs() {
|
||||
this.$checkbox = $(document.getElementById('website_sale_tc_checkbox'));
|
||||
this.$submitButton = $(document.querySelector('[name="o_payment_submit_button"]'));
|
||||
this._adaptConfirmButton();
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the data on the submit button with the status of the Terms and Conditions input.
|
||||
*
|
||||
* @private
|
||||
* @return {void}
|
||||
*/
|
||||
_adaptConfirmButton() {
|
||||
if (this.$checkbox.length > 0) {
|
||||
const disabledReasons = this.$submitButton.data('disabled_reasons') || {};
|
||||
disabledReasons.tc = !this.$checkbox.prop('checked');
|
||||
this.$submitButton.data('disabled_reasons', disabledReasons);
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
PaymentForm.include(Object.assign({}, websiteSalePaymentMixin, {
|
||||
|
||||
// #=== WIDGET LIFECYCLE ===#
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
async start() {
|
||||
this.prepareInputs();
|
||||
if (this.$checkbox.length > 0) { // The checkbox is outside the payment form.
|
||||
this.$checkbox[0].addEventListener('change', () => this._onClickTCCheckbox());
|
||||
}
|
||||
if (this.$submitButton.length > 0) { // The button is outside the payment form.
|
||||
this.$submitButton[0].addEventListener('click', ev => this._submitForm(ev));
|
||||
}
|
||||
return await this._super(...arguments);
|
||||
},
|
||||
|
||||
// #=== EVENT HANDLERS ===#
|
||||
|
||||
/**
|
||||
* Enable the submit button if it all conditions are met.
|
||||
*
|
||||
* @private
|
||||
* @return {void}
|
||||
*/
|
||||
_onClickTCCheckbox() {
|
||||
this._disableButton();
|
||||
this._adaptConfirmButton();
|
||||
this._enableButton();
|
||||
},
|
||||
|
||||
// #=== PAYMENT FLOW ===#
|
||||
|
||||
/**
|
||||
* Verify that the Terms and Condition checkbox is checked.
|
||||
*
|
||||
* @override method from @payment/js/payment_form
|
||||
* @private
|
||||
* @return {boolean} Whether the form can be submitted.
|
||||
*/
|
||||
_canSubmit() {
|
||||
const disabledReasonFound = Object.values(
|
||||
this.$submitButton.data('disabled_reasons') || {}
|
||||
).includes(true);
|
||||
return !disabledReasonFound && this._super();
|
||||
},
|
||||
|
||||
}));
|
||||
|
||||
publicWidget.registry.WebsiteSalePayment = publicWidget.Widget.extend(
|
||||
Object.assign({}, websiteSalePaymentMixin, {
|
||||
selector: 'div[name="o_website_sale_free_cart"]',
|
||||
events: {
|
||||
'change #website_sale_tc_checkbox': '_onClickTCCheckbox',
|
||||
},
|
||||
|
||||
// #=== WIDGET LIFECYCLE ===#
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
async start() {
|
||||
this.prepareInputs();
|
||||
this._onClickTCCheckbox();
|
||||
return await this._super(...arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Enable the submit button if it all conditions are met.
|
||||
*
|
||||
* @private
|
||||
* @return {void}
|
||||
*/
|
||||
_onClickTCCheckbox() {
|
||||
this._adaptConfirmButton();
|
||||
const disabledReasonFound = Object.values(
|
||||
this.$submitButton.data('disabled_reasons') || {}
|
||||
).includes(true);
|
||||
this.$submitButton.prop('disabled', disabledReasonFound);
|
||||
},
|
||||
}));
|
||||
@@ -1735,6 +1735,7 @@
|
||||
- _cta_classes: CSS classes to append on the primary navigation button; default `None`.
|
||||
- _form_send_navigation: Whether the primary button serves as a submit button for a
|
||||
form; default `None`.
|
||||
- hide_payment_button: Whether the payment button should be hidden; default: False.
|
||||
-->
|
||||
<!-- Checkout context:
|
||||
- website_sale_order: The current order.
|
||||
@@ -1755,12 +1756,12 @@
|
||||
name="csrf_token"
|
||||
t-att-value="request.csrf_token()"
|
||||
t-nocache="The csrf token must always be up to date."/>
|
||||
<t t-call="payment.submit_button">
|
||||
<t t-if="not hide_payment_button" t-call="payment.submit_button">
|
||||
<t t-set="submit_button_label">Confirm Order</t>
|
||||
</t>
|
||||
</form>
|
||||
</div>
|
||||
<t t-else="" t-call="payment.submit_button"/>
|
||||
<t t-elif="not hide_payment_button" t-call="payment.submit_button"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<a role="button" name="website_sale_main_button"
|
||||
@@ -1771,7 +1772,7 @@
|
||||
</a>
|
||||
</t>
|
||||
</t>
|
||||
<div t-attf-class="position-relative #{_form_send_navigation and 'd-flex d-lg-none' or 'd-flex'} w-100 justify-content-center align-items-center my-2 opacity-75">
|
||||
<div t-if="not hide_payment_button" t-attf-class="position-relative #{_form_send_navigation and 'd-flex d-lg-none' or 'd-flex'} w-100 justify-content-center align-items-center my-2 opacity-75">
|
||||
<hr class="w-100"/>
|
||||
<span class="px-3">or</span>
|
||||
<hr class="w-100"/>
|
||||
@@ -2088,6 +2089,7 @@
|
||||
<div class="oe_structure" id="oe_structure_website_sale_payment_2"/>
|
||||
</t>
|
||||
<div class="col-12" t-if="errors">
|
||||
<t t-set="hide_payment_button" t-value="True"/>
|
||||
<t t-foreach="errors" t-as="error">
|
||||
<div class="alert alert-danger" t-if="error" role="alert">
|
||||
<h4>
|
||||
@@ -2113,6 +2115,7 @@
|
||||
<t t-call="payment.form"/>
|
||||
</div>
|
||||
<div t-else="" class="alert alert-warning">
|
||||
<t t-set="hide_payment_button" t-value="True"/>
|
||||
<strong>No suitable payment option could be found.</strong><br/>
|
||||
<div t-if="not request.env.is_admin()">
|
||||
If you believe that it is an error, please contact the website administrator.
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import paymentButton from '@payment/js/payment_button';
|
||||
|
||||
paymentButton.include({
|
||||
|
||||
/**
|
||||
* Verify that the payment button is ready to be enabled.
|
||||
*
|
||||
* The condition is that:
|
||||
* - The warning onsite is hidden.
|
||||
*
|
||||
* @override from @payment/js/payment_button
|
||||
* @return {boolean}
|
||||
*/
|
||||
_canSubmit() {
|
||||
return this._super(...arguments) && !document.querySelector('.onsite-warning:not(.d-none)');
|
||||
}
|
||||
|
||||
});
|
||||
@@ -20,7 +20,7 @@ publicWidget.registry.websiteSaleDelivery.include({
|
||||
);
|
||||
boldMsg.classList.add('d-block');
|
||||
this.warning.prepend(boldMsg);
|
||||
this.warning.classList.add('alert-warning', 'p-3', 'm-1', 'd-none');
|
||||
this.warning.classList.add('alert-warning', 'p-3', 'm-1', 'd-none', 'onsite-warning');
|
||||
|
||||
this.paymentMethodsContainer = document.querySelector('#payment_method');
|
||||
this.paymentMethodsContainer.querySelector(
|
||||
@@ -65,12 +65,10 @@ publicWidget.registry.websiteSaleDelivery.include({
|
||||
|
||||
const input = ev.currentTarget.querySelector('input');
|
||||
let atLeastOneOptionAvailable = false;
|
||||
// Jquery because the button does not behave nicely with vanilla dataset.
|
||||
let $payButton = $('button[name="o_payment_submit_button"]');
|
||||
for (let option of this.paymentOptions) {
|
||||
if (option.dataset.isOnsite && input.dataset.deliveryType !== 'onsite') {
|
||||
if (option.checked) { // The payment option was selected.
|
||||
$payButton.attr('disabled', true); // Reset the submit button.
|
||||
this._disablePayButton(); // Reset the submit button.
|
||||
}
|
||||
this._setEnablePaymentOption(option, false);
|
||||
} else{
|
||||
@@ -81,13 +79,13 @@ publicWidget.registry.websiteSaleDelivery.include({
|
||||
}
|
||||
}
|
||||
|
||||
let disabledReasons = $payButton.data('disabled_reasons') || {};
|
||||
disabledReasons.noOptionAvailableOnsite = false;
|
||||
|
||||
if (!atLeastOneOptionAvailable) {
|
||||
this.warning.classList.remove('d-none');
|
||||
disabledReasons.noOptionAvailableOnsite = true;
|
||||
this._disablePayButton();
|
||||
}
|
||||
$payButton.data('disabled_reasons', disabledReasons);
|
||||
}
|
||||
else {
|
||||
this._enableButton();
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user