(function () { global.dashModule .controller('shopCartCtrl', ['$scope', '$http', '$', '$translate', 'Upload', 'utilsService', 'shopCartService', shopCartCtrl]) .directive('shopCart', [shopCartDirective]); function shopCartDirective() { return { restrict: 'E', templateUrl: 'shop/html/shopCartTemplate' }; } function shopCartCtrl($scope, $http, $, $translate, Upload, utilsService, shopCartService) { let addressType = ''; const countryNames = {}; $scope.DOCUMENT_TYPES = { 'TEMPLATE_QUESTINNAIRE': 1, 'QUESTIONNAIRE': 2, 'TEMPLATE_AGREEMENT': 6, 'AGREEMENT': 7 }; $scope.startOrderDetails = startOrderDetails; $scope.cartPackages = []; $scope.countries = []; $scope.details = {}; $scope.delivery = {}; $scope.billing = {}; $scope.countryNames = {}; $scope.updateQuantity = updateQuantity; $scope.removeFromCart = removeFromCart; $scope.actionButton = 'NEXT'; $scope.prevButton = ''; $scope.isStepVisible = isStepVisible; $scope.hasPrevStep = hasPrevStep; $scope.goToNextStep = goToNextStep; $scope.showHideDialog = showHideDialog; $scope.isDialogVisible = false; $scope.placeOrder = placeOrder; $scope.changeCountryName = changeCountryName; $scope.isCartEmpty = isCartEmpty; $scope.sumPrice = shopCartService.sumPrice; $scope.isAvailable = isAvailable; $scope.getAvailabilityMessage = getAvailabilityMessage; $scope.termsAndConditionCheckbox = false; $scope.setTermsCheckboxValue = setTermsCheckboxValue; $scope.getAlertClass = getAlertClass; $scope.isActionBtnDisabled = isActionBtnDisabled; $scope.deliveryEqualsBilling = { checked: false }; $scope.setBillingSameAsDeliveryAddress = setBillingSameAsDeliveryAddress; $scope.getOptionAvailabilityClass = getOptionAvailabilityClass; $scope.documents = {}; $scope.selectionSteps = { 'show-order-items': { current: 'show-order-items', next: 'upload-customer-questionaire', prev: '', isActionPromise: false, beforeAction: isCartValid, action: getInfo }, 'upload-customer-questionaire': { current: 'upload-customer-questionaire', next: 'upload-agreement', prev: 'show-order-items', isActionPromise: false, beforeAction: isQuestionaireUploaded, action: () => { return true; } }, 'upload-agreement': { current: 'upload-agreement', next: 'show-customer-details', prev: 'upload-customer-questionaire', isActionPromise: false, beforeAction: isAgreementUploaded, action: () => { return true; } }, 'show-customer-details': { current: 'show-customer-details', next: 'show-customer-billing', prev: 'upload-agreement', isActionPromise: false, beforeAction: () => { return true; }, action: () => { return true; } }, 'show-customer-billing': { current: 'show-customer-billing', next: '', prev: 'show-customer-details', isActionPromise: false, beforeAction: () => { return true; }, action: showHideDialog }, }; $scope.step = $scope.selectionSteps['show-order-items']; $scope.uploadFile = uploadFile; $scope.isOrderPlaced = false; function startOrderDetails() { getShopCart(); isActionBtnDisabled(); utilsService.registerFunction('isActionBtnDisabled', isActionBtnDisabled); } function getOptionAvailabilityClass(isAvailable) { return isAvailable ? '' : 'not-available'; } function isStepVisible(step) { return step === $scope.step.current; } function getShopCart() { $http({ method: 'POST', url: 'shop/api/getShopCart' }).then(setShopCartPackages, utilsService.onHttpError); } function setShopCartPackages(response) { if (typeof response.data !== 'undefined') { $scope.cartPackages = response.data; $.each($scope.cartPackages, function (key, packageObject) { $scope.commercialLead = packageObject.commercialLead; packageObject.quantity = parseInt(packageObject.quantity); packageObject.extraFixedPrice = calculateTotalPrice(packageObject, 'fixedPrice'); packageObject.extraRecurrentPrice = calculateTotalPrice(packageObject, 'recurrentPrice') + calculateTotalPrice(packageObject, 'servicesPrice'); }); } } function calculateTotalPrice(packageObject, priceKey) { let prices = packageObject.options.map((option) => { return option[priceKey]; }); prices = prices.concat(packageObject.additionalPackages.map((additionalPackage) => { return additionalPackage[priceKey]; })); return shopCartService.sumPrice(prices, 1); } function updateQuantity(packageObject) { const params = $.param({ idPackage: packageObject.idPackage, idCustomerInstance: packageObject.idCustomerInstance, idPrice: packageObject.idPrice, quantity: packageObject.quantity }); $http({ method: 'POST', url: 'shop/api/updateQuantity', data: params }).then(updateMessage, utilsService.onHttpError); } function removeFromCart(packageObject) { const params = $.param({ idCart: packageObject.idCart }); $http({ method: 'POST', url: 'shop/api/removeFromCart', data: params }).then(updateMessage, utilsService.onHttpError); } function updateMessage(response) { if (typeof response.data.messages !== 'undefined') { response.data.messages.forEach((messageObj) => { const key = messageObj.key ? $translate.instant('shop.messages.' + messageObj.key) : ''; let translatedMessage = $translate.instant('shop.messages.' + messageObj.message); translatedMessage = key !== '' ? key + ': ' + translatedMessage : translatedMessage; if (messageObj.message !== 'NO_CHANGE') { utilsService.displayMessage(messageObj.code, translatedMessage); } if (messageObj.message === 'PACKAGE_REMOVED_FROM_CART') { getShopCart(); shopCartService.updateShopCartCount(); } if (messageObj.message === 'ORDER_PLACED') { getShopCart(); shopCartService.updateShopCartCount(); $scope.isOrderPlaced = true; } if (messageObj.message === 'FILE_UPLOADED') { getCartDocuments(); } }); } } function hasPrevStep() { return $scope.prevButton !== ''; } function showWarning(translateKey) { const translatedMessage = $translate.instant('shop.messages.' + translateKey); utilsService.displayMessage('warning', translatedMessage); } function goToNextStep(action, promiseFinished) { if ($scope.step.isActionPromise && !promiseFinished) { $scope.step.beforeAction(); } else { const beforeActionSuccesfull = promiseFinished || $scope.step.beforeAction(); if (!$scope.isBtnDisabled && action === 'next' && beforeActionSuccesfull) { $scope.step.action(); } if ($scope.step[action] !== '' && (beforeActionSuccesfull || action === 'prev')) { const newClassForActive = action === 'next' ? 'done-step' : 'inactive-step'; const removeClassForNew = action === 'next' ? 'inactive-step' : 'done-step'; $('.' + $scope.step.current).removeClass('active-step'); $('.' + $scope.step.current).addClass(newClassForActive); $('.' + $scope.step[action]).removeClass(removeClassForNew); $('.' + $scope.step[action]).addClass('active-step'); $scope.step = $scope.selectionSteps[$scope.step[action]]; if (action === 'next' && $scope.step.next === '') { $scope.actionButton = 'SAVE'; isActionBtnDisabled(); } else { isActionBtnDisabled(false); $scope.actionButton = 'NEXT'; } $scope.prevButton = (action === 'prev' && $scope.step.prev === '') ? '' : 'PREV'; } } } function isCartValid() { let isCartValid = { qunatity: true, available: true }; $scope.cartPackages.forEach((cartPackage) => { if (!cartPackage.quantity || cartPackage.quantity <= 0 || cartPackage.quantity > 100) { isCartValid.qunatity = false; } if (!isAvailable(cartPackage)) { isCartValid.available = false; } }); if (!isCartValid.qunatity) { showWarning('INVALID_QUANTITY'); } if (!isCartValid.available) { showWarning('PRODUCT_NOT_AVAILABLE'); } return isCartValid.qunatity && isCartValid.available; } function getInfo() { if (isCartValid) { Promise.all([getCustomerDetails(), getCountries(), getCartDocuments()]).then(values => { $scope.$evalAsync(() => { setCustomerDetails(values[0]); setCountries(values[1]); }); }); } } function getCustomerDetails() { return $http({ method: 'POST', url: 'shop/api/getCustomerDetails' }); } function setCustomerDetails(response) { if (response.data) { $scope.delivery = response.data.delivery ? response.data.delivery : $scope.delivery; $scope.billing = response.data.billing ? response.data.billing : $scope.billing; $scope.vatCode = response.data.vat ? response.data.vat : ''; $scope.countryNames = response.data.countryNames ? response.data.countryNames : $scope.countryNames; } } function getCountries() { return $http({ method: 'POST', url: 'shop/api/getCountries' }); } function setCountries(response) { $scope.countries = response.data || []; } function setBillingSameAsDeliveryAddress() { if (Object.keys($scope.delivery).length) { if ($scope.deliveryEqualsBilling.checked) { $scope.billing.detailedAddress = $scope.delivery.detailedAddress; $scope.billing.idCountrySelected = $scope.delivery.idCountrySelected; changeCountryName('billing', $scope.billing.idCountrySelected); $scope.billing.city = $scope.delivery.city; $scope.billing.zipCode = $scope.delivery.zipCode; } else { $scope.billing.detailedAddress = ''; $scope.billing.idCountrySelected = 0; $scope.billing.city = ''; $scope.billing.zipCode = ''; } } } function showHideDialog() { $scope.$evalAsync(() => { $scope.isDialogVisible = !$scope.isDialogVisible; }); } function placeOrder() { $scope.isTermsChecked = shopCartService.getTermsCheckboxValue(); if ($scope.isTermsChecked) { const params = $.param({ cartPackages: JSON.stringify($scope.cartPackages), deliveryInfo: JSON.stringify($scope.delivery), billingInfo: JSON.stringify($scope.billing), details: JSON.stringify($scope.details) }); $http({ method: 'POST', url: 'shop/api/placeOrder', data: params }).then(updateMessage, utilsService.onHttpError); } else { const errorMessage = $translate.instant('shop.messages.NOT_ACCEPTED_TERMS'); utilsService.displayMessage('error', errorMessage); } } function changeCountryName(addrType, idCountry) { addressType = addrType; $http({ method: 'POST', url: 'shop/api/getCountryDetailsById', data: $.param({ idCountry }) }).then(setCountryName, utilsService.onHttpError); } function setCountryName(response) { if (response && response.data.length > 0) { countryNames[addressType] = response.data[0]['countryName']; } if ($scope.countryNames) { $scope.countryNames[addressType] = countryNames[addressType]; } else { $scope.countryNames = countryNames; } } function isCartEmpty() { return $scope.cartPackages.length === 0; } function getCartDocuments() { let packagesIds = []; $scope.cartPackages.forEach((pkg) => { packagesIds.push(pkg.idPackage); }); $http({ method: 'POST', url: 'shop/api/getCartDocuments', data: $.param({ packages: JSON.stringify(packagesIds) }) }).then(setDocuments, utilsService.onHttpError); } function setDocuments(response) { if (response.data) { $scope.documents[$scope.DOCUMENT_TYPES['TEMPLATE_QUESTINNAIRE']] = response.data[$scope.DOCUMENT_TYPES['TEMPLATE_QUESTINNAIRE']] ? response.data[$scope.DOCUMENT_TYPES['TEMPLATE_QUESTINNAIRE']] : []; $scope.documents[$scope.DOCUMENT_TYPES['TEMPLATE_AGREEMENT']] = response.data[$scope.DOCUMENT_TYPES['TEMPLATE_AGREEMENT']] ? response.data[$scope.DOCUMENT_TYPES['TEMPLATE_AGREEMENT']] : []; } } function isOrderDocumentUploaded(documentType) { let areAllDocumentsUploaded = true; $scope.documents[documentType].forEach((document) => { if (!document.isUploaded) { areAllDocumentsUploaded = false; } }); if (!areAllDocumentsUploaded) { showWarning('NOT_UPLOADED'); } return areAllDocumentsUploaded; } function isQuestionaireUploaded() { return isOrderDocumentUploaded(1); } function isAgreementUploaded() { return isOrderDocumentUploaded(6); } function uploadFile(file, idPackage, documentType) { const idDocumentType = documentType === 'questionnaire' ? $scope.DOCUMENT_TYPES['QUESTIONNAIRE'] : $scope.DOCUMENT_TYPES['AGREEMENT']; if (file) { Upload.upload({ url: 'shop/api/uploadOrderDocument', method: 'POST', file: file, data: { idDocumentType, idPackage } }).then(updateMessage, utilsService.onHttpError); } else { let translatedMessage = $translate.instant('shop.messages.NO_FILE'); utilsService.displayMessage('error', translatedMessage); } } function isAvailable(packageObj) { return packageObj.status === 'available' && parseInt(packageObj.isLinkEnabled) === 1 && packageObj.areOptionsAvailable && packageObj.areAdditionalAvailable; } function getAvailabilityMessage(packageObj) { if (packageObj.status !== 'available') { return 'PACKAGE_UNAVIALABLE'; } if (parseInt(packageObj.isLinkEnabled) !== 1) { return 'CL_UNAVIALABLE'; } if (!packageObj.areOptionsAvailable) { return 'OPTIONS_UNAVAILABLE'; } if (!packageObj.areAdditionalAvailable) { return 'ADDITIONAL_PACKAGES_UNAVAILABLE'; } return ''; } function setTermsCheckboxValue(termsAndConditionCheckbox) { shopCartService.setTermsCheckboxValues(termsAndConditionCheckbox); } function getAlertClass(termsAndConditionCheckbox) { return termsAndConditionCheckbox ? 'alert-success' : 'alert-warning'; } function isActionBtnDisabled(isDisabled = true) { $scope.isBtnDisabled = $scope.actionButton === 'SAVE' ? isDisabled : false; } } })();