/* adds sherpa location checker to cart page (c) Min Liu 2020 */ var SherpaApp = (function() { var sherpaLang = { "widget-selectshipping-title": "Select shipping method", "widget-selectshipping-desc": "Costs will be calculated at checkout", "widget-selectshipping-button-sherpa": "2 Hour Delivery - available within 50km Brisbane area and surrounds", "widget-selectshipping-button-sherpa-desc": "Order cut off times:
Mon & Tues 6:30pm, Weds through to Sat 8:30pm, Sun 5:30pm", "widget-selectshipping-button-shipping": "Click & Collect, Standard and Express postage options", "widget-selectshipping-button-shipping-desc": "Click & Collect (Free), Standard ($10), Express ($15) International ($25).", "widget-checkpostcode-title": "Check delivery eligibility", "widget-checkpostcode-desc": "Enter your postcode to see if all items in your cart are available for local delivery.", "widget-input-placeholder": "Enter your postcode to check if we can deliver", "widget-invalid-postcode": "Please double check you have entered a valid postcode.", "widget-all-fulfillable": "Great! Items in your cart are available for local delivery.", "widget-none-fulfillable": "Local delivery not available to your location. Other shipping options, if available, will be shown at checkout.", "widget-no-rates": "Local delivery not available to your location. Other shipping options, if available, will be shown at checkout.", "widget-removed-offending": "Items not available for local delivery to your location have been removed from your cart.", "widget-calendar-placeholder": "Select a date", "widget-delivery-notes-title": "Note for delivery driver", "widget-delivery-notes-placeholder": "Add note", "modal-title": "Local 2 Hour Delivery is not available for some items.", "modal-desc": "Please remove these items to proceed. Items must be in stock from the same location to receive 2 hour delivery.", "modal-button": "Remove items and continue", "modal-skip-button": "Skip this step - other shipping options will be shown at checkout", }; var widgetLoading = false; var widgetLoaded = false; var checkoutItems = {}; var itemsToRemove = []; var checkoutSelector = "[name='checkout']"; var insertionSelector = "[name='checkout']"; var sherpaIdVar = '_sherpaid'; var showLocationWidget = true; var showCalendarWidget = false; var showDeliveryNotes = true; var calendarBlockoutDates = {"DEFAULT":["2022-12-25","2023-12-25","2024-12-25","2025-12-25"]}; var allowPopupSkip = true; var selectedDate = null; var selectedLocation = null; var shipWithSherpa = false; var isWidgetLoaded = function() { return widgetLoaded; }; var destroy = function($) { console.log('sherpa destroy'); $('.sherpa-container').remove(); $(document).off('click','.sherpa_btnSkip'); $(document).off('click','.sherpa-modal-close'); $(document).off('click','.sherpa_btnUseSherpa'); $(document).off('click','.sherpa_btnUseShipping'); $(document).off('keydown','.sherpa_txtPostcode'); $(document).off('click','.sherpa_btnCheckPostcode'); $(document).off('click','.sherpa_btnRemoveItems'); $(document).off('click','.sherpa_btnCalendar'); $(document).off('keydown','#sherpa-deliverynotes'); }; var checkCartTags = function($) { console.log('checkCartTags'); var inflight = 0; var hasExcludeTag = false; $.ajax({ type: "GET", url: "/cart.js", processData: false, dataType: 'json', async: false, success: function(cart) { $(cart.items).each(function(k,v) { inflight += 1; $.ajax({ type: "GET", url: "/products/"+v.handle+".js", processData: false, dataType: 'json', async: true, success: function(product) { inflight -= 1; if (product.tags.indexOf('sherpa-exclude') > -1) { hasExcludeTag = true; } if (inflight == 0) { if (hasExcludeTag) { console.log('skip UI: has sherpa-exclude'); //re-enable checkout button $(checkoutSelector).prop('disabled',false).removeClass('disabled'); } else { initUIElements($); } } } }); }); } }); }; var addCartToken = function($,forceUpdate) { console.log('addCartToken'); if (typeof forceUpdate == 'undefined') force = false; var cartToken = null; var cartData = {}; //get current cart $.ajax({ type: "GET", url: "/cart.js", processData: false, dataType: 'json', async: false, success: function(cart) { //set on all items in the cart that requires shipping cartToken = cart.token; console.log('cart token: '+cartToken); var sherpaID = 'T='+cartToken; if (showCalendarWidget) { sherpaID = sherpaID+'&D='+selectedDate; } sherpaID = sherpaID+'&TS='+Date.now(); for (idx=0; idx < cart.items.length; idx++) { var item = cart.items[idx]; if (item.requires_shipping && (!(item.properties && item.properties[sherpaIdVar] && item.properties[sherpaIdVar] != '') || forceUpdate)) { cartData.line = idx+1; cartData.quantity = item.quantity; cartData.properties = item.properties; if (cartData.properties === null) { //no existing properties cartData.properties = {}; cartData.properties[sherpaIdVar] = sherpaID; } else { cartData.properties[sherpaIdVar] = sherpaID; } $.ajax({ url: '/cart/sherpachange.js', type: 'POST', dataType: 'json', data: cartData, async: false, complete: function(data) { console.log('line item updated'); } }); } } } }); }; var removeCartToken = function($) { console.log('removeCartToken'); //get current cart $.ajax({ type: "GET", url: "/cart.js", processData: false, dataType: 'json', async: false, success: function(cart) { for (idx=0; idx < cart.items.length; idx++) { var item = cart.items[idx]; if (item.properties && item.properties[sherpaIdVar]) { console.log('property requires removing: '+(idx+1)); var cartData = {}; cartData.line = idx+1; cartData.quantity = item.quantity; cartData.properties = item.properties; cartData.properties[sherpaIdVar] = ''; $.ajax({ url: '/cart/sherpachange.js', type: 'POST', dataType: 'json', data: cartData, async: false, success: function(data) { console.log('removed property line: '+cartData.line); } }); } } } }); }; var showNextStep = function($,currentStep) { if (currentStep == 'SHOWEND') { $(checkoutSelector).prop('disabled',false).removeClass('disabled'); } if (currentStep == 'LOCATION') { if (showCalendarWidget && shipWithSherpa) { $('.sherpa-wrapper-calendar').show(); } else { if (shipWithSherpa) $('.sherpa-wrapper-deliverynotes').show(); $(checkoutSelector).prop('disabled',false).removeClass('disabled'); } } if (currentStep == 'CALENDAR') { $(checkoutSelector).prop('disabled',false).removeClass('disabled'); $('.sherpa-wrapper-deliverynotes').show(); } }; var getDateStr = function(date) { var _day = date.getDate()+''; var _month = (date.getMonth()+1)+''; if (_day.length == 1) _day = '0'+_day; if (_month.length == 1) _month = '0'+_month; return date.getFullYear()+'-'+_month+'-'+_day; }; var dateFormatddmmyyyy = function(date) { var day = date.getDate()+""; var month = (date.getMonth()+1)+""; var year = date.getFullYear(); if (day.length == 1) day = '0'+day; if (month.length == 1) month = '0'+month; return day+'/'+month+'/'+year; }; var calendarAvailDOW = []; var isDateValid = function($,date,cutoffTimeDOW,_readyTS) { var dow = new Array(7); dow[0] = "sun"; dow[1] = "mon"; dow[2] = "tue"; dow[3] = "wed"; dow[4] = "thu"; dow[5] = "fri"; dow[6] = "sat"; // console.log('selected location: '+selectedLocation+', date: '+getDateStr(date)); cutoffTimeLoc = selectedLocation; if (cutoffTimeLoc === null || typeof cutoffTimeDOW[cutoffTimeLoc] === 'undefined') cutoffTimeLoc = 'DEFAULT'; blockoutLoc = selectedLocation; if (blockoutLoc === null || typeof calendarBlockoutDates[blockoutLoc] === 'undefined') blockoutLoc = 'DEFAULT'; var mydow = dow[date.getDay()]; var mydateStr = getDateStr(date); var _date = new Date(date.getTime()); //check business hour dow if (calendarAvailDOW.length > 0) { if (!calendarAvailDOW[mydow]) { return false; } } //check blockout date if (typeof calendarBlockoutDates[blockoutLoc] !== 'undefined' && calendarBlockoutDates[blockoutLoc].includes(mydateStr)) { return false; } if (cutoffTimeDOW[cutoffTimeLoc][mydow] === false) { return false; } else { var matches = cutoffTimeDOW[cutoffTimeLoc][mydow].match(/(\d+)(\d\d)$/); var windowEndHr = parseInt(matches[1]); var windowEndMin = parseInt(matches[2]); _date.setHours(windowEndHr,windowEndMin); if ((_date.getTime()/1000) < _readyTS) { //is today and after cutoff time return false; } else { return true; } } }; var _postcodeAutoSubmitTimer = null; var initUI = function($) { if ($(checkoutSelector).length > 0) { //disable checkout button $(checkoutSelector).prop('disabled',true).addClass('disabled'); checkCartTags($); } }; var initUIElements = function($) { console.log('cart page found'); addAjaxHooks($); //add css var css = document.createElement('link'); css.rel = 'stylesheet'; css.type = 'text/css'; css.href = '//plugin-app.sherpa.net.au/css/widget.css?20211124'; $('head').append(css) //disable checkout button $(checkoutSelector).prop('disabled',true).addClass('disabled'); var css = document.createElement('link'); css.rel = 'stylesheet'; css.type = 'text/css'; css.href = '//plugin-app.sherpa.net.au/css/jquery-ui.min.css?20211124'; $('head').append(css) console.log('sherpa headless'); var insertionPoint = $(insertionSelector); $(insertionPoint).after('
'); //check to see if all items can be fulfilled from ANY location, if yes, add the line item properties - ignore calendar //if no, remove all line item properties //get current items var itemsPayload = {}; var itemsSerialised = []; $.ajax({ url: '/cart.js', type: 'GET', dataType: 'json', async: false, success: function(cart) { for (idx=0; idx < cart.items.length; idx++) { var item = cart.items[idx]; checkoutItems[item.variant_id] = {"key":item.key,"title":item.title,"qty":item.quantity,"vid":item.variant_id,"image":item.image}; if (typeof itemsPayload[item.variant_id] === 'undefined') itemsPayload[item.variant_id] = 0; itemsPayload[item.variant_id] += item.quantity; } } }); $.each(itemsPayload,function(vid,qty) { itemsSerialised.push(vid+'|'+qty); }); //do check $.ajax({ url: 'https://plugin-app.sherpa.net.au/api.php', type: 'POST', dataType: 'json', data: { 'a': 'checkLocation', 's': 'naughty-but-nice-cannon-hill.myshopify.com', 'p': 'ANY', 'c': ' ', 'i': itemsSerialised.join(','), }, success: function(data) { //turn off calendar if (typeof data.forceCalendarOff !== 'undefined' && data.forceCalendarOff === true) { console.log('has sherpa-no-cal'); showCalendarWidget = false; } if (data.locationsAllInStock.length > 0) { console.log('all fulfillable'); addCartToken($); } else { console.log('not all fulfillable'); removeCartToken($); } console.log('sherpa headless check complete'); $(checkoutSelector).prop('disabled',false).removeClass('disabled'); $('#checkoutSpinner').remove(); }, error: function() { $(checkoutSelector).prop('disabled',false).removeClass('disabled'); $('#checkoutSpinner').remove(); } }); widgetLoading = false; widgetLoaded = true; }; var sherpaOnCartChange = function($) { console.log('sherpa on cart change'); $('.sherpa-selectshipping').show(); $('.sherpa-checkpostcode').hide(); $(checkoutSelector).prop('disabled',true).addClass('disabled'); checkoutItems = {}; $('.sherpa-results').html(''); }; var addAjaxHooks = function($) { var oldOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function() { if (arguments[1].indexOf('sherpaupdate.js') > -1) { arguments[1] = arguments[1].replace('sherpaupdate.js','update.js'); } else if (arguments[1].indexOf('sherpachange.js') > -1) { arguments[1] = arguments[1].replace('sherpachange.js','change.js'); } else { if (arguments[1].indexOf('/cart/add.js')>-1 || arguments[1].indexOf('/cart/change.js')>-1 || arguments[1].indexOf('/cart/update.js')>-1) { console.log('sherpa attaching listener'); this.addEventListener('load', function() { sherpaOnCartChange($); }); } } oldOpen.apply(this, arguments); }; }; var runSherpa = function($) { if (widgetLoading) return; destroy($); console.log('sherpa init'); widgetLoading = true; initUI($); }; var waitjQueryLoad = function(cb) { if (typeof window.jQuery != "undefined" && typeof window.jQuery.fx != "undefined") { var myJQ = window.jQuery.noConflict(); cb(myJQ); } else { //reschedule window.setTimeout(function() { waitjQueryLoad(cb); },100); } }; var waitjQueryUILoad = function($,cb) { if (typeof $.datepicker != "undefined") { cb($); } else { //reschedule window.setTimeout(function() { waitjQueryUILoad($,cb); },100); } }; var loadJQUI = function($) { if (typeof $.datepicker == "undefined") { console.log('sherpa load jQ UI'); var jqueryuisrc = document.createElement('script'); jqueryuisrc.type = 'text/javascript'; jqueryuisrc.src = '//code.jquery.com/ui/1.12.1/jquery-ui.min.js'; var oldjQuery = window.jQuery; window.jQuery = $; document.body.appendChild(jqueryuisrc); window.jQuery = oldjQuery; waitjQueryUILoad($,function(jq) { runSherpa(jq); }); } else { runSherpa($); } }; var jquery; if (window.jQuery) { jquery = window.jQuery.noConflict(); } else if (window.Checkout && window.Checkout.$) { jquery = window.Checkout.$.noConflict(); } if (typeof jquery == "undefined" || typeof jquery.fx == "undefined") { console.log('sherpa load jQ'); var jquerysrc = document.createElement('script'); jquerysrc.type = 'text/javascript'; jquerysrc.src = '//ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.min.js'; document.body.appendChild(jquerysrc); waitjQueryLoad(function(jq) { loadJQUI(jq); }); } else { loadJQUI(jquery); } return { runSherpa: runSherpa, initUI: initUI, destroy: destroy, isWidgetLoaded: isWidgetLoaded }; })();