From e56b6da6f834fcaa1e414355e8a805751faa2895 Mon Sep 17 00:00:00 2001 From: "jacob.viertel@wunderbyte.at" Date: Fri, 10 Jan 2025 12:09:17 +0100 Subject: [PATCH] Improvement: GH-106 Body process implementation --- amd/build/cart.min.js | 4 +- amd/build/cart.min.js.map | 2 +- amd/build/cashier.min.js | 2 +- amd/build/cashier.min.js.map | 2 +- amd/build/cashier_modal.min.js | 2 +- amd/build/cashier_modal.min.js.map | 2 +- amd/build/checkout_manager.min.js | 4 +- amd/build/checkout_manager.min.js.map | 2 +- amd/src/cart.js | 2 +- amd/src/checkout_manager.js | 69 ++++++++++--- checkout.php | 34 +------ classes/external/control_checkout_process.php | 7 +- classes/local/cartstore.php | 43 ++++++++ .../checkout_process/checkout_base_item.php | 16 +++ .../checkout_process/checkout_manager.php | 98 +++++++++++++++---- .../checkout_process/items/addresses.php | 14 +-- .../items/termsandconditions.php | 46 ++++++--- .../checkout_process/items/vatnrchecker.php | 29 +++--- classes/local/vatnrchecker.php | 42 ++++++-- lang/de/local_shopping_cart.php | 9 ++ lang/en/local_shopping_cart.php | 9 ++ settings.php | 15 +++ templates/address.mustache | 1 + templates/checkout.mustache | 7 +- templates/checkout_manager_feedback.mustache | 84 ++++++++++++++++ templates/checkout_manager_form.mustache | 9 +- .../checkout_manager_form_buttons.mustache | 8 ++ ...heckout_manager_form_progress_bar.mustache | 32 +++--- ...che => checkout_payment_checkout.mustache} | 1 + templates/termsandconditions.mustache | 65 ++++++++---- templates/vatnrchecker.mustache | 6 +- tests/vatnrchecker_test.php | 88 +++++++++++++++++ 32 files changed, 595 insertions(+), 159 deletions(-) create mode 100644 templates/checkout_manager_feedback.mustache rename templates/{checkout_payment_region.mustache => checkout_payment_checkout.mustache} (98%) create mode 100644 tests/vatnrchecker_test.php diff --git a/amd/build/cart.min.js b/amd/build/cart.min.js index 66fec056..97898c2f 100644 --- a/amd/build/cart.min.js +++ b/amd/build/cart.min.js @@ -1,8 +1,8 @@ -define("local_shopping_cart/cart",["exports","core/ajax","core/templates","core/modal_factory","core/modal_events","local_shopping_cart/cashier","local_shopping_cart/notifications","core_form/dynamicform","core/str"],(function(_exports,_ajax,_templates,_modal_factory,_modal_events,_cashier,_notifications,_dynamicform,_str){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.addItem=void 0,_exports.addItemShowNotification=addItemShowNotification,_exports.init=_exports.deleteItem=_exports.deleteAllItems=_exports.buttoninit=void 0,_exports.initPriceLabel=function(userid){console.log("initpricelabel"),userid<1&&(userid=0);const checkbox=document.querySelector(SELECTORS.PRICELABELCHECKBOX),installmentscheckbox=document.querySelector(SELECTORS.INSTALLMENTSCHECKBOX);checkbox&&!checkbox.initialized&&(checkbox.initialized=!0,checkbox.addEventListener("change",(event=>{var installementsvalue=!1;installmentscheckbox&&(installementsvalue=installmentscheckbox.checked),event.currentTarget.checked?updateTotalPrice(userid,!0,installementsvalue):updateTotalPrice(userid,!1,installementsvalue)})));installmentscheckbox&&!installmentscheckbox.initialized&&(installmentscheckbox.initialized=!0,console.log("add event listener to installment"),installmentscheckbox.addEventListener("change",(event=>{console.log(event.currentTarget,event.currentTarget.checked),console.log(checkbox);let checkboxchecked=null;checkbox&&(checkboxchecked=checkbox.checked),updateTotalPrice(userid,checkboxchecked,event.currentTarget.checked)})))},_exports.visbilityevent=_exports.updateTotalPrice=_exports.reinit=_exports.interval=void 0,_ajax=_interopRequireDefault(_ajax),_templates=_interopRequireDefault(_templates),_modal_factory=_interopRequireDefault(_modal_factory),_modal_events=_interopRequireDefault(_modal_events),_dynamicform=_interopRequireDefault(_dynamicform);var _systemImportTransformerGlobalIdentifier="undefined"!=typeof window?window:"undefined"!=typeof self?self:"undefined"!=typeof global?global:{}; +define("local_shopping_cart/cart",["exports","core/ajax","core/templates","core/modal_factory","core/modal_events","local_shopping_cart/cashier","local_shopping_cart/notifications","core_form/dynamicform","core/str","./cashier"],(function(_exports,_ajax,_templates,_modal_factory,_modal_events,_cashier,_notifications,_dynamicform,_str,_cashier2){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.addItem=void 0,_exports.addItemShowNotification=addItemShowNotification,_exports.init=_exports.deleteItem=_exports.deleteAllItems=_exports.buttoninit=void 0,_exports.initPriceLabel=function(userid){console.log("initpricelabel"),userid<1&&(userid=0);const checkbox=document.querySelector(SELECTORS.PRICELABELCHECKBOX),installmentscheckbox=document.querySelector(SELECTORS.INSTALLMENTSCHECKBOX);checkbox&&!checkbox.initialized&&(checkbox.initialized=!0,checkbox.addEventListener("change",(event=>{var installementsvalue=!1;installmentscheckbox&&(installementsvalue=installmentscheckbox.checked),event.currentTarget.checked?updateTotalPrice(userid,!0,installementsvalue):updateTotalPrice(userid,!1,installementsvalue)})));installmentscheckbox&&!installmentscheckbox.initialized&&(installmentscheckbox.initialized=!0,console.log("add event listener to installment"),installmentscheckbox.addEventListener("change",(event=>{console.log(event.currentTarget,event.currentTarget.checked),console.log(checkbox);let checkboxchecked=null;checkbox&&(checkboxchecked=checkbox.checked),updateTotalPrice(userid,checkboxchecked,event.currentTarget.checked)})))},_exports.visbilityevent=_exports.updateTotalPrice=_exports.reinit=_exports.interval=void 0,_ajax=_interopRequireDefault(_ajax),_templates=_interopRequireDefault(_templates),_modal_factory=_interopRequireDefault(_modal_factory),_modal_events=_interopRequireDefault(_modal_events),_dynamicform=_interopRequireDefault(_dynamicform);var _systemImportTransformerGlobalIdentifier="undefined"!=typeof window?window:"undefined"!=typeof self?self:"undefined"!=typeof global?global:{}; /* * @package local_shopping_cart * @copyright Wunderbyte GmbH * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}var interval=_exports.interval=null,visbilityevent=_exports.visbilityevent=!1;const SELECTORS={SHOPPING_CART_ITEM:'[data-item="shopping_cart_item"]',NAVBARCONTAINER:"#nav-shopping_cart-popover-container .shopping-cart-items-container",TRASHCLASS:"fa-trash-o",DISCOUNTCLASS:"shoppingcart-discount-icon",BADGECOUNT:"#nav-shopping_cart-popover-container div.count-container",COUNTDOWN:"#nav-shopping_cart-popover-container span.expirationtime",CASHIERSCART:"div.shopping-cart-cashier-items-container",CHECKOUTCART:"div.shopping-cart-checkout-items-container",PRICELABELCHECKBOX:".sc_price_label input.usecredit-checkbox",INSTALLMENTSCHECKBOX:".sc_price_label input.useinstallments-checkbox",PRICELABELAREA:".sc_price_label",CHECKOUTBUTTON:"#nav-shopping_cart-popover-container #shopping-cart-checkout-button",PAYMENTREGIONBUTTON:"div.shopping_cart_payment_region button",ACCEPTTERMS:"#accepttermsnandconditions",CHECKVATNRFORM:"div.form_vatnrchecker"};_exports.init=(expirationtime,nowdate)=>{console.log(expirationtime,nowdate),initTimer(expirationtime,nowdate);let containers=[];containers=document.querySelectorAll(SELECTORS.NAVBARCONTAINER+","+SELECTORS.CASHIERSCART+","+SELECTORS.CHECKOUTCART),containers.forEach((container=>{container.addEventListener("click",(event=>{const element=event.target;if(element.classList.contains(SELECTORS.TRASHCLASS)){const userid=element.dataset.userid?element.dataset.userid:0,component=element.dataset.component,area=element.dataset.area,itemid=element.dataset.itemid;deleteItem(itemid,component,area,userid)}else element.classList.contains(SELECTORS.DISCOUNTCLASS)&&(0,_cashier.discountModal)(event)}))})),document.addEventListener("readystatechange",(()=>{"loading"!==document.readyState&&reinit()})),0==visbilityevent&&document.addEventListener("visibilitychange",(function(){_exports.visbilityevent=visbilityevent=!0,"visible"===document.visibilityState&&reinit()}));const paymentbutton=document.querySelector(SELECTORS.PAYMENTREGIONBUTTON);if(paymentbutton){addZeroPriceListener({price:paymentbutton.dataset.price,currency:paymentbutton.dataset.currency})}const accepttermsbutton=document.querySelector(SELECTORS.ACCEPTTERMS);accepttermsbutton&&paymentbutton&&function(accepttermsbutton,paymentbutton){accepttermsbutton.addEventListener("change",(event=>{event.currentTarget.checked?paymentbutton.disabled=!1:paymentbutton.disabled=!0}))}(accepttermsbutton,paymentbutton),initVATNRChecker()};const initVATNRChecker=()=>{const vatnrchecker=document.querySelector(SELECTORS.CHECKVATNRFORM);if(vatnrchecker){const vatnrcheckerform=new _dynamicform.default(vatnrchecker,"local_shopping_cart\\form\\dynamicvatnrchecker");vatnrcheckerform.addEventListener("change",(e=>{console.log(e.target.checked,e.target.name),e.target.name&&"usevatnr"==e.target.name&&!1===e.target.checked&&(console.log(e.target.value),vatnrcheckerform.submitFormAjax())})),vatnrcheckerform.addEventListener(vatnrcheckerform.events.FORM_SUBMITTED,(()=>{vatnrcheckerform.load(),console.log("form submitted"),reinit()}))}},buttoninit=(itemid,component,area)=>{if(!itemid||!component||!area){const selector='[data-objecttable="local_shopping_cart"';return void document.querySelectorAll(selector).forEach((button=>{const itemid=button.dataset.itemid,area=button.dataset.area,component=button.dataset.component;buttoninit(itemid,component,area)}))}document.querySelectorAll('div[data-itemid="'+itemid+'"][data-component="'+component+'"][data-area="'+area+'"][data-objecttable="local_shopping_cart"').forEach((addtocartbutton=>{toggleActiveButtonState(addtocartbutton),addtocartbutton&&"true"!==addtocartbutton.dataset.initialized&&(addtocartbutton.dataset.initialized="true",addtocartbutton.dataset.nojs||addtocartbutton.addEventListener("click",(event=>{"true"!=addtocartbutton.dataset.blocked&&(addtocartbutton.classList.contains("disabled")?(event.preventDefault(),event.stopPropagation()):addItem(itemid,component,area))})))}))};_exports.buttoninit=buttoninit;const reinit=function(){let userid=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;userid=transformUserIdForCashier(userid),_ajax.default.call([{methodname:"local_shopping_cart_get_shopping_cart_items",args:{userid:userid},done:function(data){const oncashier=window.location.href.indexOf("cashier.php");data.iscashier=oncashier>0;let containers=[];containers=0!=userid&&data.iscashier?document.querySelectorAll(SELECTORS.CASHIERSCART):document.querySelectorAll(SELECTORS.NAVBARCONTAINER+","+SELECTORS.CHECKOUTCART);let promises=[];convertPricesToNumberFormat(data),promises.push(_templates.default.renderForPromise("local_shopping_cart/shopping_cart_items",data).then((_ref=>{let{html:html,js:js}=_ref;return containers.forEach((container=>{_templates.default.replaceNodeContents(container,html,js)})),!0})).catch((e=>{console.log(e)}))),Promise.all(promises).then((()=>{0!=userid&&data.iscashier||(clearInterval(interval),initTimer(data.expirationtime,data.nowdate),function(count){const badge=document.querySelector(SELECTORS.BADGECOUNT);count>0?(badge.innerHTML=count,badge.classList.remove("hidden")):(badge.innerHTML=count,badge.classList.add("hidden"))}(data.count)),toggleActiveButtonState(),updateTotalPrice(userid),function(data){data.items.forEach((item=>{document.querySelectorAll('[data-itemid="'+item.itemid+'"][data-component="'+item.componentname+'"][data-area="'+item.area+'"][data-objecttable="local_shopping_cart"]').forEach((element=>{element.closest(".pricecontainer").querySelector("span.pricecurrency").innerHTML=item.price+" "+item.currency}))}))}(data)})).catch((e=>{console.log(e)}))},fail:ex=>{console.log("ex:"+ex)}}])};_exports.reinit=reinit;_exports.deleteAllItems=function(){let userid=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;_ajax.default.call([{methodname:"local_shopping_cart_delete_all_items_from_cart",args:{userid:userid},done:function(){reinit(0)},fail:function(ex){console.log(ex)}}])};const deleteItem=(itemid,component,area,userid)=>{userid=transformUserIdForCashier(userid),_ajax.default.call([{methodname:"local_shopping_cart_delete_item",args:{itemid:itemid,component:component,area:area,userid:userid},done:function(data){(0,_str.get_string)("item_deleted","local_shopping_cart",data.itemname).then((message=>{(0,_notifications.showNotification)(message,"success")})).catch((e=>{console.log(e)})),reinit(userid),("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["local_wunderbyte_table/reload"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("local_wunderbyte_table/reload")):Promise.resolve(_systemImportTransformerGlobalIdentifier["local_wunderbyte_table/reload"])).then((wbt=>{wbt.reloadAllTables()})).catch((err=>{console.log(err)}))},fail:function(){reinit(userid)}}])};_exports.deleteItem=deleteItem;const addItem=(itemid,component,area)=>{let userid=transformUserIdForCashier();Number.isInteger(userid)||(userid=parseInt(userid)),_ajax.default.call([{methodname:"local_shopping_cart_add_item",args:{area:area,component:component,itemid:itemid,userid:userid},done:function(data){data.component=component,data.area=area,data.itemid=itemid,data.userid=userid,addItemShowNotification(data)},fail:function(ex){console.log("error",ex)}}],!0)};_exports.addItem=addItem;const updateTotalPrice=function(){let userid=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,usecredit=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],useinstallments=arguments.length>2&&void 0!==arguments[2]&&arguments[2];window.location.href.indexOf("cashier.php")>0&&(userid=-1),Number.isInteger(userid)||(userid=parseInt(userid));const checkboxes=document.querySelectorAll(SELECTORS.PRICELABELCHECKBOX);1==checkboxes.length?checkboxes.forEach((checkbox=>{usecredit=checkbox.checked?1:0})):usecredit=usecredit?1:0,useinstallments=useinstallments?1:0,_ajax.default.call([{methodname:"local_shopping_cart_get_price",args:{userid:userid,usecredit:usecredit,useinstallments:useinstallments},done:function(data){1==data.usecredit?data.usecreditvalue="checked":data.usecreditvalue="",data.checkboxid=Math.random().toString(36).slice(2,5),data.installments.length>0&&(data.installmentscheckboxid="i"+data.checkboxid),data.userid=userid;const labelareas=document.querySelectorAll(SELECTORS.PRICELABELAREA);convertPricesToNumberFormat(data),_templates.default.renderForPromise("local_shopping_cart/price_label",data).then((_ref2=>{let{html:html,js:js}=_ref2;return labelareas.forEach((labelarea=>{labelarea.dataset.noupdate||(_templates.default.replaceNodeContents(labelarea,html,js),addZeroPriceListener(data))})),!0})).catch((e=>{console.log(e)}));const checkoutButton=document.querySelector(SELECTORS.CHECKOUTBUTTON),paymentbutton=document.querySelector(SELECTORS.PAYMENTREGIONBUTTON);0==data.count?(checkoutButton&&checkoutButton.classList.add("disabled"),paymentbutton&&(paymentbutton.style.display="none")):(checkoutButton&&checkoutButton.classList.remove("disabled"),paymentbutton&&(paymentbutton.style.display="inline"))},fail:function(ex){console.log("error",ex)}}],!0)};function addZeroPriceListener(data){let paymentbutton=document.querySelector(".shopping_cart_payment_region button");if(paymentbutton){if(paymentbutton.classList.contains("disabled"))return;const price=data.price,currency=data.currency;paymentbutton.dataset.cost=price+" "+currency,0==price?paymentbutton.addEventListener("click",dealWithZeroPrice):paymentbutton.removeEventListener("click",dealWithZeroPrice)}}function addItemShowNotification(data){switch(data.success){case 0:return void reinit();case 1:return(0,_str.get_string)("addedtocart","local_shopping_cart",data.itemname).then((message=>{(0,_notifications.showNotification)(message,"success")})).catch((e=>{console.log(e)})),void reinit(data.userid);case 2:return void(0,_str.get_strings)([{key:"cartisfull",component:"local_shopping_cart"},{key:"ok",component:"core"}]).then((strings=>(_modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL}).then((modal=>(modal.setBody(strings[0]),modal.setSaveButtonText(strings[1]),modal.show(),modal))).catch((e=>{console.log(e)})),!0))).catch((e=>{console.log(e)}));case 3:return void(0,_str.get_strings)([{key:"error:costcentertitle",component:"local_shopping_cart"},{key:"error:costcentersdonotmatch",component:"local_shopping_cart"},{key:"ok",component:"core"}]).then((strings=>(_modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL}).then((modal=>(modal.setTitle(strings[0]),modal.setBody(strings[1]),modal.setSaveButtonText(strings[2]),modal.show(),modal))).catch((e=>{console.log(e)})),!0))).catch((e=>{console.log(e)}));case 4:return void(0,_str.get_strings)([{key:"error:fullybookedtitle",component:"local_shopping_cart"},{key:"error:fullybooked",component:"local_shopping_cart"},{key:"ok",component:"core"}]).then((strings=>(_modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL}).then((modal=>(modal.setTitle(strings[0]),modal.setBody(strings[1]),modal.setSaveButtonText(strings[2]),modal.getRoot().on(_modal_events.default.save,(function(){window.location.reload()})),modal.show(),modal))).catch((e=>{console.log(e)})),!0))).catch((e=>{console.log(e)}));case 5:return void(0,_str.get_strings)([{key:"error:alreadybookedtitle",component:"local_shopping_cart"},{key:"error:alreadybooked",component:"local_shopping_cart"},{key:"ok",component:"core"}]).then((strings=>(_modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL}).then((modal=>(modal.setTitle(strings[0]),modal.setBody(strings[1]),modal.setSaveButtonText(strings[2]),modal.getRoot().on(_modal_events.default.save,(function(){window.location.reload()})),modal.show(),modal))).catch((e=>{console.log(e)})),!0))).catch((e=>{console.log(e)}));default:return void(0,_str.get_strings)([{key:"error:generalcarterror",component:"local_shopping_cart"},{key:"ok",component:"core"}]).then((strings=>(_modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL}).then((modal=>(modal.setBody(strings[0]),modal.setSaveButtonText(strings[1]),modal.show(),modal))).catch((e=>{console.log(e)})),!0))).catch((e=>{console.log(e)}))}}async function dealWithZeroPrice(event){var element;event.stopPropagation(),event.preventDefault(),element=event.target,(0,_str.get_strings)([{key:"confirmzeropricecheckouttitle",component:"local_shopping_cart"},{key:"confirmzeropricecheckoutbody",component:"local_shopping_cart"},{key:"confirmzeropricecheckout",component:"local_shopping_cart"}]).then((strings=>(_modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL}).then((modal=>(modal.setTitle(strings[0]),modal.setBody(strings[1]),modal.setSaveButtonText(strings[2]),modal.getRoot().on(_modal_events.default.save,(function(){const userid=element.dataset.userid;userid&&(0,_cashier.confirmPayment)(userid,2)})),modal.show(),modal))).catch((e=>{console.log(e)})),!0))).catch((e=>{console.log(e)}))}function initTimer(){let expirationtime=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,nowdate=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;const countdownelement=document.querySelector(SELECTORS.COUNTDOWN);if(!countdownelement||!nowdate)return;interval&&clearInterval(interval);let delta=0;var display,minutes,seconds,timer;expirationtime&&(delta=expirationtime-nowdate),delta<=0?(delta=0,countdownelement.classList.add("hidden")):delta>0&&(countdownelement.classList.remove("hidden"),display=countdownelement,timer=delta,_exports.interval=interval=setInterval((function(){minutes=parseInt(timer/60,10),seconds=parseInt(timer%60,10),minutes=minutes<10?"0"+minutes:minutes,seconds=seconds<10?"0"+seconds:seconds,display.textContent=minutes+":"+seconds,--timer<0&&(setTimeout((()=>{reinit(0)}),2e3),clearInterval(interval))}),1e3))}function toggleActiveButtonState(){let button=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,selector="",component=null,area=null,itemid=null;button?(itemid=button.dataset.itemid,component=button.dataset.component,area=button.dataset.area,selector='div[data-itemid="'+itemid+'"][data-component="'+component+'"][data-area="'+area+'"][data-objecttable="local_shopping_cart"'):selector='div[data-objecttable="local_shopping_cart"';const buttons=document.querySelectorAll(selector);let shoppingcart=document.querySelector(SELECTORS.CASHIERSCART);shoppingcart||(shoppingcart=document.querySelector(SELECTORS.NAVBARCONTAINER)),buttons.forEach((addtocartbutton=>{component=addtocartbutton.dataset.component,area=addtocartbutton.dataset.area,itemid=addtocartbutton.dataset.itemid;shoppingcart.querySelector('[id="item-'+component+"-"+area+"-"+itemid+'"]')?addtocartbutton.classList.add("disabled"):addtocartbutton.classList.remove("disabled")}))}function transformUserIdForCashier(){let userid=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;const oncashier=window.location.href.indexOf("cashier.php");return(-1==userid||0!==userid&&"0"!==userid)&&oncashier>0?userid=-1:null===userid&&(userid=0),Number.isInteger(userid)||(userid=parseInt(userid)),userid}function convertPricesToNumberFormat(data){if(data.price&&(data.price=Number(data.price).toFixed(2)),data.initialtotal&&(data.initialtotal=Number(data.initialtotal).toFixed(2)),data.initialtotal_net&&(data.initialtotal_net=Number(data.initialtotal_net).toFixed(2)),data.discount&&(data.discount=Number(data.discount).toFixed(2)),data.deductible&&(data.deductible=Number(data.deductible).toFixed(2)),data.credit&&(data.credit=Number(data.credit).toFixed(2)),data.remainingcredit&&(data.remainingcredit=Number(data.remainingcredit).toFixed(2)),data.price_net&&(data.price_net=Number(data.price_net).toFixed(2)),data.price_gross&&(data.price_gross=Number(data.price_gross).toFixed(2)),data.items)for(var i=0;i{console.log(expirationtime,nowdate),initTimer(expirationtime,nowdate);let containers=[];containers=document.querySelectorAll(SELECTORS.NAVBARCONTAINER+","+SELECTORS.CASHIERSCART+","+SELECTORS.CHECKOUTCART),containers.forEach((container=>{container.addEventListener("click",(event=>{const element=event.target;if(element.classList.contains(SELECTORS.TRASHCLASS)){const userid=element.dataset.userid?element.dataset.userid:0,component=element.dataset.component,area=element.dataset.area,itemid=element.dataset.itemid;deleteItem(itemid,component,area,userid)}else element.classList.contains(SELECTORS.DISCOUNTCLASS)?(0,_cashier.discountModal)(event):element.classList.contains(SELECTORS.MODIFYTIMECLASS)&&(0,_cashier2.modifyTimeModal)(event)}))})),document.addEventListener("readystatechange",(()=>{"loading"!==document.readyState&&reinit()})),0==visbilityevent&&document.addEventListener("visibilitychange",(function(){_exports.visbilityevent=visbilityevent=!0,"visible"===document.visibilityState&&reinit()}));const paymentbutton=document.querySelector(SELECTORS.PAYMENTREGIONBUTTON);if(paymentbutton){addZeroPriceListener({price:paymentbutton.dataset.price,currency:paymentbutton.dataset.currency})}const accepttermsbutton=document.querySelector(SELECTORS.ACCEPTTERMS);accepttermsbutton&&paymentbutton&&function(accepttermsbutton,paymentbutton){accepttermsbutton.addEventListener("change",(event=>{event.currentTarget.checked?paymentbutton.disabled=!1:paymentbutton.disabled=!0}))}(accepttermsbutton,paymentbutton),initVATNRChecker()};const initVATNRChecker=()=>{const vatnrchecker=document.querySelector(SELECTORS.CHECKVATNRFORM);if(vatnrchecker){const vatnrcheckerform=new _dynamicform.default(vatnrchecker,"local_shopping_cart\\form\\dynamicvatnrchecker");vatnrcheckerform.addEventListener("change",(e=>{console.log(e.target.checked,e.target.name),e.target.name&&"usevatnr"==e.target.name&&!1===e.target.checked&&(console.log(e.target.value),vatnrcheckerform.submitFormAjax())})),vatnrcheckerform.addEventListener(vatnrcheckerform.events.FORM_SUBMITTED,(()=>{vatnrcheckerform.load(),console.log("form submitted"),reinit()}))}},buttoninit=(itemid,component,area)=>{if(!itemid||!component||!area){const selector='[data-objecttable="local_shopping_cart"';return void document.querySelectorAll(selector).forEach((button=>{const itemid=button.dataset.itemid,area=button.dataset.area,component=button.dataset.component;buttoninit(itemid,component,area)}))}document.querySelectorAll('div[data-itemid="'+itemid+'"][data-component="'+component+'"][data-area="'+area+'"][data-objecttable="local_shopping_cart"').forEach((addtocartbutton=>{toggleActiveButtonState(addtocartbutton),addtocartbutton&&"true"!==addtocartbutton.dataset.initialized&&(addtocartbutton.dataset.initialized="true",addtocartbutton.dataset.nojs||addtocartbutton.addEventListener("click",(event=>{"true"!=addtocartbutton.dataset.blocked&&(addtocartbutton.classList.contains("disabled")?(event.preventDefault(),event.stopPropagation()):addItem(itemid,component,area))})))}))};_exports.buttoninit=buttoninit;const reinit=function(){let userid=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;userid=transformUserIdForCashier(userid),_ajax.default.call([{methodname:"local_shopping_cart_get_shopping_cart_items",args:{userid:userid},done:function(data){const oncashier=window.location.href.indexOf("cashier.php");data.iscashier=oncashier>0;let containers=[];containers=0!=userid&&data.iscashier?document.querySelectorAll(SELECTORS.CASHIERSCART):document.querySelectorAll(SELECTORS.NAVBARCONTAINER+","+SELECTORS.CHECKOUTCART);let promises=[];convertPricesToNumberFormat(data),promises.push(_templates.default.renderForPromise("local_shopping_cart/shopping_cart_items",data).then((_ref=>{let{html:html,js:js}=_ref;return containers.forEach((container=>{_templates.default.replaceNodeContents(container,html,js)})),!0})).catch((e=>{console.log(e)}))),Promise.all(promises).then((()=>{0!=userid&&data.iscashier||(clearInterval(interval),initTimer(data.expirationtime,data.nowdate),function(count){const badge=document.querySelector(SELECTORS.BADGECOUNT);count>0?(badge.innerHTML=count,badge.classList.remove("hidden")):(badge.innerHTML=count,badge.classList.add("hidden"))}(data.count)),toggleActiveButtonState(),updateTotalPrice(userid),function(data){data.items.forEach((item=>{document.querySelectorAll('[data-itemid="'+item.itemid+'"][data-component="'+item.componentname+'"][data-area="'+item.area+'"][data-objecttable="local_shopping_cart"]').forEach((element=>{element.closest(".pricecontainer").querySelector("span.pricecurrency").innerHTML=item.price+" "+item.currency}))}))}(data)})).catch((e=>{console.log(e)}))},fail:ex=>{console.log("ex:"+ex)}}])};_exports.reinit=reinit;_exports.deleteAllItems=function(){let userid=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;_ajax.default.call([{methodname:"local_shopping_cart_delete_all_items_from_cart",args:{userid:userid},done:function(){reinit(0)},fail:function(ex){console.log(ex)}}])};const deleteItem=(itemid,component,area,userid)=>{userid=transformUserIdForCashier(userid),_ajax.default.call([{methodname:"local_shopping_cart_delete_item",args:{itemid:itemid,component:component,area:area,userid:userid},done:function(data){(0,_str.get_string)("item_deleted","local_shopping_cart",data.itemname).then((message=>{(0,_notifications.showNotification)(message,"success")})).catch((e=>{console.log(e)})),reinit(userid),("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["local_wunderbyte_table/reload"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("local_wunderbyte_table/reload")):Promise.resolve(_systemImportTransformerGlobalIdentifier["local_wunderbyte_table/reload"])).then((wbt=>{wbt.reloadAllTables()})).catch((err=>{console.log(err)}))},fail:function(){reinit(userid)}}])};_exports.deleteItem=deleteItem;const addItem=(itemid,component,area)=>{let userid=transformUserIdForCashier();Number.isInteger(userid)||(userid=parseInt(userid)),_ajax.default.call([{methodname:"local_shopping_cart_add_item",args:{area:area,component:component,itemid:itemid,userid:userid},done:function(data){data.component=component,data.area=area,data.itemid=itemid,data.userid=userid,addItemShowNotification(data)},fail:function(ex){console.log("error",ex)}}],!0)};_exports.addItem=addItem;const updateTotalPrice=function(){let userid=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,usecredit=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],useinstallments=arguments.length>2&&void 0!==arguments[2]&&arguments[2];window.location.href.indexOf("cashier.php")>0&&(userid=-1),Number.isInteger(userid)||(userid=parseInt(userid));const checkboxes=document.querySelectorAll(SELECTORS.PRICELABELCHECKBOX);1==checkboxes.length?checkboxes.forEach((checkbox=>{usecredit=checkbox.checked?1:0})):usecredit=usecredit?1:0,useinstallments=useinstallments?1:0,_ajax.default.call([{methodname:"local_shopping_cart_get_price",args:{userid:userid,usecredit:usecredit,useinstallments:useinstallments},done:function(data){1==data.usecredit?data.usecreditvalue="checked":data.usecreditvalue="",data.checkboxid=Math.random().toString(36).slice(2,5),data.installments.length>0&&(data.installmentscheckboxid="i"+data.checkboxid),data.userid=userid;const labelareas=document.querySelectorAll(SELECTORS.PRICELABELAREA);convertPricesToNumberFormat(data),_templates.default.renderForPromise("local_shopping_cart/price_label",data).then((_ref2=>{let{html:html,js:js}=_ref2;return labelareas.forEach((labelarea=>{labelarea.dataset.noupdate||(_templates.default.replaceNodeContents(labelarea,html,js),addZeroPriceListener(data))})),!0})).catch((e=>{console.log(e)}));const checkoutButton=document.querySelector(SELECTORS.CHECKOUTBUTTON),paymentbutton=document.querySelector(SELECTORS.PAYMENTREGIONBUTTON);0==data.count?(checkoutButton&&checkoutButton.classList.add("disabled"),paymentbutton&&(paymentbutton.style.display="none")):(checkoutButton&&checkoutButton.classList.remove("disabled"),paymentbutton&&(paymentbutton.style.display="inline"))},fail:function(ex){console.log("error",ex)}}],!0)};function addZeroPriceListener(data){let paymentbutton=document.querySelector(".shopping_cart_payment_region button");if(paymentbutton){if(paymentbutton.classList.contains("disabled"))return;const price=data.price,currency=data.currency;paymentbutton.dataset.cost=price+" "+currency,0==price?paymentbutton.addEventListener("click",dealWithZeroPrice):paymentbutton.removeEventListener("click",dealWithZeroPrice)}}function addItemShowNotification(data){switch(data.success){case 0:return void reinit();case 1:return(0,_str.get_string)("addedtocart","local_shopping_cart",data.itemname).then((message=>{(0,_notifications.showNotification)(message,"success")})).catch((e=>{console.log(e)})),void reinit(data.userid);case 2:return void(0,_str.get_strings)([{key:"cartisfull",component:"local_shopping_cart"},{key:"ok",component:"core"}]).then((strings=>(_modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL}).then((modal=>(modal.setBody(strings[0]),modal.setSaveButtonText(strings[1]),modal.show(),modal))).catch((e=>{console.log(e)})),!0))).catch((e=>{console.log(e)}));case 3:return void(0,_str.get_strings)([{key:"error:costcentertitle",component:"local_shopping_cart"},{key:"error:costcentersdonotmatch",component:"local_shopping_cart"},{key:"ok",component:"core"}]).then((strings=>(_modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL}).then((modal=>(modal.setTitle(strings[0]),modal.setBody(strings[1]),modal.setSaveButtonText(strings[2]),modal.show(),modal))).catch((e=>{console.log(e)})),!0))).catch((e=>{console.log(e)}));case 4:return void(0,_str.get_strings)([{key:"error:fullybookedtitle",component:"local_shopping_cart"},{key:"error:fullybooked",component:"local_shopping_cart"},{key:"ok",component:"core"}]).then((strings=>(_modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL}).then((modal=>(modal.setTitle(strings[0]),modal.setBody(strings[1]),modal.setSaveButtonText(strings[2]),modal.getRoot().on(_modal_events.default.save,(function(){window.location.reload()})),modal.show(),modal))).catch((e=>{console.log(e)})),!0))).catch((e=>{console.log(e)}));case 5:return void(0,_str.get_strings)([{key:"error:alreadybookedtitle",component:"local_shopping_cart"},{key:"error:alreadybooked",component:"local_shopping_cart"},{key:"ok",component:"core"}]).then((strings=>(_modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL}).then((modal=>(modal.setTitle(strings[0]),modal.setBody(strings[1]),modal.setSaveButtonText(strings[2]),modal.getRoot().on(_modal_events.default.save,(function(){window.location.reload()})),modal.show(),modal))).catch((e=>{console.log(e)})),!0))).catch((e=>{console.log(e)}));default:return void(0,_str.get_strings)([{key:"error:generalcarterror",component:"local_shopping_cart"},{key:"ok",component:"core"}]).then((strings=>(_modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL}).then((modal=>(modal.setBody(strings[0]),modal.setSaveButtonText(strings[1]),modal.show(),modal))).catch((e=>{console.log(e)})),!0))).catch((e=>{console.log(e)}))}}async function dealWithZeroPrice(event){var element;event.stopPropagation(),event.preventDefault(),element=event.target,(0,_str.get_strings)([{key:"confirmzeropricecheckouttitle",component:"local_shopping_cart"},{key:"confirmzeropricecheckoutbody",component:"local_shopping_cart"},{key:"confirmzeropricecheckout",component:"local_shopping_cart"}]).then((strings=>(_modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL}).then((modal=>(modal.setTitle(strings[0]),modal.setBody(strings[1]),modal.setSaveButtonText(strings[2]),modal.getRoot().on(_modal_events.default.save,(function(){const userid=element.dataset.userid;userid&&(0,_cashier.confirmPayment)(userid,2)})),modal.show(),modal))).catch((e=>{console.log(e)})),!0))).catch((e=>{console.log(e)}))}function initTimer(){let expirationtime=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,nowdate=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;const countdownelement=document.querySelector(SELECTORS.COUNTDOWN);if(!countdownelement||!nowdate)return;interval&&clearInterval(interval);let delta=0;var display,minutes,seconds,timer;expirationtime&&(delta=expirationtime-nowdate),delta<=0?(delta=0,countdownelement.classList.add("hidden")):delta>0&&(countdownelement.classList.remove("hidden"),display=countdownelement,timer=delta,_exports.interval=interval=setInterval((function(){minutes=parseInt(timer/60,10),seconds=parseInt(timer%60,10),minutes=minutes<10?"0"+minutes:minutes,seconds=seconds<10?"0"+seconds:seconds,display.textContent=minutes+":"+seconds,--timer<0&&(setTimeout((()=>{reinit(0)}),2e3),clearInterval(interval))}),1e3))}function toggleActiveButtonState(){let button=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,selector="",component=null,area=null,itemid=null;button?(itemid=button.dataset.itemid,component=button.dataset.component,area=button.dataset.area,selector='div[data-itemid="'+itemid+'"][data-component="'+component+'"][data-area="'+area+'"][data-objecttable="local_shopping_cart"'):selector='div[data-objecttable="local_shopping_cart"';const buttons=document.querySelectorAll(selector);let shoppingcart=document.querySelector(SELECTORS.CASHIERSCART);shoppingcart||(shoppingcart=document.querySelector(SELECTORS.NAVBARCONTAINER)),buttons.forEach((addtocartbutton=>{component=addtocartbutton.dataset.component,area=addtocartbutton.dataset.area,itemid=addtocartbutton.dataset.itemid;shoppingcart.querySelector('[id="item-'+component+"-"+area+"-"+itemid+'"]')?addtocartbutton.classList.add("disabled"):addtocartbutton.classList.remove("disabled")}))}function transformUserIdForCashier(){let userid=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;const oncashier=window.location.href.indexOf("cashier.php");return(-1==userid||0!==userid&&"0"!==userid)&&oncashier>0?userid=-1:null===userid&&(userid=0),Number.isInteger(userid)||(userid=parseInt(userid)),userid}function convertPricesToNumberFormat(data){if(data.price&&(data.price=Number(data.price).toFixed(2)),data.initialtotal&&(data.initialtotal=Number(data.initialtotal).toFixed(2)),data.initialtotal_net&&(data.initialtotal_net=Number(data.initialtotal_net).toFixed(2)),data.discount&&(data.discount=Number(data.discount).toFixed(2)),data.deductible&&(data.deductible=Number(data.deductible).toFixed(2)),data.credit&&(data.credit=Number(data.credit).toFixed(2)),data.remainingcredit&&(data.remainingcredit=Number(data.remainingcredit).toFixed(2)),data.price_net&&(data.price_net=Number(data.price_net).toFixed(2)),data.price_gross&&(data.price_gross=Number(data.price_gross).toFixed(2)),data.items)for(var i=0;i.\n\n/*\n * @package local_shopping_cart\n * @copyright Wunderbyte GmbH \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport Templates from 'core/templates';\n\nimport ModalFactory from 'core/modal_factory';\nimport ModalEvents from 'core/modal_events';\n\nimport {confirmPayment} from 'local_shopping_cart/cashier';\nimport {discountModal} from 'local_shopping_cart/cashier';\nimport {showNotification} from 'local_shopping_cart/notifications';\n\nimport DynamicForm from 'core_form/dynamicform';\n\nimport {\n get_strings as getStrings,\n get_string as getString\n }\n from 'core/str';\n\nexport var interval = null;\nexport var visbilityevent = false;\n\n// This file inits the cart on every page, on checkout and cashier.\n// The cart is always loaed entirely and replaced via css.\n// The cashiers cart are identified in the DOM via userid -1 (CASHIERUSER).\n// The translation to real userids is done in the PHP only.\n\nconst CASHIERUSER = -1;\n\nconst SELECTORS = {\n SHOPPING_CART_ITEM: '[data-item=\"shopping_cart_item\"]',\n NAVBARCONTAINER: '#nav-shopping_cart-popover-container .shopping-cart-items-container',\n TRASHCLASS: 'fa-trash-o',\n DISCOUNTCLASS: 'shoppingcart-discount-icon',\n BADGECOUNT: '#nav-shopping_cart-popover-container div.count-container',\n COUNTDOWN: '#nav-shopping_cart-popover-container span.expirationtime',\n CASHIERSCART: 'div.shopping-cart-cashier-items-container',\n CHECKOUTCART: 'div.shopping-cart-checkout-items-container',\n PRICELABELCHECKBOX: '.sc_price_label input.usecredit-checkbox',\n INSTALLMENTSCHECKBOX: '.sc_price_label input.useinstallments-checkbox',\n PRICELABELAREA: '.sc_price_label',\n CHECKOUTBUTTON: '#nav-shopping_cart-popover-container #shopping-cart-checkout-button',\n PAYMENTREGIONBUTTON: 'div.shopping_cart_payment_region button',\n ACCEPTTERMS: '#accepttermsnandconditions',\n CHECKVATNRFORM: 'div.form_vatnrchecker',\n};\n/**\n *\n * @param {*} expirationtime\n */\n\n export const init = (expirationtime, nowdate) => {\n\n // eslint-disable-next-line no-console\n console.log(expirationtime, nowdate);\n\n initTimer(expirationtime, nowdate);\n\n // We might have more than one container.\n let containers = [];\n containers = document.querySelectorAll(SELECTORS.NAVBARCONTAINER\n + \",\" + SELECTORS.CASHIERSCART\n + \",\" + SELECTORS.CHECKOUTCART);\n\n containers.forEach(container => {\n\n container.addEventListener('click', event => {\n\n // Decide the target of the click.\n const element = event.target;\n\n if (element.classList.contains(SELECTORS.TRASHCLASS)) {\n\n const userid = element.dataset.userid ? element.dataset.userid : 0;\n const component = element.dataset.component;\n const area = element.dataset.area;\n const itemid = element.dataset.itemid;\n\n deleteItem(itemid, component, area, userid);\n } else if (element.classList.contains(SELECTORS.DISCOUNTCLASS)) {\n\n discountModal(event);\n }\n });\n });\n\n // Re-init cart on page reload or navigation to another page - required for 2-digit price precision visibility.\n document.addEventListener(\"readystatechange\", () => {\n if (document.readyState !== 'loading') {\n reinit();\n }\n });\n\n if (visbilityevent == false) {\n document.addEventListener(\"visibilitychange\", function() {\n visbilityevent = true;\n if (document.visibilityState === 'visible') {\n reinit();\n }\n });\n }\n\n // Initially, we need to add the zeroPriceListener once.\n const paymentbutton = document.querySelector(SELECTORS.PAYMENTREGIONBUTTON);\n if (paymentbutton) {\n const data = {\n price: paymentbutton.dataset.price,\n currency: paymentbutton.dataset.currency,\n };\n addZeroPriceListener(data);\n }\n\n const accepttermsbutton = document.querySelector(SELECTORS.ACCEPTTERMS);\n if (accepttermsbutton && paymentbutton) {\n addAcceptTermsListener(accepttermsbutton, paymentbutton);\n }\n\n initVATNRChecker();\n};\n\nconst initVATNRChecker = () => {\n\n const vatnrchecker = document.querySelector(SELECTORS.CHECKVATNRFORM);\n\n if (vatnrchecker) {\n const vatnrcheckerform = new DynamicForm(\n vatnrchecker,\n 'local_shopping_cart\\\\form\\\\dynamicvatnrchecker'\n );\n\n vatnrcheckerform.addEventListener('change', (e) => {\n\n // eslint-disable-next-line no-console\n console.log(e.target.checked, e.target.name);\n\n if (!e.target.name) {\n return;\n }\n\n if (e.target.name == 'usevatnr'\n && e.target.checked === false) {\n\n // eslint-disable-next-line no-console\n console.log(e.target.value);\n\n vatnrcheckerform.submitFormAjax();\n }\n });\n\n // After submitting we want to reload the window to update the rule list.\n vatnrcheckerform.addEventListener(vatnrcheckerform.events.FORM_SUBMITTED, () => {\n\n vatnrcheckerform.load();\n // eslint-disable-next-line no-console\n console.log('form submitted');\n\n reinit();\n });\n }\n\n};\n\nexport const buttoninit = (itemid, component, area) => {\n\n // If we don't have an itemid, we need to look for all the buttons.\n if (!itemid || !component || !area) {\n const selector = '[data-objecttable=\"local_shopping_cart\"';\n const allbuttons = document.querySelectorAll(\n selector);\n\n allbuttons.forEach(button => {\n const itemid = button.dataset.itemid;\n const area = button.dataset.area;\n const component = button.dataset.component;\n buttoninit(itemid, component, area);\n });\n return;\n }\n\n // Return all buttons with the add to cart functionality.\n const buttons =\n document.querySelectorAll(\n 'div'\n + '[data-itemid=\"' + itemid + '\"]'\n + '[data-component=\"' + component + '\"]'\n + '[data-area=\"' + area + '\"]'\n + '[data-objecttable=\"local_shopping_cart\"');\n\n buttons.forEach(addtocartbutton => {\n\n // We need to check all the buttons.\n toggleActiveButtonState(addtocartbutton);\n\n // We only ever initialize the button once.\n if (!addtocartbutton || addtocartbutton.dataset.initialized === 'true') {\n return;\n }\n addtocartbutton.dataset.initialized = 'true';\n\n // If the button has the nojs flag, we don't add the listener at all.\n\n if (addtocartbutton.dataset.nojs) {\n return;\n }\n\n // Add click eventlistern to oneself.\n addtocartbutton.addEventListener('click', event => {\n\n if (addtocartbutton.dataset.blocked == 'true') {\n return;\n }\n\n // If we find the disabled class, the click event is aborted.\n if (addtocartbutton.classList.contains('disabled')) {\n event.preventDefault();\n event.stopPropagation();\n // DeleteItem(itemid, component, area);\n } else {\n // Event.preventDefault();\n // Event.stopPropagation();\n addItem(itemid, component, area);\n }\n });\n });\n\n return;\n};\n\n/**\n * Function to reload the cart. We can pass on the certain component if we need to make sure that not only the cart is reloaded.\n * This is the case when adding or deleting a certain item and a special button has to be reset.\n * @param {*} userid\n */\nexport const reinit = (userid = 0) => {\n\n userid = transformUserIdForCashier(userid);\n\n Ajax.call([{\n methodname: \"local_shopping_cart_get_shopping_cart_items\",\n args: {\n userid\n },\n done: function(data) {\n\n // If we are on the cashier page, we add the possibility to add a discount to the cart items.\n const oncashier = window.location.href.indexOf(\"cashier.php\");\n\n if (oncashier > 0) {\n data.iscashier = true;\n } else {\n data.iscashier = false;\n }\n\n let containers = [];\n\n if (userid != 0 && data.iscashier) {\n containers = document.querySelectorAll(SELECTORS.CASHIERSCART);\n } else {\n containers = document.querySelectorAll(SELECTORS.NAVBARCONTAINER\n + \",\" + SELECTORS.CHECKOUTCART);\n }\n\n let promises = [];\n\n // Before rendering, we convert all prices to strings with 2 fixed decimals.\n convertPricesToNumberFormat(data);\n\n // We render for promise for all the containers.\n promises.push(Templates.renderForPromise('local_shopping_cart/shopping_cart_items', data).then(({html, js}) => {\n containers.forEach(container => {\n // We know we will always find the Navbar, so we can do this right away.\n Templates.replaceNodeContents(container, html, js);\n });\n return true;\n }).catch((e) => {\n // eslint-disable-next-line no-console\n console.log(e);\n }));\n\n Promise.all(promises).then(() => {\n\n // If we are on the cashier page, we add the possibility to add a discount to the cart items.\n if (!(userid != 0 && data.iscashier)) {\n clearInterval(interval);\n initTimer(data.expirationtime, data.nowdate);\n\n updateBadge(data.count);\n }\n\n toggleActiveButtonState();\n\n updateTotalPrice(userid);\n\n updateItemPrice(data);\n return;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n\n },\n fail: ex => {\n // eslint-disable-next-line no-console\n console.log(\"ex:\" + ex);\n },\n }]);\n};\n\n/**\n * Update item price.\n *\n * @param {mixed} data\n *\n */\nfunction updateItemPrice(data) {\n data.items.forEach(item => {\n document.querySelectorAll(\n '[data-itemid=\"'\n + item.itemid\n + '\"][data-component=\"'\n + item.componentname\n + '\"][data-area=\"'\n + item.area\n + '\"][data-objecttable=\"local_shopping_cart\"]'\n ).forEach(element => {\n const pricecontainer = element.closest(\".pricecontainer\");\n const pricecurrency = pricecontainer.querySelector(\"span.pricecurrency\");\n pricecurrency.innerHTML = item.price + \" \" + item.currency;\n });\n });\n}\n\n/**\n * This function is only called when the timer invalidates the cart.\n * If no userid is provided the logged in USER will be used.\n * The USER-user is chosen with the userid 0, we just reinit everything after sending.\n * @param {*} userid\n */\nexport const deleteAllItems = (userid = 0) => {\n Ajax.call([{\n methodname: \"local_shopping_cart_delete_all_items_from_cart\",\n args: {\n 'userid': userid\n },\n done: function() {\n reinit(0);\n },\n fail: function(ex) {\n // eslint-disable-next-line no-console\n console.log(ex);\n },\n }]);\n};\n\nexport const deleteItem = (itemid, component, area, userid) => {\n\n userid = transformUserIdForCashier(userid);\n\n Ajax.call([{\n methodname: \"local_shopping_cart_delete_item\",\n args: {\n 'itemid': itemid,\n 'component': component,\n 'area': area,\n 'userid': userid\n },\n done: function(data) {\n\n getString('item_deleted', 'local_shopping_cart', data.itemname).then(message => {\n showNotification(message, 'success');\n return;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n\n reinit(userid);\n\n import('local_wunderbyte_table/reload')\n // eslint-disable-next-line promise/always-return\n .then(wbt => {\n wbt.reloadAllTables();\n })\n .catch(err => {\n // Handle any errors, including if the module doesn't exist\n // eslint-disable-next-line no-console\n console.log(err);\n });\n\n },\n fail: function() {\n\n reinit(userid);\n },\n }]);\n};\n\nexport const addItem = (itemid, component, area) => {\n\n let userid = transformUserIdForCashier();\n\n if (!Number.isInteger(userid)) {\n userid = parseInt(userid);\n }\n\n Ajax.call([{\n methodname: \"local_shopping_cart_add_item\",\n args: {\n 'area': area,\n 'component': component,\n 'itemid': itemid,\n 'userid': userid\n },\n done: function(data) {\n data.component = component;\n data.area = area;\n data.itemid = itemid;\n data.userid = userid; // For the mustache template, we need to obey structure.\n addItemShowNotification(data);\n },\n fail: function(ex) {\n // eslint-disable-next-line no-console\n console.log('error', ex);\n }\n }], true);\n};\n\n/**\n *\n * @param {*} userid\n * @param {*} usecredit\n * @param {*} useinstallments\n */\nexport const updateTotalPrice = (userid = 0, usecredit = true, useinstallments = false) => {\n\n // On cashier, update price must always be for cashier user.\n const oncashier = window.location.href.indexOf(\"cashier.php\");\n\n if (oncashier > 0) {\n userid = CASHIERUSER;\n }\n\n if (!Number.isInteger(userid)) {\n userid = parseInt(userid);\n }\n\n // We must make sure the checkbox is only once visible on the site.\n const checkboxes = document.querySelectorAll(SELECTORS.PRICELABELCHECKBOX);\n\n if (checkboxes.length == 1) {\n checkboxes.forEach(checkbox => {\n usecredit = checkbox.checked ? 1 : 0;\n });\n } else {\n usecredit = usecredit ? 1 : 0;\n }\n useinstallments = useinstallments ? 1 : 0;\n\n Ajax.call([{\n methodname: \"local_shopping_cart_get_price\",\n args: {\n userid,\n usecredit,\n useinstallments\n },\n done: function(data) {\n\n // We take the usecredit value we receive from the server.\n if (data.usecredit == 1) {\n data.usecreditvalue = 'checked';\n } else {\n data.usecreditvalue = '';\n }\n\n data.checkboxid = Math.random().toString(36).slice(2, 5);\n\n if (data.installments.length > 0) {\n data.installmentscheckboxid = 'i' + data.checkboxid;\n }\n\n data.userid = userid;\n\n const labelareas = document.querySelectorAll(SELECTORS.PRICELABELAREA);\n\n // Before rendering, we convert all prices to strings with 2 fixed decimals.\n convertPricesToNumberFormat(data);\n\n Templates.renderForPromise('local_shopping_cart/price_label', data).then(({html, js}) => {\n\n labelareas.forEach(labelarea => {\n\n // There are labelareas we don't want to update.\n if (!labelarea.dataset.noupdate) {\n Templates.replaceNodeContents(labelarea, html, js);\n addZeroPriceListener(data);\n }\n });\n\n return true;\n }).catch((e => {\n // eslint-disable-next-line no-console\n console.log(e);\n }));\n\n const checkoutButton = document.querySelector(SELECTORS.CHECKOUTBUTTON);\n const paymentbutton = document.querySelector(SELECTORS.PAYMENTREGIONBUTTON);\n if (data.count == 0) {\n if (checkoutButton) {\n checkoutButton.classList.add(\"disabled\");\n }\n if (paymentbutton) {\n paymentbutton.style.display = \"none\";\n }\n } else {\n if (checkoutButton) {\n checkoutButton.classList.remove(\"disabled\");\n }\n if (paymentbutton) {\n paymentbutton.style.display = \"inline\";\n }\n }\n },\n fail: function(ex) {\n // eslint-disable-next-line no-console\n console.log('error', ex);\n }\n }], true);\n};\n\n/**\n * Looks for the payment buttun, updates cost and adds the listener.\n * @param {*} data\n */\nfunction addZeroPriceListener(data) {\n\n let paymentbutton = document.querySelector(\".shopping_cart_payment_region button\");\n\n if (paymentbutton) {\n\n if (paymentbutton.classList.contains('disabled')) {\n return;\n }\n\n const price = data.price;\n const currency = data.currency;\n\n paymentbutton.dataset.cost = price + \" \" + currency;\n\n if (price == 0) {\n\n paymentbutton.addEventListener('click', dealWithZeroPrice);\n } else {\n\n paymentbutton.removeEventListener('click', dealWithZeroPrice);\n }\n }\n}\n\n/**\n * Function to show notifications when items are added.\n * @param {*} data\n */\nexport function addItemShowNotification(data) {\n const CARTPARAM_ALREADYINCART = 0; // Already in cart.\n const CARTPARAM_SUCCESS = 1; // Item added to cart successfully.\n const CARTPARAM_CARTISFULL = 2; // Item added to cart successfully.\n const CARTPARAM_COSTCENTER = 3; // Item added to cart successfully.\n const CARTPARAM_FULLYBOOKED = 4; // Item not added because item is already fully booked.\n const CARTPARAM_ALREADYBOOKED = 5; // Item not added because item was already booked before.\n\n switch (data.success) {\n case CARTPARAM_ALREADYINCART:\n reinit();\n return;\n case CARTPARAM_SUCCESS:\n getString('addedtocart', 'local_shopping_cart', data.itemname).then(message => {\n showNotification(message, 'success');\n return;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n reinit(data.userid);\n return;\n case CARTPARAM_CARTISFULL:\n getStrings([\n {key: 'cartisfull', component: 'local_shopping_cart'},\n {key: 'ok', component: 'core'},\n ]).then(strings => {\n // eslint-disable-next-line promise/no-nesting\n ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}).then(modal => {\n modal.setBody(strings[0]);\n modal.setSaveButtonText(strings[1]);\n modal.show();\n return modal;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return true;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return;\n case CARTPARAM_COSTCENTER:\n getStrings([\n {key: 'error:costcentertitle', component: 'local_shopping_cart'},\n {key: 'error:costcentersdonotmatch', component: 'local_shopping_cart'},\n {key: 'ok', component: 'core'},\n ]).then(strings => {\n // eslint-disable-next-line promise/no-nesting\n ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}).then(modal => {\n modal.setTitle(strings[0]);\n modal.setBody(strings[1]);\n modal.setSaveButtonText(strings[2]);\n modal.show();\n return modal;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return true;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return;\n case CARTPARAM_FULLYBOOKED:\n getStrings([\n {key: 'error:fullybookedtitle', component: 'local_shopping_cart'},\n {key: 'error:fullybooked', component: 'local_shopping_cart'},\n {key: 'ok', component: 'core'},\n ]).then(strings => {\n // eslint-disable-next-line promise/no-nesting\n ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}).then(modal => {\n modal.setTitle(strings[0]);\n modal.setBody(strings[1]);\n modal.setSaveButtonText(strings[2]);\n\n // Reload when OK button is clicked.\n modal.getRoot().on(ModalEvents.save, function() {\n window.location.reload();\n });\n\n modal.show();\n return modal;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return true;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return;\n case CARTPARAM_ALREADYBOOKED:\n getStrings([\n {key: 'error:alreadybookedtitle', component: 'local_shopping_cart'},\n {key: 'error:alreadybooked', component: 'local_shopping_cart'},\n {key: 'ok', component: 'core'},\n ]).then(strings => {\n // eslint-disable-next-line promise/no-nesting\n ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}).then(modal => {\n modal.setTitle(strings[0]);\n modal.setBody(strings[1]);\n modal.setSaveButtonText(strings[2]);\n\n // Reload when OK button is clicked.\n modal.getRoot().on(ModalEvents.save, function() {\n window.location.reload();\n });\n\n modal.show();\n return modal;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return true;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return;\n default:\n getStrings([\n {key: 'error:generalcarterror', component: 'local_shopping_cart'},\n {key: 'ok', component: 'core'},\n ]).then(strings => {\n // eslint-disable-next-line promise/no-nesting\n ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}).then(modal => {\n modal.setBody(strings[0]);\n modal.setSaveButtonText(strings[1]);\n modal.show();\n return modal;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return true;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return;\n }\n\n}\n\n/**\n *\n * @param {*} event\n */\nasync function dealWithZeroPrice(event) {\n\n event.stopPropagation();\n event.preventDefault();\n\n confirmZeroPriceCheckoutModal(event.target);\n}\n\n/**\n * Start the timer.\n *\n * @param {integer} duration\n * @param {integer} display\n */\nfunction startTimer(duration, display) {\n\n var timer = duration,\n minutes,\n seconds;\n interval = setInterval(function() {\n\n minutes = parseInt(timer / 60, 10);\n seconds = parseInt(timer % 60, 10);\n\n minutes = minutes < 10 ? \"0\" + minutes : minutes;\n seconds = seconds < 10 ? \"0\" + seconds : seconds;\n\n display.textContent = minutes + \":\" + seconds;\n\n if (--timer < 0) {\n\n // We so the expiration time has already kicked in on the server.\n setTimeout(() => {\n reinit(0);\n }, 2000);\n\n // We don't actually need to make this call.\n // deleteAllItems();\n\n clearInterval(interval);\n }\n }, 1000);\n}\n\n\n/**\n * Initialize Timer.\n *\n * @param {integer} expirationtime\n * @param {integer} nowdate\n *\n */\nfunction initTimer(expirationtime = null, nowdate = null) {\n\n const countdownelement = document.querySelector(SELECTORS.COUNTDOWN);\n\n if (!countdownelement || !nowdate) {\n return;\n }\n\n if (interval) {\n clearInterval(interval);\n }\n let delta = 0;\n let now = nowdate;\n if (expirationtime) {\n delta = (expirationtime - now);\n }\n if (delta <= 0) {\n delta = 0;\n countdownelement.classList.add(\"hidden\");\n } else if (delta > 0) {\n countdownelement.classList.remove(\"hidden\");\n startTimer(delta, countdownelement);\n }\n}\n\n/**\n *\n * @param {*} element\n */\nfunction confirmZeroPriceCheckoutModal(element) {\n\n getStrings([\n {key: 'confirmzeropricecheckouttitle', component: 'local_shopping_cart'},\n {key: 'confirmzeropricecheckoutbody', component: 'local_shopping_cart'},\n {key: 'confirmzeropricecheckout', component: 'local_shopping_cart'}\n ]\n ).then(strings => {\n // eslint-disable-next-line promise/no-nesting\n ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}).then(modal => {\n\n modal.setTitle(strings[0]);\n modal.setBody(strings[1]);\n modal.setSaveButtonText(strings[2]);\n modal.getRoot().on(ModalEvents.save, function() {\n\n const userid = element.dataset.userid;\n\n if (userid) {\n // The second parameter designs the payment method.\n // In the cart, the constant PAYMENT_METHOD_CREDITS translates to 2.\n confirmPayment(userid, 2);\n }\n });\n\n modal.show();\n return modal;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return true;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n}\n\n/**\n * Function to update the page in the nav bar.\n * @param {*} count\n */\nfunction updateBadge(count) {\n\n const badge = document.querySelector(SELECTORS.BADGECOUNT);\n\n if (count > 0) {\n badge.innerHTML = count;\n badge.classList.remove('hidden');\n } else {\n badge.innerHTML = count;\n badge.classList.add('hidden');\n }\n}\n\n/**\n * Function to toggle the active state.\n * @param {*} button\n */\nfunction toggleActiveButtonState(button = null) {\n\n let selector = '';\n let component = null;\n let area = null;\n let itemid = null;\n\n // If we have a button, we only look for this particular itemid.\n if (button) {\n\n // We'll find the right variables in the DOM.\n itemid = button.dataset.itemid;\n component = button.dataset.component;\n area = button.dataset.area;\n\n selector =\n 'div'\n + '[data-itemid=\"' + itemid + '\"]'\n + '[data-component=\"' + component + '\"]'\n + '[data-area=\"' + area + '\"]'\n + '[data-objecttable=\"local_shopping_cart\"';\n } else {\n // As we might have more than one of these buttons, we always need to look for all of them in the document.\n // We will update for all the buttons we find.\n selector =\n 'div'\n + '[data-objecttable=\"local_shopping_cart\"';\n }\n\n const buttons = document.querySelectorAll(selector);\n\n // Make sure item is not yet in shopping cart. If so, add disabled class.\n let shoppingcart = document.querySelector(SELECTORS.CASHIERSCART);\n\n if (!shoppingcart) {\n shoppingcart = document.querySelector(SELECTORS.NAVBARCONTAINER);\n }\n\n buttons.forEach(addtocartbutton => {\n\n component = addtocartbutton.dataset.component;\n area = addtocartbutton.dataset.area;\n itemid = addtocartbutton.dataset.itemid;\n\n const cartitem = shoppingcart.querySelector('[id=\"item-' + component + '-' + area + '-' + itemid + '\"]');\n\n if (cartitem) {\n\n addtocartbutton.classList.add('disabled');\n } else {\n\n addtocartbutton.classList.remove('disabled');\n }\n });\n}\n\n/**\n * Function to init Price Label and add Listener.\n * @param {*} userid\n */\nexport function initPriceLabel(userid) {\n\n // eslint-disable-next-line no-console\n console.log('initpricelabel');\n\n if (userid < 1) {\n userid = 0;\n }\n\n const checkbox = document.querySelector(SELECTORS.PRICELABELCHECKBOX);\n const installmentscheckbox = document.querySelector(SELECTORS.INSTALLMENTSCHECKBOX);\n\n if (checkbox && !checkbox.initialized) {\n checkbox.initialized = true;\n checkbox.addEventListener('change', event => {\n\n var installementsvalue = false;\n if (installmentscheckbox) {\n installementsvalue = installmentscheckbox.checked;\n }\n\n if (event.currentTarget.checked) {\n updateTotalPrice(userid, true, installementsvalue);\n } else {\n updateTotalPrice(userid, false, installementsvalue);\n }\n });\n }\n\n if (installmentscheckbox && !installmentscheckbox.initialized) {\n installmentscheckbox.initialized = true;\n\n // eslint-disable-next-line no-console\n console.log('add event listener to installment');\n installmentscheckbox.addEventListener('change', event => {\n\n // eslint-disable-next-line no-console\n console.log(event.currentTarget, event.currentTarget.checked);\n\n // eslint-disable-next-line no-console\n console.log(checkbox);\n\n let checkboxchecked = null;\n if (checkbox) {\n checkboxchecked = checkbox.checked;\n }\n\n updateTotalPrice(userid, checkboxchecked, event.currentTarget.checked);\n\n });\n }\n}\n\n/**\n * We need to know if we are on the cashier page to transform userid if necessary.\n * @param {integer} userid\n * @returns {integer}\n */\nfunction transformUserIdForCashier(userid = null) {\n\n const oncashier = window.location.href.indexOf(\"cashier.php\");\n\n if ((userid == CASHIERUSER || !(userid === 0 || userid === \"0\")) && oncashier > 0) {\n userid = CASHIERUSER;\n } else if (userid === null) {\n userid = 0;\n }\n\n if (!Number.isInteger(userid)) {\n userid = parseInt(userid);\n }\n\n return userid;\n}\n\n/**\n * Helper function to convert prices to number format before rendering.\n * @param {Object} data the data containing the price values\n */\nfunction convertPricesToNumberFormat(data) {\n // Render all prices to 2 fixed decimals.\n if (data.price) {\n data.price = Number(data.price).toFixed(2);\n }\n if (data.initialtotal) {\n data.initialtotal = Number(data.initialtotal).toFixed(2);\n }\n if (data.initialtotal_net) {\n // eslint-disable-next-line camelcase\n data.initialtotal_net = Number(data.initialtotal_net).toFixed(2);\n }\n if (data.discount) {\n data.discount = Number(data.discount).toFixed(2);\n }\n if (data.deductible) {\n data.deductible = Number(data.deductible).toFixed(2);\n }\n if (data.credit) {\n data.credit = Number(data.credit).toFixed(2);\n }\n if (data.remainingcredit) {\n data.remainingcredit = Number(data.remainingcredit).toFixed(2);\n }\n if (data.price_net) {\n // eslint-disable-next-line camelcase\n data.price_net = Number(data.price_net).toFixed(2);\n }\n if (data.price_gross) {\n // eslint-disable-next-line camelcase\n data.price_gross = Number(data.price_gross).toFixed(2);\n }\n if (data.items) {\n for (var i = 0; i < data.items.length; i++) {\n if (data.items[i].price) {\n data.items[i].price = Number(data.items[i].price).toFixed(2);\n }\n if (data.items[i].price_gross) {\n // eslint-disable-next-line camelcase\n data.items[i].price_gross = Number(data.items[i].price_gross).toFixed(2);\n }\n if (data.items[i].price_net) {\n // eslint-disable-next-line camelcase\n data.items[i].price_net = Number(data.items[i].price_net).toFixed(2);\n }\n }\n }\n}\n\n/**\n * Add Accept terms listener to set the right class to payment region button.\n * @param {element} accepttermsbutton\n * @param {element} paymentbutton\n */\nfunction addAcceptTermsListener(accepttermsbutton, paymentbutton) {\n\n accepttermsbutton.addEventListener('change', event => {\n if (event.currentTarget.checked) {\n paymentbutton.disabled = false;\n } else {\n paymentbutton.disabled = true;\n }\n });\n}"],"names":["userid","console","log","checkbox","document","querySelector","SELECTORS","PRICELABELCHECKBOX","installmentscheckbox","INSTALLMENTSCHECKBOX","initialized","addEventListener","event","installementsvalue","checked","currentTarget","updateTotalPrice","checkboxchecked","_ajax","_interopRequireDefault","_templates","_modal_factory","_modal_events","_dynamicform","_systemImportTransformerGlobalIdentifier","window","self","global","e","__esModule","default","interval","_exports","visbilityevent","SHOPPING_CART_ITEM","NAVBARCONTAINER","TRASHCLASS","DISCOUNTCLASS","BADGECOUNT","COUNTDOWN","CASHIERSCART","CHECKOUTCART","PRICELABELAREA","CHECKOUTBUTTON","PAYMENTREGIONBUTTON","ACCEPTTERMS","CHECKVATNRFORM","init","expirationtime","nowdate","initTimer","containers","querySelectorAll","forEach","container","element","target","classList","contains","dataset","component","area","itemid","deleteItem","discountModal","readyState","reinit","visibilityState","paymentbutton","addZeroPriceListener","price","currency","accepttermsbutton","disabled","addAcceptTermsListener","initVATNRChecker","vatnrchecker","vatnrcheckerform","DynamicForm","name","value","submitFormAjax","events","FORM_SUBMITTED","load","buttoninit","selector","button","addtocartbutton","toggleActiveButtonState","nojs","blocked","preventDefault","stopPropagation","addItem","arguments","length","undefined","transformUserIdForCashier","Ajax","call","methodname","args","done","data","oncashier","location","href","indexOf","iscashier","promises","convertPricesToNumberFormat","push","Templates","renderForPromise","then","_ref","html","js","replaceNodeContents","catch","Promise","all","clearInterval","count","badge","innerHTML","remove","add","updateBadge","items","item","componentname","closest","updateItemPrice","fail","ex","deleteAllItems","getString","get_string","itemname","message","showNotification","define","amd","resolve","reject","require","module","exports","loader","wbt","reloadAllTables","err","Number","isInteger","parseInt","addItemShowNotification","usecredit","useinstallments","checkboxes","usecreditvalue","checkboxid","Math","random","toString","slice","installments","installmentscheckboxid","labelareas","_ref2","labelarea","noupdate","checkoutButton","style","display","cost","dealWithZeroPrice","removeEventListener","success","getStrings","key","strings","ModalFactory","create","type","types","SAVE_CANCEL","modal","setBody","setSaveButtonText","show","setTitle","getRoot","on","ModalEvents","save","reload","async","confirmPayment","countdownelement","delta","minutes","seconds","timer","setInterval","textContent","setTimeout","buttons","shoppingcart","toFixed","initialtotal","initialtotal_net","discount","deductible","credit","remainingcredit","price_net","price_gross","i"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"cart.min.js","sources":["../src/cart.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/*\n * @package local_shopping_cart\n * @copyright Wunderbyte GmbH \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport Templates from 'core/templates';\n\nimport ModalFactory from 'core/modal_factory';\nimport ModalEvents from 'core/modal_events';\n\nimport {confirmPayment} from 'local_shopping_cart/cashier';\nimport {discountModal} from 'local_shopping_cart/cashier';\nimport {showNotification} from 'local_shopping_cart/notifications';\n\nimport DynamicForm from 'core_form/dynamicform';\n\nimport {\n get_strings as getStrings,\n get_string as getString\n }\n from 'core/str';\nimport {modifyTimeModal} from './cashier';\n\nexport var interval = null;\nexport var visbilityevent = false;\n\n// This file inits the cart on every page, on checkout and cashier.\n// The cart is always loaed entirely and replaced via css.\n// The cashiers cart are identified in the DOM via userid -1 (CASHIERUSER).\n// The translation to real userids is done in the PHP only.\n\nconst CASHIERUSER = -1;\n\nconst SELECTORS = {\n SHOPPING_CART_ITEM: '[data-item=\"shopping_cart_item\"]',\n NAVBARCONTAINER: '#nav-shopping_cart-popover-container .shopping-cart-items-container',\n TRASHCLASS: 'fa-trash-o',\n DISCOUNTCLASS: 'shoppingcart-discount-icon',\n MODIFYTIMECLASS: 'shoppingcart-modifytime-icon',\n BADGECOUNT: '#nav-shopping_cart-popover-container div.count-container',\n COUNTDOWN: '#nav-shopping_cart-popover-container span.expirationtime',\n CASHIERSCART: 'div.shopping-cart-cashier-items-container',\n CHECKOUTCART: 'div.shopping-cart-checkout-items-container',\n PRICELABELCHECKBOX: '.sc_price_label input.usecredit-checkbox',\n INSTALLMENTSCHECKBOX: '.sc_price_label input.useinstallments-checkbox',\n PRICELABELAREA: '.sc_price_label',\n CHECKOUTBUTTON: '#nav-shopping_cart-popover-container #shopping-cart-checkout-button',\n PAYMENTREGIONBUTTON: 'div.shopping_cart_payment_region button',\n ACCEPTTERMS: '#accepttermsandconditions',\n CHECKVATNRFORM: 'div.form_vatnrchecker',\n};\n/**\n *\n * @param {*} expirationtime\n */\n\n export const init = (expirationtime, nowdate) => {\n\n // eslint-disable-next-line no-console\n console.log(expirationtime, nowdate);\n\n initTimer(expirationtime, nowdate);\n\n // We might have more than one container.\n let containers = [];\n containers = document.querySelectorAll(SELECTORS.NAVBARCONTAINER\n + \",\" + SELECTORS.CASHIERSCART\n + \",\" + SELECTORS.CHECKOUTCART);\n\n containers.forEach(container => {\n\n container.addEventListener('click', event => {\n\n // Decide the target of the click.\n const element = event.target;\n\n if (element.classList.contains(SELECTORS.TRASHCLASS)) {\n\n const userid = element.dataset.userid ? element.dataset.userid : 0;\n const component = element.dataset.component;\n const area = element.dataset.area;\n const itemid = element.dataset.itemid;\n\n deleteItem(itemid, component, area, userid);\n } else if (element.classList.contains(SELECTORS.DISCOUNTCLASS)) {\n discountModal(event);\n } else if (element.classList.contains(SELECTORS.MODIFYTIMECLASS)) {\n modifyTimeModal(event);\n }\n });\n });\n\n // Re-init cart on page reload or navigation to another page - required for 2-digit price precision visibility.\n document.addEventListener(\"readystatechange\", () => {\n if (document.readyState !== 'loading') {\n reinit();\n }\n });\n\n if (visbilityevent == false) {\n document.addEventListener(\"visibilitychange\", function() {\n visbilityevent = true;\n if (document.visibilityState === 'visible') {\n reinit();\n }\n });\n }\n\n // Initially, we need to add the zeroPriceListener once.\n const paymentbutton = document.querySelector(SELECTORS.PAYMENTREGIONBUTTON);\n if (paymentbutton) {\n const data = {\n price: paymentbutton.dataset.price,\n currency: paymentbutton.dataset.currency,\n };\n addZeroPriceListener(data);\n }\n\n const accepttermsbutton = document.querySelector(SELECTORS.ACCEPTTERMS);\n if (accepttermsbutton && paymentbutton) {\n addAcceptTermsListener(accepttermsbutton, paymentbutton);\n }\n\n initVATNRChecker();\n};\n\nconst initVATNRChecker = () => {\n\n const vatnrchecker = document.querySelector(SELECTORS.CHECKVATNRFORM);\n\n if (vatnrchecker) {\n const vatnrcheckerform = new DynamicForm(\n vatnrchecker,\n 'local_shopping_cart\\\\form\\\\dynamicvatnrchecker'\n );\n\n vatnrcheckerform.addEventListener('change', (e) => {\n\n // eslint-disable-next-line no-console\n console.log(e.target.checked, e.target.name);\n\n if (!e.target.name) {\n return;\n }\n\n if (e.target.name == 'usevatnr'\n && e.target.checked === false) {\n\n // eslint-disable-next-line no-console\n console.log(e.target.value);\n\n vatnrcheckerform.submitFormAjax();\n }\n });\n\n // After submitting we want to reload the window to update the rule list.\n vatnrcheckerform.addEventListener(vatnrcheckerform.events.FORM_SUBMITTED, () => {\n\n vatnrcheckerform.load();\n // eslint-disable-next-line no-console\n console.log('form submitted');\n\n reinit();\n });\n }\n\n};\n\nexport const buttoninit = (itemid, component, area) => {\n\n // If we don't have an itemid, we need to look for all the buttons.\n if (!itemid || !component || !area) {\n const selector = '[data-objecttable=\"local_shopping_cart\"';\n const allbuttons = document.querySelectorAll(\n selector);\n\n allbuttons.forEach(button => {\n const itemid = button.dataset.itemid;\n const area = button.dataset.area;\n const component = button.dataset.component;\n buttoninit(itemid, component, area);\n });\n return;\n }\n\n // Return all buttons with the add to cart functionality.\n const buttons =\n document.querySelectorAll(\n 'div'\n + '[data-itemid=\"' + itemid + '\"]'\n + '[data-component=\"' + component + '\"]'\n + '[data-area=\"' + area + '\"]'\n + '[data-objecttable=\"local_shopping_cart\"');\n\n buttons.forEach(addtocartbutton => {\n\n // We need to check all the buttons.\n toggleActiveButtonState(addtocartbutton);\n\n // We only ever initialize the button once.\n if (!addtocartbutton || addtocartbutton.dataset.initialized === 'true') {\n return;\n }\n addtocartbutton.dataset.initialized = 'true';\n\n // If the button has the nojs flag, we don't add the listener at all.\n\n if (addtocartbutton.dataset.nojs) {\n return;\n }\n\n // Add click eventlistern to oneself.\n addtocartbutton.addEventListener('click', event => {\n\n if (addtocartbutton.dataset.blocked == 'true') {\n return;\n }\n\n // If we find the disabled class, the click event is aborted.\n if (addtocartbutton.classList.contains('disabled')) {\n event.preventDefault();\n event.stopPropagation();\n // DeleteItem(itemid, component, area);\n } else {\n // Event.preventDefault();\n // Event.stopPropagation();\n addItem(itemid, component, area);\n }\n });\n });\n\n return;\n};\n\n/**\n * Function to reload the cart. We can pass on the certain component if we need to make sure that not only the cart is reloaded.\n * This is the case when adding or deleting a certain item and a special button has to be reset.\n * @param {*} userid\n */\nexport const reinit = (userid = 0) => {\n\n userid = transformUserIdForCashier(userid);\n\n Ajax.call([{\n methodname: \"local_shopping_cart_get_shopping_cart_items\",\n args: {\n userid\n },\n done: function(data) {\n\n // If we are on the cashier page, we add the possibility to add a discount to the cart items.\n const oncashier = window.location.href.indexOf(\"cashier.php\");\n\n if (oncashier > 0) {\n data.iscashier = true;\n } else {\n data.iscashier = false;\n }\n\n let containers = [];\n\n if (userid != 0 && data.iscashier) {\n containers = document.querySelectorAll(SELECTORS.CASHIERSCART);\n } else {\n containers = document.querySelectorAll(SELECTORS.NAVBARCONTAINER\n + \",\" + SELECTORS.CHECKOUTCART);\n }\n\n let promises = [];\n\n // Before rendering, we convert all prices to strings with 2 fixed decimals.\n convertPricesToNumberFormat(data);\n\n // We render for promise for all the containers.\n promises.push(Templates.renderForPromise('local_shopping_cart/shopping_cart_items', data).then(({html, js}) => {\n containers.forEach(container => {\n // We know we will always find the Navbar, so we can do this right away.\n Templates.replaceNodeContents(container, html, js);\n });\n return true;\n }).catch((e) => {\n // eslint-disable-next-line no-console\n console.log(e);\n }));\n\n Promise.all(promises).then(() => {\n\n // If we are on the cashier page, we add the possibility to add a discount to the cart items.\n if (!(userid != 0 && data.iscashier)) {\n clearInterval(interval);\n initTimer(data.expirationtime, data.nowdate);\n\n updateBadge(data.count);\n }\n\n toggleActiveButtonState();\n\n updateTotalPrice(userid);\n\n updateItemPrice(data);\n return;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n\n },\n fail: ex => {\n // eslint-disable-next-line no-console\n console.log(\"ex:\" + ex);\n },\n }]);\n};\n\n/**\n * Update item price.\n *\n * @param {mixed} data\n *\n */\nfunction updateItemPrice(data) {\n data.items.forEach(item => {\n document.querySelectorAll(\n '[data-itemid=\"'\n + item.itemid\n + '\"][data-component=\"'\n + item.componentname\n + '\"][data-area=\"'\n + item.area\n + '\"][data-objecttable=\"local_shopping_cart\"]'\n ).forEach(element => {\n const pricecontainer = element.closest(\".pricecontainer\");\n const pricecurrency = pricecontainer.querySelector(\"span.pricecurrency\");\n pricecurrency.innerHTML = item.price + \" \" + item.currency;\n });\n });\n}\n\n/**\n * This function is only called when the timer invalidates the cart.\n * If no userid is provided the logged in USER will be used.\n * The USER-user is chosen with the userid 0, we just reinit everything after sending.\n * @param {*} userid\n */\nexport const deleteAllItems = (userid = 0) => {\n Ajax.call([{\n methodname: \"local_shopping_cart_delete_all_items_from_cart\",\n args: {\n 'userid': userid\n },\n done: function() {\n reinit(0);\n },\n fail: function(ex) {\n // eslint-disable-next-line no-console\n console.log(ex);\n },\n }]);\n};\n\nexport const deleteItem = (itemid, component, area, userid) => {\n\n userid = transformUserIdForCashier(userid);\n\n Ajax.call([{\n methodname: \"local_shopping_cart_delete_item\",\n args: {\n 'itemid': itemid,\n 'component': component,\n 'area': area,\n 'userid': userid\n },\n done: function(data) {\n\n getString('item_deleted', 'local_shopping_cart', data.itemname).then(message => {\n showNotification(message, 'success');\n return;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n\n reinit(userid);\n\n import('local_wunderbyte_table/reload')\n // eslint-disable-next-line promise/always-return\n .then(wbt => {\n wbt.reloadAllTables();\n })\n .catch(err => {\n // Handle any errors, including if the module doesn't exist\n // eslint-disable-next-line no-console\n console.log(err);\n });\n\n },\n fail: function() {\n\n reinit(userid);\n },\n }]);\n};\n\nexport const addItem = (itemid, component, area) => {\n\n let userid = transformUserIdForCashier();\n\n if (!Number.isInteger(userid)) {\n userid = parseInt(userid);\n }\n\n Ajax.call([{\n methodname: \"local_shopping_cart_add_item\",\n args: {\n 'area': area,\n 'component': component,\n 'itemid': itemid,\n 'userid': userid\n },\n done: function(data) {\n data.component = component;\n data.area = area;\n data.itemid = itemid;\n data.userid = userid; // For the mustache template, we need to obey structure.\n addItemShowNotification(data);\n },\n fail: function(ex) {\n // eslint-disable-next-line no-console\n console.log('error', ex);\n }\n }], true);\n};\n\n/**\n *\n * @param {*} userid\n * @param {*} usecredit\n * @param {*} useinstallments\n */\nexport const updateTotalPrice = (userid = 0, usecredit = true, useinstallments = false) => {\n\n // On cashier, update price must always be for cashier user.\n const oncashier = window.location.href.indexOf(\"cashier.php\");\n\n if (oncashier > 0) {\n userid = CASHIERUSER;\n }\n\n if (!Number.isInteger(userid)) {\n userid = parseInt(userid);\n }\n\n // We must make sure the checkbox is only once visible on the site.\n const checkboxes = document.querySelectorAll(SELECTORS.PRICELABELCHECKBOX);\n\n if (checkboxes.length == 1) {\n checkboxes.forEach(checkbox => {\n usecredit = checkbox.checked ? 1 : 0;\n });\n } else {\n usecredit = usecredit ? 1 : 0;\n }\n useinstallments = useinstallments ? 1 : 0;\n\n Ajax.call([{\n methodname: \"local_shopping_cart_get_price\",\n args: {\n userid,\n usecredit,\n useinstallments\n },\n done: function(data) {\n\n // We take the usecredit value we receive from the server.\n if (data.usecredit == 1) {\n data.usecreditvalue = 'checked';\n } else {\n data.usecreditvalue = '';\n }\n\n data.checkboxid = Math.random().toString(36).slice(2, 5);\n\n if (data.installments.length > 0) {\n data.installmentscheckboxid = 'i' + data.checkboxid;\n }\n\n data.userid = userid;\n\n const labelareas = document.querySelectorAll(SELECTORS.PRICELABELAREA);\n\n // Before rendering, we convert all prices to strings with 2 fixed decimals.\n convertPricesToNumberFormat(data);\n\n Templates.renderForPromise('local_shopping_cart/price_label', data).then(({html, js}) => {\n\n labelareas.forEach(labelarea => {\n\n // There are labelareas we don't want to update.\n if (!labelarea.dataset.noupdate) {\n Templates.replaceNodeContents(labelarea, html, js);\n addZeroPriceListener(data);\n }\n });\n\n return true;\n }).catch((e => {\n // eslint-disable-next-line no-console\n console.log(e);\n }));\n\n const checkoutButton = document.querySelector(SELECTORS.CHECKOUTBUTTON);\n const paymentbutton = document.querySelector(SELECTORS.PAYMENTREGIONBUTTON);\n if (data.count == 0) {\n if (checkoutButton) {\n checkoutButton.classList.add(\"disabled\");\n }\n if (paymentbutton) {\n paymentbutton.style.display = \"none\";\n }\n } else {\n if (checkoutButton) {\n checkoutButton.classList.remove(\"disabled\");\n }\n if (paymentbutton) {\n paymentbutton.style.display = \"inline\";\n }\n }\n },\n fail: function(ex) {\n // eslint-disable-next-line no-console\n console.log('error', ex);\n }\n }], true);\n};\n\n/**\n * Looks for the payment buttun, updates cost and adds the listener.\n * @param {*} data\n */\nfunction addZeroPriceListener(data) {\n\n let paymentbutton = document.querySelector(\".shopping_cart_payment_region button\");\n\n if (paymentbutton) {\n\n if (paymentbutton.classList.contains('disabled')) {\n return;\n }\n\n const price = data.price;\n const currency = data.currency;\n\n paymentbutton.dataset.cost = price + \" \" + currency;\n\n if (price == 0) {\n\n paymentbutton.addEventListener('click', dealWithZeroPrice);\n } else {\n\n paymentbutton.removeEventListener('click', dealWithZeroPrice);\n }\n }\n}\n\n/**\n * Function to show notifications when items are added.\n * @param {*} data\n */\nexport function addItemShowNotification(data) {\n const CARTPARAM_ALREADYINCART = 0; // Already in cart.\n const CARTPARAM_SUCCESS = 1; // Item added to cart successfully.\n const CARTPARAM_CARTISFULL = 2; // Item added to cart successfully.\n const CARTPARAM_COSTCENTER = 3; // Item added to cart successfully.\n const CARTPARAM_FULLYBOOKED = 4; // Item not added because item is already fully booked.\n const CARTPARAM_ALREADYBOOKED = 5; // Item not added because item was already booked before.\n\n switch (data.success) {\n case CARTPARAM_ALREADYINCART:\n reinit();\n return;\n case CARTPARAM_SUCCESS:\n getString('addedtocart', 'local_shopping_cart', data.itemname).then(message => {\n showNotification(message, 'success');\n return;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n reinit(data.userid);\n return;\n case CARTPARAM_CARTISFULL:\n getStrings([\n {key: 'cartisfull', component: 'local_shopping_cart'},\n {key: 'ok', component: 'core'},\n ]).then(strings => {\n // eslint-disable-next-line promise/no-nesting\n ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}).then(modal => {\n modal.setBody(strings[0]);\n modal.setSaveButtonText(strings[1]);\n modal.show();\n return modal;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return true;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return;\n case CARTPARAM_COSTCENTER:\n getStrings([\n {key: 'error:costcentertitle', component: 'local_shopping_cart'},\n {key: 'error:costcentersdonotmatch', component: 'local_shopping_cart'},\n {key: 'ok', component: 'core'},\n ]).then(strings => {\n // eslint-disable-next-line promise/no-nesting\n ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}).then(modal => {\n modal.setTitle(strings[0]);\n modal.setBody(strings[1]);\n modal.setSaveButtonText(strings[2]);\n modal.show();\n return modal;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return true;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return;\n case CARTPARAM_FULLYBOOKED:\n getStrings([\n {key: 'error:fullybookedtitle', component: 'local_shopping_cart'},\n {key: 'error:fullybooked', component: 'local_shopping_cart'},\n {key: 'ok', component: 'core'},\n ]).then(strings => {\n // eslint-disable-next-line promise/no-nesting\n ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}).then(modal => {\n modal.setTitle(strings[0]);\n modal.setBody(strings[1]);\n modal.setSaveButtonText(strings[2]);\n\n // Reload when OK button is clicked.\n modal.getRoot().on(ModalEvents.save, function() {\n window.location.reload();\n });\n\n modal.show();\n return modal;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return true;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return;\n case CARTPARAM_ALREADYBOOKED:\n getStrings([\n {key: 'error:alreadybookedtitle', component: 'local_shopping_cart'},\n {key: 'error:alreadybooked', component: 'local_shopping_cart'},\n {key: 'ok', component: 'core'},\n ]).then(strings => {\n // eslint-disable-next-line promise/no-nesting\n ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}).then(modal => {\n modal.setTitle(strings[0]);\n modal.setBody(strings[1]);\n modal.setSaveButtonText(strings[2]);\n\n // Reload when OK button is clicked.\n modal.getRoot().on(ModalEvents.save, function() {\n window.location.reload();\n });\n\n modal.show();\n return modal;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return true;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return;\n default:\n getStrings([\n {key: 'error:generalcarterror', component: 'local_shopping_cart'},\n {key: 'ok', component: 'core'},\n ]).then(strings => {\n // eslint-disable-next-line promise/no-nesting\n ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}).then(modal => {\n modal.setBody(strings[0]);\n modal.setSaveButtonText(strings[1]);\n modal.show();\n return modal;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return true;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return;\n }\n\n}\n\n/**\n *\n * @param {*} event\n */\nasync function dealWithZeroPrice(event) {\n\n event.stopPropagation();\n event.preventDefault();\n\n confirmZeroPriceCheckoutModal(event.target);\n}\n\n/**\n * Start the timer.\n *\n * @param {integer} duration\n * @param {integer} display\n */\nfunction startTimer(duration, display) {\n\n var timer = duration,\n minutes,\n seconds;\n interval = setInterval(function() {\n\n minutes = parseInt(timer / 60, 10);\n seconds = parseInt(timer % 60, 10);\n\n minutes = minutes < 10 ? \"0\" + minutes : minutes;\n seconds = seconds < 10 ? \"0\" + seconds : seconds;\n\n display.textContent = minutes + \":\" + seconds;\n\n if (--timer < 0) {\n\n // We so the expiration time has already kicked in on the server.\n setTimeout(() => {\n reinit(0);\n }, 2000);\n\n // We don't actually need to make this call.\n // deleteAllItems();\n\n clearInterval(interval);\n }\n }, 1000);\n}\n\n\n/**\n * Initialize Timer.\n *\n * @param {integer} expirationtime\n * @param {integer} nowdate\n *\n */\nfunction initTimer(expirationtime = null, nowdate = null) {\n\n const countdownelement = document.querySelector(SELECTORS.COUNTDOWN);\n\n if (!countdownelement || !nowdate) {\n return;\n }\n\n if (interval) {\n clearInterval(interval);\n }\n let delta = 0;\n let now = nowdate;\n if (expirationtime) {\n delta = (expirationtime - now);\n }\n if (delta <= 0) {\n delta = 0;\n countdownelement.classList.add(\"hidden\");\n } else if (delta > 0) {\n countdownelement.classList.remove(\"hidden\");\n startTimer(delta, countdownelement);\n }\n}\n\n/**\n *\n * @param {*} element\n */\nfunction confirmZeroPriceCheckoutModal(element) {\n\n getStrings([\n {key: 'confirmzeropricecheckouttitle', component: 'local_shopping_cart'},\n {key: 'confirmzeropricecheckoutbody', component: 'local_shopping_cart'},\n {key: 'confirmzeropricecheckout', component: 'local_shopping_cart'}\n ]\n ).then(strings => {\n // eslint-disable-next-line promise/no-nesting\n ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}).then(modal => {\n\n modal.setTitle(strings[0]);\n modal.setBody(strings[1]);\n modal.setSaveButtonText(strings[2]);\n modal.getRoot().on(ModalEvents.save, function() {\n\n const userid = element.dataset.userid;\n\n if (userid) {\n // The second parameter designs the payment method.\n // In the cart, the constant PAYMENT_METHOD_CREDITS translates to 2.\n confirmPayment(userid, 2);\n }\n });\n\n modal.show();\n return modal;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n return true;\n }).catch(e => {\n // eslint-disable-next-line no-console\n console.log(e);\n });\n}\n\n/**\n * Function to update the page in the nav bar.\n * @param {*} count\n */\nfunction updateBadge(count) {\n\n const badge = document.querySelector(SELECTORS.BADGECOUNT);\n\n if (count > 0) {\n badge.innerHTML = count;\n badge.classList.remove('hidden');\n } else {\n badge.innerHTML = count;\n badge.classList.add('hidden');\n }\n}\n\n/**\n * Function to toggle the active state.\n * @param {*} button\n */\nfunction toggleActiveButtonState(button = null) {\n\n let selector = '';\n let component = null;\n let area = null;\n let itemid = null;\n\n // If we have a button, we only look for this particular itemid.\n if (button) {\n\n // We'll find the right variables in the DOM.\n itemid = button.dataset.itemid;\n component = button.dataset.component;\n area = button.dataset.area;\n\n selector =\n 'div'\n + '[data-itemid=\"' + itemid + '\"]'\n + '[data-component=\"' + component + '\"]'\n + '[data-area=\"' + area + '\"]'\n + '[data-objecttable=\"local_shopping_cart\"';\n } else {\n // As we might have more than one of these buttons, we always need to look for all of them in the document.\n // We will update for all the buttons we find.\n selector =\n 'div'\n + '[data-objecttable=\"local_shopping_cart\"';\n }\n\n const buttons = document.querySelectorAll(selector);\n\n // Make sure item is not yet in shopping cart. If so, add disabled class.\n let shoppingcart = document.querySelector(SELECTORS.CASHIERSCART);\n\n if (!shoppingcart) {\n shoppingcart = document.querySelector(SELECTORS.NAVBARCONTAINER);\n }\n\n buttons.forEach(addtocartbutton => {\n\n component = addtocartbutton.dataset.component;\n area = addtocartbutton.dataset.area;\n itemid = addtocartbutton.dataset.itemid;\n\n const cartitem = shoppingcart.querySelector('[id=\"item-' + component + '-' + area + '-' + itemid + '\"]');\n\n if (cartitem) {\n\n addtocartbutton.classList.add('disabled');\n } else {\n\n addtocartbutton.classList.remove('disabled');\n }\n });\n}\n\n/**\n * Function to init Price Label and add Listener.\n * @param {*} userid\n */\nexport function initPriceLabel(userid) {\n\n // eslint-disable-next-line no-console\n console.log('initpricelabel');\n\n if (userid < 1) {\n userid = 0;\n }\n\n const checkbox = document.querySelector(SELECTORS.PRICELABELCHECKBOX);\n const installmentscheckbox = document.querySelector(SELECTORS.INSTALLMENTSCHECKBOX);\n\n if (checkbox && !checkbox.initialized) {\n checkbox.initialized = true;\n checkbox.addEventListener('change', event => {\n\n var installementsvalue = false;\n if (installmentscheckbox) {\n installementsvalue = installmentscheckbox.checked;\n }\n\n if (event.currentTarget.checked) {\n updateTotalPrice(userid, true, installementsvalue);\n } else {\n updateTotalPrice(userid, false, installementsvalue);\n }\n });\n }\n\n if (installmentscheckbox && !installmentscheckbox.initialized) {\n installmentscheckbox.initialized = true;\n\n // eslint-disable-next-line no-console\n console.log('add event listener to installment');\n installmentscheckbox.addEventListener('change', event => {\n\n // eslint-disable-next-line no-console\n console.log(event.currentTarget, event.currentTarget.checked);\n\n // eslint-disable-next-line no-console\n console.log(checkbox);\n\n let checkboxchecked = null;\n if (checkbox) {\n checkboxchecked = checkbox.checked;\n }\n\n updateTotalPrice(userid, checkboxchecked, event.currentTarget.checked);\n\n });\n }\n}\n\n/**\n * We need to know if we are on the cashier page to transform userid if necessary.\n * @param {integer} userid\n * @returns {integer}\n */\nfunction transformUserIdForCashier(userid = null) {\n\n const oncashier = window.location.href.indexOf(\"cashier.php\");\n\n if ((userid == CASHIERUSER || !(userid === 0 || userid === \"0\")) && oncashier > 0) {\n userid = CASHIERUSER;\n } else if (userid === null) {\n userid = 0;\n }\n\n if (!Number.isInteger(userid)) {\n userid = parseInt(userid);\n }\n\n return userid;\n}\n\n/**\n * Helper function to convert prices to number format before rendering.\n * @param {Object} data the data containing the price values\n */\nfunction convertPricesToNumberFormat(data) {\n // Render all prices to 2 fixed decimals.\n if (data.price) {\n data.price = Number(data.price).toFixed(2);\n }\n if (data.initialtotal) {\n data.initialtotal = Number(data.initialtotal).toFixed(2);\n }\n if (data.initialtotal_net) {\n // eslint-disable-next-line camelcase\n data.initialtotal_net = Number(data.initialtotal_net).toFixed(2);\n }\n if (data.discount) {\n data.discount = Number(data.discount).toFixed(2);\n }\n if (data.deductible) {\n data.deductible = Number(data.deductible).toFixed(2);\n }\n if (data.credit) {\n data.credit = Number(data.credit).toFixed(2);\n }\n if (data.remainingcredit) {\n data.remainingcredit = Number(data.remainingcredit).toFixed(2);\n }\n if (data.price_net) {\n // eslint-disable-next-line camelcase\n data.price_net = Number(data.price_net).toFixed(2);\n }\n if (data.price_gross) {\n // eslint-disable-next-line camelcase\n data.price_gross = Number(data.price_gross).toFixed(2);\n }\n if (data.items) {\n for (var i = 0; i < data.items.length; i++) {\n if (data.items[i].price) {\n data.items[i].price = Number(data.items[i].price).toFixed(2);\n }\n if (data.items[i].price_gross) {\n // eslint-disable-next-line camelcase\n data.items[i].price_gross = Number(data.items[i].price_gross).toFixed(2);\n }\n if (data.items[i].price_net) {\n // eslint-disable-next-line camelcase\n data.items[i].price_net = Number(data.items[i].price_net).toFixed(2);\n }\n }\n }\n}\n\n/**\n * Add Accept terms listener to set the right class to payment region button.\n * @param {element} accepttermsbutton\n * @param {element} paymentbutton\n */\nfunction addAcceptTermsListener(accepttermsbutton, paymentbutton) {\n\n accepttermsbutton.addEventListener('change', event => {\n if (event.currentTarget.checked) {\n paymentbutton.disabled = false;\n } else {\n paymentbutton.disabled = true;\n }\n });\n}"],"names":["userid","console","log","checkbox","document","querySelector","SELECTORS","PRICELABELCHECKBOX","installmentscheckbox","INSTALLMENTSCHECKBOX","initialized","addEventListener","event","installementsvalue","checked","currentTarget","updateTotalPrice","checkboxchecked","_ajax","_interopRequireDefault","_templates","_modal_factory","_modal_events","_dynamicform","_systemImportTransformerGlobalIdentifier","window","self","global","e","__esModule","default","interval","_exports","visbilityevent","SHOPPING_CART_ITEM","NAVBARCONTAINER","TRASHCLASS","DISCOUNTCLASS","MODIFYTIMECLASS","BADGECOUNT","COUNTDOWN","CASHIERSCART","CHECKOUTCART","PRICELABELAREA","CHECKOUTBUTTON","PAYMENTREGIONBUTTON","ACCEPTTERMS","CHECKVATNRFORM","init","expirationtime","nowdate","initTimer","containers","querySelectorAll","forEach","container","element","target","classList","contains","dataset","component","area","itemid","deleteItem","discountModal","modifyTimeModal","readyState","reinit","visibilityState","paymentbutton","addZeroPriceListener","price","currency","accepttermsbutton","disabled","addAcceptTermsListener","initVATNRChecker","vatnrchecker","vatnrcheckerform","DynamicForm","name","value","submitFormAjax","events","FORM_SUBMITTED","load","buttoninit","selector","button","addtocartbutton","toggleActiveButtonState","nojs","blocked","preventDefault","stopPropagation","addItem","arguments","length","undefined","transformUserIdForCashier","Ajax","call","methodname","args","done","data","oncashier","location","href","indexOf","iscashier","promises","convertPricesToNumberFormat","push","Templates","renderForPromise","then","_ref","html","js","replaceNodeContents","catch","Promise","all","clearInterval","count","badge","innerHTML","remove","add","updateBadge","items","item","componentname","closest","updateItemPrice","fail","ex","deleteAllItems","getString","get_string","itemname","message","showNotification","define","amd","resolve","reject","require","module","exports","loader","wbt","reloadAllTables","err","Number","isInteger","parseInt","addItemShowNotification","usecredit","useinstallments","checkboxes","usecreditvalue","checkboxid","Math","random","toString","slice","installments","installmentscheckboxid","labelareas","_ref2","labelarea","noupdate","checkoutButton","style","display","cost","dealWithZeroPrice","removeEventListener","success","getStrings","key","strings","ModalFactory","create","type","types","SAVE_CANCEL","modal","setBody","setSaveButtonText","show","setTitle","getRoot","on","ModalEvents","save","reload","async","confirmPayment","countdownelement","delta","minutes","seconds","timer","setInterval","textContent","setTimeout","buttons","shoppingcart","toFixed","initialtotal","initialtotal_net","discount","deductible","credit","remainingcredit","price_net","price_gross","i"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/cashier.min.js b/amd/build/cashier.min.js index 86e72936..164414e8 100644 --- a/amd/build/cashier.min.js +++ b/amd/build/cashier.min.js @@ -5,6 +5,6 @@ define("local_shopping_cart/cashier",["exports","core/ajax","core/url","local_sh * @package local_shopping_cart * @copyright Wunderbyte GmbH * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.confirmPayment=_exports.addPrintIdentifier=void 0,_exports.discountModal=function(event){const element=event.target.closest(".shopping-cart-item"),price=element.dataset.price,itemid=element.dataset.itemid,userid=element.dataset.userid,componentname=element.dataset.component,area=element.dataset.area,modalForm=new _modalform.default({formClass:"local_shopping_cart\\form\\modal_add_discount_to_item",args:{price:price,itemid:itemid,userid:userid,componentname:componentname,area:area},modalConfig:{title:(0,_str.get_string)("applydiscount","local_shopping_cart")},returnFocus:element});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>{(0,_cart.reinit)(-1)})),modalForm.show()},_exports.init=void 0,_exports.rebookOrderidModal=rebookOrderidModal,_exports.validateCart=void 0,_ajax=_interopRequireDefault(_ajax),_url=_interopRequireDefault(_url),_modalform=_interopRequireDefault(_modalform),_modal_factory=_interopRequireDefault(_modal_factory),_dynamicform=_interopRequireDefault(_dynamicform);const SELECTORS_USERSELECTORFORM='[data-id="sc-selectuserformcontainer"]';_exports.init=function(){let userid=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;console.log("run init",userid),document.getElementById("checkout-tab").classList.remove("success");const buybuttons=document.querySelectorAll(".buy-btn"),manualrebookbtn=document.querySelector("#cashiermanualrebook-btn"),cartcancelbtn=document.querySelector("#shoppingcart-cancel-btn");buybuttons&&buybuttons.forEach((buybutton=>{buybutton.addEventListener("click",(e=>confirmPayment(userid,e.target.dataset.paymenttype,"")))})),manualrebookbtn&&manualrebookbtn.addEventListener("click",(e=>rebookOrderidModal(userid,e.target.dataset.paymenttype))),cartcancelbtn&&cartcancelbtn.addEventListener("click",(()=>{(0,_cart.deleteAllItems)(userid);const newurl=_url.default.relativeUrl("/local/shopping_cart/cashier.php",[],!1);location.href=newurl}));const checkoutbutton=document.querySelector("#checkout-btn");console.log(checkoutbutton),checkoutbutton&&checkoutbutton.addEventListener("click",(function(){document.getElementById("checkout-tab").classList.add("success")})),function(){const element=document.querySelector(SELECTORS_USERSELECTORFORM),dynamicForm=new _dynamicform.default(element,"local_shopping_cart\\form\\dynamic_select_users");console.log(dynamicForm),dynamicForm.addEventListener(dynamicForm.events.FORM_SUBMITTED,(e=>{const response=e.detail;console.log(response),response.redirecturl?location.href=response.redirecturl:((0,_notifications.showNotification)("no user found","error"),dynamicForm.load())})),dynamicForm.load()}()};const confirmPayment=function(userid,paymenttype){let annotation=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";_ajax.default.call([{methodname:"local_shopping_cart_confirm_cash_payment",args:{userid:userid,paymenttype:paymenttype,annotation:annotation},done:function(data){if(1===data.status){console.log("payment confirmed",data),(0,_shistory.reloadHistory)(userid);if(window.location.href.indexOf("cashier.php")<1){let params={success:1,identifier:data.identifier};const newurl=_url.default.relativeUrl("/local/shopping_cart/checkout.php",params,!1);location.href=newurl}else{addPrintIdentifier(data.identifier,userid);const successtab=document.getElementById("success-tab");successtab&&(successtab.classList.add("success"),displayPaymentMessage("paymentsuccessful"))}}else{console.log("payment denied"),console.log(data),function(data){if("string"!=typeof data.error)return;let modaltitle=(0,_str.get_string)("checkouterrormodaltitle","local_shopping_cart");_modal_factory.default.create({type:_modal_factory.default.types.ALERT,title:modaltitle,body:data.error,removeOnClose:!0}).then((modal=>(modal.show(),modal))).catch((e=>{console.log(e)}))}(data),displayPaymentMessage("paymentdenied",!1);const successtab=document.getElementById("success-tab");successtab&&successtab.classList.add("error")}},fail:function(ex){displayPaymentMessage("paymentdenied",!1),console.log(ex)}}])};_exports.confirmPayment=confirmPayment;_exports.validateCart=$userid=>{alert($userid)};const addPrintIdentifier=(identifier,userid)=>{let printbtn=document.getElementById("printbtn"),href=printbtn.getAttribute("href");printbtn.setAttribute("href",href+identifier+"&userid="+userid)};function displayPaymentMessage(message){let success=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],displaymessage=document.querySelector(".payment_message_result");displaymessage&&(0,_str.get_string)(message,"local_shopping_cart").then((localizedmessage=>{displaymessage.innerText=localizedmessage,success?(0,_notifications.showNotification)(localizedmessage,"info"):(0,_notifications.showNotification)(localizedmessage,"error")})).catch((e=>{(0,_notifications.showNotification)(`Error: ${e}`,"error")}))}function rebookOrderidModal(userid,identifier){const modalForm=new _modalform.default({formClass:"local_shopping_cart\\form\\modal_cashier_manual_rebook",args:{userid:userid,identifier:identifier},modalConfig:{title:(0,_str.get_string)("annotation_rebook_desc","local_shopping_cart")}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(e=>{const response=e.detail;confirmPayment(userid,7,`${response.annotation} ${response.paidby}`)})),modalForm.show()}_exports.addPrintIdentifier=addPrintIdentifier})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.confirmPayment=_exports.addPrintIdentifier=void 0,_exports.discountModal=function(event){const element=event.target.closest(".shopping-cart-item"),price=element.dataset.price,itemid=element.dataset.itemid,userid=element.dataset.userid,componentname=element.dataset.component,area=element.dataset.area,modalForm=new _modalform.default({formClass:"local_shopping_cart\\form\\modal_add_discount_to_item",args:{price:price,itemid:itemid,userid:userid,componentname:componentname,area:area},modalConfig:{title:(0,_str.get_string)("applydiscount","local_shopping_cart")},returnFocus:element});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>{(0,_cart.reinit)(-1)})),modalForm.show()},_exports.init=void 0,_exports.modifyTimeModal=function(event){const element=event.target.closest(".shopping-cart-item"),itemid=element.dataset.itemid,userid=element.dataset.userid,componentname=element.dataset.component,area=element.dataset.area,modalForm=new _modalform.default({formClass:"local_shopping_cart\\form\\modal_modify_time_of_deletion_task",args:{itemid:itemid,userid:userid,componentname:componentname,area:area},modalConfig:{title:(0,_str.get_string)("modifytimeofdeletiontask","local_shopping_cart")},returnFocus:element});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(e=>{const response=e.detail;console.log(response);const formattedDate=new Date(1e3*response.taskdeletiontimestamp).toLocaleString(response.currentlang,{year:"numeric",month:"long",day:"numeric",hour:"2-digit",minute:"2-digit"});(0,_str.get_string)("modifytimeofdeletiontaskconfirmation","local_shopping_cart",formattedDate).then((localizedmessage=>{(0,_notifications.showNotification)(localizedmessage,"success")})).catch((e=>{(0,_notifications.showNotification)(`Error: ${e}`,"error")}))})),modalForm.show()},_exports.rebookOrderidModal=rebookOrderidModal,_exports.validateCart=void 0,_ajax=_interopRequireDefault(_ajax),_url=_interopRequireDefault(_url),_modalform=_interopRequireDefault(_modalform),_modal_factory=_interopRequireDefault(_modal_factory),_dynamicform=_interopRequireDefault(_dynamicform);const SELECTORS_USERSELECTORFORM='[data-id="sc-selectuserformcontainer"]';_exports.init=function(){let userid=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;console.log("run init",userid),document.getElementById("checkout-tab").classList.remove("success");const buybuttons=document.querySelectorAll(".buy-btn"),manualrebookbtn=document.querySelector("#cashiermanualrebook-btn"),cartcancelbtn=document.querySelector("#shoppingcart-cancel-btn");buybuttons&&buybuttons.forEach((buybutton=>{buybutton.addEventListener("click",(e=>confirmPayment(userid,e.target.dataset.paymenttype,"")))})),manualrebookbtn&&manualrebookbtn.addEventListener("click",(e=>rebookOrderidModal(userid,e.target.dataset.paymenttype))),cartcancelbtn&&cartcancelbtn.addEventListener("click",(()=>{(0,_cart.deleteAllItems)(userid);const newurl=_url.default.relativeUrl("/local/shopping_cart/cashier.php",[],!1);location.href=newurl}));const checkoutbutton=document.querySelector("#checkout-btn");console.log(checkoutbutton),checkoutbutton&&checkoutbutton.addEventListener("click",(function(){document.getElementById("checkout-tab").classList.add("success")})),function(){const element=document.querySelector(SELECTORS_USERSELECTORFORM),dynamicForm=new _dynamicform.default(element,"local_shopping_cart\\form\\dynamic_select_users");console.log(dynamicForm),dynamicForm.addEventListener(dynamicForm.events.FORM_SUBMITTED,(e=>{const response=e.detail;console.log(response),response.redirecturl?location.href=response.redirecturl:((0,_notifications.showNotification)("no user found","error"),dynamicForm.load())})),dynamicForm.load()}()};const confirmPayment=function(userid,paymenttype){let annotation=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";_ajax.default.call([{methodname:"local_shopping_cart_confirm_cash_payment",args:{userid:userid,paymenttype:paymenttype,annotation:annotation},done:function(data){if(1===data.status){console.log("payment confirmed",data),(0,_shistory.reloadHistory)(userid);if(window.location.href.indexOf("cashier.php")<1){let params={success:1,identifier:data.identifier};const newurl=_url.default.relativeUrl("/local/shopping_cart/checkout.php",params,!1);location.href=newurl}else{addPrintIdentifier(data.identifier,userid);const successtab=document.getElementById("success-tab");successtab&&(successtab.classList.add("success"),displayPaymentMessage("paymentsuccessful"))}}else{console.log("payment denied"),console.log(data),function(data){if("string"!=typeof data.error)return;let modaltitle=(0,_str.get_string)("checkouterrormodaltitle","local_shopping_cart");_modal_factory.default.create({type:_modal_factory.default.types.ALERT,title:modaltitle,body:data.error,removeOnClose:!0}).then((modal=>(modal.show(),modal))).catch((e=>{console.log(e)}))}(data),displayPaymentMessage("paymentdenied",!1);const successtab=document.getElementById("success-tab");successtab&&successtab.classList.add("error")}},fail:function(ex){displayPaymentMessage("paymentdenied",!1),console.log(ex)}}])};_exports.confirmPayment=confirmPayment;_exports.validateCart=$userid=>{alert($userid)};const addPrintIdentifier=(identifier,userid)=>{let printbtn=document.getElementById("printbtn"),href=printbtn.getAttribute("href");printbtn.setAttribute("href",href+identifier+"&userid="+userid)};function displayPaymentMessage(message){let success=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],displaymessage=document.querySelector(".payment_message_result");displaymessage&&(0,_str.get_string)(message,"local_shopping_cart").then((localizedmessage=>{displaymessage.innerText=localizedmessage,success?(0,_notifications.showNotification)(localizedmessage,"info"):(0,_notifications.showNotification)(localizedmessage,"error")})).catch((e=>{(0,_notifications.showNotification)(`Error: ${e}`,"error")}))}function rebookOrderidModal(userid,identifier){const modalForm=new _modalform.default({formClass:"local_shopping_cart\\form\\modal_cashier_manual_rebook",args:{userid:userid,identifier:identifier},modalConfig:{title:(0,_str.get_string)("annotation_rebook_desc","local_shopping_cart")}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(e=>{const response=e.detail;confirmPayment(userid,7,`${response.annotation} ${response.paidby}`)})),modalForm.show()}_exports.addPrintIdentifier=addPrintIdentifier})); //# sourceMappingURL=cashier.min.js.map \ No newline at end of file diff --git a/amd/build/cashier.min.js.map b/amd/build/cashier.min.js.map index a2bd58db..1878841d 100644 --- a/amd/build/cashier.min.js.map +++ b/amd/build/cashier.min.js.map @@ -1 +1 @@ -{"version":3,"file":"cashier.min.js","sources":["../src/cashier.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/* eslint-disable no-console */\n\n/*\n * The Cashier module.\n *\n * @package local_shopping_cart\n * @copyright Wunderbyte GmbH \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport Url from 'core/url';\nimport {showNotification} from 'local_shopping_cart/notifications';\nimport ModalForm from 'core_form/modalform';\nimport ModalFactory from 'core/modal_factory';\nimport {reinit} from 'local_shopping_cart/cart';\nimport {deleteAllItems} from 'local_shopping_cart/cart';\nimport {get_string as getString} from 'core/str';\nimport DynamicForm from 'core_form/dynamicform';\nimport {reloadHistory} from './shistory';\n\nconst SELECTORS = {\n USERSELECTORFORM: '[data-id=\"sc-selectuserformcontainer\"]',\n};\n/**\n * Init function.\n * @param {*} userid the user id, 0 means logged-in USER\n */\nexport const init = (userid = 0) => {\n\n console.log('run init', userid);\n\n document.getElementById('checkout-tab').classList.remove('success');\n\n const buybuttons = document.querySelectorAll('.buy-btn');\n const manualrebookbtn = document.querySelector('#cashiermanualrebook-btn');\n const cartcancelbtn = document.querySelector('#shoppingcart-cancel-btn');\n\n if (buybuttons) {\n buybuttons.forEach(buybutton => {\n buybutton.addEventListener('click', (e) => confirmPayment(userid, e.target.dataset.paymenttype, ''));\n });\n }\n\n if (manualrebookbtn) {\n manualrebookbtn.addEventListener('click', (e) => rebookOrderidModal(userid, e.target.dataset.paymenttype));\n }\n\n if (cartcancelbtn) {\n cartcancelbtn.addEventListener('click', () => {\n deleteAllItems(userid);\n const newurl = Url.relativeUrl(\"/local/shopping_cart/cashier.php\", [], false);\n location.href = newurl;\n });\n }\n\n const checkoutbutton = document.querySelector('#checkout-btn');\n\n console.log(checkoutbutton);\n if (checkoutbutton) {\n checkoutbutton.addEventListener('click', function() {\n\n document.getElementById('checkout-tab').classList.add('success');\n });\n }\n\n initUserSelectorForm();\n};\n\nexport const confirmPayment = (userid, paymenttype, annotation = '') => {\n\n Ajax.call([{\n methodname: \"local_shopping_cart_confirm_cash_payment\",\n args: {\n 'userid': userid,\n 'paymenttype': paymenttype,\n 'annotation': annotation,\n },\n done: function(data) {\n if (data.status === 1) {\n\n console.log('payment confirmed', data);\n reloadHistory(userid);\n\n // The function can be called via cashier, or because a user pays via credits.\n // If that's the case, we are not on the cashier site.\n\n const oncashier = window.location.href.indexOf(\"cashier.php\");\n\n // If we are not on cashier, we can just redirect.\n if (oncashier < 1) {\n\n const identifier = data.identifier;\n\n let params = {\n success: 1,\n identifier: identifier,\n };\n\n const newurl = Url.relativeUrl(\"/local/shopping_cart/checkout.php\", params, false);\n\n location.href = newurl;\n\n } else {\n // Set link to right receipt.\n addPrintIdentifier(data.identifier, userid);\n\n const successtab = document.getElementById('success-tab');\n if (successtab) {\n successtab.classList.add('success');\n displayPaymentMessage('paymentsuccessful');\n }\n\n }\n\n } else {\n console.log('payment denied');\n console.log(data);\n displayErrorModal(data);\n displayPaymentMessage('paymentdenied', false);\n\n const successtab = document.getElementById('success-tab');\n if (successtab) {\n successtab.classList.add('error');\n }\n }\n },\n fail: function(ex) {\n\n displayPaymentMessage('paymentdenied', false);\n\n console.log(ex);\n },\n }]);\n};\n\nexport const validateCart = ($userid) => {\n // eslint-disable-next-line no-alert\n alert($userid);\n};\n\n/**\n * Adds parameters to the printbutton.\n * @param {int} identifier\n * @param {int} userid\n */\nexport const addPrintIdentifier = (identifier, userid) => {\n let printbtn = document.getElementById('printbtn');\n let href = printbtn.getAttribute('href');\n printbtn.setAttribute('href', href + identifier + '&userid=' + userid);\n};\n\n/**\n *\n * @param {*} event\n */\nexport function discountModal(event) {\n\n // We two parents up, we find the right element with the necessary information.\n const element = event.target.closest('.shopping-cart-item');\n\n /* Console.log('closest', element); */\n\n const price = element.dataset.price;\n const itemid = element.dataset.itemid;\n const userid = element.dataset.userid;\n const componentname = element.dataset.component;\n const area = element.dataset.area;\n\n /* Console.log('discountModal', price, itemid, userid, componentname, 'area ' + area); */\n\n const modalForm = new ModalForm({\n\n // Name of the class where form is defined (must extend \\core_form\\dynamic_form):\n formClass: \"local_shopping_cart\\\\form\\\\modal_add_discount_to_item\",\n // Add as many arguments as you need, they will be passed to the form:\n args: {'price': price,\n 'itemid': itemid,\n 'userid': userid,\n 'componentname': componentname,\n 'area': area},\n // Pass any configuration settings to the modal dialogue, for example, the title:\n modalConfig: {title: getString('applydiscount', 'local_shopping_cart')},\n // DOM element that should get the focus after the modal dialogue is closed:\n returnFocus: element\n });\n // Listen to events if you want to execute something on form submit.\n // Event detail will contain everything the process() function returned:\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => {\n\n /* Const response = e.detail;\n console.log('confirmCancelAndSetCreditModal response: ', response); */\n\n reinit(-1);\n });\n\n // Show the form.\n modalForm.show();\n\n}\n\n/**\n * This function first displays the result at the right place.\n * It further uses the notification class to make result even more visible.\n * @param {string} message\n * @param {bool} success\n */\nfunction displayPaymentMessage(message, success = true) {\n let displaymessage = document.querySelector('.payment_message_result');\n if (displaymessage) {\n getString(message, 'local_shopping_cart').then(localizedmessage => {\n\n displaymessage.innerText = localizedmessage;\n\n if (success) {\n showNotification(localizedmessage, \"info\");\n } else {\n showNotification(localizedmessage, \"error\");\n }\n return;\n }).catch(e => {\n showNotification(`Error: ${e}`, \"error\");\n });\n }\n}\n\n/**\n * If the error returned contains a message, display it in a modal.\n * @param {object} data\n */\nfunction displayErrorModal(data) {\n\n if (typeof data.error !== \"string\") {\n return;\n }\n\n let modaltitle = getString('checkouterrormodaltitle', 'local_shopping_cart');\n ModalFactory.create({\n type: ModalFactory.types.ALERT,\n title: modaltitle,\n body: data.error,\n removeOnClose: true,\n }).then(modal => {\n modal.show();\n return modal;\n }).catch(e => {\n console.log(e);\n });\n\n}\n\n/**\n * Modal to enter OrderID for manual rebookings.\n * @param {int} userid\n * @param {int} identifier\n */\nexport function rebookOrderidModal(userid, identifier) {\n\n const modalForm = new ModalForm({\n\n // Name of the class where form is defined (must extend \\core_form\\dynamic_form):\n formClass: \"local_shopping_cart\\\\form\\\\modal_cashier_manual_rebook\",\n // Add as many arguments as you need, they will be passed to the form:\n args: {\n 'userid': userid,\n 'identifier': identifier,\n },\n // Pass any configuration settings to the modal dialogue, for example, the title:\n modalConfig: {title: getString('annotation_rebook_desc', 'local_shopping_cart')},\n // DOM element that should get the focus after the modal dialogue is closed:\n // returnFocus: button\n });\n\n // Listen to events if you want to execute something on form submit.\n // Event detail will contain everything the process() function returned:\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, (e) => {\n const response = e.detail;\n\n /* Console.log('rebookOrderidModal response: ', response); */\n\n // We just add the paidby code to the annotation.\n confirmPayment(userid, 7, `${response.annotation} ${response.paidby}`);\n });\n\n // Show the form.\n modalForm.show();\n\n}\n\n/**\n * Init the user selector form.\n *\n */\nfunction initUserSelectorForm() {\n\n const element = document.querySelector(SELECTORS.USERSELECTORFORM);\n\n // Initialize the form.\n const dynamicForm = new DynamicForm(\n element,\n 'local_shopping_cart\\\\form\\\\dynamic_select_users'\n );\n\n console.log(dynamicForm);\n // When form is submitted - remove it from DOM:\n dynamicForm.addEventListener(dynamicForm.events.FORM_SUBMITTED, e => {\n const response = e.detail;\n console.log(response);\n\n if (response.redirecturl) {\n location.href = response.redirecturl;\n } else {\n showNotification('no user found', \"error\");\n dynamicForm.load();\n }\n });\n\n dynamicForm.load();\n}\n"],"names":["_interopRequireDefault","e","__esModule","default","event","element","target","closest","price","dataset","itemid","userid","componentname","component","area","modalForm","ModalForm","formClass","args","modalConfig","title","getString","returnFocus","addEventListener","events","FORM_SUBMITTED","reinit","show","_ajax","_url","_modalform","_modal_factory","_dynamicform","SELECTORS","_exports","init","arguments","length","undefined","console","log","document","getElementById","classList","remove","buybuttons","querySelectorAll","manualrebookbtn","querySelector","cartcancelbtn","forEach","buybutton","confirmPayment","paymenttype","rebookOrderidModal","deleteAllItems","newurl","Url","relativeUrl","location","href","checkoutbutton","add","dynamicForm","DynamicForm","response","detail","redirecturl","showNotification","load","initUserSelectorForm","annotation","Ajax","call","methodname","done","data","status","reloadHistory","window","indexOf","params","success","identifier","addPrintIdentifier","successtab","displayPaymentMessage","error","modaltitle","ModalFactory","create","type","types","ALERT","body","removeOnClose","then","modal","catch","displayErrorModal","fail","ex","validateCart","$userid","alert","printbtn","getAttribute","setAttribute","message","displaymessage","localizedmessage","innerText","paidby"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"cashier.min.js","sources":["../src/cashier.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/* eslint-disable no-console */\n\n/*\n * The Cashier module.\n *\n * @package local_shopping_cart\n * @copyright Wunderbyte GmbH \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport Url from 'core/url';\nimport {showNotification} from 'local_shopping_cart/notifications';\nimport ModalForm from 'core_form/modalform';\nimport ModalFactory from 'core/modal_factory';\nimport {reinit} from 'local_shopping_cart/cart';\nimport {deleteAllItems} from 'local_shopping_cart/cart';\nimport {get_string as getString} from 'core/str';\nimport DynamicForm from 'core_form/dynamicform';\nimport {reloadHistory} from './shistory';\n\nconst SELECTORS = {\n USERSELECTORFORM: '[data-id=\"sc-selectuserformcontainer\"]',\n};\n/**\n * Init function.\n * @param {*} userid the user id, 0 means logged-in USER\n */\nexport const init = (userid = 0) => {\n\n console.log('run init', userid);\n\n document.getElementById('checkout-tab').classList.remove('success');\n\n const buybuttons = document.querySelectorAll('.buy-btn');\n const manualrebookbtn = document.querySelector('#cashiermanualrebook-btn');\n const cartcancelbtn = document.querySelector('#shoppingcart-cancel-btn');\n\n if (buybuttons) {\n buybuttons.forEach(buybutton => {\n buybutton.addEventListener('click', (e) => confirmPayment(userid, e.target.dataset.paymenttype, ''));\n });\n }\n\n if (manualrebookbtn) {\n manualrebookbtn.addEventListener('click', (e) => rebookOrderidModal(userid, e.target.dataset.paymenttype));\n }\n\n if (cartcancelbtn) {\n cartcancelbtn.addEventListener('click', () => {\n deleteAllItems(userid);\n const newurl = Url.relativeUrl(\"/local/shopping_cart/cashier.php\", [], false);\n location.href = newurl;\n });\n }\n\n const checkoutbutton = document.querySelector('#checkout-btn');\n\n console.log(checkoutbutton);\n if (checkoutbutton) {\n checkoutbutton.addEventListener('click', function() {\n\n document.getElementById('checkout-tab').classList.add('success');\n });\n }\n\n initUserSelectorForm();\n};\n\nexport const confirmPayment = (userid, paymenttype, annotation = '') => {\n\n Ajax.call([{\n methodname: \"local_shopping_cart_confirm_cash_payment\",\n args: {\n 'userid': userid,\n 'paymenttype': paymenttype,\n 'annotation': annotation,\n },\n done: function(data) {\n if (data.status === 1) {\n\n console.log('payment confirmed', data);\n reloadHistory(userid);\n\n // The function can be called via cashier, or because a user pays via credits.\n // If that's the case, we are not on the cashier site.\n\n const oncashier = window.location.href.indexOf(\"cashier.php\");\n\n // If we are not on cashier, we can just redirect.\n if (oncashier < 1) {\n\n const identifier = data.identifier;\n\n let params = {\n success: 1,\n identifier: identifier,\n };\n\n const newurl = Url.relativeUrl(\"/local/shopping_cart/checkout.php\", params, false);\n\n location.href = newurl;\n\n } else {\n // Set link to right receipt.\n addPrintIdentifier(data.identifier, userid);\n\n const successtab = document.getElementById('success-tab');\n if (successtab) {\n successtab.classList.add('success');\n displayPaymentMessage('paymentsuccessful');\n }\n\n }\n\n } else {\n console.log('payment denied');\n console.log(data);\n displayErrorModal(data);\n displayPaymentMessage('paymentdenied', false);\n\n const successtab = document.getElementById('success-tab');\n if (successtab) {\n successtab.classList.add('error');\n }\n }\n },\n fail: function(ex) {\n\n displayPaymentMessage('paymentdenied', false);\n\n console.log(ex);\n },\n }]);\n};\n\nexport const validateCart = ($userid) => {\n // eslint-disable-next-line no-alert\n alert($userid);\n};\n\n/**\n * Adds parameters to the printbutton.\n * @param {int} identifier\n * @param {int} userid\n */\nexport const addPrintIdentifier = (identifier, userid) => {\n let printbtn = document.getElementById('printbtn');\n let href = printbtn.getAttribute('href');\n printbtn.setAttribute('href', href + identifier + '&userid=' + userid);\n};\n\n/**\n *\n * @param {*} event\n */\nexport function discountModal(event) {\n\n // We two parents up, we find the right element with the necessary information.\n const element = event.target.closest('.shopping-cart-item');\n\n /* Console.log('closest', element); */\n\n const price = element.dataset.price;\n const itemid = element.dataset.itemid;\n const userid = element.dataset.userid;\n const componentname = element.dataset.component;\n const area = element.dataset.area;\n\n /* Console.log('discountModal', price, itemid, userid, componentname, 'area ' + area); */\n\n const modalForm = new ModalForm({\n\n // Name of the class where form is defined (must extend \\core_form\\dynamic_form):\n formClass: \"local_shopping_cart\\\\form\\\\modal_add_discount_to_item\",\n // Add as many arguments as you need, they will be passed to the form:\n args: {'price': price,\n 'itemid': itemid,\n 'userid': userid,\n 'componentname': componentname,\n 'area': area},\n // Pass any configuration settings to the modal dialogue, for example, the title:\n modalConfig: {title: getString('applydiscount', 'local_shopping_cart')},\n // DOM element that should get the focus after the modal dialogue is closed:\n returnFocus: element\n });\n // Listen to events if you want to execute something on form submit.\n // Event detail will contain everything the process() function returned:\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => {\n\n /* Const response = e.detail;\n console.log('confirmCancelAndSetCreditModal response: ', response); */\n\n reinit(-1);\n });\n\n // Show the form.\n modalForm.show();\n\n}\n\n/**\n * This function first displays the result at the right place.\n * It further uses the notification class to make result even more visible.\n * @param {string} message\n * @param {bool} success\n */\nfunction displayPaymentMessage(message, success = true) {\n let displaymessage = document.querySelector('.payment_message_result');\n if (displaymessage) {\n getString(message, 'local_shopping_cart').then(localizedmessage => {\n\n displaymessage.innerText = localizedmessage;\n\n if (success) {\n showNotification(localizedmessage, \"info\");\n } else {\n showNotification(localizedmessage, \"error\");\n }\n return;\n }).catch(e => {\n showNotification(`Error: ${e}`, \"error\");\n });\n }\n}\n\n/**\n * If the error returned contains a message, display it in a modal.\n * @param {object} data\n */\nfunction displayErrorModal(data) {\n\n if (typeof data.error !== \"string\") {\n return;\n }\n\n let modaltitle = getString('checkouterrormodaltitle', 'local_shopping_cart');\n ModalFactory.create({\n type: ModalFactory.types.ALERT,\n title: modaltitle,\n body: data.error,\n removeOnClose: true,\n }).then(modal => {\n modal.show();\n return modal;\n }).catch(e => {\n console.log(e);\n });\n\n}\n\n/**\n * Modal to enter OrderID for manual rebookings.\n * @param {int} userid\n * @param {int} identifier\n */\nexport function rebookOrderidModal(userid, identifier) {\n\n const modalForm = new ModalForm({\n\n // Name of the class where form is defined (must extend \\core_form\\dynamic_form):\n formClass: \"local_shopping_cart\\\\form\\\\modal_cashier_manual_rebook\",\n // Add as many arguments as you need, they will be passed to the form:\n args: {\n 'userid': userid,\n 'identifier': identifier,\n },\n // Pass any configuration settings to the modal dialogue, for example, the title:\n modalConfig: {title: getString('annotation_rebook_desc', 'local_shopping_cart')},\n // DOM element that should get the focus after the modal dialogue is closed:\n // returnFocus: button\n });\n\n // Listen to events if you want to execute something on form submit.\n // Event detail will contain everything the process() function returned:\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, (e) => {\n const response = e.detail;\n\n /* Console.log('rebookOrderidModal response: ', response); */\n\n // We just add the paidby code to the annotation.\n confirmPayment(userid, 7, `${response.annotation} ${response.paidby}`);\n });\n\n // Show the form.\n modalForm.show();\n\n}\n\n/**\n * Init the user selector form.\n *\n */\nfunction initUserSelectorForm() {\n\n const element = document.querySelector(SELECTORS.USERSELECTORFORM);\n\n // Initialize the form.\n const dynamicForm = new DynamicForm(\n element,\n 'local_shopping_cart\\\\form\\\\dynamic_select_users'\n );\n\n console.log(dynamicForm);\n // When form is submitted - remove it from DOM:\n dynamicForm.addEventListener(dynamicForm.events.FORM_SUBMITTED, e => {\n const response = e.detail;\n console.log(response);\n\n if (response.redirecturl) {\n location.href = response.redirecturl;\n } else {\n showNotification('no user found', \"error\");\n dynamicForm.load();\n }\n });\n\n dynamicForm.load();\n}\n\n/**\n *\n * @param {*} event\n */\nexport function modifyTimeModal(event) {\n\n // We two parents up, we find the right element with the necessary information.\n const element = event.target.closest('.shopping-cart-item');\n\n const itemid = element.dataset.itemid;\n const userid = element.dataset.userid;\n const componentname = element.dataset.component;\n const area = element.dataset.area;\n\n const modalForm = new ModalForm({\n\n // Name of the class where form is defined (must extend \\core_form\\dynamic_form):\n formClass: \"local_shopping_cart\\\\form\\\\modal_modify_time_of_deletion_task\",\n // Add as many arguments as you need, they will be passed to the form:\n args: {'itemid': itemid,\n 'userid': userid,\n 'componentname': componentname,\n 'area': area},\n // Pass any configuration settings to the modal dialogue, for example, the title:\n modalConfig: {title: getString('modifytimeofdeletiontask', 'local_shopping_cart')},\n // DOM element that should get the focus after the modal dialogue is closed:\n returnFocus: element\n });\n // Listen to events if you want to execute something on form submit.\n // Event detail will contain everything the process() function returned:\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, e => {\n\n const response = e.detail;\n console.log(response);\n const deletionDate = new Date(response.taskdeletiontimestamp * 1000);\n const formattedDate = deletionDate.toLocaleString(response.currentlang, {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n getString('modifytimeofdeletiontaskconfirmation', 'local_shopping_cart', formattedDate).then(localizedmessage => {\n\n showNotification(localizedmessage, \"success\");\n return;\n }).catch(e => {\n showNotification(`Error: ${e}`, \"error\");\n });\n });\n\n // Show the form.\n modalForm.show();\n\n}\n"],"names":["_interopRequireDefault","e","__esModule","default","event","element","target","closest","price","dataset","itemid","userid","componentname","component","area","modalForm","ModalForm","formClass","args","modalConfig","title","getString","returnFocus","addEventListener","events","FORM_SUBMITTED","reinit","show","response","detail","console","log","formattedDate","Date","taskdeletiontimestamp","toLocaleString","currentlang","year","month","day","hour","minute","get_string","then","localizedmessage","showNotification","catch","_ajax","_url","_modalform","_modal_factory","_dynamicform","SELECTORS","_exports","init","arguments","length","undefined","document","getElementById","classList","remove","buybuttons","querySelectorAll","manualrebookbtn","querySelector","cartcancelbtn","forEach","buybutton","confirmPayment","paymenttype","rebookOrderidModal","deleteAllItems","newurl","Url","relativeUrl","location","href","checkoutbutton","add","dynamicForm","DynamicForm","redirecturl","load","initUserSelectorForm","annotation","Ajax","call","methodname","done","data","status","reloadHistory","window","indexOf","params","success","identifier","addPrintIdentifier","successtab","displayPaymentMessage","error","modaltitle","ModalFactory","create","type","types","ALERT","body","removeOnClose","modal","displayErrorModal","fail","ex","validateCart","$userid","alert","printbtn","getAttribute","setAttribute","message","displaymessage","innerText","paidby"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/cashier_modal.min.js b/amd/build/cashier_modal.min.js index b7b5d36f..dca4df90 100644 --- a/amd/build/cashier_modal.min.js +++ b/amd/build/cashier_modal.min.js @@ -5,6 +5,6 @@ define("local_shopping_cart/cashier_modal",["exports","core/modal_factory","core * @module core_payment/gateways_modal * @copyright Wunderbyte GmbH * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const show=async function(rootNode){let{focusOnClose:focusOnClose=null}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const modal=await _modal_factory.default.create({type:_modal_gateways.default.TYPE,title:await(0,_str.get_string)("selectpaymenttype","core_payment"),body:await _templates.default.render("core_payment/gateways_modal",{})}),rootElement=modal.getRoot()[0];(0,_toast.addToastRegion)(rootElement),modal.show(),modal.getRoot().on(_modal_events.default.hidden,(()=>{modal.destroy();try{focusOnClose.focus()}catch(e){console.log("error: ",e)}})),modal.getRoot().on(_events.default.proceed,(e=>{const gateway=(rootElement.querySelector(_selectors.default.values.gateway)||{value:""}).value;gateway?processPayment(gateway,rootNode.dataset.component,rootNode.dataset.paymentarea,rootNode.dataset.itemid,rootNode.dataset.description).then((message=>(modal.hide(),(0,_notifications.showNotification)(message,"success"),location.href=rootNode.dataset.successurl,message))).catch((message=>_notification.default.alert("",message))):(0,_str.get_string)("nogatewayselected","core_payment").then((message=>(0,_toast.add)(message,{type:"warning"}))),e.preventDefault()})),rootElement.addEventListener("change",(e=>{e.target.matches(_selectors.default.elements.gateways)&&updateCostRegion(rootElement,rootNode.dataset.cost)}));const context={gateways:await(0,_repository.getAvailableGateways)(rootNode.dataset.component,rootNode.dataset.paymentarea,rootNode.dataset.itemid)},{html:html,js:js}=await _templates.default.renderForPromise("core_payment/gateways",context);_templates.default.replaceNodeContents(rootElement.querySelector(_selectors.default.regions.gatewaysContainer),html,js),selectSingleGateway(rootElement),await updateCostRegion(rootElement,rootNode.dataset.cost)},selectSingleGateway=root=>{const gateways=root.querySelectorAll(_selectors.default.elements.gateways);1==gateways.length&&(gateways[0].checked=!0)},updateCostRegion=async function(root){let defaultCost=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";const gatewayElement=root.querySelector(_selectors.default.values.gateway),surcharge=parseInt((gatewayElement||{dataset:{surcharge:0}}).dataset.surcharge),cost=(gatewayElement||{dataset:{cost:defaultCost}}).dataset.cost,{html:html,js:js}=await _templates.default.renderForPromise("core_payment/fee_breakdown",{fee:cost,surcharge:surcharge});_templates.default.replaceNodeContents(root.querySelector(_selectors.default.regions.costContainer),html,js)},processPayment=async(gateway,component,paymentArea,itemId,description)=>(await("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require([`paygw_${gateway}/gateways_modal`],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require(`paygw_${gateway}/gateways_modal`)):Promise.resolve(_systemImportTransformerGlobalIdentifier[`paygw_${gateway}/gateways_modal`]))).process(component,paymentArea,itemId,description),init=()=>{init.initialised||(init.initialised=!0,document.addEventListener("click",(e=>{const gatewayTrigger=e.target.closest('[data-action="core_payment/triggerPayment"]');gatewayTrigger&&(e.preventDefault(),show(gatewayTrigger,{focusOnClose:e.target}))})))};_exports.init=init,init.initialised=!1})); + */function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const show=async function(rootNode){let{focusOnClose:focusOnClose=null}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const modal=await _modal_factory.default.create({type:_modal_gateways.default.TYPE,title:await(0,_str.get_string)("selectpaymenttype","core_payment"),body:await _templates.default.render("core_payment/gateways_modal",{})});console.log("initt23432532532tt");const rootElement=modal.getRoot()[0];(0,_toast.addToastRegion)(rootElement),modal.show(),modal.getRoot().on(_modal_events.default.hidden,(()=>{modal.destroy();try{focusOnClose.focus()}catch(e){console.log("error: ",e)}})),modal.getRoot().on(_events.default.proceed,(e=>{const gateway=(rootElement.querySelector(_selectors.default.values.gateway)||{value:""}).value;gateway?processPayment(gateway,rootNode.dataset.component,rootNode.dataset.paymentarea,rootNode.dataset.itemid,rootNode.dataset.description).then((message=>(modal.hide(),(0,_notifications.showNotification)(message,"success"),location.href=rootNode.dataset.successurl,message))).catch((message=>_notification.default.alert("",message))):(0,_str.get_string)("nogatewayselected","core_payment").then((message=>(0,_toast.add)(message,{type:"warning"}))),e.preventDefault()})),rootElement.addEventListener("change",(e=>{e.target.matches(_selectors.default.elements.gateways)&&updateCostRegion(rootElement,rootNode.dataset.cost)}));const context={gateways:await(0,_repository.getAvailableGateways)(rootNode.dataset.component,rootNode.dataset.paymentarea,rootNode.dataset.itemid)},{html:html,js:js}=await _templates.default.renderForPromise("core_payment/gateways",context);_templates.default.replaceNodeContents(rootElement.querySelector(_selectors.default.regions.gatewaysContainer),html,js),selectSingleGateway(rootElement),await updateCostRegion(rootElement,rootNode.dataset.cost)},selectSingleGateway=root=>{const gateways=root.querySelectorAll(_selectors.default.elements.gateways);1==gateways.length&&(gateways[0].checked=!0)},updateCostRegion=async function(root){let defaultCost=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";const gatewayElement=root.querySelector(_selectors.default.values.gateway),surcharge=parseInt((gatewayElement||{dataset:{surcharge:0}}).dataset.surcharge),cost=(gatewayElement||{dataset:{cost:defaultCost}}).dataset.cost,{html:html,js:js}=await _templates.default.renderForPromise("core_payment/fee_breakdown",{fee:cost,surcharge:surcharge});_templates.default.replaceNodeContents(root.querySelector(_selectors.default.regions.costContainer),html,js)},processPayment=async(gateway,component,paymentArea,itemId,description)=>{console.log("initt23432532532tt");return(await("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require([`paygw_${gateway}/gateways_modal`],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require(`paygw_${gateway}/gateways_modal`)):Promise.resolve(_systemImportTransformerGlobalIdentifier[`paygw_${gateway}/gateways_modal`]))).process(component,paymentArea,itemId,description)},init=()=>{console.log("initt23432532532tt"),init.initialised||(init.initialised=!0,document.addEventListener("click",(e=>{const gatewayTrigger=e.target.closest('[data-action="core_payment/triggerPayment"]');gatewayTrigger&&(e.preventDefault(),show(gatewayTrigger,{focusOnClose:e.target}))})))};_exports.init=init,init.initialised=!1})); //# sourceMappingURL=cashier_modal.min.js.map \ No newline at end of file diff --git a/amd/build/cashier_modal.min.js.map b/amd/build/cashier_modal.min.js.map index 6f287d81..89b13965 100644 --- a/amd/build/cashier_modal.min.js.map +++ b/amd/build/cashier_modal.min.js.map @@ -1 +1 @@ -{"version":3,"file":"cashier_modal.min.js","sources":["../src/cashier_modal.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Contain the logic for the gateways modal.\n *\n * @module core_payment/gateways_modal\n * @copyright Wunderbyte GmbH \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalFactory from 'core/modal_factory';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\nimport {getAvailableGateways} from './repository';\nimport Selectors from './selectors';\nimport ModalEvents from 'core/modal_events';\nimport PaymentEvents from 'core_payment/events';\nimport {add as addToast, addToastRegion} from 'core/toast';\nimport {showNotification} from 'local_shopping_cart/notifications';\nimport ModalGateways from './modal_gateways';\nimport Notification from 'core/notification';\n\n/**\n * Register event listeners for the module.\n */\nconst registerEventListeners = () => {\n document.addEventListener('click', e => {\n const gatewayTrigger = e.target.closest('[data-action=\"core_payment/triggerPayment\"]');\n if (gatewayTrigger) {\n e.preventDefault();\n\n show(gatewayTrigger, {focusOnClose: e.target});\n }\n });\n};\n\n/**\n * Shows the gateway selector modal.\n *\n * @param {HTMLElement} rootNode\n * @param {Object} options - Additional options\n * @param {HTMLElement} options.focusOnClose The element to focus on when the modal is closed.\n */\nconst show = async(rootNode, {\n focusOnClose = null,\n} = {}) => {\n const modal = await ModalFactory.create({\n type: ModalGateways.TYPE,\n title: await getString('selectpaymenttype', 'core_payment'),\n body: await Templates.render('core_payment/gateways_modal', {}),\n });\n\n const rootElement = modal.getRoot()[0];\n addToastRegion(rootElement);\n\n modal.show();\n\n modal.getRoot().on(ModalEvents.hidden, () => {\n // Destroy when hidden.\n modal.destroy();\n try {\n focusOnClose.focus();\n } catch (e) {\n // eslint-disable-next-line no-console\n console.log('error: ', e);\n }\n });\n\n modal.getRoot().on(PaymentEvents.proceed, (e) => {\n const gateway = (rootElement.querySelector(Selectors.values.gateway) || {value: ''}).value;\n\n if (gateway) {\n processPayment(\n gateway,\n rootNode.dataset.component,\n rootNode.dataset.paymentarea,\n rootNode.dataset.itemid,\n rootNode.dataset.description\n )\n .then(message => {\n modal.hide();\n showNotification(message, 'success');\n\n location.href = rootNode.dataset.successurl;\n\n // The following return statement is never reached. It is put here just to make eslint happy.\n return message;\n })\n .catch(message => Notification.alert('', message));\n } else {\n // We cannot use await in the following line.\n // The reason is that we are preventing the default action of the save event being triggered,\n // therefore we cannot define the event handler function asynchronous.\n // eslint-disable-next-line promise/catch-or-return\n getString('nogatewayselected', 'core_payment').then(message => addToast(message, {type: 'warning'}));\n }\n\n e.preventDefault();\n });\n\n // Re-calculate the cost when gateway is changed.\n rootElement.addEventListener('change', e => {\n if (e.target.matches(Selectors.elements.gateways)) {\n updateCostRegion(rootElement, rootNode.dataset.cost);\n }\n });\n\n const gateways = await getAvailableGateways(rootNode.dataset.component, rootNode.dataset.paymentarea, rootNode.dataset.itemid);\n const context = {\n gateways\n };\n\n const {html, js} = await Templates.renderForPromise('core_payment/gateways', context);\n Templates.replaceNodeContents(rootElement.querySelector(Selectors.regions.gatewaysContainer), html, js);\n selectSingleGateway(rootElement);\n await updateCostRegion(rootElement, rootNode.dataset.cost);\n};\n\n/**\n * Auto-select the gateway if there is only one gateway.\n *\n * @param {HTMLElement} root An HTMLElement that contains the cost region\n */\nconst selectSingleGateway = root => {\n const gateways = root.querySelectorAll(Selectors.elements.gateways);\n\n if (gateways.length == 1) {\n gateways[0].checked = true;\n }\n};\n\n/**\n * Shows the cost of the item the user is purchasing in the cost region.\n *\n * @param {HTMLElement} root An HTMLElement that contains the cost region\n * @param {string} defaultCost The default cost that is going to be displayed if no gateway is selected\n * @returns {Promise}\n */\nconst updateCostRegion = async(root, defaultCost = '') => {\n const gatewayElement = root.querySelector(Selectors.values.gateway);\n const surcharge = parseInt((gatewayElement || {dataset: {surcharge: 0}}).dataset.surcharge);\n const cost = (gatewayElement || {dataset: {cost: defaultCost}}).dataset.cost;\n\n const {html, js} = await Templates.renderForPromise('core_payment/fee_breakdown', {fee: cost, surcharge});\n Templates.replaceNodeContents(root.querySelector(Selectors.regions.costContainer), html, js);\n};\n\n/**\n * Process payment using the selected gateway.\n *\n * @param {string} gateway The gateway to be used for payment\n * @param {string} component Name of the component that the itemId belongs to\n * @param {string} paymentArea Name of the area in the component that the itemId belongs to\n * @param {number} itemId An internal identifier that is used by the component\n * @param {string} description Description of the payment\n * @returns {Promise}\n */\nconst processPayment = async(gateway, component, paymentArea, itemId, description) => {\n const paymentMethod = await import(`paygw_${gateway}/gateways_modal`);\n return paymentMethod.process(component, paymentArea, itemId, description);\n};\n\n/**\n * Set up the payment actions.\n */\nexport const init = () => {\n if (!init.initialised) {\n // Event listeners should only be registered once.\n init.initialised = true;\n registerEventListeners();\n }\n};\n\n/**\n * Whether the init function was called before.\n *\n * @static\n * @type {boolean}\n */\ninit.initialised = false;\n"],"names":["_modal_factory","_interopRequireDefault","_templates","_selectors","_modal_events","_events","_modal_gateways","_notification","_systemImportTransformerGlobalIdentifier","window","self","global","e","__esModule","default","show","async","rootNode","focusOnClose","arguments","length","undefined","modal","ModalFactory","create","type","ModalGateways","TYPE","title","getString","body","Templates","render","rootElement","getRoot","addToastRegion","on","ModalEvents","hidden","destroy","focus","console","log","PaymentEvents","proceed","gateway","querySelector","Selectors","values","value","processPayment","dataset","component","paymentarea","itemid","description","then","message","hide","showNotification","location","href","successurl","catch","Notification","alert","get_string","addToast","add","preventDefault","addEventListener","target","matches","elements","gateways","updateCostRegion","cost","context","getAvailableGateways","html","js","renderForPromise","replaceNodeContents","regions","gatewaysContainer","selectSingleGateway","root","querySelectorAll","checked","defaultCost","gatewayElement","surcharge","parseInt","fee","costContainer","paymentArea","itemId","define","amd","Promise","resolve","reject","require","module","exports","loader","process","init","initialised","document","gatewayTrigger","closest","_exports"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"cashier_modal.min.js","sources":["../src/cashier_modal.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Contain the logic for the gateways modal.\n *\n * @module core_payment/gateways_modal\n * @copyright Wunderbyte GmbH \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalFactory from 'core/modal_factory';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\nimport {getAvailableGateways} from './repository';\nimport Selectors from './selectors';\nimport ModalEvents from 'core/modal_events';\nimport PaymentEvents from 'core_payment/events';\nimport {add as addToast, addToastRegion} from 'core/toast';\nimport {showNotification} from 'local_shopping_cart/notifications';\nimport ModalGateways from './modal_gateways';\nimport Notification from 'core/notification';\n\n/**\n * Register event listeners for the module.\n */\nconst registerEventListeners = () => {\n document.addEventListener('click', e => {\n const gatewayTrigger = e.target.closest('[data-action=\"core_payment/triggerPayment\"]');\n if (gatewayTrigger) {\n e.preventDefault();\n\n show(gatewayTrigger, {focusOnClose: e.target});\n }\n });\n};\n\n/**\n * Shows the gateway selector modal.\n *\n * @param {HTMLElement} rootNode\n * @param {Object} options - Additional options\n * @param {HTMLElement} options.focusOnClose The element to focus on when the modal is closed.\n */\nconst show = async(rootNode, {\n focusOnClose = null,\n} = {}) => {\n const modal = await ModalFactory.create({\n type: ModalGateways.TYPE,\n title: await getString('selectpaymenttype', 'core_payment'),\n body: await Templates.render('core_payment/gateways_modal', {}),\n });\n // eslint-disable-next-line no-console\n console.log('initt23432532532tt');\n\n const rootElement = modal.getRoot()[0];\n addToastRegion(rootElement);\n\n modal.show();\n\n modal.getRoot().on(ModalEvents.hidden, () => {\n // Destroy when hidden.\n modal.destroy();\n try {\n focusOnClose.focus();\n } catch (e) {\n // eslint-disable-next-line no-console\n console.log('error: ', e);\n }\n });\n\n modal.getRoot().on(PaymentEvents.proceed, (e) => {\n const gateway = (rootElement.querySelector(Selectors.values.gateway) || {value: ''}).value;\n\n if (gateway) {\n processPayment(\n gateway,\n rootNode.dataset.component,\n rootNode.dataset.paymentarea,\n rootNode.dataset.itemid,\n rootNode.dataset.description\n )\n .then(message => {\n modal.hide();\n showNotification(message, 'success');\n\n location.href = rootNode.dataset.successurl;\n\n // The following return statement is never reached. It is put here just to make eslint happy.\n return message;\n })\n .catch(message => Notification.alert('', message));\n } else {\n // We cannot use await in the following line.\n // The reason is that we are preventing the default action of the save event being triggered,\n // therefore we cannot define the event handler function asynchronous.\n // eslint-disable-next-line promise/catch-or-return\n getString('nogatewayselected', 'core_payment').then(message => addToast(message, {type: 'warning'}));\n }\n\n e.preventDefault();\n });\n\n // Re-calculate the cost when gateway is changed.\n rootElement.addEventListener('change', e => {\n if (e.target.matches(Selectors.elements.gateways)) {\n updateCostRegion(rootElement, rootNode.dataset.cost);\n }\n });\n\n const gateways = await getAvailableGateways(rootNode.dataset.component, rootNode.dataset.paymentarea, rootNode.dataset.itemid);\n const context = {\n gateways\n };\n\n const {html, js} = await Templates.renderForPromise('core_payment/gateways', context);\n Templates.replaceNodeContents(rootElement.querySelector(Selectors.regions.gatewaysContainer), html, js);\n selectSingleGateway(rootElement);\n await updateCostRegion(rootElement, rootNode.dataset.cost);\n};\n\n/**\n * Auto-select the gateway if there is only one gateway.\n *\n * @param {HTMLElement} root An HTMLElement that contains the cost region\n */\nconst selectSingleGateway = root => {\n const gateways = root.querySelectorAll(Selectors.elements.gateways);\n\n if (gateways.length == 1) {\n gateways[0].checked = true;\n }\n};\n\n/**\n * Shows the cost of the item the user is purchasing in the cost region.\n *\n * @param {HTMLElement} root An HTMLElement that contains the cost region\n * @param {string} defaultCost The default cost that is going to be displayed if no gateway is selected\n * @returns {Promise}\n */\nconst updateCostRegion = async(root, defaultCost = '') => {\n const gatewayElement = root.querySelector(Selectors.values.gateway);\n const surcharge = parseInt((gatewayElement || {dataset: {surcharge: 0}}).dataset.surcharge);\n const cost = (gatewayElement || {dataset: {cost: defaultCost}}).dataset.cost;\n\n const {html, js} = await Templates.renderForPromise('core_payment/fee_breakdown', {fee: cost, surcharge});\n Templates.replaceNodeContents(root.querySelector(Selectors.regions.costContainer), html, js);\n};\n\n/**\n * Process payment using the selected gateway.\n *\n * @param {string} gateway The gateway to be used for payment\n * @param {string} component Name of the component that the itemId belongs to\n * @param {string} paymentArea Name of the area in the component that the itemId belongs to\n * @param {number} itemId An internal identifier that is used by the component\n * @param {string} description Description of the payment\n * @returns {Promise}\n */\nconst processPayment = async(gateway, component, paymentArea, itemId, description) => {\n // eslint-disable-next-line no-console\n console.log('initt23432532532tt');\n const paymentMethod = await import(`paygw_${gateway}/gateways_modal`);\n return paymentMethod.process(component, paymentArea, itemId, description);\n};\n\n/**\n * Set up the payment actions.\n */\nexport const init = () => {\n // eslint-disable-next-line no-console\n console.log('initt23432532532tt');\n if (!init.initialised) {\n // Event listeners should only be registered once.\n init.initialised = true;\n registerEventListeners();\n }\n};\n\n/**\n * Whether the init function was called before.\n *\n * @static\n * @type {boolean}\n */\ninit.initialised = false;\n"],"names":["_modal_factory","_interopRequireDefault","_templates","_selectors","_modal_events","_events","_modal_gateways","_notification","_systemImportTransformerGlobalIdentifier","window","self","global","e","__esModule","default","show","async","rootNode","focusOnClose","arguments","length","undefined","modal","ModalFactory","create","type","ModalGateways","TYPE","title","getString","body","Templates","render","console","log","rootElement","getRoot","addToastRegion","on","ModalEvents","hidden","destroy","focus","PaymentEvents","proceed","gateway","querySelector","Selectors","values","value","processPayment","dataset","component","paymentarea","itemid","description","then","message","hide","showNotification","location","href","successurl","catch","Notification","alert","get_string","addToast","add","preventDefault","addEventListener","target","matches","elements","gateways","updateCostRegion","cost","context","getAvailableGateways","html","js","renderForPromise","replaceNodeContents","regions","gatewaysContainer","selectSingleGateway","root","querySelectorAll","checked","defaultCost","gatewayElement","surcharge","parseInt","fee","costContainer","paymentArea","itemId","define","amd","Promise","resolve","reject","require","module","exports","loader","process","init","initialised","document","gatewayTrigger","closest","_exports"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/checkout_manager.min.js b/amd/build/checkout_manager.min.js index b115d758..bab9eeb6 100644 --- a/amd/build/checkout_manager.min.js +++ b/amd/build/checkout_manager.min.js @@ -1,9 +1,9 @@ -define("local_shopping_cart/checkout_manager",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){initControlListener(),function(){const formBody=document.querySelector(SELECTORS.CHECKBOXITEMBODY);formBody&&formBody.addEventListener("change",(function(event){const target=event.target;if(["INPUT","SELECT","TEXTAREA"].includes(target.tagName)){"checkbox"==target.type&&(target.value=target.checked);const changedInput={name:target.name||"unnamed",value:target.value};triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS,{action:formBody.dataset.action,currentstep:formBody.dataset.currentstep,identifier:formBody.dataset.identifier,changedinput:JSON.stringify(changedInput)})}}))}(),function(){const vatNumber=document.getElementById("shopping-cart-checkout-manager-verify-vat");if(vatNumber){const formBody=document.querySelector(SELECTORS.CHECKBOXITEMBODY);vatNumber.addEventListener("click",(function(){const countryCode=document.getElementById("shopping-cart-checkout-manager-country-select").value,vatNumber=document.getElementById("shopping-cart-checkout-manager-vat-number").value;if(!countryCode||!vatNumber)return void alert("Please select a country and enter a valid VAT number.");const changedInput={vatCodeCountry:`${countryCode},${vatNumber}`};triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS,{action:formBody.dataset.action,currentstep:formBody.dataset.currentstep,identifier:formBody.dataset.identifier,changedinput:JSON.stringify(changedInput)})}))}}(),document.addEventListener(EVENTSLISTENING.ADDRESSREDRAWN,(function(){!function(){const formBody=document.querySelector(SELECTORS.CHECKBOXITEMBODY),currentstep=formBody?formBody.dataset.currentstep:null;null!==currentstep&&triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS,{action:"",currentstep:currentstep})}()}))}; +define("local_shopping_cart/checkout_manager",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){initControlListener(),function(){const formBody=document.querySelector(SELECTORS.CHECKBOXITEMBODY);formBody&&formBody.addEventListener("change",(function(event){const target=event.target;if(["INPUT","SELECT","TEXTAREA"].includes(target.tagName)){const processElements=document.querySelectorAll('[data-shopping-cart-process-data="true"]'),changedInputs=Array.from(processElements).map((element=>{const value="checkbox"===element.type?element.checked:element.value;return"radio"==element.type?element.checked?{name:element.name||"unnamed",value:value}:null:{name:element.name||"unnamed",value:value}})).filter((item=>null!==item));if(target.hasAttribute("data-skip-webservice"))return;"checkbox"==target.type&&(target.value=target.checked),triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS,{action:formBody.dataset.action,currentstep:formBody.dataset.currentstep,identifier:formBody.dataset.identifier,changedinput:JSON.stringify(changedInputs)})}}))}(),function(){const vatNumber=document.getElementById("shopping-cart-checkout-manager-verify-vat");if(vatNumber){const formBody=document.querySelector(SELECTORS.CHECKBOXITEMBODY);vatNumber.addEventListener("click",(function(){const countryCode=document.getElementById("shopping-cart-checkout-manager-country-select").value,vatNumber=document.getElementById("shopping-cart-checkout-manager-vat-number").value;if(!countryCode||!vatNumber)return void alert("Please select a country and enter a valid VAT number.");const changedInput={vatCodeCountry:`${countryCode},${vatNumber}`};triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS,{action:formBody.dataset.action,currentstep:formBody.dataset.currentstep,identifier:formBody.dataset.identifier,changedinput:JSON.stringify(changedInput)})}))}}(),document.addEventListener(EVENTSLISTENING.ADDRESSREDRAWN,(function(){!function(){const formBody=document.querySelector(SELECTORS.CHECKBOXITEMBODY),currentstep=formBody?formBody.dataset.currentstep:null;null!==currentstep&&triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS,{action:"",currentstep:currentstep})}()}))}; /* * @package local_shopping_cart * @copyright Wunderbyte GmbH * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -const SELECTORS={CHECKOUTMANAGERFORMID:"#shopping-cart-checkout-manager-form",CHECKOUTMANAGERFORMTEMPLATE:"local_shopping_cart/checkout_manager_form",CHECKOUTMANAGERBUTTONSTEMPLATE:"local_shopping_cart/checkout_manager_form_buttons",CHECKOUTMANAGERBUTTONSID:"shopping-cart-checkout-manager-buttons",CHECKOUTMANAGERPROGRESSBARTEMPLATE:"local_shopping_cart/checkout_manager_form_progress_bar",CHECKOUTMANAGERPROGRESSBARID:"shopping-cart-checkout-manager-status-bar",BUTTONS:".shopping-cart-checkout-manager-buttons button",PROGRESSBUTTONS:".shopping-cart-checkout-manager-status-bar button",CHECKBOXITEMBODY:"#shopping-cart-checkout-manager-form-body",NEWADDRESSBUTTON:".shopping-cart-new-address"},WEBSERVICE={CHECKOUTPROCESS:"local_shopping_cart_control_checkout_process"},EVENTSLISTENING={ADDRESSREDRAWN:"local_shopping_cart/addressesRedrawn"};function initControlListener(){[SELECTORS.BUTTONS,SELECTORS.PROGRESSBUTTONS].forEach((selector=>{document.querySelectorAll(selector).forEach((button=>{button.addEventListener("click",(function(){const action=this.getAttribute("data-action"),currentstep=this.getAttribute("data-currentstep");triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS,{action:action,currentstep:currentstep})}))}))}))}function triggerButtonControlWebService(serviceName,params){require(["core/ajax"],(function(Ajax){Ajax.call([{methodname:serviceName,args:params}])[0].done((function(response){var data;(data=response).data=JSON.parse(data.data),data.reloadbody?require(["core/templates"],(function(templates){templates.render(SELECTORS.CHECKOUTMANAGERFORMTEMPLATE,data.data).then((function(html,js){return templates.replaceNodeContents(document.querySelector(SELECTORS.CHECKOUTMANAGERFORMID),html,js)})).then((function(){if(data.jsscript){const scriptContent=data.jsscript.replace(/]*>|<\/script>/gi,"");try{templates.appendNodeContents(document.querySelector(SELECTORS.CHECKOUTMANAGERFORMID),"",scriptContent)}catch(err){console.error("Error executing script:",err)}}})).catch((function(err){console.error("Error rendering body: ",err)}))})):require(["core/templates"],(function(templates){const controlButtons=document.getElementById(SELECTORS.CHECKOUTMANAGERBUTTONSID),progressBar=document.getElementById(SELECTORS.CHECKOUTMANAGERPROGRESSBARID);if(!controlButtons)return void console.error("Target div not found in the DOM.");const renderButtonTemplate=templates.render(SELECTORS.CHECKOUTMANAGERBUTTONSTEMPLATE,data.data).then((function(html){controlButtons.innerHTML=html})).catch((function(err){console.error("Error updating the specific div:",err)})),progressBarTemplate=templates.render(SELECTORS.CHECKOUTMANAGERPROGRESSBARTEMPLATE,data.data).then((function(html){progressBar.innerHTML=html})).catch((function(err){console.error("Error updating the specific div:",err)}));Promise.all([renderButtonTemplate,progressBarTemplate]).then((function(){console.log("Both templates have been updated."),initControlListener()})).catch((function(err){console.error("Render problem:",err)}))}))})).fail((function(err){console.error("Failed to complete action. Error: ",err)}))}))}})); +const SELECTORS={CHECKOUTMANAGERFORMID:"#shopping-cart-checkout-manager-form",CHECKOUTMANAGERFORMTEMPLATE:"local_shopping_cart/checkout_manager_form",CHECKOUTMANAGERBUTTONSTEMPLATE:"local_shopping_cart/checkout_manager_form_buttons",CHECKOUTMANAGERBUTTONSID:"shopping-cart-checkout-manager-buttons",CHECKOUTMANAGERPROGRESSBARTEMPLATE:"local_shopping_cart/checkout_manager_form_progress_bar",CHECKOUTMANAGERPROGRESSBARID:"shopping-cart-checkout-manager-status-bar",BUTTONS:".shopping-cart-checkout-manager-buttons button",PROGRESSBUTTONS:".shopping-cart-checkout-manager-status-bar button",CHECKBOXITEMBODY:"#shopping-cart-checkout-manager-form-body",NEWADDRESSBUTTON:".shopping-cart-new-address",FEEDBACKMESSAGE:".shopping-cart-checkout-manager-alert-container"},WEBSERVICE={CHECKOUTPROCESS:"local_shopping_cart_control_checkout_process"},EVENTSLISTENING={ADDRESSREDRAWN:"local_shopping_cart/addressesRedrawn"};function initControlListener(){[SELECTORS.BUTTONS,SELECTORS.PROGRESSBUTTONS].forEach((selector=>{document.querySelectorAll(selector).forEach((button=>{button.addEventListener("click",(function(){const action=this.getAttribute("data-action"),currentstep=this.getAttribute("data-currentstep");null!=action&&null!=currentstep&&triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS,{action:action,currentstep:currentstep})}))}))}))}function triggerButtonControlWebService(serviceName,params){require(["core/ajax"],(function(Ajax){Ajax.call([{methodname:serviceName,args:params}])[0].done((function(response){var data;(data=response).data=JSON.parse(data.data),data.reloadbody?require(["core/templates"],(function(templates){templates.render(SELECTORS.CHECKOUTMANAGERFORMTEMPLATE,data.data).then((function(html,js){return templates.replaceNodeContents(document.querySelector(SELECTORS.CHECKOUTMANAGERFORMID),html,js)})).then((function(){if(data.jsscript){const scriptContent=data.jsscript.replace(/]*>|<\/script>/gi,"");try{templates.appendNodeContents(document.querySelector(SELECTORS.CHECKOUTMANAGERFORMID),"",scriptContent)}catch(err){console.error("Error executing script:",err)}}})).catch((function(err){console.error("Error rendering body: ",err)}))})):require(["core/templates"],(function(templates){const controlButtons=document.getElementById(SELECTORS.CHECKOUTMANAGERBUTTONSID),progressBar=document.getElementById(SELECTORS.CHECKOUTMANAGERPROGRESSBARID),feedbackMessageContainer=document.querySelector(SELECTORS.FEEDBACKMESSAGE);if(!controlButtons)return void console.error("Target div not found in the DOM.");const renderButtonTemplate=templates.render(SELECTORS.CHECKOUTMANAGERBUTTONSTEMPLATE,data.data).then((function(html){controlButtons.innerHTML=html})).catch((function(err){console.error("Error updating the specific div:",err)}));console.log("updating the specific div:",data);const progressBarTemplate=templates.render(SELECTORS.CHECKOUTMANAGERPROGRESSBARTEMPLATE,data.data).then((function(html){progressBar.innerHTML=html})).catch((function(err){console.error("Error updating the specific div:",err)}));if(feedbackMessageContainer){const datafeedback=JSON.parse(data.managerdata);feedbackMessageContainer&&null!=datafeedback.feedback&&templates.render("local_shopping_cart/checkout_manager_feedback",datafeedback.feedback).then((function(html){feedbackMessageContainer.innerHTML=html})).catch((function(err){console.error("Error updating feedback message:",err)}))}Promise.all([renderButtonTemplate,progressBarTemplate]).then((function(){console.log("Both templates have been updated."),initControlListener()})).catch((function(err){console.error("Render problem:",err)}))}))})).fail((function(err){console.error("Failed to complete action. Error: ",err)}))}))}})); //# sourceMappingURL=checkout_manager.min.js.map \ No newline at end of file diff --git a/amd/build/checkout_manager.min.js.map b/amd/build/checkout_manager.min.js.map index 6b230d5f..658fd57c 100644 --- a/amd/build/checkout_manager.min.js.map +++ b/amd/build/checkout_manager.min.js.map @@ -1 +1 @@ -{"version":3,"file":"checkout_manager.min.js","sources":["../src/checkout_manager.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/*\n * @package local_shopping_cart\n * @copyright Wunderbyte GmbH \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nconst SELECTORS = {\n CHECKOUTMANAGERFORMID: '#shopping-cart-checkout-manager-form',\n CHECKOUTMANAGERFORMTEMPLATE: 'local_shopping_cart/checkout_manager_form',\n CHECKOUTMANAGERBUTTONSTEMPLATE: 'local_shopping_cart/checkout_manager_form_buttons',\n CHECKOUTMANAGERBUTTONSID: 'shopping-cart-checkout-manager-buttons',\n CHECKOUTMANAGERPROGRESSBARTEMPLATE: 'local_shopping_cart/checkout_manager_form_progress_bar',\n CHECKOUTMANAGERPROGRESSBARID: 'shopping-cart-checkout-manager-status-bar',\n BUTTONS: '.shopping-cart-checkout-manager-buttons button',\n PROGRESSBUTTONS: '.shopping-cart-checkout-manager-status-bar button',\n CHECKBOXITEMBODY: '#shopping-cart-checkout-manager-form-body',\n NEWADDRESSBUTTON: '.shopping-cart-new-address',\n};\n\nconst WEBSERVICE = {\n CHECKOUTPROCESS: 'local_shopping_cart_control_checkout_process',\n};\n\nconst EVENTSLISTENING = {\n ADDRESSREDRAWN: 'local_shopping_cart/addressesRedrawn',\n};\n/**\n * Initializes the checkout manager functionality.\n */\nfunction init() {\n initControlListener();\n initChangeListener();\n initVatNumberVerifyListener();\n document.addEventListener(EVENTSLISTENING.ADDRESSREDRAWN, function() {\n getNewAddress();\n });\n}\n\n/**\n * Initializes the change listener for the form body.\n */\nfunction getNewAddress() {\n const formBody = document.querySelector(SELECTORS.CHECKBOXITEMBODY);\n const currentstep = formBody ? formBody.dataset.currentstep : null;\n if (currentstep !== null) {\n triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS, {\n action: '',\n currentstep: currentstep,\n });\n }\n}\n\n/**\n * Initializes the change listener for the form body.\n */\nfunction initVatNumberVerifyListener() {\n const vatNumber = document.getElementById('shopping-cart-checkout-manager-verify-vat');\n if (vatNumber) {\n const formBody = document.querySelector(SELECTORS.CHECKBOXITEMBODY);\n vatNumber.addEventListener('click', function() {\n const countrySelect = document.getElementById('shopping-cart-checkout-manager-country-select');\n const countryCode = countrySelect.value;\n\n const vatNumberInput = document.getElementById('shopping-cart-checkout-manager-vat-number');\n const vatNumber = vatNumberInput.value;\n\n if (!countryCode || !vatNumber) {\n alert('Please select a country and enter a valid VAT number.');\n return;\n }\n const vatCountryCodeNumber = `${countryCode},${vatNumber}`;\n const changedInput = {\n 'vatCodeCountry': vatCountryCodeNumber,\n };\n triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS, {\n action: formBody.dataset.action,\n currentstep: formBody.dataset.currentstep,\n identifier: formBody.dataset.identifier,\n changedinput: JSON.stringify(changedInput)\n });\n });\n }\n}\n\n/**\n * Initializes the change listener for the form body.\n */\nfunction initControlListener() {\n const buttonSelectors = [SELECTORS.BUTTONS, SELECTORS.PROGRESSBUTTONS];\n buttonSelectors.forEach(selector => {\n const buttons = document.querySelectorAll(selector);\n buttons.forEach(button => {\n button.addEventListener('click', function() {\n const action = this.getAttribute('data-action');\n const currentstep = this.getAttribute('data-currentstep');\n triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS, {\n action: action,\n currentstep: currentstep,\n });\n });\n });\n });\n}\n\n/**\n * Initializes the change listener for the form body.\n */\nfunction initChangeListener() {\n const formBody = document.querySelector(SELECTORS.CHECKBOXITEMBODY);\n if (formBody) {\n formBody.addEventListener('change', function(event) {\n const target = event.target;\n if (['INPUT', 'SELECT', 'TEXTAREA'].includes(target.tagName)) {\n if (target.type == 'checkbox') {\n target.value = target.checked;\n }\n const changedInput = {\n name: target.name || 'unnamed',\n value: target.value,\n };\n triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS, {\n action: formBody.dataset.action,\n currentstep: formBody.dataset.currentstep,\n identifier: formBody.dataset.identifier,\n changedinput: JSON.stringify(changedInput)\n });\n }\n });\n }\n}\n\n/**\n * Handles button control for the checkout process.\n * @param {string} serviceName - The name of the web service.\n * @param {Object} params - The parameters for the web service call.\n */\nfunction triggerButtonControlWebService(serviceName, params) {\n require(['core/ajax'], function (Ajax) {\n const requests = Ajax.call([{\n methodname: serviceName,\n args: params,\n }]);\n requests[0].done(function(response) {\n updateCheckoutManagerPartials(response);\n }).fail(function(err) {\n // eslint-disable-next-line no-console\n console.error('Failed to complete action. Error: ', err);\n return;\n });\n });\n}\n\n/**\n * Updates specific Mustache partials dynamically based on the web service response.\n * @param {Object} data - The data returned from the web service.\n */\nfunction updateCheckoutManagerPartials(data) {\n data.data = JSON.parse(data.data);\n if (data.reloadbody) {\n require(['core/templates'], function(templates) {\n templates.render(SELECTORS.CHECKOUTMANAGERFORMTEMPLATE, data.data)\n .then(function(html, js) {\n return templates.replaceNodeContents(document.querySelector(SELECTORS.CHECKOUTMANAGERFORMID), html, js);\n })\n .then(function() {\n if (data.jsscript) {\n // Extract the raw JavaScript from the script tag\n const scriptContent = data.jsscript.replace(/]*>|<\\/script>/gi, '');\n // Execute the script safely\n try {\n templates.appendNodeContents(\n document.querySelector(SELECTORS.CHECKOUTMANAGERFORMID),\n '',\n scriptContent\n );\n\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error('Error executing script:', err);\n }\n }\n return;\n })\n .catch(function(err) {\n // eslint-disable-next-line no-console\n console.error('Error rendering body: ', err);\n return;\n });\n });\n } else {\n require(['core/templates'], function(templates) {\n // Target a specific div in the DOM\n const controlButtons = document.getElementById(SELECTORS.CHECKOUTMANAGERBUTTONSID);\n const progressBar = document.getElementById(SELECTORS.CHECKOUTMANAGERPROGRESSBARID);\n\n if (!controlButtons) {\n // eslint-disable-next-line no-console\n console.error('Target div not found in the DOM.');\n return;\n }\n // Render new content for the div\n const renderButtonTemplate = templates.render(SELECTORS.CHECKOUTMANAGERBUTTONSTEMPLATE, data.data)\n .then(function(html) {\n controlButtons.innerHTML = html;\n return;\n })\n .catch(function(err) {\n // eslint-disable-next-line no-console\n console.error('Error updating the specific div:', err);\n });\n const progressBarTemplate = templates.render(SELECTORS.CHECKOUTMANAGERPROGRESSBARTEMPLATE, data.data)\n .then(function(html) {\n progressBar.innerHTML = html;\n return;\n })\n .catch(function(err) {\n // eslint-disable-next-line no-console\n console.error('Error updating the specific div:', err);\n });\n Promise.all([renderButtonTemplate, progressBarTemplate]).then(function() {\n // eslint-disable-next-line no-console\n console.log('Both templates have been updated.');\n initControlListener();\n return;\n }).catch(function(err) {\n // eslint-disable-next-line no-console\n console.error('Render problem:', err);\n });\n });\n\n }\n}\n\nexport {init};"],"names":["initControlListener","formBody","document","querySelector","SELECTORS","CHECKBOXITEMBODY","addEventListener","event","target","includes","tagName","type","value","checked","changedInput","name","triggerButtonControlWebService","WEBSERVICE","CHECKOUTPROCESS","action","dataset","currentstep","identifier","changedinput","JSON","stringify","initChangeListener","vatNumber","getElementById","countryCode","alert","vatCodeCountry","initVatNumberVerifyListener","EVENTSLISTENING","ADDRESSREDRAWN","getNewAddress","CHECKOUTMANAGERFORMID","CHECKOUTMANAGERFORMTEMPLATE","CHECKOUTMANAGERBUTTONSTEMPLATE","CHECKOUTMANAGERBUTTONSID","CHECKOUTMANAGERPROGRESSBARTEMPLATE","CHECKOUTMANAGERPROGRESSBARID","BUTTONS","PROGRESSBUTTONS","NEWADDRESSBUTTON","forEach","selector","querySelectorAll","button","this","getAttribute","serviceName","params","require","Ajax","call","methodname","args","done","response","data","parse","reloadbody","templates","render","then","html","js","replaceNodeContents","jsscript","scriptContent","replace","appendNodeContents","err","console","error","catch","controlButtons","progressBar","renderButtonTemplate","innerHTML","progressBarTemplate","Promise","all","log","fail"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"checkout_manager.min.js","sources":["../src/checkout_manager.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/*\n * @package local_shopping_cart\n * @copyright Wunderbyte GmbH \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nconst SELECTORS = {\n CHECKOUTMANAGERFORMID: '#shopping-cart-checkout-manager-form',\n CHECKOUTMANAGERFORMTEMPLATE: 'local_shopping_cart/checkout_manager_form',\n CHECKOUTMANAGERBUTTONSTEMPLATE: 'local_shopping_cart/checkout_manager_form_buttons',\n CHECKOUTMANAGERBUTTONSID: 'shopping-cart-checkout-manager-buttons',\n CHECKOUTMANAGERPROGRESSBARTEMPLATE: 'local_shopping_cart/checkout_manager_form_progress_bar',\n CHECKOUTMANAGERPROGRESSBARID: 'shopping-cart-checkout-manager-status-bar',\n BUTTONS: '.shopping-cart-checkout-manager-buttons button',\n PROGRESSBUTTONS: '.shopping-cart-checkout-manager-status-bar button',\n CHECKBOXITEMBODY: '#shopping-cart-checkout-manager-form-body',\n NEWADDRESSBUTTON: '.shopping-cart-new-address',\n FEEDBACKMESSAGE: '.shopping-cart-checkout-manager-alert-container'\n};\n\nconst WEBSERVICE = {\n CHECKOUTPROCESS: 'local_shopping_cart_control_checkout_process',\n};\n\nconst EVENTSLISTENING = {\n ADDRESSREDRAWN: 'local_shopping_cart/addressesRedrawn',\n};\n/**\n * Initializes the checkout manager functionality.\n */\nfunction init() {\n initControlListener();\n initChangeListener();\n initVatNumberVerifyListener();\n document.addEventListener(EVENTSLISTENING.ADDRESSREDRAWN, function() {\n getNewAddress();\n });\n}\n\n/**\n * Initializes the change listener for the form body.\n */\nfunction getNewAddress() {\n const formBody = document.querySelector(SELECTORS.CHECKBOXITEMBODY);\n const currentstep = formBody ? formBody.dataset.currentstep : null;\n if (currentstep !== null) {\n triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS, {\n action: '',\n currentstep: currentstep,\n });\n }\n}\n\n/**\n * Initializes the change listener for the form body.\n */\nfunction initVatNumberVerifyListener() {\n const vatNumber = document.getElementById('shopping-cart-checkout-manager-verify-vat');\n if (vatNumber) {\n const formBody = document.querySelector(SELECTORS.CHECKBOXITEMBODY);\n vatNumber.addEventListener('click', function() {\n const countrySelect = document.getElementById('shopping-cart-checkout-manager-country-select');\n const countryCode = countrySelect.value;\n\n const vatNumberInput = document.getElementById('shopping-cart-checkout-manager-vat-number');\n const vatNumber = vatNumberInput.value;\n\n if (!countryCode || !vatNumber) {\n alert('Please select a country and enter a valid VAT number.');\n return;\n }\n const vatCountryCodeNumber = `${countryCode},${vatNumber}`;\n const changedInput = {\n 'vatCodeCountry': vatCountryCodeNumber,\n };\n triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS, {\n action: formBody.dataset.action,\n currentstep: formBody.dataset.currentstep,\n identifier: formBody.dataset.identifier,\n changedinput: JSON.stringify(changedInput)\n });\n });\n }\n}\n\n/**\n * Initializes the change listener for the form body.\n */\nfunction initControlListener() {\n const buttonSelectors = [SELECTORS.BUTTONS, SELECTORS.PROGRESSBUTTONS];\n buttonSelectors.forEach(selector => {\n const buttons = document.querySelectorAll(selector);\n buttons.forEach(button => {\n button.addEventListener('click', function() {\n const action = this.getAttribute('data-action');\n const currentstep = this.getAttribute('data-currentstep');\n if (\n action != undefined &&\n currentstep != undefined\n ) {\n triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS, {\n action: action,\n currentstep: currentstep,\n });\n }\n });\n });\n });\n}\n\n/**\n * Initializes the change listener for the form body.\n */\nfunction initChangeListener() {\n const formBody = document.querySelector(SELECTORS.CHECKBOXITEMBODY);\n if (formBody) {\n formBody.addEventListener('change', function(event) {\n const target = event.target;\n if (['INPUT', 'SELECT', 'TEXTAREA'].includes(target.tagName)) {\n const processElements = document.querySelectorAll('[data-shopping-cart-process-data=\"true\"]');\n const changedInputs = Array.from(processElements).map(element => {\n const value = element.type === 'checkbox' ? element.checked : element.value;\n if (\n element.type == 'radio'\n ) {\n if (element.checked) {\n return {\n name: element.name || 'unnamed',\n value: value,\n };\n }\n return null;\n } else {\n return {\n name: element.name || 'unnamed',\n value: value,\n };\n }\n })\n .filter(item => item !== null);\n if (\n target.hasAttribute('data-skip-webservice')\n ) {\n return;\n }\n if (target.type == 'checkbox') {\n target.value = target.checked;\n }\n triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS, {\n action: formBody.dataset.action,\n currentstep: formBody.dataset.currentstep,\n identifier: formBody.dataset.identifier,\n changedinput: JSON.stringify(changedInputs)\n });\n }\n });\n }\n}\n\n/**\n * Handles button control for the checkout process.\n * @param {string} serviceName - The name of the web service.\n * @param {Object} params - The parameters for the web service call.\n */\nfunction triggerButtonControlWebService(serviceName, params) {\n require(['core/ajax'], function (Ajax) {\n const requests = Ajax.call([{\n methodname: serviceName,\n args: params,\n }]);\n requests[0].done(function(response) {\n updateCheckoutManagerPartials(response);\n }).fail(function(err) {\n // eslint-disable-next-line no-console\n console.error('Failed to complete action. Error: ', err);\n return;\n });\n });\n}\n\n/**\n * Updates specific Mustache partials dynamically based on the web service response.\n * @param {Object} data - The data returned from the web service.\n */\nfunction updateCheckoutManagerPartials(data) {\n data.data = JSON.parse(data.data);\n if (data.reloadbody) {\n require(['core/templates'], function(templates) {\n templates.render(SELECTORS.CHECKOUTMANAGERFORMTEMPLATE, data.data)\n .then(function(html, js) {\n return templates.replaceNodeContents(document.querySelector(SELECTORS.CHECKOUTMANAGERFORMID), html, js);\n })\n .then(function() {\n if (data.jsscript) {\n const scriptContent = data.jsscript.replace(/]*>|<\\/script>/gi, '');\n try {\n templates.appendNodeContents(\n document.querySelector(SELECTORS.CHECKOUTMANAGERFORMID),\n '',\n scriptContent\n );\n\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error('Error executing script:', err);\n }\n }\n return;\n })\n .catch(function(err) {\n // eslint-disable-next-line no-console\n console.error('Error rendering body: ', err);\n return;\n });\n });\n } else {\n require(['core/templates'], function(templates) {\n const controlButtons = document.getElementById(SELECTORS.CHECKOUTMANAGERBUTTONSID);\n const progressBar = document.getElementById(SELECTORS.CHECKOUTMANAGERPROGRESSBARID);\n const feedbackMessageContainer = document.querySelector(SELECTORS.FEEDBACKMESSAGE);\n\n if (!controlButtons) {\n // eslint-disable-next-line no-console\n console.error('Target div not found in the DOM.');\n return;\n }\n // Render new content for the div\n const renderButtonTemplate = templates.render(SELECTORS.CHECKOUTMANAGERBUTTONSTEMPLATE, data.data)\n .then(function(html) {\n controlButtons.innerHTML = html;\n return;\n })\n .catch(function(err) {\n // eslint-disable-next-line no-console\n console.error('Error updating the specific div:', err);\n });\n // eslint-disable-next-line no-console\n console.log('updating the specific div:', data);\n const progressBarTemplate = templates.render(SELECTORS.CHECKOUTMANAGERPROGRESSBARTEMPLATE, data.data)\n .then(function(html) {\n progressBar.innerHTML = html;\n return;\n })\n .catch(function(err) {\n // eslint-disable-next-line no-console\n console.error('Error updating the specific div:', err);\n });\n if (feedbackMessageContainer) {\n const datafeedback = JSON.parse(data.managerdata);\n if (\n feedbackMessageContainer &&\n datafeedback.feedback != undefined\n ) {\n templates.render('local_shopping_cart/checkout_manager_feedback', datafeedback.feedback)\n .then(function(html) {\n feedbackMessageContainer.innerHTML = html;\n return;\n })\n .catch(function(err) {\n // eslint-disable-next-line no-console\n console.error('Error updating feedback message:', err);\n });\n }\n }\n Promise.all([renderButtonTemplate, progressBarTemplate]).then(function() {\n // eslint-disable-next-line no-console\n console.log('Both templates have been updated.');\n\n initControlListener();\n return;\n }).catch(function(err) {\n // eslint-disable-next-line no-console\n console.error('Render problem:', err);\n });\n });\n\n }\n}\n\nexport {init};"],"names":["initControlListener","formBody","document","querySelector","SELECTORS","CHECKBOXITEMBODY","addEventListener","event","target","includes","tagName","processElements","querySelectorAll","changedInputs","Array","from","map","element","value","type","checked","name","filter","item","hasAttribute","triggerButtonControlWebService","WEBSERVICE","CHECKOUTPROCESS","action","dataset","currentstep","identifier","changedinput","JSON","stringify","initChangeListener","vatNumber","getElementById","countryCode","alert","changedInput","vatCodeCountry","initVatNumberVerifyListener","EVENTSLISTENING","ADDRESSREDRAWN","getNewAddress","CHECKOUTMANAGERFORMID","CHECKOUTMANAGERFORMTEMPLATE","CHECKOUTMANAGERBUTTONSTEMPLATE","CHECKOUTMANAGERBUTTONSID","CHECKOUTMANAGERPROGRESSBARTEMPLATE","CHECKOUTMANAGERPROGRESSBARID","BUTTONS","PROGRESSBUTTONS","NEWADDRESSBUTTON","FEEDBACKMESSAGE","forEach","selector","button","this","getAttribute","undefined","serviceName","params","require","Ajax","call","methodname","args","done","response","data","parse","reloadbody","templates","render","then","html","js","replaceNodeContents","jsscript","scriptContent","replace","appendNodeContents","err","console","error","catch","controlButtons","progressBar","feedbackMessageContainer","renderButtonTemplate","innerHTML","log","progressBarTemplate","datafeedback","managerdata","feedback","Promise","all","fail"],"mappings":"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"} \ No newline at end of file diff --git a/amd/src/cart.js b/amd/src/cart.js index ce26d36c..26d658ad 100644 --- a/amd/src/cart.js +++ b/amd/src/cart.js @@ -63,7 +63,7 @@ const SELECTORS = { PRICELABELAREA: '.sc_price_label', CHECKOUTBUTTON: '#nav-shopping_cart-popover-container #shopping-cart-checkout-button', PAYMENTREGIONBUTTON: 'div.shopping_cart_payment_region button', - ACCEPTTERMS: '#accepttermsnandconditions', + ACCEPTTERMS: '#accepttermsandconditions', CHECKVATNRFORM: 'div.form_vatnrchecker', }; /** diff --git a/amd/src/checkout_manager.js b/amd/src/checkout_manager.js index 3a08d46a..35146a0d 100644 --- a/amd/src/checkout_manager.js +++ b/amd/src/checkout_manager.js @@ -30,6 +30,7 @@ const SELECTORS = { PROGRESSBUTTONS: '.shopping-cart-checkout-manager-status-bar button', CHECKBOXITEMBODY: '#shopping-cart-checkout-manager-form-body', NEWADDRESSBUTTON: '.shopping-cart-new-address', + FEEDBACKMESSAGE: '.shopping-cart-checkout-manager-alert-container' }; const WEBSERVICE = { @@ -108,10 +109,15 @@ function initControlListener() { button.addEventListener('click', function() { const action = this.getAttribute('data-action'); const currentstep = this.getAttribute('data-currentstep'); - triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS, { - action: action, - currentstep: currentstep, - }); + if ( + action != undefined && + currentstep != undefined + ) { + triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS, { + action: action, + currentstep: currentstep, + }); + } }); }); }); @@ -126,18 +132,40 @@ function initChangeListener() { formBody.addEventListener('change', function(event) { const target = event.target; if (['INPUT', 'SELECT', 'TEXTAREA'].includes(target.tagName)) { + const processElements = document.querySelectorAll('[data-shopping-cart-process-data="true"]'); + const changedInputs = Array.from(processElements).map(element => { + const value = element.type === 'checkbox' ? element.checked : element.value; + if ( + element.type == 'radio' + ) { + if (element.checked) { + return { + name: element.name || 'unnamed', + value: value, + }; + } + return null; + } else { + return { + name: element.name || 'unnamed', + value: value, + }; + } + }) + .filter(item => item !== null); + if ( + target.hasAttribute('data-skip-webservice') + ) { + return; + } if (target.type == 'checkbox') { target.value = target.checked; } - const changedInput = { - name: target.name || 'unnamed', - value: target.value, - }; triggerButtonControlWebService(WEBSERVICE.CHECKOUTPROCESS, { action: formBody.dataset.action, currentstep: formBody.dataset.currentstep, identifier: formBody.dataset.identifier, - changedinput: JSON.stringify(changedInput) + changedinput: JSON.stringify(changedInputs) }); } }); @@ -179,9 +207,7 @@ function updateCheckoutManagerPartials(data) { }) .then(function() { if (data.jsscript) { - // Extract the raw JavaScript from the script tag const scriptContent = data.jsscript.replace(/]*>|<\/script>/gi, ''); - // Execute the script safely try { templates.appendNodeContents( document.querySelector(SELECTORS.CHECKOUTMANAGERFORMID), @@ -204,9 +230,9 @@ function updateCheckoutManagerPartials(data) { }); } else { require(['core/templates'], function(templates) { - // Target a specific div in the DOM const controlButtons = document.getElementById(SELECTORS.CHECKOUTMANAGERBUTTONSID); const progressBar = document.getElementById(SELECTORS.CHECKOUTMANAGERPROGRESSBARID); + const feedbackMessageContainer = document.querySelector(SELECTORS.FEEDBACKMESSAGE); if (!controlButtons) { // eslint-disable-next-line no-console @@ -232,9 +258,24 @@ function updateCheckoutManagerPartials(data) { // eslint-disable-next-line no-console console.error('Error updating the specific div:', err); }); + if (feedbackMessageContainer) { + const datafeedback = JSON.parse(data.managerdata); + if ( + feedbackMessageContainer && + datafeedback.feedback != undefined + ) { + templates.render('local_shopping_cart/checkout_manager_feedback', datafeedback.feedback) + .then(function(html) { + feedbackMessageContainer.innerHTML = html; + return; + }) + .catch(function(err) { + // eslint-disable-next-line no-console + console.error('Error updating feedback message:', err); + }); + } + } Promise.all([renderButtonTemplate, progressBarTemplate]).then(function() { - // eslint-disable-next-line no-console - console.log('Both templates have been updated.'); initControlListener(); return; }).catch(function(err) { diff --git a/checkout.php b/checkout.php index 60076ca7..eb8cd8f0 100644 --- a/checkout.php +++ b/checkout.php @@ -128,39 +128,7 @@ } else { $cartstore = cartstore::instance($userid); $data = $cartstore->get_localized_data(); - - $data["mail"] = $USER->email; - $data["name"] = $USER->firstname . $USER->lastname; - $data["userid"] = $USER->id; - - // Makes sure no open purchase stays active. - shopping_cart::check_for_ongoing_payment($userid); - - // This creates just our list of boght items. - $historylist = new shoppingcart_history_list($userid); - $historylist->insert_list($data); - - // Here we are before checkout. - $expirationtime = shopping_cart::get_expirationtime(); - - // Add or reschedule all delete_item_tasks for all the items in the cart. - shopping_cart::add_or_reschedule_addhoc_tasks($expirationtime, $userid); - - // The modifier "checkout" prepares our data for the checkout page. - // During this process,the new identifier is created, if necessary. - checkout::prepare_checkout($data); - - // We add the vatnrcheckerform here, if necessary. - if ( - get_config('local_shopping_cart', 'showvatnrchecker') - && !empty(get_config('local_shopping_cart', 'owncountrycode') - && !empty(get_config('local_shopping_cart', 'ownvatnrnumber'))) - ) { - $vatnrchecker = new dynamicvatnrchecker(); - $vatnrchecker->set_data_for_dynamic_submission(); - //$data['showvatnrchecker'] = $vatnrchecker->render(); - } - $data['usecreditvalue'] = $data['usecredit'] == 1 ? 'checked' : ''; + $cartstore->get_expanded_checkout_data($data); } // Address handling. diff --git a/classes/external/control_checkout_process.php b/classes/external/control_checkout_process.php index a02677e2..96fcde82 100644 --- a/classes/external/control_checkout_process.php +++ b/classes/external/control_checkout_process.php @@ -31,6 +31,7 @@ use external_function_parameters; use external_value; use external_single_structure; +use local_shopping_cart\local\cartstore; use local_shopping_cart\local\checkout_process\checkout_manager; defined('MOODLE_INTERNAL') || die(); @@ -98,8 +99,12 @@ public static function execute( } $checkoutmanagerdata = $checkoutmanager->render_overview(); $jsfooter = $PAGE->requires->get_end_code(); + $cartstore = cartstore::instance((int)$USER->id); + $data = $cartstore->get_localized_data(); + $cartstore->get_expanded_checkout_data($data); + $data = array_merge($data, $checkoutmanagerdata); return [ - 'data' => json_encode($checkoutmanagerdata), + 'data' => json_encode($data), 'jsscript' => $jsfooter, 'reloadbody' => $reloadbody, 'managerdata' => json_encode($managerdata), diff --git a/classes/local/cartstore.php b/classes/local/cartstore.php index 0cbab873..c6034404 100644 --- a/classes/local/cartstore.php +++ b/classes/local/cartstore.php @@ -26,8 +26,10 @@ namespace local_shopping_cart\local; use coding_exception; +use local_shopping_cart\form\dynamicvatnrchecker; use local_shopping_cart\local\entities\cartitem; use local_shopping_cart\local\pricemodifier\modifier_info; +use local_shopping_cart\output\shoppingcart_history_list; use local_shopping_cart\shopping_cart; use moodle_exception; use context_system; @@ -507,6 +509,47 @@ public function get_localized_data() { return $data; } + /** + * Return the data with localized strings. + * + * @return mixed + */ + public function get_expanded_checkout_data(&$data) { + global $USER; + $data["mail"] = $USER->email; + $data["name"] = $USER->firstname . $USER->lastname; + $data["userid"] = $USER->id; + + // Makes sure no open purchase stays active. + shopping_cart::check_for_ongoing_payment($USER->id); + + // This creates just our list of boght items. + $historylist = new shoppingcart_history_list($USER->id); + $historylist->insert_list($data); + + // Here we are before checkout. + $expirationtime = shopping_cart::get_expirationtime(); + + // Add or reschedule all delete_item_tasks for all the items in the cart. + shopping_cart::add_or_reschedule_addhoc_tasks($expirationtime, $USER->id); + + // The modifier "checkout" prepares our data for the checkout page. + // During this process,the new identifier is created, if necessary. + checkout::prepare_checkout($data); + + // We add the vatnrcheckerform here, if necessary. + if ( + get_config('local_shopping_cart', 'showvatnrchecker') + && !empty(get_config('local_shopping_cart', 'owncountrycode') + && !empty(get_config('local_shopping_cart', 'ownvatnrnumber'))) + ) { + $vatnrchecker = new dynamicvatnrchecker(); + $vatnrchecker->set_data_for_dynamic_submission(); + //$data['showvatnrchecker'] = $vatnrchecker->render(); + } + $data['usecreditvalue'] = $data['usecredit'] == 1 ? 'checked' : ''; + } + /** * Reset the singleton to force new build from cache and price modifiers. diff --git a/classes/local/checkout_process/checkout_base_item.php b/classes/local/checkout_process/checkout_base_item.php index d1df44dd..4cf7e7a6 100644 --- a/classes/local/checkout_process/checkout_base_item.php +++ b/classes/local/checkout_process/checkout_base_item.php @@ -78,4 +78,20 @@ public static function get_icon_progress_bar() { public static function get_status_progress_bar() { return 'inactive'; } + + /** + * Validation feedback. + * @return string + */ + public static function get_validation_feedback() { + return null; + } + + /** + * Validation feedback. + * @return string + */ + public static function get_error_feedback() { + return null; + } } diff --git a/classes/local/checkout_process/checkout_manager.php b/classes/local/checkout_process/checkout_manager.php index 7a169c94..e06be8da 100644 --- a/classes/local/checkout_process/checkout_manager.php +++ b/classes/local/checkout_process/checkout_manager.php @@ -76,8 +76,8 @@ public function __construct( $this->controlparameter = $controlparameter; $this->managercache = self::get_cache($identifier); $this->itemlist = self::get_itemlist_preprocess(); - // TESTING - // $this->controlparameter['currentstep'] = 2; + self::set_body_mandatory_count(); + //$this->controlparameter['currentstep'] = 2; } /** @@ -105,14 +105,18 @@ public function render_overview() { } $currentstep = self::set_current_step(); $checkoutmanager['checkout_manager_body']['currentstep'] = $currentstep; + $checkoutmanager['checkout_manager_body']['show_progress_line'] = + count($checkoutmanager['checkout_manager_body']['item_list']) > 1 ? true : false; self::set_active_page($checkoutmanager['checkout_manager_body']['item_list'], $currentstep); if (self::has_multiple_items($checkoutmanager['checkout_manager_body'])) { $checkoutmanager['checkout_manager_body']['buttons'] = - self::render_checkout_buttons( + self::render_navigation_buttons( $checkoutmanager['checkout_manager_body']['item_list'], $currentstep ); } + $checkoutmanager['checkout_manager_body']['buttons']['checkout_button'] = + self::render_checkout_button(); $checkoutmanager['checkout_manager_body']['body'] = self::render_checkout_body($checkoutmanager['checkout_manager_body']['item_list']); self::render_checkout_head($checkoutmanager['checkout_manager_head']); @@ -134,7 +138,6 @@ public function get_itemlist_preprocess() { */ public function check_preprocess($changedinput) { $bodycounter = 0; - $mandatorycounter = 0; foreach ($this->itemlist as $item) { $filename = basename($item, '.php'); $classname = self::NAMESPACE_PREFIX . $filename; @@ -145,33 +148,78 @@ public function check_preprocess($changedinput) { $this->managercache['steps'][$filename], $changedinput ); + if ($this->managercache['steps'][$filename]['valid']) { + $this->managercache['feedback'] = [ + 'validationmessage' => $iteminstance->get_validation_feedback(), + ]; + } else { + $this->managercache['feedback'] = [ + 'errormessage' => $iteminstance->get_error_feedback(), + ]; + } } if ($iteminstance->is_head() === false) { $bodycounter += 1; } - if ($iteminstance->is_mandatory()) { - $mandatorycounter += 1; - } } } - self::get_checkout_validation($mandatorycounter); + self::get_checkout_validation(); self::set_cache(); return $this->managercache; } /** - * Applies the given price modifiers on the cached data. + * Sets the body and mandatory count if not there yet. */ - public function get_checkout_validation($mandatorycounter) { - $this->managercache['checkout_validation'] = true; - foreach ($this->managercache['steps'] as $step) { - if ($step['valid'] === false) { - $this->managercache['checkout_validation'] = false; - break; + public function set_body_mandatory_count() { + if (!isset($this->managercache['body_mandatory_count'])) { + $bodycounter = 0; + $mandatorycounter = 0; + foreach ($this->itemlist as $item) { + $filename = basename($item, '.php'); + $classname = self::NAMESPACE_PREFIX . $filename; + if (self::class_exists_is_active($classname)) { + $iteminstance = new $classname(); + if ($iteminstance->is_head() === false) { + $bodycounter += 1; + } + if ($iteminstance->is_mandatory()) { + $mandatorycounter += 1; + } + } } + $this->managercache['body_mandatory_count'] = [ + 'body_count' => $bodycounter, + 'mandatory_count' => $mandatorycounter, + ]; + self::set_cache(); } - if ($mandatorycounter !== count($this->managercache['steps'])) { - $this->managercache['checkout_validation'] = false; + } + + /** + * Applies the given price modifiers on the cached data. + */ + public function get_checkout_validation() { + $mandatorycachedcounter = $this->managercache['body_mandatory_count']['mandatory_count']; + $mandatorycurrentcounter = 0; + $bodycounter = $this->managercache['body_mandatory_count']['body_count']; + $this->managercache['checkout_validation'] = false; + if (isset($this->managercache['steps'])) { + foreach ($this->managercache['steps'] as $step) { + if ($step['mandatory'] === true) { + if ($step['valid'] === false) { + return; + } else { + $mandatorycurrentcounter++; + } + } + } + if ( + $mandatorycachedcounter <= $mandatorycurrentcounter && + $bodycounter <= count($this->managercache['viewed']) + ) { + $this->managercache['checkout_validation'] = true; + } } } @@ -255,6 +303,12 @@ public function render_checkout_body($itemlist) { if ($item['status'] == 'active') { $iteminstance = new $item['classname'](); $classname = self::get_class_name($item['classname']); + if (!isset($this->managercache['viewed'])) { + $this->managercache['viewed'] = []; + } + $this->managercache['viewed'][$classname] = true; + self::get_checkout_validation(); + self::set_cache(); return $iteminstance->render_body($this->managercache['steps'][$classname] ?? []); } } @@ -273,12 +327,20 @@ public static function set_first_step_active(&$itemlist) { } } + /** + * Applies the given price modifiers on the cached data. + * @param array $itemlist + */ + public function render_checkout_button() { + return $this->managercache['checkout_validation'] ?? false; + } + /** * Applies the given price modifiers on the cached data. * @param array $classname * @return array */ - public function render_checkout_buttons($itemlist, $currentstep) { + public function render_navigation_buttons($itemlist, $currentstep) { $previousbutton = [ 'text' => get_string('previousbutton', 'local_shopping_cart'), 'hidden' => $currentstep == 0 ? true : false, diff --git a/classes/local/checkout_process/items/addresses.php b/classes/local/checkout_process/items/addresses.php index 613cbe08..94298610 100644 --- a/classes/local/checkout_process/items/addresses.php +++ b/classes/local/checkout_process/items/addresses.php @@ -176,14 +176,16 @@ public static function get_required_address_keys(): array { */ public static function check_status( $managercachestep, - $changedinput + $validationdata ) { $data = $managercachestep['data']; $requiredaddresskeys = self::get_required_address_keys(); - $changedinput = json_decode($changedinput); + $validationdata = json_decode($validationdata); foreach ($requiredaddresskeys as $requiredaddresskey) { - if (str_contains($changedinput->name, $requiredaddresskey)) { - $data[$changedinput->name] = $changedinput->value; + foreach ($validationdata as $address) { + if (str_contains($address->name, $requiredaddresskey)) { + $data[$address->name] = $address->value; + } } } return [ @@ -202,10 +204,10 @@ public static function is_valid( $requiredaddresskeys, $data ) { - $requiredkeys = count($requiredaddresskeys); + $requiredkeys = $requiredaddresskeys ? count($requiredaddresskeys) : null; $currentkeys = count($data); - if ($requiredkeys == $currentkeys) { + if ($requiredkeys === $currentkeys) { return true; } return false; diff --git a/classes/local/checkout_process/items/termsandconditions.php b/classes/local/checkout_process/items/termsandconditions.php index 727841ae..eda337fc 100644 --- a/classes/local/checkout_process/items/termsandconditions.php +++ b/classes/local/checkout_process/items/termsandconditions.php @@ -41,7 +41,13 @@ class termsandconditions extends checkout_base_item { * @return bool */ public static function is_active() { - return get_config('local_shopping_cart', 'accepttermsandconditions') ? true : false; + if ( + get_config('local_shopping_cart', 'accepttermsandconditions') || + get_config('local_shopping_cart', 'acceptadditionalconditions') + ) { + return true; + } + return false; } /** @@ -66,7 +72,12 @@ public static function is_mandatory() { public static function render_body($cachedata) { global $PAGE; $data = []; - $data['termsandconditions'] = get_config('local_shopping_cart', 'termsandconditions'); + if (get_config('local_shopping_cart', 'accepttermsandconditions')) { + $data['termsandconditions'] = get_config('local_shopping_cart', 'termsandconditions'); + } + if (get_config('local_shopping_cart', 'acceptadditionalconditions')) { + $data['additionalconditions'] = get_config('local_shopping_cart', 'additionalconditions'); + } self::set_data_from_cache($data, $cachedata['data']); $template = $PAGE->get_renderer('local_shopping_cart') @@ -83,26 +94,35 @@ public static function render_body($cachedata) { */ public static function check_status( $managercachestep, - $changedinput + $validationdata ) { - $changedinput = json_decode($changedinput); + $validationdata = json_decode($validationdata); $data = []; - $data[$changedinput->name] = $changedinput->value; - + foreach ($validationdata as $validationvalue) { + $data[$validationvalue->name] = $validationvalue->value; + } return [ 'data' => $data, 'mandatory' => self::is_mandatory(), - 'valid' => self::is_valid($changedinput->value), + 'valid' => self::is_valid($validationdata), ]; } /** * Returns the required-address keys as specified in the plugin config. - * + * @param array $validationdata * @return bool list of all required address keys */ - public static function is_valid($validationstring) { - return $validationstring === 'true'; + public static function is_valid($validationdata) { + foreach ($validationdata as $validationvalue) { + if ( + !isset($validationvalue->value) || + $validationvalue->value == false + ) { + return false; + } + } + return true; } /** @@ -111,10 +131,6 @@ public static function is_valid($validationstring) { * @param array $cachedata */ public static function set_data_from_cache(&$termsandconditions, $cachedata) { - if ($cachedata['accepttermsnandconditions']) { - $termsandconditions['selected'] = true; - } else { - unset($termsandconditions['selected']); - } + $termsandconditions = array_merge($termsandconditions, $cachedata ?? []); } } diff --git a/classes/local/checkout_process/items/vatnrchecker.php b/classes/local/checkout_process/items/vatnrchecker.php index 2862c9ab..1cae385b 100644 --- a/classes/local/checkout_process/items/vatnrchecker.php +++ b/classes/local/checkout_process/items/vatnrchecker.php @@ -84,7 +84,7 @@ public static function render_body($cachedata) { /** * Generates the data for rendering the templates/address.mustache template. - * @param array $termsandconditions + * @param array $vatnrcheckerdata * @param array $cachedata */ public static function set_data_from_cache(&$vatnrcheckerdata, $cachedata) { @@ -108,15 +108,6 @@ public static function set_cached_selected_country(&$vatnrcheckerdata, $countryc } } - /** - * Generates the data for rendering the templates/address.mustache template. - * @param array $vatnrcheckerdata - * @param array $country - */ - public static function set_cached_vatnumber(&$vatnrcheckerdata, $vatnumber) { - ; - } - /** * Renders checkout item. * @return array @@ -156,6 +147,7 @@ public static function check_status( $changedinput ): array { $data = $changedinput ?? []; + $vatnumbercheck = false; try { $changedinput = self::get_input_data($changedinput); if (isset($changedinput['country']) && isset($changedinput['vatnumber'])) { @@ -180,7 +172,6 @@ public static function check_status( 'valid' => $vatnumbercheck, ]; } - /** * Returns the required-address keys as specified in the plugin config. * @@ -197,4 +188,20 @@ public static function get_input_data( 'vatnumber' => $vatnumber, ]; } + + /** + * Validation feedback. + * @return string + */ + public static function get_validation_feedback() { + return get_string('vatnrvalidationfeedback', 'local_shopping_cart'); + } + + /** + * Validation feedback. + * @return string + */ + public static function get_error_feedback() { + return get_string('vatnrerrorfeedback', 'local_shopping_cart'); + } } diff --git a/classes/local/vatnrchecker.php b/classes/local/vatnrchecker.php index 805c89ad..72a98eb3 100644 --- a/classes/local/vatnrchecker.php +++ b/classes/local/vatnrchecker.php @@ -25,6 +25,8 @@ namespace local_shopping_cart\local; +use SoapClient; + /** * Class templaterule * @@ -82,7 +84,6 @@ public static function check_vatnr_number(string $countrycode, string $vatnrnumb $response = self::validate_with_vatcomply($vatnrnumber); break; } - $response = json_decode($response, true); if (isset($response['valid']) && $response['valid']) { return true; } @@ -93,23 +94,46 @@ public static function check_vatnr_number(string $countrycode, string $vatnrnumb * Function to return an array of localized country codes. * @param string $countrycode * @param string $vatnumber - * @return string + * @return array */ public static function validate_with_vies($countrycode, $vatnumber) { - $url = self::VATVIESCHECKERURL; - $data = json_encode(['countryCode' => $countrycode, 'vatNumber' => $vatnumber]); - return self::make_vat_post_request($url, $data); + $wsdl = "https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl"; + try { + $client = new SoapClient($wsdl); + return (array) $client->checkVat([ + 'countryCode' => $countrycode, + 'vatNumber' => $vatnumber, + ]); + } catch (\Exception $e) { + return [ + 'error' => true, + 'message' => $e->getMessage(), + ]; + } } /** * Function to return an array of localized country codes. * @param string $vatnumber - * @return string + * @return array */ public static function validate_with_hmrc($vatnumber) { - $url = self::VATHMRCCHECKERURL; - $data = json_encode(['vatNumber' => $vatnumber]); - return self::make_vat_post_request($url, $data); + if (!preg_match('/^\d{9}$/', $vatnumber)) { + return [ + 'error' => true, + ]; + } + $digits = str_split($vatnumber); + $weights = [8, 7, 6, 5, 4, 3, 2, 1]; + $sum = 0; + for ($i = 0; $i < 8; $i++) { + $sum += $digits[$i] * $weights[$i]; + } + $remainder = $sum % 97; + $checkdigit = 97 - $remainder; + return [ + 'valid' => (int)$digits[8] === $checkdigit, + ]; } /** diff --git a/lang/de/local_shopping_cart.php b/lang/de/local_shopping_cart.php index 5e98973d..67d54413 100644 --- a/lang/de/local_shopping_cart.php +++ b/lang/de/local_shopping_cart.php @@ -25,6 +25,8 @@ defined('MOODLE_INTERNAL') || die(); +$string['acceptadditionalconditions'] = "Bestätigung zusätzlicher Konditionen verlangen"; +$string['acceptadditionalconditions:description'] = "Ohne Häkchen bei den zusätzlichen Konditionen ist buchen nicht möglich."; $string['accepttermsandconditions'] = "Bestätigung der AGBs verlangen"; $string['accepttermsandconditions:description'] = "Ohne Häkchen bei den AGBs ist buchen nicht möglich."; $string['accessdenied'] = 'Zugriff verweigert'; @@ -34,6 +36,9 @@ $string['adddiscounttoitem'] = 'Der Preis dieses Artikels kann entweder um einen absoluten Betrag oder einen Prozentwert reduziert werden, nicht aber um beides.'; $string['addedtocart'] = '{$a} wurde in den Warenkorb gelegt.'; +$string['additionalconditions'] = "Zusätzliche Konditionen"; +$string['additionalconditions:description'] = "Sie können hier z.B. ein PDF verlinken. Für Übersetzungen verwenden Sie die + Moodle Sprachfilter."; $string['additonalcashiersection'] = 'Text für den Kassa-Bereich'; $string['additonalcashiersection:description'] = 'HTML Shortcodes oder Buchungsoptionen für den Kassabereich hinzufügen'; $string['addon'] = 'Zusätzliche Zeit festlegen'; @@ -171,6 +176,7 @@ $string['choosehighertimestamp'] = 'Wählen Sie einen späteren Zeipunkt'; $string['chooseplatform'] = 'Plattform wählen'; $string['chooseplatformdesc'] = 'Wählen Sie Ihre Rechnungsplattform aus.'; +$string['confirmadditionalconditions'] = "Zusätzliche Konditionen akzeptieren"; $string['confirmcancelallbody'] = 'Möchten Sie den Kauf für alle aktuellen Käufer:innen wirklich stornieren? Folgende Nutzer:innen erhalten den Kaufpreis zurück: {$a->userlist} @@ -219,6 +225,7 @@ $string['confirmpaidback'] = 'Bestätige Auszahlung'; $string['confirmpaidbackbody'] = 'Wollen Sie die Auszahlung bestätigen? Das setzt das Guthaben auf 0.'; $string['confirmpaidbacktitle'] = 'Bestätige Auszahlung'; +$string['confirmpayment'] = 'Bezahlung bestätigen'; $string['confirmterms'] = "AGBs akzeptieren"; $string['confirmzeropricecheckout'] = 'Bestätige'; $string['confirmzeropricecheckoutbody'] = 'Für diese Buchung ist keine Zahlung notwendig. @@ -604,6 +611,8 @@ $string['usevatnr'] = "UID eingeben"; $string['vatnrcheckerheading'] = "UID überprüfen"; $string['vatnrcheckerheadingdescription'] = "Vor dem Zahlen kann eine UID eingegeben und überprüft werden"; +$string['vatnrerrorfeedback'] = 'UID ist nicht gültig!'; +$string['vatnrvalidationfeedback'] = 'Gültige UID erkannt'; $string['verify'] = "UID prüfen"; $string['wronginputvalue'] = 'Die eingegebenen Werte sind ungültig.'; $string['xi'] = "Nordirland"; diff --git a/lang/en/local_shopping_cart.php b/lang/en/local_shopping_cart.php index f0048e06..256516f4 100644 --- a/lang/en/local_shopping_cart.php +++ b/lang/en/local_shopping_cart.php @@ -25,6 +25,8 @@ defined('MOODLE_INTERNAL') || die(); +$string['acceptadditionalconditions'] = "Require acceptance of additional conditions"; +$string['acceptadditionalconditions:description'] = "Without accepting additional conditions, buying is not possible."; $string['accepttermsandconditions'] = "Require acceptance of terms and conditions"; $string['accepttermsandconditions:description'] = "Without accepting terms and conditions, buying is not possible."; $string['accessdenied'] = 'Access denied'; @@ -33,6 +35,9 @@ $string['adddiscounttoitem'] = 'You can reduce the price of this item either by a fixed sum or a percentage of the initial price. You can\'t apply both at the same time.'; $string['addedtocart'] = '{$a} was added to your cart.'; +$string['additionalconditions'] = "Additional Conditions"; +$string['additionalconditions:description'] = "You can link to your PDF. For localization of this field, use + Moodle multi-language filters."; $string['additonalcashiersection'] = 'Add text for cashier section'; $string['additonalcashiersection:description'] = 'Add HTML shortcodes or items to buy for the cashier shopping tab'; $string['addon'] = 'Set addon time'; @@ -170,6 +175,7 @@ $string['choosehighertimestamp'] = 'Choose a later time'; $string['chooseplatform'] = 'Choose Platform'; $string['chooseplatformdesc'] = 'Select your invoicing platform.'; +$string['confirmadditionalconditions'] = "I accept the additional conditions"; $string['confirmcancelallbody'] = 'Do you really want to cancel this purchase for all users? The following users will get their money back as credit: {$a->userlist} @@ -225,6 +231,7 @@ $string['confirmpaidbackbody'] = 'Do you really want to confirm that you have paid back the user her credit? This will set her credit to 0.'; $string['confirmpaidbacktitle'] = 'Confirm Payback'; +$string['confirmpayment'] = 'Confirm payment'; $string['confirmterms'] = "I accept the terms and conditions"; $string['confirmzeropricecheckout'] = 'Confirm'; $string['confirmzeropricecheckoutbody'] = 'You do not have to pay anything. Do you want to proceed and book?'; @@ -675,6 +682,8 @@ $string['usevatnr'] = "Enter VAT number"; $string['vatnrcheckerheading'] = "Check VAT number"; $string['vatnrcheckerheadingdescription'] = "A VAT number can be entered and checked before payment"; +$string['vatnrerrorfeedback'] = 'Vat number is invalid!'; +$string['vatnrvalidationfeedback'] = 'Vat number was successfull validated'; $string['verify'] = "Verify validity of VAT number"; $string['wronginputvalue'] = 'The provided input value is invalid.'; $string['xi'] = "Northern Ireland"; diff --git a/settings.php b/settings.php index 9dac56b4..3e1e092c 100644 --- a/settings.php +++ b/settings.php @@ -258,6 +258,21 @@ ) ); + $settings->add( + new admin_setting_configcheckbox('local_shopping_cart/acceptadditionalconditions', + get_string('acceptadditionalconditions', 'local_shopping_cart'), + get_string('acceptadditionalconditions:description', 'local_shopping_cart'), 0)); + + $settings->add( + new admin_setting_configtextarea( + 'local_shopping_cart/additionalconditions', + get_string('additionalconditions', 'local_shopping_cart'), + get_string('additionalconditions:description', 'local_shopping_cart'), + null, + PARAM_RAW + ) + ); + // If this setting is turned on, all customers have to pay the sellers tax template. $settings->add( new admin_setting_configcheckbox('local_shopping_cart/owncountrytax', diff --git a/templates/address.mustache b/templates/address.mustache index 27f482b8..21a18b73 100644 --- a/templates/address.mustache +++ b/templates/address.mustache @@ -52,6 +52,7 @@ {{#selected}} checked {{/selected}} + data-shopping-cart-process-data="true" />