function getHashData() { var hash = window.location.hash.substr(1); var data = hash.split("&").reduce(function (result, item) { var parts = item.split("="); result[parts[0]] = decodeURIComponent(parts[1]); return result; }, {}); return data; } /** * Logger object provides abstraction for logging */ function Logger(){ var self = this; } Logger.logEnabled = true; Logger.log = function(context, message){ if(typeof message == "undefined"){ message = context; context = "COMMON"; } //if log is enabled, we console log message if(Logger.logEnabled){ console.log(context+': '+message); } } Logger.error = function(context, message){ if(typeof message == "undefined"){ message = context; context = "COMMON"; } //if log is enabled, we console log message if(Logger.logEnabled){ console.error(context+': '+message); } } Logger.warn = function(context, message){ if(typeof message == "undefined"){ message = context; context = "COMMON"; } //if log is enabled, we console log message if(Logger.logEnabled){ console.warn(context+': '+message); } } /** * FilipAlert system ... contains queue of alerts * and provides interface for showing alerts */ function FilipAlert(){ var self = this; self.queue = []; self.active = false; } FilipAlert.prototype.queue = []; FilipAlert.prototype.elements = { overlay: document.getElementById("filip_overlay"), title: document.getElementById("filip_header"), message: document.getElementById("filip_text"), buttonsBar: document.getElementById("filip_actionBar"), actionButton: document.getElementById("filip_action"), closeButton: document.getElementById("filip_close_action"), note: document.getElementById("filip_note"), } FilipAlert.prototype.active = false; FilipAlert.prototype.show = function(){ var self = this; Logger.log("FilipAlert", "called show()"); if(self.active){ Logger.log("FilipAlert", "Alert is already active."); return; } if(self.queue.length == 0){ Logger.log("FilipAlert", "Queue is empty."); return; } //get first alert from queue var alertObject = self.queue.shift(); Logger.log("FilipAlert", "Showing alert: "+alertObject.title); //show alert self.active = true; //set title self.elements.title.innerHTML = alertObject.title; //set message self.elements.message.innerHTML = alertObject.message; //set note if(alertObject.note){ self.elements.note.innerHTML = alertObject.note; self.elements.note.style.display = "block"; } else { self.elements.note.style.display = "none"; } var showButtonBar = false; //set action button if(alertObject.action){ self.elements.actionButton.innerHTML = alertObject.action.text; self.elements.actionButton.onclick = alertObject.action.action; showButtonBar = true; } //set close button if(alertObject.close){ self.elements.closeButton.innerHTML = alertObject.close.text; showButtonBar = true; } if(showButtonBar){ self.elements.buttonsBar.style.display = "flex"; } else { self.elements.buttonsBar.style.display = "none"; } //show overlay self.elements.overlay.style.display = "block"; } FilipAlert.prototype.open = function(alertObject){ var self = this; Logger.log("FilipAlert", "New alert: "+alertObject.title); //add alert to queue self.queue.push(alertObject); //if alert is not active, we show it if(!self.active){ self.show(); } } FilipAlert.prototype.close = function(){ var self = this; Logger.log("FilipAlert", "Closing alert."); //hide alert self.active = false; //hide overlay self.elements.overlay.style.display = "none"; //if queue is not empty, we show next alert if(self.queue.length > 0){ self.show(); } } /** * eshopApi object provide abstraction interfase for the API Calls */ function EshopApi(){ Logger.log("EshopApi", "Creating EshopApi object."); var self = this; //base url for the API self.baseUrl = "/wp-json/slovanet-eshop"; } EshopApi.prototype.baseUrl = null; EshopApi.prototype.request = async function(method, url, data){ Logger.log("EshopApi", "Request: "+method+" "+url); //create xhttp request var xhttp = new XMLHttpRequest(); //create promise return new Promise(function(resolve, reject){ xhttp.open(method, url, true); xhttp.setRequestHeader("Content-Type", "application/json"); xhttp.onreadystatechange = function(){ if (xhttp.readyState == 4) { if(xhttp.status == 200){ try { var response = JSON.parse(xhttp.responseText); return resolve(response); } catch (e) { Logger.error("EshopApi", "Error parsing response: " + e.message); return resolve(xhttp.responseText); } } else { try { var response = JSON.parse(xhttp.responseText); if(response.error){ return reject(response.error); } Logger.error("EshopApi", "No error in response!") return reject(xhttp.status); } catch (e) { Logger.error("EshopApi", "Error parsing (error) response: " + e.message); return reject(xhttp.status); } } } }; if(data){ xhttp.send(JSON.stringify(data)); } else { xhttp.send(); } }); } EshopApi.prototype.searchCities = async function(query){ Logger.log("EshopApi", "Searching cities for query: "+query); var self = this; return self.request("GET", self.baseUrl+"/search/cities?query="+query); } EshopApi.prototype.searchStreets = async function(city, query){ Logger.log("EshopApi", "Searching streets for city: "+city+"; query: "+query); var self = this; return self.request("GET", self.baseUrl+"/search/streets?city="+city+"&query="+query); } EshopApi.prototype.getProducts = async function(address){ Logger.log("EshopApi", "Getting products for address: "+address.city+", "+address.street+" "+address.number); var self = this; //if any of alwaysAvailableST, alwaysAvailableVSD, alwaysAvailableSSD is set and true use getCategoryProducts instead getProducts var useCategoryProducts = false; var alwaysAvailableST = false; var alwaysAvailableVSD = false; var alwaysAvailableSSD = false; if(typeof address.alwaysAvailableST != "undefined" && address.alwaysAvailableST){ alwaysAvailableST = true; useCategoryProducts = true; } if(typeof address.alwaysAvailableVSD != "undefined" && address.alwaysAvailableVSD){ alwaysAvailableVSD = true; useCategoryProducts = true; } if(typeof address.alwaysAvailableSSD != "undefined" && address.alwaysAvailableSSD){ alwaysAvailableSSD = true; useCategoryProducts = true; } if(useCategoryProducts){ return self.request("GET", self.baseUrl+"/products/getCategoryProducts?city="+address.city+"&street="+address.street+"&number="+address.number+"&st="+alwaysAvailableST+"&vsd="+alwaysAvailableVSD+"&ssd="+alwaysAvailableSSD); } return self.request("GET", self.baseUrl+"/products/getProducts?city="+address.city+"&street="+address.street+"&number="+address.number); } EshopApi.prototype.getTitulus = async function(){ Logger.log("EshopApi", "Getting titulus"); var self = this; return self.request("GET", self.baseUrl+"/enums/titulus"); } EshopApi.prototype.getCompanyTypes = async function(){ Logger.log("EshopApi", "Getting company types"); var self = this; return self.request("GET", self.baseUrl+"/enums/companyTypes"); } EshopApi.prototype.getBuildingTypes = async function(){ Logger.log("EshopApi", "Getting building types"); var self = this; return self.request("GET", self.baseUrl+"/enums/buildingTypes"); } EshopApi.prototype.getZipByCity = async function(city){ Logger.log("EshopApi", "Getting zip by city: "+city); var self = this; return self.request("GET", self.baseUrl+"/search/zip?city="+city); } EshopApi.prototype.closeOrder = async function(data){ Logger.log("EshopApi", "Closing order: "); var self = this; return self.request("POST", self.baseUrl+"/orders/close", data); } DatalayerWrapper = function(){ var self = this; self.events = []; } DatalayerWrapper.prototype.events = []; DatalayerWrapper.prototype.push = function(event){ var self = this; self.events.push(event); Logger.log("Datalayer", "Pushing event to datalayer: "+JSON.stringify(event)); if(window.dataLayer){ window.dataLayer.push(event); } } var datalayerWrapper = new DatalayerWrapper(); //create eshopApi instance var eshopApi = new EshopApi(); /** * cart object stores information about the current "cart" and "order" * e.g. selected address, selected products, client information, etc. * * cart automatically saves its state to localStorage, and restores it on page load */ function Cart(){ Logger.log("Cart", "Creating Cart object."); let self = this; //set default values self.selectedAddress = self.emptyAddress; self.products = self.emptyProducts; self.client = self.emptyClient; //chache for avaliable products,if address is not changed, we dont need to load products again self.avaliableProducts = null; //set random id self.id = Math.random().toString(36).substring(7); //load saved values from localStorage self.load(); } Cart.prototype.selectedAddress = null; Cart.prototype.products = null; Cart.prototype.client = null; Cart.prototype.subcategory = null; Cart.prototype.isVerified = false; Cart.prototype.id = null; Cart.prototype.save = function(){ Logger.log("Cart", "Saving cart to LS"); let self = this; localStorage.setItem("cart", JSON.stringify({ id: self.id, selectedAddress: self.selectedAddress, products: self.products, client: self.client, subcategory: self.subcategory, isVerified: self.isVerified })); }; Cart.prototype.load = function(){ let self = this; let cart = localStorage.getItem("cart"); if(cart){ Logger.log("Cart", "Loading cart from LS"); self.loading = true; cart = JSON.parse(cart); self.selectedAddress = cart.selectedAddress; if(typeof forcedAddress!=="undefined" && forcedAddress!=null){ self.selectedAddress = forcedAddress; } let hashData = getHashData(); if(hashData.mesto && hashData.ulica && hashData.cislo){ self.selectedAddress.city = hashData.mesto; self.selectedAddress.street = hashData.ulica; self.selectedAddress.number = hashData.cislo; } self.products = cart.products; self.client = cart.client; self.subcategory = cart.subcategory; self.isVerified = cart.isVerified; if(cart.id){ self.id = cart.id; } else { self.id = Math.random().toString(36).substring(7); self.save(); } //get avaliable products self.loadAvaliableProducts().then(function(){ self.loading = false; }); } else { let hashData = getHashData(); if(hashData.mesto && hashData.ulica && hashData.cislo){ self.selectedAddress.city = hashData.mesto; self.selectedAddress.street = hashData.ulica; self.selectedAddress.number = hashData.cislo; setTimeout(function(){ self.setAddress({ city: hashData.mesto, street: hashData.ulica, number: hashData.cislo }); }, 0); } } } Cart.prototype.emptyClient = { short: { name: "", surname: "", email: "", phone: "", titulus: "" }, full: null }; Cart.prototype.emptyProducts = { topProduct: null, subProducts: { net: null, tv: null, voice: null }, additional: [] }; Cart.prototype.emptyAddress = { city: "", street: "", number: "" }; Cart.prototype.loading = false; Cart.prototype.previewAddress = { city: "Bratislava (Bratislava)", street: "Kresánkova", number: "4" }; Cart.prototype.isInCart = function(productCode){ let self = this; productCode = productCode.toLowerCase(); //check if product is in subProducts for(let type in self.products.subProducts){ if(!self.products.subProducts[type]){ continue; } if(self.products.subProducts[type].toLowerCase() == productCode){ return true; } } if(self.products.topProduct!=null && self.products.topProduct.toLowerCase() == productCode){ return true; } //check if product is in additional for(let i = 0; i < self.products.additional.length; i++){ if(self.products.additional[i].toLowerCase() == productCode){ return true; } } return false; } Cart.prototype.getFullInfo = function(){ /** * returns full cart information * means array of "flat" sections * { * price: 0, //sum of flat prices at given flat period * packageDiscount: 0, //discount for package - ussualy price of topProduct is less than sum of flat prices of subProducts it contains, difference is package discount * start: 1, //start month of flat period (one based, starting 1st month means now) * duration: 3, //duration of flat period * products: [ * { * name: "Internet 100", * price: 10, //price of product at given flat period * code: "B_NP_1235" //product code * }, * ... * ] * } * and "install" section * { * price: 0, //sum of install prices of all products * packageDiscount: 0, //discount for package - ussualy price of topProduct is less than sum of install prices of subProducts it contains, difference is package discount * products: [ * { * name: "Internet 100", * price: 10, //price of product at given flat period * code: "B_NP_1235" //product code * }, * ... * ] * } */ let self = this; var result = { flatSections: [], installSection: { price: 0, packageDiscount: 0, products: [] } }; //get topProduct var topProduct = self.getTopProduct(self.products.topProduct); if(!topProduct){ return result; } //we create two arrays of products, //one for topProduct + additional products (aditional, devices, tvPackages) to calculate package price //second for subProducts (net, voice, tv) + additional products (aditional, devices, tvPackages) to full price var fullProducts = []; var packageProducts = []; //add topProduct to packageProducts packageProducts.push(topProduct); //add subProducts to fullProducts for(let type in self.products.subProducts){ if(self.products.subProducts[type]){ var sProduct = self.products.subProducts[type]; var subProduct = topProduct.prodList[sProduct]; if(subProduct){ fullProducts.push(subProduct); } } } //add additional products to both arrays for(let i = 0; i < self.products.additional.length; i++){ var aProduct = self.products.additional[i]; var additionalProduct = topProduct.prodList[aProduct]; if(additionalProduct){ fullProducts.push(additionalProduct); packageProducts.push(additionalProduct); } } //add devices to both arrays /*for(let i = 0; i < self.products.devices.length; i++){ var dProduct = self.products.devices[i]; var deviceProduct = topProduct.prodList[dProduct]; if(deviceProduct){ fullProducts.push(deviceProduct); packageProducts.push(deviceProduct); } }*/ //add tvPackages to both arrays /*for(let i = 0; i < self.products.tvPackages.length; i++){ var tProduct = self.products.tvPackages[i]; var tvProduct = topProduct.prodList[tProduct]; if(tvProduct){ fullProducts.push(tvProduct); packageProducts.push(tvProduct); } }*/ //create install section var installSection = { price: 0, packageDiscount: 0, products: [] }; var fullPrice = 0; //calculate full price and add products to install section for(let i = 0; i < fullProducts.length; i++){ var product = fullProducts[i]; fullPrice += product.prices.install; installSection.products.push({ name: product.name, price: product.prices.install, code: product.code, description: product.description }); } //calculate package price var packagePrice = 0; for(let i = 0; i < packageProducts.length; i++){ var product = packageProducts[i]; packagePrice += product.prices.install; } //set install section price installSection.price = packagePrice; //set install section package discount installSection.packageDiscount = fullPrice - packagePrice; result.installSection = installSection; /** * Flat sections * every product can have different flat prices for different periods, * we need to create "breakpoints" whenever any product price changes * */ var breakpoints = []; //we iterate over all products and create breakpoints (add unique start months) for(let i = 0; i < fullProducts.length; i++){ var product = fullProducts[i]; for(let j = 0; j < product.prices.flatPrices.length; j++){ var flatPrice = product.prices.flatPrices[j]; if(breakpoints.indexOf(flatPrice.startMonth) == -1){ breakpoints.push(flatPrice.startMonth); } } } result.breakpoints = breakpoints; //sort breakpoints breakpoints.sort(function(a, b){ return a - b; }); //create flat sections var flatSections = []; for(let i = 0; i < breakpoints.length; i++){ var duration = null; if(i < breakpoints.length - 1){ duration = breakpoints[i+1] - breakpoints[i]; } var fullPrice = 0; var packagePrice = 0; var products = []; //calculate full price and add products to flat section for(let j = 0; j < fullProducts.length; j++){ var product = fullProducts[j]; //we need to find flat price for current month, so we iterate over //all flat prices of product and find one where startMonth is less //or equal to sections start month and endMonth (startMonth + duration) //is greater than sections start month var flatPrice = null; for(let k = 0; k < product.prices.flatPrices.length; k++){ var fPrice = product.prices.flatPrices[k]; if(fPrice.duration == null){ fPrice.duration = 1000; } var endMonth = fPrice.startMonth + fPrice.duration; if(fPrice.startMonth <= breakpoints[i] && endMonth > breakpoints[i]){ flatPrice = fPrice; break; } } if(flatPrice){ fullPrice += flatPrice.price; products.push({ name: product.name, price: flatPrice.price, code: product.code, description: product.description }); } } //calculate package price for(let j = 0; j < packageProducts.length; j++){ var product = packageProducts[j]; //we need to find flat price for current month, so we iterate over //all flat prices of product and find one where startMonth is less //or equal to sections start month and endMonth (startMonth + duration) //is greater than sections start month var flatPrice = null; for(let k = 0; k < product.prices.flatPrices.length; k++){ var fPrice = product.prices.flatPrices[k]; if(fPrice.duration == null){ fPrice.duration = 1000; } var endMonth = fPrice.startMonth + fPrice.duration; if(fPrice.startMonth <= breakpoints[i] && endMonth > breakpoints[i]){ flatPrice = fPrice; break; } } if(flatPrice){ packagePrice += flatPrice.price; } } //create flat section var flatSection = { price: packagePrice, packageDiscount: fullPrice - packagePrice, start: breakpoints[i], duration: duration, products: products }; flatSections.push(flatSection); } result.flatSections = flatSections; return result; } Cart.prototype.getProducts = function(){ var self = this; return self.products; } Cart.prototype.getSummaryInfo = function(){ /** * returns object with summary information about cart, { * totatFlatPrice: 0, //flat price of all products at first month * totalInstallPrice: 0, * topProductName: "", * } * * OR * * null if cart is empty //e.g. no topProduct selected */ let self = this; if(!self.products.topProduct){ return null; } //get topProduct var topProduct = self.getTopProduct(self.products.topProduct); if(!topProduct){ return null; } var summary = { totalFlatPrice: 0, totalInstallPrice: 0, topProductName: topProduct.name, boundPeriod: topProduct.boundPeriod }; //get flat price of topProduct var flatPrice = topProduct.prices.flatPrices[0].price; //get install price of topProduct var installPrice = topProduct.prices.install; //add prices of additional products for(let i = 0; i < self.products.additional.length; i++){ //find product code in topProduct.additional[anyType] var additionalProduct = self.getProduct(self.products.additional[i]); if(!additionalProduct){ continue; } //add flat price if(additionalProduct.prices.flatPrices[0]){ flatPrice += additionalProduct.prices.flatPrices[0].price; } //add install price if(additionalProduct.prices.install){ installPrice += additionalProduct.prices.install; } } //set summary prices summary.totalFlatPrice = flatPrice; summary.totalInstallPrice = installPrice; return summary; } Cart.prototype.setSubcategory = function(subcategory){ Logger.log("Cart", "Setting subcategory: "+subcategory); let self = this; //check if subcategory is primary or secondary offer if(self.avaliableProducts.offers.primary != subcategory && self.avaliableProducts.offers.secondary != subcategory){ //subcategory is not valid Logger.error("Cart", "Subcategory is not valid: "+subcategory); return; } //if subcategory is not changed, we dont need to load products again if(self.subcategory == subcategory){ return; } //set subcategory self.subcategory = subcategory; //we need to clear products self.products = self.emptyProducts; //save cart self.save(); //emit event setTimeout(function(){ var event = new CustomEvent("cartSubcategoryChanged", {detail: subcategory}); document.dispatchEvent(event); }, 0); } Cart.prototype.getSubcategory = function(){ var self = this; return self.subcategory; } Cart.prototype.getTopProductWaiting = function(callback){ var self = this; if( self.loading){ console.log("Waiting for loading to finish."); setTimeout(function(){ self.getTopProductWaiting(callback); }, 100); return; } return callback(self.getTopProduct(self.products.topProduct)); } Cart.prototype.getTopProductPromise = function(){ var self = this; return new Promise(function(resolve, reject){ if(!self.products.topProduct){ return resolve(null); } if(self.loading){ //we wait for loading to finish return self.getTopProductWaiting(resolve); } //get topProduct return resolve(self.getTopProduct(self.products.topProduct)); }) } Cart.prototype.getTopProduct = function(productCode){ var self = this; if(!self.avaliableProducts){ return null; } if(!self.avaliableProducts.subcategories[self.subcategory]){ return null; } //get current subcategory var subcategory = self.avaliableProducts.subcategories[self.subcategory]; //check if product is in topProducts for(var i = 0; i < subcategory.topProducts.length; i++){ var topProduct = subcategory.topProducts[i]; if(topProduct.code.toLowerCase() == productCode.toLowerCase()){ return topProduct; } } return null; } Cart.prototype.findTopProduct = function(topProducts, subProducts){ //check if topProduct exists var tProduct = null; for(var i = 0; i < topProducts.length; i++){ var topProduct = topProducts[i]; //we trying to found bad examples to fast determine that topProduct not contains current combination of subProducts //first we check if situations where top products contains (netProduct, voiceProduct, tvProduct) but we dont have any in cart // or oposit situations where we have some subProducts in cart but not in topProduct if((topProduct.netProduct!=null && subProducts.net == null) || (topProduct.netProduct==null && subProducts.net != null)){ continue; } if((topProduct.voiceProduct!=null && subProducts.voice == null) || (topProduct.voiceProduct==null && subProducts.voice != null)){ continue; } if((topProduct.tvProduct!=null && subProducts.tv == null) || (topProduct.tvProduct==null && subProducts.tv != null)){ continue; } //so now either selected subProducts are in both topProduct and cart or not in both //if is in both, we need to check if they are different e.g. topProduct.[netProduct|voiceProduct|tvProduct].code != subProducts.[net|voice|tv] if(topProduct.netProduct!=null && topProduct.netProduct.toLowerCase() != subProducts.net.toLowerCase()){ continue; } if(topProduct.voiceProduct!=null && topProduct.voiceProduct.toLowerCase() != subProducts.voice.toLowerCase()){ continue; } if(topProduct.tvProduct!=null && topProduct.tvProduct.toLowerCase() != subProducts.tv.toLowerCase()){ continue; } //if we are here, we found topProduct that contains current combination of subProducts tProduct = topProduct; } if(tProduct == null){ return null; } return tProduct; } Cart.prototype.isPosibleToAddSubProduct = function(productCode, type){ var self = this; if(!cart.isVerified){ filipAlert("Chyba", "Je potrebné najprv overiť adresu."); return; } //check if product is already in cart if(self.isInCart(productCode)){ Logger.error("Cart", "Product already in cart: "+productCode); return false; } //check if product is in avaliable products if(!self.avaliableProducts){ Logger.error("Cart", "Avaliable products not loaded."); return false; } if(!self.avaliableProducts.subcategories[self.subcategory]){ Logger.error("Cart", "Subcategory not found: "+self.subcategory); return false; } //get current subcategory var subcategory = self.avaliableProducts.subcategories[self.subcategory]; //check if product is in subcategory if(!subcategory.subProducts[type]){ Logger.error("Cart", "Subcategory does not contain type: "+type); return false; } var exists = false; for (var i = 0; i < subcategory.subProducts[type].length; i++) { if(subcategory.subProducts[type][i].code == productCode){ exists = true; break; } } if(!exists){ Logger.error("Cart", "Product not found in subcategory: "+productCode); return false; } //check product conditions //check product conditions var condition = self.checkProductConditions(productCode); if(condition !== true){ if(condition!==false){ if(condition.message.title && condition.message.text){ filipAlert(condition.message.title, condition.message.text); } } Logger.log("Cart", "Conditions not met for product: "+productCode); return; } //check if topProduct exists that contains curently selected combination of subProducts (after adding/replacing new subProduct) var subProducts = self.products.subProducts; //replace subProduct with new one subProducts[type] = productCode; //check if topProduct exists var topProduct = self.findTopProduct(subcategory.topProducts, subProducts); //if topProduct exists, we return topProduct, otherwise false if(topProduct){ return topProduct; }else{ Logger.error("Cart", "Imposible combination. TopProduct not found."); } return false; } Cart.prototype.isPosibleToRemoveSubProduct = function(productCode, type){ var self = this; //check if product is already in cart if(self.isInCart(productCode)){ return false; } //check if product is in avaliable products if(!self.avaliableProducts){ return false; } if(!self.avaliableProducts.subcategories[self.subcategory]){ return false; } //get current subcategory var subcategory = self.avaliableProducts.subcategories[self.subcategory]; //check if topProduct exists that contains curently selected combination of subProducts (after adding/replacing new subProduct) var subProducts = self.products.subProducts; //replace subProduct with new one subProducts[type] = productCode; //check if topProduct exists var topProduct = self.findTopProduct(subcategory.topProducts, subProducts); //if topProduct exists, we return topProduct, otherwise false if(topProduct){ return topProduct; } return false; } Cart.prototype.addSubProduct = function(productCode, type){ Logger.log("Cart", "Adding product to cart: "+productCode); let self = this; var topProduct = self.isPosibleToAddSubProduct(productCode, type); if(!topProduct){ Logger.error("Cart", "Product cannot be added to cart: "+productCode); //we just dont add product to cart return; } //add product to subProducts self.products.subProducts[type] = productCode; //set topProduct self.products.topProduct = topProduct.code; //clear additional products self.products.additional = []; self.save(); //create and dispatch event setTimeout(function(){ var event = new CustomEvent("cartProductAdded", {detail: productCode}); document.dispatchEvent(event); }, 0); } Cart.prototype.rmSubProduct = function(productCode, type){ Logger.log("Cart", "Removing product from cart: "+productCode); let self = this; var topProduct = self.isPosibleToRemoveSubProduct(productCode, type); if(!topProduct){ Logger.error("Cart", "Product cannot be removed from cart: "+productCode); //we remove all subProducts self.products.subProducts = { net: null, tv: null, voice: null }; Logger.error("Cart", "Imposible combination. All subProducts removed from cart."); //set topProduct self.products.topProduct = null; //remove additional products self.products.additional = []; self.save(); //create and dispatch event setTimeout(function(){ var event = new CustomEvent("cartProductRemoved", {detail: productCode}); document.dispatchEvent(event); }, 0); return; } //remove product from subProducts self.products.subProducts[type] = null; //set topProduct self.products.topProduct = topProduct.code; self.save(); //create and dispatch event setTimeout(function(){ var event = new CustomEvent("cartProductRemoved", {detail: productCode}); document.dispatchEvent(event); }, 0); } Cart.prototype.checkProductConditions = function(productCode){ let self = this; //get product data we want to add var product = self.getProduct(productCode); if(!product){ Logger.error("Cart", "Product not found: "+productCode); return false; } if(!product.conditions){ //nothig to check return true; } //types we have var types = { "net": false, "tv": false, "voice": false } if(self.products.subProducts.net){ types.net = true; } if(self.products.subProducts.tv){ types.tv = true; } if(self.products.subProducts.voice){ types.voice = true; } //check conditions for(var i = 0; i < product.conditions.length; i++){ var condition = product.conditions[i]; /** * worksOnSubcategory * do checks only if product current subcategory is one of worksOnSubcategory */ var currentSubcategory = self.subcategory; /*if(condition.conditions.worksOnSubcategory && condition.conditions.worksOnSubcategory.indexOf(currentSubcategory) == -1){ continue; }*/ /** * subTypeRequired */ if(condition.conditions.subTypeRequired){ //all subTypes must be in cart for(var j = 0; j < condition.conditions.subTypeRequired.length; j++){ var subType = condition.conditions.subTypeRequired[j]; if(!types[subType]){ return condition; } } } /** * prodsRejected * any of prodsRejected must not be in cart * if any of prodsRejected is in cart, we return false */ if(condition.conditions.prodsRejected){ //any of prodsRejected must not be in cart for(var j = 0; j < condition.conditions.prodsRejected.length; j++){ var prod = condition.conditions.prodsRejected[j]; if(self.isInCart(prod)){ return condition; } } } /** * prodsRequired * all prodsRequired must be in cart * if not, we return false * */ if(condition.conditions.prodsRequired){ for(var j = 0; j < condition.conditions.prodsRequired.length; j++){ var prod = condition.conditions.prodsRequired[j]; if(!self.isInCart(prod)){ return condition; } } } } //if we are here, all conditions are met return true; } Cart.prototype.addProduct = function(productCode, type){ let self = this; if(self.isInCart(productCode)){ return; } if(type == "sub"){ return self.addSubProduct(productCode); } if(!cart.isVerified){ filipAlert("Chyba", "Je potrebné najprv overiť adresu."); return; } //check product conditions var condition = self.checkProductConditions(productCode); if(condition !== true){ if(condition.message.title && condition.message.text){ filipAlert(condition.message.title, condition.message.text); } Logger.log("Cart", "Conditions not met for product: "+productCode); return; } Logger.log("Cart", "Adding product to cart: "+productCode); //if(type == "additional"){ //get product data var product = self.getProduct(productCode); if(!product){ Logger.error("Cart", "Product not found: "+productCode); return; } //add product to additional self.products.additional.push(productCode); //} self.save(); //create and dispatch event setTimeout(function(){ var event = new CustomEvent("cartProductAdded", {detail: productCode}); document.dispatchEvent(event); }, 0); } Cart.prototype.removeProduct = function(productCode){ //remove product from cart whene is is subProduct, tvPackage, additional or device Logger.log("Cart", "Removing product from cart: "+productCode); let self = this; //check if product is in subProducts for(let type in self.products.subProducts){ if(self.products.subProducts[type] && self.products.subProducts[type].toLowerCase() == productCode.toLowerCase()){ return self.rmSubProduct(productCode, type); } } //check if product is in additional for(let i = 0; i < self.products.additional.length; i++){ if(self.products.additional[i].toLowerCase() == productCode.toLowerCase()){ self.products.additional.splice(i, 1); self.save(); //create and dispatch event setTimeout(function(){ var event = new CustomEvent("cartProductRemoved", {detail: productCode}); document.dispatchEvent(event); }, 0); return; } } } Cart.prototype.getTopProduct = function(){ //returns current topProduct let self = this; if(!self.avaliableProducts){ return null; } if(!self.avaliableProducts.subcategories[self.subcategory]){ return null; } //get current subcategory var subcategory = self.avaliableProducts.subcategories[self.subcategory]; //check if topProduct exists for(var i = 0; i < subcategory.topProducts.length; i++){ var topProduct = subcategory.topProducts[i]; if(topProduct.code.toLowerCase() == self.products.topProduct.toLowerCase()){ return topProduct; } } return null; } Cart.prototype.getProduct = function(productCode){ //returns product by productCode let self = this; //get current subcategory var subcategory = self.avaliableProducts.subcategories[self.subcategory]; //iterate over topProducts for(var i = 0; i < subcategory.topProducts.length; i++){ var topProduct = subcategory.topProducts[i]; //find product in topProduct.prodList if(topProduct.prodList[productCode]){ return topProduct.prodList[productCode]; } } return null; } Cart.prototype.avaliableProducts = null; Cart.prototype.closeOrder = function(type){ Logger.log("Cart", "Closing order"); var self = this; eshopApi.closeOrder({ type: type, contactInfo: cart.getContactInfo(), address: cart.getAddress(), fullInfo: cart.getFullInfo(), products: cart.getProducts() }).then(function(response){ //clear cart self.clear(); }).catch(function(error){ Logger.error("Cart", "Error closing order: "+error.message); }); } Cart.prototype.clear = function(){ Logger.log("Cart", "Clearing cart"); var self = this; //clear client self.id = Math.random().toString(36).substring(7); self.client = self.emptyClient; self.products = self.emptyProducts; self.selectedAddress = self.emptyAddress; self.isVerified = false; self.subcategory = null; //remove avaliable products self.avaliableProducts = null; self.save(); //create and dispatch event setTimeout(function(){ var event = new CustomEvent("cartCleared"); document.dispatchEvent(event); }, 0); } Cart.prototype.setAddress = function(address){ Logger.log("Cart", "Setting address: "+address.city+", "+address.street+" "+address.number); var self = this; self.clear(); self.selectedAddress = { city: address.city, street: address.street, number: address.number, alwaysAvailableST: address.alwaysAvailableST, alwaysAvailableVSD: address.alwaysAvailableVSD, alwaysAvailableSSD: address.alwaysAvailableSSD }; self.isVerified = true; self.subcategory = null; self.save(); //create and dispatch event setTimeout(function(){ var event = new CustomEvent("cartAddressChanged", {detail: address}); document.dispatchEvent(event); }, 0); //load products self.avaliableProducts = null; //we get available products for address ... //we dont need to wait for it, when new products are needed, we generate event self.loadAvaliableProducts(); } Cart.prototype.getAddress = function(){ return this.selectedAddress; } Cart.prototype.loadAvaliableProducts = function(){ Logger.log("Cart", "Loading avaliable products."); var self = this; return new Promise(function(resolve, reject){ if(self.avaliableProducts!=null){ return resolve(true); } //create and dispatch cartLoading event setTimeout(function(){ var event = new CustomEvent("cartLoading", {detail: "start"}); document.dispatchEvent(event); }, 0); var address = self.selectedAddress; if(!address.city || !address.street || !address.number || !self.isVerified){ selectedAddress = self.emptyAddress; address = self.previewAddress; } eshopApi.getProducts(address).then(function(products){ self.avaliableProducts = products.products; //set subcategory to primary offer if not set if(!self.subcategory){ self.subcategory = products.products.offers.primary; } setTimeout(function(){ var event = new CustomEvent("cartLoading", {detail: "end"}); document.dispatchEvent(event); }, 0); //create and dispatch event setTimeout(function(){ var event = new CustomEvent("cartAvaliableProducts", {detail: products.products}); document.dispatchEvent(event); }, 0); return resolve(true); }).catch(function(error){ Logger.error("Cart", "Error loading avaliable products: "+error.message); return resolve(false); }); }); } Cart.prototype.setContactInfo = function(contactInfo){ var self = this; self.client.short = contactInfo; self.save(); } Cart.prototype.getContactInfo = function(){ return this.client.short; } Cart.prototype.getClientInfo = function(){ return this.client.full; } Cart.prototype.setClientInfo = function(clientInfo){ var self = this; self.client.full = clientInfo; self.save(); } //create cart instance var cart = new Cart(); /** * CartSummaryTemplate object provides abstraction for the cart summary element */ function CartSummaryTemplate(cartObject){ var self = this; self.cartObject = cartObject; //listen on cartProductAdded, cartCleared and cartAddressChanged events document.addEventListener("cartProductAdded", function(e){ self.render(); }); document.addEventListener("cartProductRemoved", function(e){ self.render(); }); document.addEventListener("cartCleared", function(e){ self.render(); }); document.addEventListener("cartAddressChanged", function(e){ self.render(); }); document.addEventListener("cartSubcategoryChanged", function(e){ self.render(); }); //listen on cartLoading event document.addEventListener("cartLoading", function(e){ self.render(); }); } CartSummaryTemplate.prototype.element = document.getElementById("summary"); CartSummaryTemplate.prototype.elementFlatPrice = document.getElementById("summary-flat-price"); CartSummaryTemplate.prototype.elementInstallPrice = document.getElementById("summary-install-price"); CartSummaryTemplate.prototype.elementTitle = document.getElementById("summary-title"); CartSummaryTemplate.prototype.elementDescription = document.getElementById("summary-desc"); CartSummaryTemplate.prototype.cartObject = null; CartSummaryTemplate.prototype.render = function(){ var self = this; if(!self.cartObject){ //nothing to render return; } var cartSummary = self.cartObject.getSummaryInfo(); Logger.log("CartSummaryTemplate", "Rendering cart summary"); if(!cartSummary){ self.element.style.display = "none"; return; } self.element.style.display = "block"; self.elementFlatPrice.innerText = formatPrice(cartSummary.totalFlatPrice); self.elementInstallPrice.innerText = formatPrice(cartSummary.totalInstallPrice); self.elementTitle.innerText = cartSummary.topProductName; if(cartSummary.boundPeriod == 0){ self.elementDescription.innerText = "Bez viazanosti"; }else{ self.elementDescription.innerText = "Viazanosť: " + cartSummary.boundPeriod + " mesiacov"; } } function CartTemplate(cartObject){ var self = this; self.cartObject = cartObject; //listen on cartProductAdded, cartCleared and cartAddressChanged events document.addEventListener("cartProductAdded", function(e){ self.render(); }); document.addEventListener("cartProductRemoved", function(e){ self.render(); }); document.addEventListener("cartCleared", function(e){ self.render(); }); document.addEventListener("cartSubcategoryChanged", function(e){ self.render(); }); document.addEventListener("cartAddressChanged", function(e){ self.render(); }); } CartTemplate.prototype.cartObject = null; CartTemplate.prototype.element = document.getElementById("cart"); CartTemplate.prototype.elementFlatSection = document.getElementById("CartFlatPrices"); CartTemplate.prototype.elementInstallSection = document.getElementById("CartInstallPrices"); CartTemplate.prototype.elementPageContainer = document.getElementById("st-container"); CartTemplate.prototype.open = function(){ var self = this; //add class st-menu-open to page container self.elementPageContainer.classList.add("st-menu-open"); //set isOpened to true self.isOpened = true; //render cart (in case of changes) self.render(); } CartTemplate.prototype.close = function(){ var self = this; //set isOpened to false self.isOpened = true; //remove class st-menu-open from page container self.elementPageContainer.classList.remove("st-menu-open"); } CartTemplate.prototype.toggle = function(){ var self = this; if(self.isOpened){ return self.close(); } return self.open(); } CartTemplate.prototype.renderFlatSection = function(flatSection){ var src = ''; src += '
'+"\n"; src += '
'+"\n"; src += '

Mesačné poplatky Od '+flatSection.start+'. mesiaca

'+"\n"; src += '
'+"\n"; src += '
'+"\n"; for(var i = 0; i < flatSection.products.length; i++){ var product = flatSection.products[i]; src += '
'+"\n"; src += '
'+"\n"; src += ' x'+"\n"; src += '
'+"\n"; src += '
'+product.name+'
'+"\n"; src += '
'+formatPrice(product.price)+'€
'+"\n"; src += '
'+"\n"; } src += '
'+"\n"; src += '
Balíková zľava
'+"\n"; src += '
-'+formatPrice(flatSection.packageDiscount)+'€
'+"\n"; src += '
'+"\n"; src += '
'+"\n"; src += '
Spolu
'+"\n"; src += '
'+formatPrice(flatSection.price)+'€
'+"\n"; src += '


'+"\n"; return src; } CartTemplate.prototype.isOpened = false; CartTemplate.prototype.renderInstallSection = function(installSection){ var src = ''; src += '
'+"\n"; src += '
'+"\n"; src += '

Jednorazové poplatky

'+"\n"; src += '
'+"\n"; src += '
'+"\n"; for(var i = 0; i < installSection.products.length; i++){ var product = installSection.products[i]; src += '
'+"\n"; src += '
'+"\n"; src += ' x'+"\n"; src += '
'+"\n"; src += '
'+product.name+'
'+"\n"; src += '
'+formatPrice(product.price)+'€
'+"\n"; src += '
'+"\n"; } src += '
'+"\n"; src += '
Balíková zľava
'+"\n"; src += '
-'+formatPrice(installSection.packageDiscount)+'€
'+"\n"; src += '
'+"\n"; src += '
'+"\n"; src += '
Spolu
'+"\n"; src += '
'+formatPrice(installSection.price)+'€
'+"\n"; src += '


'+"\n"; return src; } CartTemplate.prototype.render = function(){ var self = this; if(!self.cartObject){ //nothing to render return; } var cartInfo = self.cartObject.getFullInfo(); if(!cartInfo){ //nothing to render return; } //clear elements self.elementFlatSection.innerHTML = ""; self.elementInstallSection.innerHTML = ""; //render flat sections for(var i = 0; i < cartInfo.flatSections.length; i++){ var flatSection = cartInfo.flatSections[i]; self.elementFlatSection.innerHTML += self.renderFlatSection(flatSection); } //render install section self.elementInstallSection.innerHTML = self.renderInstallSection(cartInfo.installSection); } /** * -------------------------------------------------------- * -------------------------------------------------------- * ----------------TEMPLATE SPECIFIC CODE------------------ * -------------------------------------------------------- * e.g. Listening on events on DOM elements, creating new * DOM elements from data, etc. */ //eshopTemplate object provides abstraction for the template function EshopTemplateStep1(){ var self = this; //search elements self.addressSearchElements.city = self.getElement("mesto"); self.addressSearchElements.street = self.getElement("ulica"); self.addressSearchElements.number = self.getElement("cislo"); self.addressSearchElements.availabilityBar = self.getElement("availability"); self.addressSearchElements.addressBar = self.getElement("address-bar"); self.addressSearchElements.addressText = self.getElement("address-bar__address"); self.addressSearchElements.searchForm = self.getElement("eshop_finder"); self.productsElements.intetnetRow = self.getElement("internet-new"); self.productsElements.telefonovanieRow = self.getElement("telefonovanie-new"); self.productsElements.televiziaRow = self.getElement("televizia-new"); self.productsElements.loadingOverlay = self.getElement("loading"); self.productsElements.primaryOffer = self.getElement("base-products"); //self.productsElements.secondaryOffers = self.getElement("more-products"); self.cartSummary = new CartSummaryTemplate(cart); self.cartTemplate = new CartTemplate(cart); //it is posible that cart loading event is triggered before we add event listeners so we need to check if cart is loading //and show loading overlay if it is if(cart.loading){ self.loadStart(); } //get address from cart var address = cart.getAddress(); //listen to cartProductAdded event document.addEventListener("cartProductAdded", function(e){ //get available products from cart if(cart.avaliableProducts){ self.renderProducts(cart.avaliableProducts); } }); document.addEventListener("cartProductRemoved", function(e){ //get available products from cart if(cart.avaliableProducts){ self.renderProducts(cart.avaliableProducts); } }); //listen to cartAvailableProducts event document.addEventListener("cartAvaliableProducts", function(e){ self.renderProducts(e.detail); }); //add event listeners on cartSubcategoryChanged event document.addEventListener("cartSubcategoryChanged", function(e){ self.renderProducts(cart.avaliableProducts); }); //add event listeners on cartLoading event document.addEventListener("cartLoading", function(e){ Logger.log("Eshop.step1", "Cart loading event triggered: "+e.detail); if(e.detail == "start"){ self.loadStart(); } else { self.loadEnd(); } }); //if city, street or number is empty, show availability bar if(address.city == "" || address.street == "" || address.number == ""){ self.showAvailability(); //we disable and clear street and number inputs self.addressSearchElements.street.disabled = true; self.addressSearchElements.street.value = ""; self.addressSearchElements.number.disabled = true; self.addressSearchElements.number.value = ""; self.aCitySelected = false; self.aStreetSelected = false; } else { //we set address to the inputs in case client wants to change it self.addressSearchElements.city.value = address.city; self.addressSearchElements.street.value = address.street; self.addressSearchElements.number.value = address.number; //if ST, VSD and SSD elements exists, we check if they are in cart //if element id alwaysAvailableST, then set alwaysAvailableST to true if is checked if(document.getElementById("alwaysAvailableST")){ document.getElementById("alwaysAvailableST").checked = (typeof address.alwaysAvailableST != "undefined" && address.alwaysAvailableST); } //if element id alwaysAvailableSSD, then set alwaysAvailableSSD to true if is checked if(document.getElementById("alwaysAvailableSSD")){ document.getElementById("alwaysAvailableSSD").checked = (typeof address.alwaysAvailableSSD != "undefined" && address.alwaysAvailableSSD); } //if element id alwaysAvailableVSD, then set alwaysAvailableVSD to true if is checked if(document.getElementById("alwaysAvailableVSD")){ document.getElementById("alwaysAvailableVSD").checked = (typeof address.alwaysAvailableVSD != "undefined" && address.alwaysAvailableVSD); } self.aCitySelected = true; self.aStreetSelected = true; self.showAddress(address); } //add event listeners on city and street search elements (keyup) self.addressSearchElements.city.addEventListener("keyup", function(){ //we disable and clear street and number inputs self.addressSearchElements.street.disabled = true; self.addressSearchElements.street.value = ""; self.addressSearchElements.number.disabled = true; self.addressSearchElements.number.value = ""; self.aCitySelected = false; self.aStreetSelected = false; //we add input-loading class to city input self.addressSearchElements.city.classList.add("input-loading"); //get value of the city input var city = self.addressSearchElements.city.value; if(city.length < 1){ $(self.addressSearchElements.city).autocomplete({ source: [], messages: { noResults: "", results: function(){} } }).autocomplete("close"); } eshopApi.searchCities(city).then(function(cityData){ //we remove input-loading class from city input self.addressSearchElements.city.classList.remove("input-loading"); var cityFound = false; //if response has only one city, and is the same as the input, we select it if(cityData.cities.length == 1){ if(cityData.cities[0] == city){ self.aCitySelected = true; self.addressSearchElements.street.disabled = false; cityFound = true; } } if(!cityFound){ //if there are more cities, we show autocomplete $(self.addressSearchElements.city).autocomplete({ /*source: function(request, response){ //show first 10 results of str - it is already filtered response(cityData.cities.slice(0, 10)); },*/ source: function(request, response) { //show first 10 results of str - it is already filtered response(cityData.cities.slice(0, 10)); }, //source: cityData.cities.slice(0, 10), messages: { noResults: "", results: function(){} }, select: function(event, ui){ setTimeout(function(){ self.aCitySelected = true; self.addressSearchElements.street.disabled = false; }, 200); } }).autocomplete("search", city); //$(self.addressSearchElements.city).keydown(); } }).catch(function(error){ Logger.error("Eshop.step1", "Error searching cities: "+error.message); }); }); self.addressSearchElements.street.addEventListener("keyup", function(){ //we disable and clear number inputs self.addressSearchElements.number.disabled = true; self.addressSearchElements.number.value = ""; self.aStreetSelected = false; //we add input-loading class to city input self.addressSearchElements.street.classList.add("input-loading"); //get value of the city input var city = self.addressSearchElements.city.value; var street = self.addressSearchElements.street.value; if(street.length < 1){ $(self.addressSearchElements.street).autocomplete({ source: [], messages: { noResults: "", results: function(){} } }).autocomplete("close"); return; } eshopApi.searchStreets(city, street).then(function(streetData){ //we remove input-loading class from city input self.addressSearchElements.street.classList.remove("input-loading"); var streetFound = false; //if response has only one city, and is the same as the input, we select it if(streetData.streets.length == 1){ if(streetData.streets[0] == street){ self.aStreetSelected = true; self.addressSearchElements.number.disabled = false; streetFound = true; } } if(!streetFound){ //if there are more cities, we show autocomplete $(self.addressSearchElements.street).autocomplete({ //source: streetData.streets.slice(0, 10), source: function(request, response) { //show first 10 results of str - it is already filtered response(streetData.streets.slice(0, 10)); }, messages: { noResults: "", results: function(){} }, select: function(event, ui){ setTimeout(function(){ self.aStreetSelected = true; self.addressSearchElements.number.disabled = false; }, 200); } }).autocomplete("search", street); //$(self.addressSearchElements.street).keydown(); } }).catch(function(error){ Logger.error("Eshop.step1", "Error searching streets: "+error.message); }); }); self.addressSearchElements.searchForm.addEventListener("submit", function(e){ e.preventDefault(); self.setAddress(); }); } EshopTemplateStep1.prototype.aCitySelected = false; EshopTemplateStep1.prototype.aStreetSelected = false; EshopTemplateStep1.prototype.cartSummary = null; EshopTemplateStep1.prototype.cartTemplate = null; EshopTemplateStep1.prototype.showCart = function(){ var self = this; if(!self.cartTemplate){ return; } self.cartTemplate.open(); } EshopTemplateStep1.prototype.hideCart = function(){ var self = this; if(!self.cartTemplate){ return; } self.cartTemplate.close(); } EshopTemplateStep1.prototype.toggleCart = function(){ var self = this; if(!self.cartTemplate){ return; } self.cartTemplate.toggle(); } EshopTemplateStep1.prototype.loadStart = function(){ var self = this; self.productsElements.loadingOverlay.style.display = "flex"; self.productsElements.loadingOverlay.style.visibility = "visible"; self.productsElements.primaryOffer.style.display = "none"; //self.productsElements.secondaryOffers.style.display = "none"; } EshopTemplateStep1.prototype.loadEnd = function(){ var self = this; //hide loading overlay self.productsElements.loadingOverlay.style.display = "none"; self.productsElements.loadingOverlay.style.visibility = "hidden"; } EshopTemplateStep1.prototype.getElement = function(id){ var elm = document.getElementById(id); if(!elm){ Logger.error("Eshop.step1", "Element with id '"+id+"' not found!"); return null; } return elm; } EshopTemplateStep1.prototype.addressSearchElements = { city: null, street: null, number: null, availabilityBar: null, addressBar: null, addressText: null }; EshopTemplateStep1.prototype.productsElements = { intetnetRow: null, telefonovanieRow: null, televiziaRow: null }; EshopTemplateStep1.prototype.showAvailability = function(){ var self = this; //make availability bar visible self.addressSearchElements.availabilityBar.style.display = "block"; //hide address bar self.addressSearchElements.addressBar.style.display = "none"; } EshopTemplateStep1.prototype.showAddress = function(address){ var self = this; //make availability bar not visible self.addressSearchElements.availabilityBar.style.display = "none"; //show address bar self.addressSearchElements.addressBar.style.display = "flex"; //set address text self.addressSearchElements.addressText.innerHTML = address.city + ", " + address.street + " " + address.number; } function formatPrice(price){ if(!price){ price = 0; } //if price is whole number, show it without decimal places if(price % 1 == 0){ return price.toFixed(0).replace(".", ","); } //else show it with two decimal places return price.toFixed(2).replace(".", ","); } /** Nové slideri v eshope pre produkty */ function initializeSwiper(){ function disableEnableSwiper(swiperBox, box) { if (swiperBox.length <= 3 && window.innerWidth > 1164) { $('#' + box + '-swiper .swiper-wrapper').addClass( "disabled" ); $('#' + box + '-swiper .swiper-button-prev').addClass( "disabled" ); $('#' + box + '-swiper .swiper-button-next').addClass( "disabled" ); } else { $('#' + box + '-swiper .swiper-wrapper').removeClass( "disabled" ); $('#' + box + '-swiper .swiper-button-prev').removeClass( "disabled" ); $('#' + box + '-swiper .swiper-button-next').removeClass( "disabled" ); } } setTimeout(function foo() { const boxes = [ 'internet', 'telefonovanie', 'televizia', 'internet_more', 'telefonovanie_more', 'televizia_more' ]; boxes.map(function (box) { const swiperBox = $('#' + box + '-swiper .box'); const swiperElm = document.querySelector('#' + box + '-swiper'); if (swiperElm) { const swiperInstance = document.querySelector('#' + box + '-swiper').swiper; if (swiperInstance != undefined) { swiperInstance.update(); disableEnableSwiper(swiperBox, box); return; } } if (swiperBox.length > 0) { if (typeof Swiper !== "undefined") { const swiper = new Swiper('#' + box + '-swiper', { navigation: { nextEl: ".swiper-button-next." + box, prevEl: ".swiper-button-prev." + box, }, grabCursor: true, slidesPerView: 1, breakpoints: { 768: { slidesPerView: 3 } }, }) } } disableEnableSwiper(swiperBox, box); }) },100) } EshopTemplateStep1.prototype.renderSubProduct = function(product){ var str = ""; //type of product ... if basetype = sub then type = net, voice, tv - product.type var type = ""; if (product.baseType == "sub") { type = product.type; } //get color of the box var color = "green"; if (type == "voice") { color = "orange"; } if (type == "tv") { color = "brown"; } var isInCart = cart.isInCart(product.code); //get flat price - price in product.prices.flatPrices[0] (if exists) var flatPrice = product.prices.flatPrices[0]; var flatNormalPrice = product.prices.flatPrices[(product.prices.flatPrices.length - 1)]; var discount = 0; var oldPrice = formatPrice(0); var priceInfo = ""; if(product.prices.flatPrices.length > 1){ //calculate discount discount = Math.round(((flatNormalPrice.price - flatPrice.price) / flatNormalPrice.price) * 100); oldPrice = formatPrice(flatNormalPrice.price); //for each price in flatPrices, we add price info for(var i = 0; i < product.prices.flatPrices.length; i++){ //if first price ... if(i == 0){ priceInfo += "Zvýhodnená cena na "; if(flatPrice.duration == 1){ priceInfo += "prvý mesiac. "; }else{ if(flatPrice.duration >= 2 && flatPrice.duration <= 4){ priceInfo += "prvé " + flatPrice.duration + " mesiace. "; } else { priceInfo += "prvých " + flatPrice.duration + " mesiacov. "; } } continue; } //if last price ... if(i == product.prices.flatPrices.length - 1){ priceInfo += "Následne vám bude účtovana mesačná cena " + formatPrice(product.prices.flatPrices[i].price) + " €."; continue; } //"middle prices" priceInfo += "Následne vám bude, po dobu "; if(product.prices.flatPrices[i].duration == 1){ priceInfo += product.prices.flatPrices[i].duration + " mesiaca, "; } else { priceInfo += product.prices.flatPrices[i].duration + " mesiacov, "; } priceInfo += " účtovana mesačná cena " + formatPrice(product.prices.flatPrices[i].price) + " €. "; } } var price = formatPrice(0); if(flatPrice){ price = formatPrice(flatPrice.price); } var code = product.code; code = code.toLowerCase(); if (code === "c_np_tel01") { product.description = "Volania do pevných a mobilných sietí v SR za zvýhodnené ceny"; } if (code === "c_np_tel02") { product.description = "Vybrané volania do Európskych krajín za zvýhodnené ceny"; } var cls = " "; if (isInCart) { cls = " selected "; } str += '
'; str += '
'; if(discount>0){ str += '
'; str += ' Zľava '+discount+'%'; str += '
'; } str += "

" + product.name + "

"; if (type == "net") { str += "

" + product.description + "

"; } str += '

'; str += '

'; if(discount>0){ str += ' '+oldPrice+' €'; } str += price + " "; str += " mesačne,
"; if (!product.boundPeriod || product.boundPeriod == 0) { str += "bez viazanosti"; } else { str += "s viazanosťou " + product.boundPeriod + " mesiacov"; } str += "
"; str += "

"; str += '
'; str += '
'; str +=priceInfo; str += '
'; str += '
'; str +=' Viac o produkte'; str += "
"; str += '
'; if (!isInCart) { str += " vybrať"; }else{ str += " "; } str += "
"; str += "
"; str += "
"; str += "
"; return str; } EshopTemplateStep1.prototype.renderSubProducts = function(subProducts, rowElm, contentElm){ var self = this; //hide row rowElm.style.display = "none"; //set contentElm innerHTML to "" contentElm.innerHTML = ""; //if subProducts is not empty, we hide row if(Object.keys(subProducts).length > 0){ var productsHtml = ""; for(var code in subProducts){ var product = subProducts[code]; productsHtml += self.renderSubProduct(product); } //append productsHtml to internet row internetRow >> #internet-swiper .swiper-wrapper contentElm.innerHTML = productsHtml; //show row rowElm.style.display = "flex"; } } EshopTemplateStep1.prototype.boundAlertShown = false; EshopTemplateStep1.prototype.renderProducts = function(products){ Logger.log("Eshop.step1", "Rendering products."); var self = this; //hide offers self.productsElements.primaryOffer.style.display = "none"; //self.productsElements.secondaryOffers.style.display = "none"; //if primary offer is null, we hide product selection and show message if(!products.offers.primary){ //no products available filipAlert("Produkty nenájdené!", "Na uvedenej adrese v existujúcich databázach nevedieme dostupnosť pripojenia a služieb. V niektorých prípadoch je však možné alternatívne pripojenie. Pre bližšie preverenie a informácie nás kontaktujte na sluzbyzakaznikom@slovanet.net alebo na tel. č.: 02/208 28 208. Ďakujeme!"); return; } //get primary offer /*var primaryOfferSubcategory = products.offers.primary; var primaryOffer = products.subcategories[primaryOfferSubcategory];*/ var currentSubcategory = cart.getSubcategory(); if(!currentSubcategory){ return; } var currentOffer = products.subcategories[currentSubcategory]; if(!currentOffer){ return; } let boundPeriod = 0; //check if any of topProducts has boundPeriod > 0 for(var i = 0; i < currentOffer.topProducts.length; i++){ var topProduct = currentOffer.topProducts[i]; if(parseInt(topProduct.boundPeriod) > boundPeriod){ boundPeriod = parseInt(topProduct.boundPeriod); } } if(boundPeriod > 0 && !self.boundAlertShown){ //show filipAlert //filipAlert("Vážený zákazník,", 'chceli by sme Vás upozorniť, že akciové ceny za zobrazené služby sú s viazanosťou '+boundPeriod+' mesiacov.
V prípade záujmu o neviazané služby na tejto infraštruktúre Vám radi vyhovieme a poskytneme viac informácii na sluzbyzakaznikom@slovanet.net alebo na bezplatnej linke 0800/608 608.

Ďakujeme za pochopenie

Slovanet
'); self.boundAlertShown = true; } //show primary offer self.productsElements.primaryOffer.style.display = "block"; //render internet products var internetRow = self.productsElements.intetnetRow.querySelector("#internet-swiper .swiper-wrapper"); self.renderSubProducts(currentOffer.subProducts.net, self.productsElements.intetnetRow, internetRow);1 //render telefonovanie products var telefonovanieRow = self.productsElements.telefonovanieRow.querySelector("#telefonovanie-swiper .swiper-wrapper"); self.renderSubProducts(currentOffer.subProducts.voice, self.productsElements.telefonovanieRow, telefonovanieRow); //render televizia products var televiziaRow = self.productsElements.televiziaRow.querySelector("#televizia-swiper .swiper-wrapper"); self.renderSubProducts(currentOffer.subProducts.tv, self.productsElements.televiziaRow, televiziaRow); initializeSwiper(); } EshopTemplateStep1.prototype.setAddress = function(){ var self = this; if(self.aCitySelected && self.aStreetSelected){ var address = { city: self.addressSearchElements.city.value, street: self.addressSearchElements.street.value, number: self.addressSearchElements.number.value, alwaysAvailableST: false, alwaysAvailableSSD: false, alwaysAvailableVSD: false }; //if element id alwaysAvailableST, then set alwaysAvailableST to true if is checked if(document.getElementById("alwaysAvailableST") && document.getElementById("alwaysAvailableST").checked){ address.alwaysAvailableST = true; } //if element id alwaysAvailableSSD, then set alwaysAvailableSSD to true if is checked if(document.getElementById("alwaysAvailableSSD") && document.getElementById("alwaysAvailableSSD").checked){ address.alwaysAvailableSSD = true; } //if element id alwaysAvailableVSD, then set alwaysAvailableVSD to true if is checked if(document.getElementById("alwaysAvailableVSD") && document.getElementById("alwaysAvailableVSD").checked){ address.alwaysAvailableVSD = true; } self.boundAlertShown = false; cart.products = cart.emptyProducts; cart.save(); cart.setAddress(address); self.showAddress(address); } } EshopTemplateStep1.prototype.setAddressForced = function(address){ var self = this; self.boundAlertShown = false; cart.products = cart.emptyProducts; cart.save(); cart.setAddress(address); self.showAddress(address); } EshopTemplateStep1.prototype.continue = function(){ //TODO: some posible checks //cart has to be isVerified if(!cart.isVerified){ filipAlert("Chyba", "Je potrebné najprv overiť adresu."); return; } //check if there are any available tvPackages var topProduct = cart.getTopProduct(); if(!topProduct){ //cant continue return; } //check if topProduct has any tvPackages if(topProduct.tvPackages.length == 0){ //skip tvPackages selection location.href = "/eshop/doplnkove-sluzby"; return; } //go to next step location.href = "/eshop/tv-balicky"; } function EshopTemplateStep2(){ var self = this; self.cartSummary = new CartSummaryTemplate(cart); self.cartTemplate = new CartTemplate(cart); self.productsElements = { loadingOverlay: document.getElementById("loading") }; //listen to cartProductAdded event document.addEventListener("cartProductAdded", function(e){ //get available products from cart if(cart.avaliableProducts){ self.renderProducts(cart.avaliableProducts); } }); document.addEventListener("cartProductRemoved", function(e){ //get available products from cart if(cart.avaliableProducts){ self.renderProducts(cart.avaliableProducts); } }); //listen to cartAvailableProducts event document.addEventListener("cartAvaliableProducts", function(e){ self.renderProducts(e.detail); }); } EshopTemplateStep2.prototype.continue = function(){ //TODO: some posible checks //check if there are any available tvPackages var topProduct = cart.getTopProduct(); if(!topProduct){ //cant continue return; } //go to next step location.href = "/eshop/doplnkove-sluzby"; } EshopTemplateStep2.prototype.showCart = function(){ var self = this; if(!self.cartTemplate){ return; } self.cartTemplate.open(); } EshopTemplateStep2.prototype.hideCart = function(){ var self = this; if(!self.cartTemplate){ return; } self.cartTemplate.close(); } EshopTemplateStep2.prototype.toggleCart = function(){ var self = this; if(!self.cartTemplate){ return; } self.cartTemplate.toggle(); } EshopTemplateStep2.prototype.renderProducts = function(){ Logger.log("Eshop.step2", "Rendering tvPackages."); var self = this; var topProduct = cart.getTopProduct(); if(!topProduct){ //cant continue return; } //empty tvPackagesWrapper self.elementTvPackagesWrapper.innerHTML = ""; for(var i = 0; i < topProduct.tvPackages.length; i++){ var tvPackageCode = topProduct.tvPackages[i]; //get tvPackage from prodList var tvPackage = topProduct.prodList[tvPackageCode]; if(!tvPackage){ Logger.error("Eshop.step2", "TvPackage with code '"+tvPackageCode+"' not found!"); continue; } /*var flatPrice = 0; if(tvPackage.prices.flatPrices[0]){ flatPrice = tvPackage.prices.flatPrices[0].price; }*/ var priceInfo = ""; var flatPrice = tvPackage.prices.flatPrices[0]; var flatNormalPrice = tvPackage.prices.flatPrices[(tvPackage.prices.flatPrices.length - 1)]; var discount = 0; var oldPrice = formatPrice(0); if(tvPackage.prices.flatPrices.length > 1){ //calculate discount discount = Math.round(((flatNormalPrice.price - flatPrice.price) / flatNormalPrice.price) * 100); oldPrice = formatPrice(flatNormalPrice.price); //for each price in flatPrices, we add price info for(var j = 0; j < tvPackage.prices.flatPrices.length; j++){ //if first price ... if(j == 0){ priceInfo += "Zvýhodnená cena na "; if(flatPrice.duration == 1){ priceInfo += "prvý mesiac. "; }else{ if(flatPrice.duration >= 2 && flatPrice.duration <= 4){ priceInfo += "prvé " + flatPrice.duration + " mesiace. "; } else { priceInfo += "prvých " + flatPrice.duration + " mesiacov. "; } } continue; } //if last price ... if(j == tvPackage.prices.flatPrices.length - 1){ priceInfo += "Následne vám bude účtovana mesačná cena " + formatPrice(tvPackage.prices.flatPrices[j].price) + " €."; continue; } //"middle prices" priceInfo += "Následne vám bude, po dobu "; if(tvPackage.prices.flatPrices[j].duration == 1){ priceInfo += tvPackage.prices.flatPrices[j].duration + " mesiaca, "; } else { priceInfo += tvPackage.prices.flatPrices[j].duration + " mesiacov, "; } priceInfo += " účtovana mesačná cena " + formatPrice(tvPackage.prices.flatPrices[j].price) + " €. "; } } var cls = " "; if(cart.isInCart(tvPackageCode)){ cls = " selected "; } var str = ""; str += '
'; str += '
'; str += '

' + tvPackage.name + '

'; str += '

' + tvPackage.description + '

'; str += '

'; if (tvPackage.image){ str += ''+tvPackage.name+''; } str += '

'; str += '

'; if(discount>0){ str += ' '+oldPrice+' €'; } var price = formatPrice(0); if(flatPrice){ price = formatPrice(flatPrice.price); } str += price + ' mesačne

'; str += '
' + priceInfo + '
'; str += ' viac informácií'; if(cart.isInCart(tvPackageCode)){ str += ' '; }else{ str += ' vybrať'; } str += '
'; str += '
'; self.elementTvPackagesWrapper.innerHTML += str; } } EshopTemplateStep2.prototype.elementTvPackagesWrapper = document.getElementById("TVPackagesList"); function EshopTemplateStep3(){ var self = this; self.cartSummary = new CartSummaryTemplate(cart); self.cartTemplate = new CartTemplate(cart); self.productsElements = { loadingOverlay: document.getElementById("loading") }; //listen to cartProductAdded event document.addEventListener("cartProductAdded", function(e){ //get available products from cart if(cart.avaliableProducts){ self.renderProducts(cart.avaliableProducts); } }); document.addEventListener("cartProductRemoved", function(e){ //get available products from cart if(cart.avaliableProducts){ self.renderProducts(cart.avaliableProducts); } }); //listen to cartAvailableProducts event document.addEventListener("cartAvaliableProducts", function(e){ self.renderProducts(e.detail); }); } EshopTemplateStep3.prototype.continue = function(){ //TODO: some posible checks //check if there are any available tvPackages var topProduct = cart.getTopProduct(); if(!topProduct){ //cant continue return; } //go to next step location.href = "/eshop/zariadenia"; } EshopTemplateStep3.prototype.showCart = function(){ var self = this; if(!self.cartTemplate){ return; } self.cartTemplate.open(); } EshopTemplateStep3.prototype.hideCart = function(){ var self = this; if(!self.cartTemplate){ return; } self.cartTemplate.close(); } EshopTemplateStep3.prototype.toggleCart = function(){ var self = this; if(!self.cartTemplate){ return; } self.cartTemplate.toggle(); } EshopTemplateStep3.prototype.renderProducts = function(){ Logger.log("Eshop.step2", "Rendering tvPackages."); var self = this; var topProduct = cart.getTopProduct(); if(!topProduct){ //cant continue return; } //empty tvPackagesWrapper self.elementAdditionalProdsWrapper.innerHTML = ""; for (var type in topProduct.additional){ for(var i = 0; i < topProduct.additional[type].length; i++){ var additionalCode = topProduct.additional[type][i]; //get tvPackage from prodList var additionalProd = topProduct.prodList[additionalCode]; if(!additionalProd){ Logger.error("Eshop.step3", "AdditionalProd with code '"+additionalCode+"' not found!"); continue; } var flatPrice = 0; if(additionalProd.prices.flatPrices[0]){ flatPrice = additionalProd.prices.flatPrices[0].price; } var cls = " "; if(cart.isInCart(additionalCode)){ cls = " selected "; } var str = ""; str += '
'; str += '
'; str += '

' + additionalProd.name + '

'; str += '

' + additionalProd.description + '

'; str += '

'; if (additionalProd.image){ str += ''+additionalProd.name+''; } str += '

'; str += '

' + formatPrice(flatPrice) + ' mesačne

'; str += '
'; str += ' viac informácií'; if(cart.isInCart(additionalCode)){ str += ' '; }else{ str += ' vybrať'; } str += '
'; str += '
'; self.elementAdditionalProdsWrapper.innerHTML += str; } } } EshopTemplateStep3.prototype.elementAdditionalProdsWrapper = document.getElementById("AdditionalList"); function EshopTemplateStep4(){ var self = this; self.cartSummary = new CartSummaryTemplate(cart); self.cartTemplate = new CartTemplate(cart); self.productsElements = { loadingOverlay: document.getElementById("loading") }; //listen to cartProductAdded event document.addEventListener("cartProductAdded", function(e){ //get available products from cart if(cart.avaliableProducts){ self.renderProducts(cart.avaliableProducts); } }); document.addEventListener("cartProductRemoved", function(e){ //get available products from cart if(cart.avaliableProducts){ self.renderProducts(cart.avaliableProducts); } }); //listen to cartAvailableProducts event document.addEventListener("cartAvaliableProducts", function(e){ self.renderProducts(e.detail); }); } EshopTemplateStep4.prototype.selectedDeviceCount = { net: 0, voice: 0, tv: 0 } EshopTemplateStep4.prototype.activeDeviceCount = { net: 0, voice: 0, tv: 0 } EshopTemplateStep4.prototype.activeProducts = [ "Z_NP_WRST1", "Z_NP_WRST2", "Z_NP_WRST3", "Z_NP_WR001", "Z_NP_WR002", "Z_NP_WR004", "Z_NP_WR005", "Z_NP_WR006", "Z_NP_WR007", "Z_NP_WR008", "Z_NP_WR009", "Z_NP_KON01", "Z_NP_KM001", "Z_NP_ZEZ01", "Z_NP_AZG11", "Z_NP_AZG21", "Z_NP_AZG22", "Z_NP_AZG41", "Z_NP_AZG42", "Z_NP_AZG51", "Z_NP_CPE19", "Z_NP_STB01", "Z_NP_STB02", "Z_NP_STB03", "C_NP_STB01", "C_NP_STB02", "Z_NP_DVBC1", "Z_NP_OTB01", "Z_NP_OTB02", ]; EshopTemplateStep4.prototype.skipCheck = false; EshopTemplateStep4.prototype.continue = function(){ let self = this; //check if there are any available tvPackages var topProduct = cart.getTopProduct(); if(!topProduct){ //cant continue return; } if(!self.skipCheck){ let types = ["net", "voice", "tv"]; for(let i = 0; i < types.length; i++){ if(self.activeDeviceCount[types[i]] > 0 && self.selectedDeviceCount[types[i]] == 0){ //only check once self.skipCheck = true; filipConfirm( "Vážený zákazník,", "všimli sme si, že ste si k zvoleným službám nevybrali žiadne z ponúknutých koncových zariadení. Chcete pokračovať bez výberu koncových zariadení?", { "text": "Mám vyhovujúce zariadenia", "action": function(){ location.href = "/eshop/kontaktne-udaje"; } }, { "text": "Späť na výber zariadení", }, "Ak potrebujete poradiť môžete použiť chat na stránke www.slovanet.sk (v pravom dolnom rohu) alebo sme vám k dispozícii na tel. č. 02 02/208 28 208 - voľba 1 poprípade nám napíšte na sluzbyzakaznikom@slovanet.net" ) //cant continue return; } } } //go to next step location.href = "/eshop/kontaktne-udaje"; } EshopTemplateStep4.prototype.showCart = function(){ var self = this; if(!self.cartTemplate){ return; } self.cartTemplate.open(); } EshopTemplateStep4.prototype.hideCart = function(){ var self = this; if(!self.cartTemplate){ return; } self.cartTemplate.close(); } EshopTemplateStep4.prototype.toggleCart = function(){ var self = this; if(!self.cartTemplate){ return; } self.cartTemplate.toggle(); } EshopTemplateStep4.prototype.renderProducts = function(){ Logger.log("Eshop.step4", "Rendering tvPackages."); var self = this; var topProduct = cart.getTopProduct(); if(!topProduct){ //cant continue return; } //empty tvPackagesWrapper self.elementDeviceProdsWrapper.innerHTML = ""; //set active and selected device count to 0 self.selectedDeviceCount.net = 0; self.selectedDeviceCount.voice = 0; self.selectedDeviceCount.tv = 0; self.activeDeviceCount.net = 0; self.activeDeviceCount.voice = 0; self.activeDeviceCount.tv = 0; for (var type in topProduct.devices){ for(var i = 0; i < topProduct.devices[type].length; i++){ var deviceCode = topProduct.devices[type][i]; //it device is in activeProducts list set activeDeviceCount for type +1 if(self.activeProducts.indexOf(deviceCode) > -1){ //if type dont exists in activeDeviceCount,set it to 0 if(!self.activeDeviceCount[type]){ self.activeDeviceCount[type] = 0; } self.activeDeviceCount[type]++; } //get tvPackage from prodList var deviceProd = topProduct.prodList[deviceCode]; if(!deviceProd){ Logger.error("Eshop.step4", "DeviceProd with code '"+deviceCode+"' not found!"); continue; } var flatPrice = 0; if(deviceProd.prices.flatPrices[0]){ flatPrice = deviceProd.prices.flatPrices[0].price; } var cls = " "; if(cart.isInCart(deviceCode)){ cls = " selected "; //if not exists in selectedDeviceCount, set it to 0 if(!self.selectedDeviceCount[type]){ self.selectedDeviceCount[type] = 0; } self.selectedDeviceCount[type]++; } var str = ""; str += '
'; str += '
'; str += '

' + deviceProd.name + '

'; str += '

' + deviceProd.description + '

'; str += '

'; if (deviceProd.image){ str += ''+deviceProd.name+''; } str += '

'; str += '

' + formatPrice(flatPrice) + ' mesačne

'; str += '
'; str += ' viac informácií'; if(cart.isInCart(deviceCode)){ str += ' '; }else{ str += ' vybrať'; } str += '
'; str += '
'; self.elementDeviceProdsWrapper.innerHTML += str; } } } EshopTemplateStep4.prototype.elementDeviceProdsWrapper = document.getElementById("DevicesList"); function EshopTemplateStep5(){ var self = this; self.loadTitles(); } EshopTemplateStep5.prototype.setValues = function (){ var self = this; var contactInfo = cart.getContactInfo(); self.elements.email.elm.value = contactInfo.email; self.elements.phone.elm.value = contactInfo.phone; self.elements.firstName.elm.value = contactInfo.firstName; self.elements.lastName.elm.value = contactInfo.lastName; self.elements.titulus.elm.value = contactInfo.titulus; } EshopTemplateStep5.prototype.elements = { titulus:{ elm: document.getElementById("inp_customer_titulus"), }, firstName: { elm: document.getElementById("inp_customer_contact_name"), }, lastName: { elm: document.getElementById("inp_customer_contact_surname"), }, email: { elm: document.getElementById("inp_customer_primary_email"), }, phone: { elm: document.getElementById("inp_customer_phone_number"), }, }; EshopTemplateStep5.prototype.agreeElm = document.getElementById("podmienky"); EshopTemplateStep5.prototype.loadTitles = function(){ var self = this; eshopApi.getTitulus().then(function(titlesResult){ var options = ""; for(var uuid in titlesResult.titles){ options += ''; } self.elements.titulus.elm.innerHTML = options; //set default value var def = "3a91b3b5-dd3e-4a99-8802-7c2be6f0747d"; if(self.elements.titulus.elm.value == ""){ self.elements.titulus.elm.value = def; } }).catch(function(error){ Logger.error("Eshop.step5", "Error loading titles: "+error.message); }); } EshopTemplateStep5.prototype.continue = function(){ //check if fields are filled var self = this; //check if all fields are filled var valid = true; for(var key in self.elements){ var elm = self.elements[key].elm; if(elm.value == ""){ valid = false; elm.classList.add("error"); }else{ elm.classList.remove("error"); } } if(!valid){ filipAlert("Chyba", "Všetky polia musia byť vyplnené!"); return; } //check if agree checkbox is checked if(!self.agreeElm.checked){ filipAlert("Chyba", "Pre odoslanie musíte zaskrtnúť súhlas s Podmienkami spracúvania osobných údajov."); return; } //set client info to cart cart.setContactInfo({ email: self.elements.email.elm.value, phone: self.elements.phone.elm.value, firstName: self.elements.firstName.elm.value, lastName: self.elements.lastName.elm.value, titulus: self.elements.titulus.elm.value }); //go to next step location.href = "/eshop/sumar"; } function EshopTemplateStep6(){ var self = this; document.addEventListener("cartLoading", function(e){ if(e.detail == "end"){ self.renderSummary(); } }); } EshopTemplateStep6.prototype.elements = { flatSections: document.getElementById("flatPrices"), installSection: document.getElementById("installPrices") } EshopTemplateStep6.prototype.setInputValue = function (id, value){ var elm = document.getElementById(id); if(elm){ elm.value = value; } } EshopTemplateStep6.prototype.renderSummary = function (){ var self = this; //get cart full info var fullInfo = cart.getFullInfo(); var contactInfo = cart.getContactInfo(); var address = cart.getAddress(); //set contact info //contact person = firstName + lastName self.setInputValue("inp_customer_contact_person", contactInfo.firstName + ' ' + contactInfo.lastName); self.setInputValue("inp_customer_primary_email", contactInfo.email); self.setInputValue("inp_customer_phone_number", contactInfo.phone); //set address self.setInputValue("inp_delivery_address_street", address.street); self.setInputValue("inp_delivery_address_number", address.number); self.setInputValue("inp_delivery_address_city", address.city); //flat sections //empty flatSections self.elements.flatSections.innerHTML = ""; for(var i = 0; i < fullInfo.flatSections.length; i++){ var section = fullInfo.flatSections[i]; /** *
*

Mesačné poplatky od 1. mesiaca

*
* * * *
* *** *
* * * *
* *** *
* * * *
*
* * * *
*
*/ var str = ""; str += '
'; str += '

Mesačné poplatky od ' + section.start + '. mesiaca

'; for(var j = 0; j < section.products.length; j++){ var product = section.products[j]; str += '
'; str += ' '; str += ' '; str += ' '; str += '
'; } str += '
'; str += ' '; str += ' '; str += ' '; str += '
'; str += '
'; str += ' '; str += ' '; str += ' '; str += '
'; //append str to flatSections self.elements.flatSections.innerHTML += str; } /**render install section */ self.elements.installSection.innerHTML = ""; installSection = fullInfo.installSection; str = ""; str += '
'; str += '

Jednorazové poplatky

'; for(var i = 0; i < installSection.products.length; i++){ var product = installSection.products[i]; str += '
'; str += ' '; str += ' '; str += ' '; str += '
'; } str += '
'; str += ' '; str += ' '; str += ' '; str += '
'; str += '
'; str += ' '; str += ' '; str += ' '; str += '
'; str += '
'; self.elements.installSection.innerHTML = str; } EshopTemplateStep6.prototype.postJSONasForm = function(url, data, newWindow){ var self = this; //if newWindow not set, we set it to false if(typeof newWindow == "undefined"){ newWindow = false; } //create form var form = document.createElement("form"); form.setAttribute("method", "post"); form.setAttribute("action", url); if(newWindow){ form.setAttribute("target", "_blank"); } form.style.display = "none"; //create form input var input = document.createElement("input"); input.setAttribute("type", "hidden"); input.setAttribute("name", "data"); input.setAttribute("value", JSON.stringify(data)); //append input to form form.appendChild(input); //append form to body document.body.appendChild(form); //submit form form.submit(); //remove form document.body.removeChild(form); } EshopTemplateStep6.prototype.contactMe = function(){ /** * send fullInfo to /eshop/kontaktujte-ma as JSON in one urlencoded fom field * */ var self = this; var data = { contactInfo: cart.getContactInfo(), clientInfo: cart.getClientInfo(), address: cart.getAddress(), fullInfo: cart.getFullInfo(), products: cart.getProducts() }; if (data.contactInfo.phone.startsWith("+")) { data.contactInfo.phone = data.contactInfo.phone.replace("+", "00"); } let contact = cart.getContactInfo(); datalayerWrapper.push({ 'event': 'form_sent', 'formId': 'contactForm', 'formType': 'Contact', 'enhanced_conversions': { 'email': contact.email, 'phone': contact.phone } }); self.postJSONasForm("/eshop/kontaktujte-ma", data, false); } EshopTemplateStep6.prototype.printSummary = function(){ var self = this; /** * send fullInfo to /eshop/kontaktujte-ma as JSON in one urlencoded fom field * */ var self = this; var fullInfo = cart.getFullInfo(); var contactInfo = cart.getContactInfo(); var address = cart.getAddress(); var data = { contactInfo: contactInfo, address: address, fullInfo: fullInfo }; if (data.contactInfo.phone.startsWith("+")) { data.contactInfo.phone = data.contactInfo.phone.replace("+", "00"); } self.postJSONasForm("/eshop/vytlacit-sumar", data, true); } var FAlert = new FilipAlert(); function filipAlert(title, message){ //todo: create nice alert //alert(title + "\n\n" + message); FAlert.open({ title: title, message: message }); } function filipConfirm(title, message, action, close, note){ FAlert.open({ title: title, message: message, action: action, close: close, note: note ?? null }); } function filipAlertClose(){ FAlert.close(); } function showProductModal(code){ //get product from cart var product = cart.getProduct(code); if(!product){ Logger.error("Eshop", "Product with code '"+code+"' not found!"); return; } //open magnificPopup if (typeof $.fn.magnificPopup !== "undefined") { $.magnificPopup.open({ items: { src: product.detail, type: 'inline' }, enableEscapeKey: true, showCloseBtn: true, closeOnBgClick: true, closeOnContentClick: false, callbacks: { open: function() { $(".mfp-close").click(function(){ $.magnificPopup.close(); }); $(".mfp-bg").click(function(){ $.magnificPopup.close(); }); $(".mfp-content").click(function(){ $.magnificPopup.close(); }); } } }); } } function FromValidator(id){ var self = this; self.formElement = document.getElementById(id); //create event listener for each input on change var inputs = self.formElement.querySelectorAll(".validate"); for(var i = 0; i < inputs.length; i++){ var input = inputs[i]; input.addEventListener("change", function(){ self.validateInput(this); }); } } FromValidator.prototype.formElement = null; FromValidator.prototype.validate = function(){ var self = this; //get all inputs from form with class "validate" var inputs = self.formElement.querySelectorAll(".validate"); //set valid to true var valid = true; //iterate over inputs for(var i = 0; i < inputs.length; i++){ var input = inputs[i]; //remove error class from parent self.validateInput(input); } } FromValidator.prototype.validateInput = function(elm){ var self = this; elm.parentElement.classList.remove("error"); //find any of validation classes vld-email, vld-phone, vld-required, vld-name, vld-bn, vld-idcard //vld-empty, vld-zip const vldPairs = { "vld-email": self.validateEmail, "vld-phone": self.validatePhone, "vld-required": self.validateRequired, "vld-name": self.validateName, "vld-bn": self.validateBN, "vld-idcard": self.validateIDCard, "vld-empty": self.validateEmpty, "vld-zip": self.validateZIP }; for(var key in vldPairs){ if(elm.classList.contains(key)){ if(!vldPairs[key](input)){ valid = false; //add error class to parent elm.parentElement.classList.add("error"); } } } } FromValidator.prototype.validateEmail = function(elm){ var self = this; var email = elm.value; if(email == ""){ return true; } var re = /\S+@\S+\.\S+/; if(!re.test(email)){ return false; } } FromValidator.prototype.validatePhone = function(elm){ var self = this; var phone = elm.value; if(phone == ""){ return true; } //remove spaces phone = phone.replace(/\s/g, ""); //replace first 0 with +421 phone = phone.replace(/^0/, "+421"); //set phone to elm elm.value = phone; var re = /^\+?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{3})$/; if(!re.test(phone)){ return false; } } FromValidator.prototype.validateRequired = function(elm){ var self = this; if(elm.value == ""){ return false; } } FromValidator.prototype.validateName = function(elm){ var self = this; var name = elm.value; if(name == ""){ return true; } var re = /^[a-zA-Z\s]*$/; if(!re.test(name)){ return false; } } FromValidator.prototype.validateBN = function(elm){ var self = this; var bn = elm.value; //remove spaces bn = bn.replace(/\s/g, ""); //remove / bn = bn.replace(/\//g, ""); if(bn == ""){ return true; } //9 or 10 numbers var re = /^[0-9]{9,10}$/; if(!re.test(bn)){ return false; } } FromValidator.prototype.validateIDCard = function(elm){ var self = this; var idcard = elm.value; if(idcard == ""){ return true; } //anythig more than 6 characters var re = /^.{6,}$/; if(!re.test(idcard)){ return false; } } FromValidator.prototype.validateEmpty = function(elm){ var self = this; if(elm.value == ""){ return false; } } FromValidator.prototype.validateZIP = function(elm){ var self = this; var zip = elm.value; if(zip == ""){ return true; } //remove spaces zip = zip.replace(/\s/g, ""); var re = /^[0-9]{5}$/; if(!re.test(zip)){ return false; } }