const CART_ITEM_INDEX = 'CART_ITEM_INDEX'; const PRODUCT_HEADER = 'PRODUCT_HEADER'; const PRODUCT_IMAGE = 'PRODUCT_IMAGE'; const PRODUCT_OPTION = 'PRODUCT_OPTION'; const PRODUCT_PRICE = 'PRODUCT_PRICE'; const CART_ITEM_TEMPLATE = `

PRODUCT_HEADER

PRODUCT_OPTION

PRODUCT_PRICE

`; // Initialization if (!localStorage.getItem('chiringoCart')) initializeCart(); function buildCart() { console.log('buildCart(): building the cart item'); const cartItems = document.getElementById('cartItems'); cartItems.innerHTML = ''; var i = 0; for (const productInCart of getCart()) { const cartItem = buildCartItem(productInCart, i); if (!cartItem) continue; i++; cartItems.appendChild(cartItem); } const [ productTotal, shippingTotal, total ] = calculateTotals(); // Set totals in UI document.getElementById('cartProductTotal').innerText = formatPriceToLocale(shiftCommaForDecimals(productTotal + ''), CURRENCY); document.getElementById('cartShippingTotal').innerText = formatPriceToLocale(shiftCommaForDecimals(shippingTotal + ''), CURRENCY); document.getElementById('cartTotal').innerText = formatPriceToLocale(shiftCommaForDecimals(total + ''), CURRENCY); } function calculateTotals() { // Product const productTotal = getProductTotal(); // Shipping const shippingTotal = getShippingTotal(); // Total const total = productTotal + shippingTotal; console.log("getProductTotal(): the final total is " + total); return [ productTotal, shippingTotal, total ]; } function getProductTotal() { var subTotal = 0; for (const product of getCart()) { subTotal += Number(findProduct(product.label).price); } console.log("getProductTotal(): the product total is " + subTotal); return subTotal; } function getShippingTotal() { var highestShippingCost = 0; for (const product of getCart()) { const qo = findProduct(product.label); const shippingOption = qo.shippingOptions[product.shippingOption]; if (!shippingOption) continue; // Products with no shipping options const currentShippingCost = Number(shippingOption.price); if (currentShippingCost > highestShippingCost) { highestShippingCost = currentShippingCost; } } console.log("getProductTotal(): the shipping total is " + highestShippingCost); return highestShippingCost; } function buildCartItem(productInCart, index) { const productDetails = getProductDetailsByLabel(productInCart.label); if (!productDetails) return; const cartItem = document.createElement('div'); cartItem.id = 'cartItem_' + index; cartItem.innerHTML = CART_ITEM_TEMPLATE .replace(PRODUCT_HEADER, productDetails.title) .replace(PRODUCT_IMAGE, productDetails.thumbnail) .replace(PRODUCT_OPTION, productInCart.productOption ? productInCart.productOption : '') .replace(PRODUCT_HEADER, productDetails.title) .replace(CART_ITEM_INDEX, index) .replace(PRODUCT_PRICE, productDetails.paybuttontext); return cartItem; } function cartIsEmpty() { return (getCart().length == 0); } function getProductDetailsByLabel(label) { for (const qo of quickoffers) { if (qo.label == label) { return qo; } } return; } function initializeCart() { localStorage.setItem('chiringoCart', '[]'); } function saveCart(cartJSONObject) { localStorage.setItem('chiringoCart', JSON.stringify(cartJSONObject)); updateCartItemCount(); } function getCart() { return JSON.parse(localStorage.getItem('chiringoCart')); } async function addToCart(label) { var selectedProductOption; var selectedShippingOption; console.log('addToCart(): adding product ' + label); var product = findProduct(label); // console.log('addToCart(): the product ' + JSON.stringify(findProduct(label), null, 2)); // // 1) What option from those available (stock)? if (thereAreProductOptions(product)) { const result = await generateProductOptionAlert(product); if (result.isConfirmed) { selectedProductOption = result.value; } } if (thereAreProductOptions(product) && !selectedProductOption) return; // 2) What shipping option? if (thereAreShippingOptions(product)) { const result = await generateShippingOptionAlert(product); if (result.isConfirmed) { selectedShippingOption = result.value; } } if (thereAreShippingOptions(product) && !selectedShippingOption) return; console.log('addToCart(): selected options are ' + selectedProductOption + ' ' + selectedShippingOption); // 3) Then add to the cart addProductToCart(label, selectedProductOption, selectedShippingOption); } function addProductToCart(label, productOption, shippingOption) { // 1) Get current cart var currentCart = getCart(); // 2) Add new product currentCart.push({ label: label, productOption: productOption, shippingOption: shippingOption }); // 3) Save new cart saveCart(currentCart); animateCart(); } function animateCart() { document.getElementById('cartIcon').classList.add('theItemAmount'); setTimeout(() => { document.getElementById('cartIcon').classList.remove('theItemAmount'); }, 2000); } function deleteProductFromCart(indexInCart) { Swal.fire({ title: "Are you sure?", showCancelButton: true, confirmButtonColor: "#6e7881", cancelButtonColor: "#3085d6", confirmButtonText: "Yes, delete it!", cancelButtonText: "Cancelar" }).then((result) => { if (result.isConfirmed) { // 1) Get current cart var currentCart = getCart(); // 2) Add new product currentCart.splice(indexInCart, 1); // 3) Save new cart saveCart(currentCart); // 4) If no items in the cart, close the checkout overlay, refresh the cart otherwise if (cartIsEmpty()) { closeCart(); return; } buildCart(); } }); } function generateProductOptionAlert(product) { var availableOptions = {}; for (const option of Object.keys(product.productOptions)) { if (product.productOptions[option].stock > 0) availableOptions[option] = option; } console.log('generateProductOptionAlert(): availableOptions are ' + JSON.stringify(availableOptions, null, 2)); return Swal.fire({ title: "Select the option", input: 'select', inputOptions: availableOptions, inputPlaceholder: "Select the option", confirmButtonColor: "#0071e3", showCancelButton: true, inputValidator: function (value) { return new Promise(function (resolve, reject) { if (value !== '') { resolve(); } else { resolve("You need to select an option"); } }); } }); } function generateShippingOptionAlert(product) { var availableOptions = product.shippingOptions; var formattedOptions = {}; for (const option of Object.keys(availableOptions)) { const theOption = availableOptions[option]; formattedOptions[option] = theOption.regions.toString() + ' ' + theOption.ETA + ' ' + formatPriceToLocale(shiftCommaForDecimals(theOption.price + ''), product.currency) } return Swal.fire({ title: "Select the shipping method", input: 'select', inputOptions: formattedOptions, inputPlaceholder: "Select the option", confirmButtonColor: "#0071e3", showCancelButton: true, inputValidator: function (value) { return new Promise(function (resolve, reject) { if (value !== '') { resolve(); } else { resolve("You need to select an option"); } }); } }); } function findProduct(label) { for (var productIndex in quickoffers) { var theProduct = quickoffers[productIndex]; if (theProduct.label == label) return theProduct; } return undefined; } function openCart() { if (cartIsEmpty()) { Swal.fire("Your cart is empty"); return; } console.log('openCart(): opening the cart'); document.getElementById('cartWrapper').style.display = 'inline-block'; buildCart(); } function closeCart() { console.log('closeCart(): closing the cart'); document.getElementById('cartWrapper').style.display = 'none'; } function checkout() { closeCart(); document.getElementById('checkoutflowcontainer').style.display = 'inline-block'; } function closeCheckout() { document.getElementById('checkoutflowcontainer').style.display = 'none'; } function thereAreProductOptions(product) { return (Object.keys(product.productOptions).length > 0); } function thereAreShippingOptions(product) { return (Object.keys(product.shippingOptions).length > 0); } function updateCartItemCount() { document.getElementById('cartProductCounter').innerText = Object.keys(JSON.parse(localStorage.getItem('chiringoCart'))).length; } function formatPriceToLocale(amount, currency) { if ((!amount && amount != 0) || (!currency)) { console.error('formatPriceToLocale(): params amount ' + amount + ' or currency ' + currency + ' are invalid!'); throw Error('formatPriceToLocale(): params amount ' + amount + ' or currency ' + currency + ' are invalid!'); } var amountAsNumber = Number(amount); // Locale needs to come from the server and be passed in place of the undefined below return amountAsNumber.toLocaleString(LOCALE, { style: "currency", currency: currency }); } function shiftCommaForDecimals(nonDecimalAmount) { if ((!nonDecimalAmount) || (nonDecimalAmount == '0')) return '0.00'; if ((nonDecimalAmount.length < 2)) { return '0.' + nonDecimalAmount; } var position = nonDecimalAmount.length - 2; var decimalPrice = [nonDecimalAmount.slice(0, position), '.', nonDecimalAmount.slice(position)].join(''); // CONSTANTS.LOGGER.info('getPriceWithDecimals(): converting ' + nonDecimalAmount + ' into ' + decimalPrice); // console.log('shiftCommaForDecimals(): turned ' + nonDecimalAmount + ' into ' + decimalPrice); return decimalPrice; }