Add new payment and shipping parsers for various integrations
- Implemented Google Pay parser in bongooglepay.js - Added Buckaroo 3 payment parser in buckaroo3.js - Introduced DataTrans CW Mastercard parser in datatranscw.js - Created DataTrans CW Credit Card parser in datatranscw_creditcard.js - Developed DHL Assistant shipping parser in dhlassistant.js - Added Estimated Delivery parser in estimateddelivery.js - Implemented Floapay payment parser in floapay.js - Created FS Pickup at Store shipping parser in fspickupatstore.js - Developed Generic Iframe parser in generic_iframe_parser.js - Added Geodis Officiel shipping parser in geodisofficiel.js - Implemented Glob Kurier module shipping parser in globkuriermodule.js - Created Latvija Post Express Pickup Terminal parser in latvijaspastsexpresspastspostterminalslv.js - Developed LP Shipping parser in lpshipping.js - Added Mijora Venipak parser in mijoravenipak.js - Implemented Apple Pay parser in pm_applepay.js - Created Przelewy24 payment parser in przelewy24.js - Developed Pshugls shipping parser in pshugls.js - Added Redsys Insite payment parser in redsysinsite.js - Implemented Tpay payment parser in tpay.js - Updated third-party integration documentation for FedEx DotCom
This commit is contained in:
@@ -93,7 +93,7 @@ $(document).ready(function () {
|
||||
checkAndHideGlobalError();
|
||||
});
|
||||
|
||||
$('body').on('change', '#js-delivery input', function () {
|
||||
$('body').on('change', '#js-delivery .shipping-radio input', function () {
|
||||
selectDeliveryOption($('#js-delivery')); // delivery form object as parameter
|
||||
});
|
||||
|
||||
@@ -190,6 +190,12 @@ $(document).ready(function () {
|
||||
});
|
||||
|
||||
$('body').on('change', '[data-link-action=x-ship-to-different-address]', function () {
|
||||
// Hook to this:
|
||||
// prestashop.on('thecheckout_changeSecondAddress', function(data) { console.log('second address block toggled!', data); })
|
||||
prestashop.emit('thecheckout_changeSecondAddress', {
|
||||
'addressType': 'delivery',
|
||||
'isCollapsing': $('#thecheckout-address-delivery').is(':visible')
|
||||
});
|
||||
|
||||
if ($('#thecheckout-address-delivery').is(':visible')) {
|
||||
$(this).prop('checked', false);
|
||||
@@ -210,6 +216,11 @@ $(document).ready(function () {
|
||||
});
|
||||
|
||||
$('body').on('change', '[data-link-action=x-bill-to-different-address]', function () {
|
||||
prestashop.emit('thecheckout_changeSecondAddress', {
|
||||
'addressType': 'invoice',
|
||||
'isCollapsing': $('#thecheckout-address-invoice').is(':visible')
|
||||
});
|
||||
|
||||
if ($('#thecheckout-address-invoice').is(':visible')) {
|
||||
$(this).prop('checked', false);
|
||||
$('#thecheckout-address-invoice').hide(10, function () {
|
||||
@@ -256,6 +267,7 @@ $(document).ready(function () {
|
||||
if ($('#dni-placeholder').length && $('#thecheckout-address-invoice .business-field.dni').length) {
|
||||
swapElements($('#dni-placeholder'), $('#thecheckout-address-invoice .business-field.dni'));
|
||||
}
|
||||
removeError('.business-private-checkboxes > .error-msg');
|
||||
|
||||
return false;
|
||||
});
|
||||
@@ -280,6 +292,7 @@ $(document).ready(function () {
|
||||
if ($('#dni-placeholder-delivery').length && $('#thecheckout-address-delivery .business-field.dni').length) {
|
||||
swapElements($('#dni-placeholder-delivery'), $('#thecheckout-address-delivery .business-field.dni'));
|
||||
}
|
||||
removeError('.business-private-checkboxes > .error-msg');
|
||||
|
||||
return false;
|
||||
});
|
||||
@@ -304,6 +317,7 @@ $(document).ready(function () {
|
||||
if ($('#dni-placeholder-private').length && $('#thecheckout-address-invoice .private-field.dni').length) {
|
||||
swapElements($('#dni-placeholder-private'), $('#thecheckout-address-invoice .private-field.dni'));
|
||||
}
|
||||
removeError('.business-private-checkboxes > .error-msg');
|
||||
|
||||
return false;
|
||||
});
|
||||
@@ -328,10 +342,37 @@ $(document).ready(function () {
|
||||
if ($('#dni-placeholder-private-delivery').length && $('#thecheckout-address-delivery .private-field.dni').length) {
|
||||
swapElements($('#dni-placeholder-private-delivery'), $('#thecheckout-address-delivery .private-field.dni'));
|
||||
}
|
||||
removeError('.business-private-checkboxes > .error-msg');
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$('body').on('change', '[data-link-action^=x-i-am-private],[data-link-action^=x-i-am-business]', function () {
|
||||
const linkAction = $(this).data('link-action');
|
||||
const isBusiness = linkAction.startsWith('x-i-am-business');
|
||||
const addressType = linkAction.endsWith('delivery') ? 'delivery' : 'invoice';
|
||||
const isChecked = $(this).prop('checked');
|
||||
|
||||
// prestashop.on('thecheckout_businessPrivateChecked', function(data) { console.log('business or private checkbox selected!', data); })
|
||||
prestashop.emit('thecheckout_businessPrivateChecked', {
|
||||
addressType, isBusiness, isChecked
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (config_use_other_for_business_private) {
|
||||
prestashop.on('thecheckout_businessPrivateChecked', function (data) {
|
||||
const field = $(`#thecheckout-address-${data.addressType} [name=other]`);
|
||||
const isBusinessMsg = i18_business ?? 'business';
|
||||
const isPrivateMsg = i18_private ?? 'private';
|
||||
let msg = '';
|
||||
if (data.isChecked) {
|
||||
msg = data.isBusiness ? isBusinessMsg : isPrivateMsg;
|
||||
}
|
||||
field.val(msg);
|
||||
});
|
||||
}
|
||||
|
||||
$('body').on('click', '[data-link-action=toggle-password-visibility]', function () {
|
||||
var input = $(this).closest('label').find('input');
|
||||
@@ -367,7 +408,10 @@ $(document).ready(function () {
|
||||
});
|
||||
$('body').on('click', '[data-link-action=x-update-cart-quantity-up]', function () {
|
||||
var inputEl = $(this).parent().find('[data-link-action=x-update-cart-quantity]');
|
||||
inputEl.val(parseInt(inputEl.val()) + 1).data('no-wait', 1); // .trigger('input');
|
||||
const data = inputEl.data();
|
||||
const qtyHave = parseInt(inputEl.val());
|
||||
const qtyChange = data?.step ?? 1;
|
||||
inputEl.val(qtyHave + qtyChange).data('no-wait', 1); // .trigger('input');
|
||||
inputEl.get(0).dispatchEvent(new Event('input', {
|
||||
bubbles: true
|
||||
}))
|
||||
@@ -375,8 +419,11 @@ $(document).ready(function () {
|
||||
});
|
||||
$('body').on('click', '[data-link-action=x-update-cart-quantity-down]', function () {
|
||||
var inputEl = $(this).parent().find('[data-link-action=x-update-cart-quantity]');
|
||||
if (parseInt(inputEl.attr('min')) < parseInt(inputEl.val())) {
|
||||
inputEl.val(parseInt(inputEl.val()) - 1).data('no-wait', 1); // .trigger('input');
|
||||
const data = inputEl.data();
|
||||
const qtyHave = parseInt(inputEl.val());
|
||||
const qtyChange = data?.step ?? 1;
|
||||
if (parseInt(inputEl.attr('min')) <= qtyHave - qtyChange) {
|
||||
inputEl.val(qtyHave - qtyChange).data('no-wait', 1); // .trigger('input');
|
||||
inputEl.get(0).dispatchEvent(new Event('input', {
|
||||
bubbles: true
|
||||
}))
|
||||
@@ -518,6 +565,11 @@ $(document).ready(function () {
|
||||
$('[data-link-action="toggle-password-visibility"]').removeClass('hidden');
|
||||
|
||||
$(document).ajaxError(function myErrorHandler(event, xhr, ajaxOptions, thrownError) {
|
||||
if (['abort', 'canceled'].includes(thrownError)) {
|
||||
// console.log('Ajax aborted', ajaxOptions)
|
||||
return;
|
||||
}
|
||||
|
||||
console.info("Ajax error \n\nDetails:\nError thrown: " + thrownError + "\n" +
|
||||
'event: ');
|
||||
console.info(event);
|
||||
@@ -534,6 +586,7 @@ $(document).ready(function () {
|
||||
var modalTriggeredToBeShown = 0;
|
||||
setTimeout( function() {
|
||||
$(".js-terms a").off('click');
|
||||
$(".dm_gdpr_active a.iframe").removeClass('iframe');
|
||||
$("body#checkout").on("click", ".js-terms a", function (t) {
|
||||
modalTriggeredToBeShown++;
|
||||
setTimeout(function() { modalTriggeredToBeShown--; }, 1000);
|
||||
@@ -597,7 +650,7 @@ $(document).ready(function () {
|
||||
}
|
||||
// Attach also loading-remove handler, when (this) ajax is finished
|
||||
jqxhr.always(function() {
|
||||
$(settings.customPropAffectedBlocks).find('.inner-area > .tc-ajax-loading').remove();
|
||||
$(settings.customPropAffectedBlocks).find('.inner-area > .tc-ajax-loading').remove();
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -638,13 +691,14 @@ function initBlocksSelectors() {
|
||||
}
|
||||
|
||||
function handleWindowResize(win) {
|
||||
if (win.width() <= tcMobileViewThreshold && !tcIsMobileView) {
|
||||
const winWidth = window.innerWidth; // win.width()
|
||||
if (winWidth <= tcMobileViewThreshold && !tcIsMobileView) {
|
||||
tcIsMobileView = true;
|
||||
// Take out all checkout blocks from their desktop layout and put into new container for mobile sorting
|
||||
$('.checkout-block').each(function () {
|
||||
$(this).appendTo('#tc-container-mobile');
|
||||
});
|
||||
} else if (win.width() > tcMobileViewThreshold && tcIsMobileView) {
|
||||
} else if (winWidth > tcMobileViewThreshold && tcIsMobileView) {
|
||||
tcIsMobileView = false;
|
||||
// Put .checkout-block containers back to desktop (out of mobile / single column layout)
|
||||
$('.checkout-block').each(function () {
|
||||
@@ -706,6 +760,13 @@ function checkAndHideGlobalError() {
|
||||
function showGlobalError() {
|
||||
$('#tc-payment-confirmation > .error-msg').show();
|
||||
scrollToError();
|
||||
if (typeof grecaptcha !== 'undefined' && typeof grecaptcha.reset === 'function') {
|
||||
try {
|
||||
grecaptcha.reset();
|
||||
} catch (error) {
|
||||
// intentionally empty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function scrollToError() {
|
||||
@@ -779,6 +840,13 @@ function modifyRadioOption(radioElements) {
|
||||
});
|
||||
}
|
||||
|
||||
function printContextNotices(blockSel, notices) {
|
||||
$.each(notices, function (index, value) {
|
||||
$(blockSel + ' [name=' + index + ']').addClass('-notice');
|
||||
$(blockSel + ' [name=' + index + ']').after('<div class="field notice-msg">' + value + '</div>');
|
||||
});
|
||||
}
|
||||
|
||||
function printContextErrors(blockSel, errors, triggerElement, dontShowGlobal) {
|
||||
|
||||
var highlightOnElements = [];
|
||||
@@ -818,6 +886,13 @@ function printContextErrors(blockSel, errors, triggerElement, dontShowGlobal) {
|
||||
if (switchToStep > 0 && typeof setHash === 'function') {
|
||||
setHash(switchToStep);
|
||||
}
|
||||
|
||||
// For invisible or non-existing fields, let's collect all errors inside 'general_error'
|
||||
if (!$(blockSel + ' [name=' + index + ']').is(':visible')) {
|
||||
value = index + ': ' + value;
|
||||
index = 'general_error';
|
||||
}
|
||||
|
||||
$(blockSel + ' [name=' + index + ']').addClass('-error');
|
||||
if ($(blockSel + ' [name=' + index + ']').is(':checkbox') || $(blockSel + ' [name=' + index + ']').is(':radio')) {
|
||||
$(blockSel + ' [name=' + index + ']').closest('.form-group').append('<div class="field error-msg">' + value + '</div>');
|
||||
@@ -931,7 +1006,7 @@ function addVoucher() {
|
||||
// so we need to fetch this again; only enable if voucher affect shipping cost
|
||||
getShippingAndPaymentBlocks();
|
||||
} else {
|
||||
updateCheckoutBlocks(jsonData, true, false, false);
|
||||
updateCheckoutBlocks(jsonData, true, false, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -960,7 +1035,7 @@ function removeVoucher(data) {
|
||||
if (tcGlobal_fetchAgainAfterVoucher) {
|
||||
getShippingAndPaymentBlocks();
|
||||
} else {
|
||||
updateCheckoutBlocks(jsonData, true, true, tc_updatePaymentWithShipping);
|
||||
updateCheckoutBlocks(jsonData, true, false, tc_updatePaymentWithShipping, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -979,6 +1054,7 @@ function confirmOrder(confirmButtonEl) {
|
||||
var validationFailed = false;
|
||||
|
||||
// clear shipping error before validations
|
||||
$('#thecheckout-shipping .error-msg').not(':first-child').remove();
|
||||
$('#thecheckout-shipping .error-msg').hide();
|
||||
|
||||
$.each(tc_confirmOrderValidations, function (validationName, validationCallback) {
|
||||
@@ -1113,6 +1189,12 @@ function updateQuantityFromInput(el) {
|
||||
// $('#thecheckout-cart-summary').prepend('<div class="error-msg">' + errMsg + '</div>')
|
||||
// $('#thecheckout-cart-summary > .error-msg').show();
|
||||
// }
|
||||
prestashop.emit('updateCart', { reason: {
|
||||
idProduct: data["idProduct"],
|
||||
idProductAttribute: data["idProductAttribute"],
|
||||
idProductCustomization: data["idCustomization"],
|
||||
action: 'updateQuantity'
|
||||
}, resp: jsonData });
|
||||
|
||||
updateCheckoutBlocks(jsonData, true, true, tc_updatePaymentWithShipping);
|
||||
}
|
||||
@@ -1213,6 +1295,12 @@ function checkEmail(accountFormSelector, triggerEl, callback) {
|
||||
blockSel = ':is(#thecheckout-account, #thecheckout-data-privacy, #thecheckout-psgdpr)';
|
||||
printContextErrors(blockSel, jsonData.errors, undefined, true);
|
||||
} else {
|
||||
blockSelAccount = ':is(#thecheckout-account)';
|
||||
removeError(blockSelAccount + ' .field.notice-msg');
|
||||
if (typeof jsonData.notices !== 'undefined' && jsonData.notices['email']) {
|
||||
printContextNotices(blockSelAccount, jsonData.notices);
|
||||
}
|
||||
|
||||
updateAccountToken(jsonData.newToken);
|
||||
updateStaticToken(jsonData.newStaticToken);
|
||||
// if out of some reason, shipping/payment blocks are still disallowed, maybe entering email
|
||||
@@ -1358,6 +1446,10 @@ function _getExtraAccountParams() {
|
||||
if ($('[name=colissimo_is_mobile_valid]').length) {
|
||||
extraAccountParams += '&colissimo_is_mobile_valid=' + encodeURIComponent($('[name=colissimo_is_mobile_valid]').val());
|
||||
}
|
||||
// lpshipping module (terminal selection)
|
||||
if ($('[name=lpshipping_express_terminal]').length) {
|
||||
extraAccountParams += '&lpshipping_express_terminal=' + encodeURIComponent($('[name=lpshipping_express_terminal]').val());
|
||||
}
|
||||
// djtalbrazilianregister (CPF/CNPJ fields module)
|
||||
if ($('[name=document_type]').length && $('[name=document_number]').length) {
|
||||
$('input[name=document_type]:checked, input[name=document_number], input[name=rg], input[name=ie]').each( (key, item) => {
|
||||
@@ -1368,6 +1460,19 @@ function _getExtraAccountParams() {
|
||||
if ($('#parcel_codigo').length === 1) {
|
||||
extraAccountParams += '&parcel[codigo]=' + encodeURIComponent($('#parcel_codigo').val());
|
||||
}
|
||||
// dpdbaltics
|
||||
if ($('.carrier-extra-content.dpdbaltics:visible [name=dpd-phone]').length === 1) {
|
||||
extraAccountParams += '&dpd-phone=' + encodeURIComponent($('.carrier-extra-content.dpdbaltics:visible [name=dpd-phone]').val());
|
||||
}
|
||||
if ($('.carrier-extra-content.dpdbaltics:visible [name=dpd-phone-area]').length === 1) {
|
||||
extraAccountParams += '&dpd-phone-area=' + encodeURIComponent($('.carrier-extra-content.dpdbaltics:visible [name=dpd-phone-area]').val());
|
||||
}
|
||||
if ($('.carrier-extra-content.dpdbaltics:visible [name=dpd-city]').length === 1) {
|
||||
extraAccountParams += '&dpd-city=' + encodeURIComponent($('.carrier-extra-content.dpdbaltics:visible [name=dpd-city]').val());
|
||||
}
|
||||
if ($('.carrier-extra-content.dpdbaltics:visible [name=dpd-street]').length === 1) {
|
||||
extraAccountParams += '&dpd-street=' + encodeURIComponent($('.carrier-extra-content.dpdbaltics:visible [name=dpd-street]').val());
|
||||
}
|
||||
return extraAccountParams;
|
||||
}
|
||||
|
||||
@@ -1403,8 +1508,8 @@ function modifyAccountAndAddress(triggerElement, callback) {
|
||||
dataType: "json",
|
||||
data: "modifyAccountAndAddress=1&ajax_request=1&action=modifyAccountAndAddress&trigger=" + triggerSection +
|
||||
"&account=" + serializeVisibleFields('form.account-fields') +
|
||||
"&invoice=" + encodeURIComponent($('#thecheckout-address-invoice form :visible').serialize()) +
|
||||
"&delivery=" + encodeURIComponent($('#thecheckout-address-delivery form :visible').serialize()) +
|
||||
"&invoice=" + encodeURIComponent($('#thecheckout-address-invoice form :visible, #thecheckout-address-invoice .use-other-for-business-private input').serialize()) +
|
||||
"&delivery=" + encodeURIComponent($('#thecheckout-address-delivery form :visible, #thecheckout-address-delivery .use-other-for-business-private input').serialize()) +
|
||||
"&passwordVisible=" + $('#thecheckout-account input[name=password]:visible').length +
|
||||
"&passwordRequired=" + $('#thecheckout-account input[name=create-account]:checked').length +
|
||||
"&invoiceVisible=" + $('#thecheckout-address-invoice form:visible').length +
|
||||
@@ -1421,13 +1526,31 @@ function modifyAccountAndAddress(triggerElement, callback) {
|
||||
|
||||
// Go through account, invoice and delivery errors, show them all
|
||||
if ("undefined" !== typeof jsonData.account && null !== jsonData.account) {
|
||||
blockSel = ':is(#thecheckout-account, #thecheckout-data-privacy, #thecheckout-psgdpr)';
|
||||
printContextErrors(blockSel, jsonData.account.errors);
|
||||
|
||||
if (typeof tc_steps !== 'undefined') {
|
||||
// When steps are enabled, these checkboxes can be on different 'steps' pages, so we need to call printContextError with correct blockSel-ector
|
||||
var checkboxes = ['data-privacy', 'psgdpr', 'required-checkbox-1', 'required-checkbox-2'];
|
||||
var checkboxErrors = false
|
||||
for (const checkboxName of checkboxes) {
|
||||
if (jsonData.account.errors[checkboxName]?.length) {
|
||||
printContextErrors(`#thecheckout-${checkboxName}`, jsonData.account.errors);
|
||||
checkboxErrors = true
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!checkboxErrors) {
|
||||
blockSel = ':is(#thecheckout-account)';
|
||||
printContextErrors(blockSel, jsonData.account.errors);
|
||||
}
|
||||
} else {
|
||||
blockSel = ':is(#thecheckout-account, #thecheckout-data-privacy, #thecheckout-psgdpr, #thecheckout-required-checkbox-1, #thecheckout-required-checkbox-2)';
|
||||
printContextErrors(blockSel, jsonData.account.errors);
|
||||
}
|
||||
|
||||
if (jsonData.account.hasErrors) {
|
||||
if (debug_js_controller) {
|
||||
var errMsg = formatErrors(jsonData.account.errors, triggerElement);
|
||||
console.info('modifyAccountAndAddress: account has errros');
|
||||
console.info('modifyAccountAndAddress: account has errors');
|
||||
console.info(errMsg);
|
||||
}
|
||||
|
||||
@@ -1515,7 +1638,7 @@ function modifyAccountAndAddress(triggerElement, callback) {
|
||||
hideConfirmButtonLoader($('[data-link-action=x-save-account-overlay]'));
|
||||
|
||||
if ("undefined" !== typeof jsonData.shippingErrors && null !== jsonData.shippingErrors && "undefined" !== typeof jsonData.shippingErrors.errors) {
|
||||
var errorsTxt = jsonData.shippingErrors.errors.join(', ');
|
||||
var errorsTxt = Object.values(jsonData.shippingErrors.errors).join(', ');
|
||||
$('<div class="error-msg shipping-errors">'+errorsTxt+'</div>').prependTo($('#thecheckout-shipping .inner-wrapper')).show();
|
||||
noErrors = false;
|
||||
showGlobalError();
|
||||
@@ -1574,6 +1697,12 @@ function signIn() {
|
||||
signedInUpdateForm();
|
||||
}
|
||||
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
if(jqXHR.status === 500) {
|
||||
console.error("Internal server error occurred: ", errorThrown);
|
||||
}
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1589,7 +1718,7 @@ function deleteFromCart(data, self) {
|
||||
// Avanto an_productfields module support
|
||||
var anGroupId = $(self).attr('href').match('an_group_id.*');
|
||||
additionalData += (anGroupId)?'&'+anGroupId:'';
|
||||
|
||||
|
||||
// url - implicitly using current
|
||||
$.ajax({
|
||||
customPropAffectedBlocks: '#thecheckout-shipping, #thecheckout-payment, #thecheckout-cart-summary',
|
||||
@@ -1605,6 +1734,13 @@ function deleteFromCart(data, self) {
|
||||
"&token=" + static_token + additionalData,
|
||||
success: function (jsonData) {
|
||||
|
||||
prestashop.emit('updateCart', { reason: {
|
||||
idProduct: data["idProduct"],
|
||||
idProductAttribute: data["idProductAttribute"],
|
||||
idProductCustomization: data["idCustomization"],
|
||||
action: 'deleteFromCart'
|
||||
}, resp: jsonData });
|
||||
|
||||
updateCheckoutBlocks(jsonData, true, true, tc_updatePaymentWithShipping);
|
||||
|
||||
}
|
||||
@@ -1852,10 +1988,63 @@ function highlightSelectedPaymentMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
function updateShippingPrices(shippingBlockHtml) {
|
||||
if ('undefined' !== shippingBlockHtml && null !== shippingBlockHtml) {
|
||||
var $parsedShippingBlock = $(shippingBlockHtml);
|
||||
|
||||
$parsedShippingBlock.find('.delivery-option').each(function() {
|
||||
var $parsedDeliveryOption = $(this);
|
||||
var carrierRef = $parsedDeliveryOption.attr('class').match(/carrier-ref-\d+/)[0];
|
||||
// if carrierRef is not found, we cannot update prices, skip this .each() iteration
|
||||
if (!carrierRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $actualDeliveryOption = $('.delivery-options-list .delivery-option.' + carrierRef);
|
||||
// if respective carrierRef delivery option is not available, skip this .each() iteration
|
||||
if (!$actualDeliveryOption.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var priceTypes = ['carrier-price', 'carrier-price-with-tax-formatted', 'carrier-price-without-tax-formatted'];
|
||||
|
||||
priceTypes.forEach(function(priceType) {
|
||||
var $parsedPrice = $parsedDeliveryOption.find('.delivery-option-detail span.' + priceType + ':first');
|
||||
|
||||
$actualDeliveryOption.find('span.' + priceType).each(function() {
|
||||
var $currentActualPrice = $(this);
|
||||
$currentActualPrice.text($parsedPrice.text());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateShippingBlock(shippingModulesList, html, checksum, triggerElementName) {
|
||||
if ('undefined' !== html && null !== html && shippingBlockChecksum != checksum) {
|
||||
html = parseShippingMethods(shippingModulesList, html);
|
||||
|
||||
// save shipping form text input fields and select boxes, so we can restore them after hook update
|
||||
var shipping_fields_values = {};
|
||||
shippingBlockElement.find('input[type=text], select, form input[type=radio]:checked, textarea').not('[name^=delivery_option]').each(function () {
|
||||
if ("undefined" !== typeof $(this).attr('id') && !$(this).is(':radio')) {
|
||||
shipping_fields_values['[id=' + $(this).attr('id') + ']'] = $(this).val();
|
||||
} else if ("undefined" !== typeof $(this).attr('name')) {
|
||||
shipping_fields_values['[name="' + $(this).attr('name') + '"]'] = $(this).val();
|
||||
}
|
||||
});
|
||||
|
||||
updateHtmlBlock(shippingBlockElement, html);
|
||||
|
||||
// restore shipping for input and select fields values
|
||||
$.each(shipping_fields_values, function (index, value) {
|
||||
if ($(index).is(':radio')) {
|
||||
$(index+'[value="'+value+'"]').prop('checked', true);
|
||||
} else {
|
||||
$(index).val(value);
|
||||
}
|
||||
});
|
||||
|
||||
shippingBlockChecksum = checksum;
|
||||
|
||||
afterShippingLoadCallbacks(shippingModulesList, html, triggerElementName);
|
||||
@@ -1882,7 +2071,9 @@ function updateShippingBlock(shippingModulesList, html, checksum, triggerElement
|
||||
// E.g. packzkomaty (sensbitpaczkomatymap) needs to trigger radio button change in order
|
||||
// to display list of pickup points; Chronopost and Mondial relay need it as well
|
||||
// forceRefreshShipping: If ="1", it will always reload shipping methods, so we need to avoid triggering click to avoid endless loop
|
||||
if ($(deliveryOptionSelector).length && !payment.isConfirmationTrigger(triggerElementName) && !forceRefreshShipping) {
|
||||
// To disable carrier initialization and 'blink' effect, add Custom JS code: const tc_initCarrierJs = false;
|
||||
if ((typeof tc_initCarrierJs !== 'undefined' ? tc_initCarrierJs : true) &&
|
||||
$(deliveryOptionSelector).length && !payment.isConfirmationTrigger(triggerElementName) && !forceRefreshShipping) {
|
||||
$(deliveryOptionSelector).prop('checked', false).trigger('click');
|
||||
return true;
|
||||
} else {
|
||||
@@ -1940,7 +2131,7 @@ function updatePaymentBlock(paymentModulesList, html, checksum, triggerElementNa
|
||||
// Shall be input[type=hidden] added here? It did not work with add_gopay_new
|
||||
// then, we need an exception: .not('[data-payment-module=add_gopay_new] input[type=hidden]')
|
||||
// Exception for hidden fields: input[name="issuer"] = mollie payments
|
||||
paymentBlockElement.find('input[type=text], select, input[name="issuer"], input[name="transferGateway"], form input[type=radio]:checked, textarea').each(function () {
|
||||
paymentBlockElement.find('input[type=text], select, input[name="issuer"], input[name="transferGateway"], form input[type=radio]:checked, textarea, input[type=date]').each(function () {
|
||||
if ("undefined" !== typeof $(this).attr('id') && !$(this).is(':radio') && $(this).attr('name') !== 'pmethod') {
|
||||
payment_fields_values['[id=' + $(this).attr('id') + ']'] = $(this).val();
|
||||
} else if ("undefined" !== typeof $(this).attr('name')) {
|
||||
@@ -1978,6 +2169,8 @@ function updatePaymentBlock(paymentModulesList, html, checksum, triggerElementNa
|
||||
|
||||
afterPaymentLoadCallbacks(paymentModulesList, html, triggerElementName);
|
||||
|
||||
// Hook to this:
|
||||
// prestashop.on('thecheckout_updatePaymentBlock', function() { console.log('payment block updated!'); })
|
||||
prestashop.emit('thecheckout_updatePaymentBlock', {
|
||||
reason: 'update',
|
||||
});
|
||||
@@ -1985,7 +2178,7 @@ function updatePaymentBlock(paymentModulesList, html, checksum, triggerElementNa
|
||||
// restore payment for input and select fields values
|
||||
$.each(payment_fields_values, function (index, value) {
|
||||
if ($(index).is(':radio')) {
|
||||
$(index+'[value='+value+']').prop('checked', true);
|
||||
$(index+'[value="'+value+'"]').prop('checked', true);
|
||||
} else {
|
||||
$(index).val(value);
|
||||
}
|
||||
@@ -1993,12 +2186,12 @@ function updatePaymentBlock(paymentModulesList, html, checksum, triggerElementNa
|
||||
|
||||
// Special molliepayments update - where we need to restore not only input/select value, but also special <button> (which replaces dropdown)
|
||||
if ($('#mollie-issuer-dropdown-button').length && $('input[name="issuer"]').length && '' != $('input[name="issuer"]').val()) {
|
||||
var selectedMolliePayment = $('input[name="issuer"]').val();
|
||||
var selectedMolliePayment = $('input[name="issuer"]').val();
|
||||
var aMollieEl = $('a[data-ideal-issuer='+selectedMolliePayment+']');
|
||||
if (aMollieEl.length) {
|
||||
$('#mollie-issuer-dropdown-button').text(aMollieEl.text());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Init PS Checkout render
|
||||
@@ -2105,7 +2298,7 @@ function updateAddressBlock(addressType, html, htmlAddressDropdown) {
|
||||
}
|
||||
}
|
||||
|
||||
// Hook to this:
|
||||
// Hook to this (alternative of prestashop.emit only on thecheckout page):
|
||||
// $(document).on('thecheckout_Address_Modified', function(event, { addressType }) {
|
||||
// console.log('Address modified!', addressType);
|
||||
// });
|
||||
@@ -2116,7 +2309,7 @@ function updateAddressBlock(addressType, html, htmlAddressDropdown) {
|
||||
|
||||
var cartTotalWeight = 0; // will be changed in updateCheckoutBlocks and then used in updateCartSummaryBlock
|
||||
|
||||
function updateCheckoutBlocks(jsonData, updateSummary, updateShipping, updatePayment) {
|
||||
function updateCheckoutBlocks(jsonData, updateSummary, updateShipping, updatePayment, updateShippingPricesOnly = false) {
|
||||
if ("undefined" !== typeof jsonData.emptyCart && jsonData.emptyCart === true) {
|
||||
$('body').addClass('is-empty-cart');
|
||||
// if ("undefined" !== typeof prestashop && "undefined" !== typeof prestashop.urls) {
|
||||
@@ -2135,6 +2328,10 @@ function updateCheckoutBlocks(jsonData, updateSummary, updateShipping, updatePay
|
||||
var shippingBlockUpdated = false;
|
||||
var paymentBlockUpdated = false;
|
||||
|
||||
if ('undefined' !== typeof updateShippingPricesOnly && updateShippingPricesOnly) {
|
||||
updateShippingPrices(jsonData.shippingBlock);
|
||||
}
|
||||
|
||||
if ('undefined' !== typeof updateShipping && updateShipping) {
|
||||
shippingBlockUpdated = updateShippingBlock(jsonData.externalShippingModules, jsonData.shippingBlock, jsonData.shippingBlockChecksum, jsonData.triggerElementName);
|
||||
}
|
||||
@@ -2178,19 +2375,22 @@ function toggleGiftMessage() {
|
||||
$(this).addClass('in show')
|
||||
});
|
||||
}
|
||||
selectDeliveryOption($('#js-delivery'));
|
||||
}
|
||||
|
||||
function selectDeliveryOption(deliveryForm) {
|
||||
|
||||
highlightSelectedShippingMethod();
|
||||
// To support mondial relay v3.0+, allow a bit of time for widget markup appear in extra content
|
||||
setTimeout(function () {
|
||||
var selectedDeliveryOptionExtra = $(deliveryOptionSelector).closest('.delivery-option-row').next('.carrier-extra-content');
|
||||
$('.carrier-extra-content').not(selectedDeliveryOptionExtra).hide();
|
||||
if (selectedDeliveryOptionExtra.height()) {
|
||||
selectedDeliveryOptionExtra.slideDown();
|
||||
}
|
||||
}, 100);
|
||||
if (installedModules['mondialrelay']) {
|
||||
setTimeout(function () {
|
||||
var selectedDeliveryOptionExtra = $(deliveryOptionSelector).closest('.delivery-option-row').next('.carrier-extra-content');
|
||||
$('.carrier-extra-content').not(selectedDeliveryOptionExtra).hide();
|
||||
if (selectedDeliveryOptionExtra.height()) {
|
||||
selectedDeliveryOptionExtra.slideDown();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// url - implicitly using current
|
||||
$.ajax({
|
||||
@@ -2225,3 +2425,97 @@ function setDeliveryMessage() {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const tc_ongoingXhrs = {}
|
||||
|
||||
const tc_getTimestamp = () => {
|
||||
const now = new Date();
|
||||
return [
|
||||
now.getTime(),
|
||||
`${now.getSeconds().toString().padStart(2, '0')}:${now.getMilliseconds().toString().padStart(3, '0')}`
|
||||
]
|
||||
}
|
||||
|
||||
const tc_getAction = (data) => {
|
||||
const match = data.match(/action=([-\w]+)/)
|
||||
|
||||
if (!match) {
|
||||
return null
|
||||
}
|
||||
|
||||
// construct 'metaAction', set of actions that we don't want to run in parallel, so that they shall be treated
|
||||
// as synchronous
|
||||
const metaAction = {
|
||||
'modifyAccountAndAddress': 'account-modification',
|
||||
'checkEmail': 'account-modification',
|
||||
}
|
||||
if (typeof metaAction[match[1]] !== 'undefined') {
|
||||
return metaAction[match[1]]
|
||||
} else {
|
||||
return match[1]
|
||||
}
|
||||
}
|
||||
|
||||
const tc_AJAX = {
|
||||
SEND: ' send ',
|
||||
COMPLETE: ' complete '
|
||||
};
|
||||
|
||||
const tc_logAction = (method, action) => {
|
||||
const [timestamp, timestamp_str] = tc_getTimestamp()
|
||||
|
||||
const ongoingXhr = typeof tc_ongoingXhrs[action] !== 'undefined'
|
||||
|
||||
if (method == tc_AJAX.COMPLETE && !ongoingXhr) {
|
||||
return
|
||||
}
|
||||
|
||||
let took = ''
|
||||
if (method == tc_AJAX.SEND) {
|
||||
// wait only 1s, if response is not received, release the lock and let the other (potential) xhr to continue
|
||||
tc_ongoingXhrs[action] = { timestamp, maxWait: 1000 }
|
||||
} else {
|
||||
took = ` (took: ${timestamp - tc_ongoingXhrs[action]?.timestamp}ms)`
|
||||
delete tc_ongoingXhrs[action]
|
||||
}
|
||||
|
||||
if (debug_js_controller) {
|
||||
console.log(`[${method}] '${action}' @ ${timestamp_str}s${took}`)
|
||||
}
|
||||
}
|
||||
|
||||
$( document ).on( "ajaxSend", function(event, jqxhr, settings) {
|
||||
if (typeof settings.data === 'string') {
|
||||
const action = tc_getAction(settings.data)
|
||||
if (action) {
|
||||
tc_logAction(tc_AJAX.SEND, action)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$( document ).on( "ajaxSuccess", function(event, jqxhr, settings) {
|
||||
if (typeof settings.data === 'string') {
|
||||
const action = tc_getAction(settings.data)
|
||||
if (action) {
|
||||
tc_logAction(tc_AJAX.COMPLETE, action)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
Disallow duplicate AJAX requests, but with max timeout (default 1s) to avoid endless waiting
|
||||
*/
|
||||
$.ajaxSetup({
|
||||
beforeSend: function(jqXHR, settings) {
|
||||
if (typeof settings.data === 'string') {
|
||||
const action = tc_getAction(settings.data)
|
||||
if (action && typeof tc_ongoingXhrs[action] !== 'undefined' && tc_ongoingXhrs[action]?.maxWait > 0) {
|
||||
tc_ongoingXhrs[action].maxWait -= 200
|
||||
setTimeout(function() {
|
||||
$.ajax(settings);
|
||||
}, 200);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user