UNPKG

cobuild-angular-stack

Version:

Base stack angular sass jade gulp

815 lines (739 loc) 34 kB
(function (module) { 'use strict'; module.controller('MainCheckoutController', MainCheckoutController); module.controller('SuccessOrderController', SuccessOrderController); MainCheckoutController.$inject = [ '$scope', '$rootScope', '$state', '$stateParams', 'CoupleAccount', 'Guest', 'toastr', '$localStorage', 'countries', '$timeout', 'currencies', 'currencyConversionPromiseFilter', 'currencyFilter', '$analytics', '$translate', 'Order', 'Card', 'account', 'lodash', '$interval' ]; function MainCheckoutController($scope, $rootScope, $state, $stateParams, CoupleAccount, Guest, toastr, $localStorage, countries, $timeout, currencies, currencyConversion, currency, $analytics, $translate, Order, Card, account, lodash, $interval) { var steps = ['guest.checkout.cart', 'guest.checkout.message', 'guest.checkout.pay', 'guest.checkout.receipt']; $scope.validPhone = /^\d{7,12}$/; $scope.validateForm = {}; $scope.goStep = function (step) { var currentStep = steps.indexOf($state.$current.name); if (currentStep < 0 || step > currentStep) { $translate('error-steps').then(function (translation) { return toastr.error(translation); }); } $state.go(steps[step]); }; // $state.go('guest.checkout.receipt') $scope.print = function (order, coupleAccount) { var buttonPrintData = { order: order.fakeid, couple: (coupleAccount.weddingData.nameP1 || '') + ' & ' + (coupleAccount.weddingData.nameP2 || ''), amount: 'MX$ ' + order.paymentData.amount.formatMoney(2), comission: 'MX$ ' + (order.comission || 0).formatMoney(2), total: 'MX$ ' + (order.paymentData.amount + order.comission).formatMoney(2), barcode_url: order.transactionData.payment_method.barcode_url, barcode: order.transactionData.payment_method.barcode }; var serialize = function(obj) { var str = []; for(var p in obj) if (obj.hasOwnProperty(p)) { str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); } return str.join("&"); }; window.open('http://front.uniko.co/partials/print.html?' + serialize(buttonPrintData), '', 'width=700,height=700'); }; $scope.$state = $state; $scope.account = null; $scope.products = []; $scope.url = $stateParams.url; $scope.birthdate = {}; $scope.address = {}; var currentYear = new Date().getFullYear(); $scope.months = lodash.range(1, 13); $scope.years = lodash.range(currentYear, currentYear + 11); $scope.birthyears = lodash.reverse(lodash.range(currentYear - 90, currentYear - 17)); $scope.countries = countries; $scope.mercadoMedios = {}; $scope.getDaysArray = function (year, month) { var date = new Date(year, month - 1, 1); var result = []; while (date.getMonth() == month - 1) { result.push(date.getDate()); date.setDate(date.getDate() + 1); } return result; }; $scope.currencies = currencies; $scope.currency = lodash.find(currencies, {code: 'MXN'}); $scope.selectCurrency = function (currency) { $scope.currency = currency; }; $scope.pay = { month: null, year: null }; $scope.payer = {}; $scope.paymentInfo = {}; $scope.disabled = false; $scope.order = null; $scope.removeItem = function (index) { $scope.products.splice(index, 1); }; var findMercadoMedios = function(){ console.log('findMercadoMedios'); Guest.getMercadoPayments(function (medios) { console.log('Medios = ', medios); $scope.mercadoMedios = medios; console.log('Medios 2 = ', $scope.mercadoMedios); }); }; findMercadoMedios(); var $w = function (newVal) { if (!$scope.products) { return; } var total = 0; lodash.forEach($scope.products, function (product) { var price = Math.$round(product.price, 2); total += price * product.bought; currencyConversion(price * product.bought, 'MXN', $scope.currency.code).then(function (price) { product.convertedPrice = currency(price, $scope.currency.symbol + ' ', 2); }); }); currencyConversion(total, 'MXN', $scope.currency.code).then(function (price) { $scope.total = currency(price, $scope.currency.symbol + ' ', 2); var paymentInfo = $scope.paymentInfo; var number = 'transfer'; if (paymentInfo.method === 'cc') { number = paymentInfo.pay.number || ''; } else if (paymentInfo.method === 'paypal') { number = 'paypal'; } else if (paymentInfo.method === 'ox') { number = 'oxxo'; } else if (paymentInfo.method === 'mercado') { number = 'mercado'; } Card.calculateComission({ cardNumber: number, value: total }, function (response) { console.log(response); currencyConversion(response.comission, 'MXN', $scope.currency.code).then(function (comission) { console.log(comission); $scope.comission = currency(comission, $scope.currency.symbol + ' ', 2); }); currencyConversion(Math.$round(response.comission + total, 2), 'MXN', $scope.currency.code).then(function (totalAndComission) { $scope.totalAndComission = currency(totalAndComission, $scope.currency.symbol + ' ', 2); }); }); }); $scope.totalMx = currency(total, 'MXN ', 2); }; $scope.updatePrices = function (item, element) { $w(); }; $scope.$watchGroup(['products', 'products.length', 'currency', 'paymentInfo.method', 'paymentInfo.pay.number'], $w); this.step3 = function () { $analytics.eventTrack('Messages', {'Messages': true}); $state.go("guest.checkout.pay", {url: $scope.url}); }; function loadPaymentInfo() { var paymentInfo = lodash.cloneDeep($scope.paymentInfo); paymentInfo.birthdate = $scope.birthdate; if (paymentInfo.pay && paymentInfo.payer) paymentInfo.pay.name = paymentInfo.payer.fullname; paymentInfo.urlRegistry = $scope.url; paymentInfo.address = $scope.address; paymentInfo.products = []; lodash.forEach($scope.products, function (product) { for (var i = 0; i < product.bought; i++) { paymentInfo.products.push(product.id); } }); return paymentInfo; } var ExceptionForm = function(message, element) { this.message = message; this.element = element; } var CardValidate = function(number, element) { this.number = number; this.element = element; this.type_card = ""; this.is_valid_number = false; this._typeCard = function() { var id = String(this.number).substring(0,1) switch(id) { case '6': var bin_60 = String(this.number).substring(0,4); var bin_range_62 = String(this.number).substring(0,6); var bin_range_64 = String(this.number).substring(0,3); var bin_65 = String(this.number).substring(0,2); if(bin_60 == "6011" || (bin_range_62 >= "622126" && bin_range_62 <= "622925") || (bin_range_64 >= "644" && bin_range_64 <= "649") || bin_65 == "65") { this.type_card = "discover" } break; case '3': var bin_range = String(this.number).substring(0,2); if(bin_range == "34" || bin_range == "37") { this.type_card = "amex" } break; case '5': case '2': var bin_range = String(this.number).substring(0,2); if(bin_range >= "51" && bin_range <= "55") { this.type_card = "mastercard"; } break; case '4': this.type_card = "visa" break; default: this.type_card = "visa" //throw new ExceptionForm("No se encontro tipo de tarjeta", element); } $scope.paymentInfo.otro = { pay_type: this.type_card } console.log("------->", $scope.paymentInfo, this.type_card); if(this.type_card == "amex" && String(this.number).length != 15) { throw new ExceptionForm("La tarjeta debe tener 15 dígitos", element); } else if (this.type_card != "amex" && String(this.number).length != 16) { throw new ExceptionForm("La tarjeta debe tener 16 dígitos", element); } } this.cardValid = function() { var type_card = this.type_card; var operation = 0; var cardNumber = String(this.number).split("").reverse(); this._typeCard(); var total = 0; for(var index = 0; index < cardNumber.length; index ++) { var positionCard = index + 1; var number = cardNumber[index]; operation = parseInt(number); operation = positionCard % 2 == 0 ? (operation * 2) : operation; operation = operation > 9 ? eval(String(operation).split("").join("+")) : operation; total = total + operation; } this.is_valid_number = total % 10 == 0 ? true : false; if(!this.is_valid_number) { throw new ExceptionForm("El número de tarjeta no es valido", element); } } switch (this.number) { case '4242424242424242': case '4012888888881881': case '5555555555554444': case '5105105105105100': case '378282246310005': case '371449635398431': this.is_valid_number = true; break; default: this.cardValid(); } } var TypeData = function(type, info, element, requerid) { this.type = type; this.info = info; this.element = element; if(requerid && $.trim(this.info).length == 0) { throw new ExceptionForm("Este campo es requerido", element); } switch (this.type) { case 'integer': if(isNaN(this.info)) { throw new ExceptionForm("El campo debe ser numérico", element); } break; case 'email': var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; if(!re.test(this.info)) { throw new ExceptionForm("El correo no es válido", element); } break; case 'select': if(!this.info) { throw new ExceptionForm("Este campo es requerido", element); } break; case 'phone': var re = /^\(?([0-9]{3})\)?([0-9]{3})[-. ]?([0-9]{1,4})$/ if(!re.test(this.info)){ throw new ExceptionForm("No es un teléfono válido", element); } } } $scope.onValidateInput = function(element, info, compare_info, isKeyup) { var verify = function() { $scope.validateForm[element+"_error"] = ""; try { switch (element) { case 'card_number' : var valid_type = new TypeData('integer', info, element, true); break; case 'year': case 'month': case 'day': case 'pay_type': case 'exp_year': var valid_type = new TypeData('select', info, element, true); break; case 'cvc': var valid_type = new TypeData('integer', info, element, true); break; case 'confirmEmail': var valid_type = new TypeData('email', info, element, true); if(info != compare_info) { throw new ExceptionForm("El correo no coincide", element); } break; case 'phone': var valid_type = new TypeData('phone', info, element); break; case 'email': var valid_type = new TypeData('email', info, element, true); break; default: var valid_type = new TypeData('string', info, element, true); } } catch (e) { $scope.validateForm[e.element+"_error"] = e.message; } } if(isKeyup && $scope.validateForm[element+"_error"] && $scope.validateForm[element+"_error"].length >0) { verify(); } else if(!isKeyup) { verify(); } else { if(element == "card_number") var card =new CardValidate(info, element); } } $scope.validateDataPayment = function() { var paymentInfo = loadPaymentInfo() if($scope.paymentInfo.method == 'cc') { $scope.onValidateInput('fullname', paymentInfo.payer.fullname); $scope.onValidateInput('email', paymentInfo.payer.email); $scope.onValidateInput('confirmEmail', $("#confirmEmail").val(), paymentInfo.payer.email); $scope.onValidateInput('phone', paymentInfo.payer.phone); $scope.onValidateInput('card_number', paymentInfo.pay.number); $scope.onValidateInput('city', paymentInfo.payer.city); $scope.onValidateInput('exp_month', paymentInfo.pay.exp_month); $scope.onValidateInput('exp_year', paymentInfo.pay.exp_year); $scope.onValidateInput('cvc', paymentInfo.pay.cvc); } return true; } var validateDataPayment = function(){ var paymentInfo = loadPaymentInfo(); if(paymentInfo.products.length == 0 ){ return { error : { message : "Debe incluir almenos un producto en el regalo" } }; } if(!paymentInfo.message || !paymentInfo.message.message || !paymentInfo.message.tel){ return { error : { message : "Debe completar los datos del mensaje" } }; } var msg = paymentInfo.message; if( !msg.emails || msg.emails.length == 0 || !lodash.every(msg.emails,'text') ){ return { error : { message : "Debe completar los datos del mensaje, debe incluir almenos un correo" } }; } if(!msg.givers || msg.givers.length == 0 || !lodash.every(msg.givers, 'text')){ return { error : { message : "Debe completar los datos del mensaje, debe incluir almenos un nombre" } }; } return {}; }; function callMercado(paymentInfo, orderId){ lodash.forEach($scope.mercadoMedios, function (medio) { if (medio.elements){ lodash.forEach(medio.elements, function(item){ if (item.id === paymentInfo.mercado.pay_type){ paymentInfo.mercado.name = item.name; $scope.methodName = item.name; } }); } }); var $promise = Guest.makeMercadoPagoPayment({paymentInfo: paymentInfo, orderId: $localStorage.orderId}) .$promise .then(function (order) { console.log('callMercado = ',order); $analytics.eventTrack('Item Purchased', { 'Payment Method': 'Mercado', 'Order ID': order.id, 'Total Amount': order.paymentData.amount, 'Total Number of Items': order.paymentData.products.length }); getMixpanel().people.increment({ 'Lifetime Acumulated': order.paymentData.amount }); $scope.showHeader = false; $scope.order = order; $state.go('guest.checkout.receipt', {url: $scope.url}); delete $localStorage.cart[$scope.account.id]; delete $localStorage.paymentInfo[$scope.account.id]; delete $localStorage.orderId; $scope.account = null; $scope.products = []; $scope.pay = { month: null, year: null }; $scope.payer = {}; $scope.paymentInfo = {}; $scope.disabled = false; }) .catch(function (err) { console.log('callMercado Error ',err); toastr.error(err.data.error.message); $scope.disabled = false; }) .finally(function () { $scope.disabled = false; }); } var init ; var loader = { show: function() { init = $interval(function() { var imgs = $(".loader-image:visible"); if(!$(".loading-init").hasClass('hidden')) { if(imgs.length == 5) { $(".loader-image").addClass("hidden") } else { $("#loader_"+(imgs.length + 1)).removeClass("hidden") } } }, 1000); $(".loading-init").removeClass("hidden"); }, hide: function() { $(".loading-init").addClass("hidden"); $interval.cancel(init); } } $scope.setFocus = function(event) { console.log(event); setTimeout(function() { $(event.currentTarget).click(); },9000); } this.pay = function () { loader.show(); var paymentInfo = loadPaymentInfo(); var validate = validateDataPayment(); if(validate.error){ loader.hide(); toastr.error(validate.error.message,'Error'); return; } $scope.disabled = true; var $promise; if (paymentInfo.method === 'dp') { Guest .updateOrder({ paymentInfo: paymentInfo, orderId: $localStorage.orderId, paymentMethod: 'Manual' }, function (order) { $scope.order = order; $state.go('guest.checkout.receipt', {url: $scope.url}); delete $localStorage.cart[$scope.account.id]; delete $localStorage.paymentInfo[$scope.account.id]; delete $localStorage.orderId; $scope.account = null; $scope.products = []; $scope.pay = { month: null, year: null }; $scope.payer = {}; $scope.paymentInfo = {}; $scope.disabled = false; loader.hide(); }); } else if (paymentInfo.method === 'cc') { var cartInfo = paymentInfo.pay; Conekta.token.create({card: paymentInfo.pay}, function (token) { paymentInfo.pay = token.id; paymentInfo.first6 = cartInfo.number.toString().substr(0, 6); $promise = Guest.makeCardPayment({paymentInfo: paymentInfo, orderId: $localStorage.orderId}) .$promise .then(function (order) { $analytics.eventTrack('Item Purchased', { 'Payment Method': 'Conekta', 'Order ID': order.id, 'Total Amount': order.paymentData.amount, 'Total Number of Items': order.paymentData.products.length }); getMixpanel().people.increment({ 'Lifetime Acumulated': order.paymentData.amount }); $scope.showHeader = false; $scope.order = order; $state.go('guest.checkout.receipt', {url: $scope.url}); delete $localStorage.cart[$scope.account.id]; delete $localStorage.paymentInfo[$scope.account.id]; delete $localStorage.orderId; $scope.account = null; $scope.products = []; $scope.pay = { month: null, year: null }; $scope.payer = {}; $scope.paymentInfo = {}; $scope.disabled = false; loader.hide(); }) .catch(function (err) { loader.hide(); toastr.error(err.data.error.message_to_purchaser); }) .finally(function () { $scope.disabled = false; }); }, function (err) { loader.hide(); toastr.error(err.message_to_purchaser); $scope.disabled = false; }); } else if (paymentInfo.method === 'ox') { $promise = Guest.makeOxxoPayment({ paymentInfo: paymentInfo, orderId: $localStorage.orderId }) .$promise .then(function (order) { $analytics.eventTrack('Item Purchased', { 'Payment Method': 'OXXO', 'Order ID': order.id, 'Total Amount': order.paymentData.amount, 'Total Number of Items': order.paymentData.products.length }); getMixpanel().people.increment({ 'Lifetime Acumulated': order.paymentData.amount }); $scope.showHeader = false; $scope.order = order; $state.go('guest.checkout.receipt', {url: $scope.url}); delete $localStorage.cart[$scope.account.id]; delete $localStorage.paymentInfo[$scope.account.id]; delete $localStorage.orderId; $scope.account = null; $scope.products = []; $scope.pay = { month: null, year: null }; $scope.payer = {}; $scope.paymentInfo = {}; $scope.disabled = false; loader.hide(); }) .catch(function (err) { toastr.error(err.data.error.message_to_purchaser); }) .finally(function () { $scope.disabled = false; }); } else if (paymentInfo.method === 'mercado') { console.log('Mercado pago request = ', paymentInfo); var createCard = 0; if (paymentInfo.mercado.method === 'credit_card' || paymentInfo.mercado.method === 'debit_card' || paymentInfo.mercado.method === 'prepaid_card' ){ createCard = { email : paymentInfo.payer.email, cardNumber : paymentInfo.pay.number, securityCode : paymentInfo.pay.cvc, cardExpirationMonth : paymentInfo.pay.exp_month, cardExpirationYear : paymentInfo.pay.exp_year, cardholderName : paymentInfo.pay.name }; console.log('Object to create = ' , createCard); } if (createCard != 0){ Mercadopago.clearSession(); Mercadopago.createToken(createCard, function(status, response){ if (status != 200 && status != 201) { $translate('mercado_'+response.cause[0].code).then(function (translation) { toastr.error(translation); }); $scope.disabled = false; }else{ paymentInfo.first6 = paymentInfo.pay.number.toString().substr(0, 6); paymentInfo.pay = response.id; console.log('Todo Bien!!!'); callMercado(paymentInfo, localStorage.orderId ); } }); } else { callMercado(paymentInfo, localStorage.orderId ); } } else { Guest.makePaypalPayment({paymentInfo: paymentInfo, orderId: $localStorage.orderId}) .$promise .then(function (data) { window.location.href = data.url; }) .catch(function (data) { if (data.data.error.httpStatusCode === 400) { var err = data.data.error.response.details; lodash.forEach(err, function (e) { toastr.error(e.issue); }); } }) .finally(function () { loader.hide(); $scope.disabled = false; }); } }; $scope.$on('$stateChangeSuccess', function () { if ($state.is("guest.checkout.receipt") && !$scope.order) { return $state.go('guest', {url: $stateParams.url}); } if (account.isDisabled) { return $state.go('guest', {url: $stateParams.url}); } $scope.account = account; var cart = $localStorage.cart; var paymentInfo = $localStorage.paymentInfo; var weddingCart = []; if (!cart) { cart = $localStorage.cart = {}; $localStorage.cartUrls = {}; } else { weddingCart = cart[account.id]; if (!weddingCart && $state.$current.name !== 'guest.checkout.receipt') { $translate('dont-have-items').then(function (translation) { return toastr.info(translation); }); return $state.go('guest.registry'); } lodash.some(cart, function (val, key) { $rootScope.cartUrl = $localStorage.cartUrls[key].url; return $rootScope.cartId = key; }); $rootScope.totalCart = weddingCart.length; } if (!paymentInfo) { paymentInfo = $localStorage.paymentInfo = {method: 'cc'}; } if (!$localStorage.cartUrls[account.id]) { $localStorage.cartUrls[account.id] = {}; } $localStorage.cartUrls[account.id].url = account.url; var currentPayment = paymentInfo[account.id]; if (!currentPayment) { currentPayment = paymentInfo[account.id] = {}; } $scope.products = weddingCart; $scope.paymentInfo = currentPayment; if (!currentPayment.pay) { currentPayment.pay = { month: null, year: null } } if (!currentPayment.payer) { currentPayment.payer = { country: 'MX' }; } if (!currentPayment.message) { currentPayment.message = { emails: [], names: [] }; } if ($state.current.name === 'guest.checkout.pay') { if ($localStorage.orderId) { $scope.orderId = $localStorage.orderId; } else { paymentInfo = loadPaymentInfo(); paymentInfo.urlRegistry = account.url; Guest .createOrder({paymentInfo: paymentInfo}) .$promise .then(function (order) { $scope.orderId = $localStorage.orderId = order.id; }); } } }); $scope.$watch(function () { return $scope.paymentInfo ? JSON.stringify($scope.paymentInfo) : null; }, function (newVal) { if (!$state.is('guest.checkout.order') && !$state.is('guest.checkout.pay')) { if (newVal && $localStorage.orderId) { Guest .updateOrder({ paymentInfo: loadPaymentInfo(), orderId: $localStorage.orderId }) .$promise .then(function(result){ },function(err){ if(err && err.data && err.data.error && err.data.error.message){ toastr.error(err.data.error.message,'Error'); } }); } } }); } SuccessOrderController.$inject = ['$scope', '$state', '$stateParams', '$location', 'Guest', '$localStorage', '$timeout', '$analytics', '$translate', 'toastr']; function SuccessOrderController($scope, $state, $stateParams, $location, Guest, $localStorage, $timeout, $analytics, $translate, toastr) { $scope = $scope.$parent; $scope.showHeader = false; var search = $location.search(); var params = $stateParams.orderId ? $stateParams.orderId.split("&paymentId=") : []; if(params.length == 2) { $stateParams.orderId = params[0]; search.paymentId = params[1]; } Guest.confirmPaypalPayment({ orderId: $stateParams.orderId, paymentId: search.paymentId, token: search.token, payerID: search.PayerID }) .$promise .then(function (order) { $analytics.eventTrack('Item Purchased', { 'Payment Method': 'Paypal', 'Order ID': order.id }); $translate('success-payment').then(function (translation) { toastr.success(translation); }); $scope.order = order; $state.go('guest.checkout.receipt', {url: $scope.url}); delete $localStorage.cart[$scope.account.id]; delete $localStorage.paymentInfo[$scope.account.id]; delete $localStorage.orderId; $scope.account = null; $scope.products = []; $scope.pay = { month: null, year: null }; $scope.payer = {}; $scope.paymentInfo = {}; $scope.disabled = false; }); } })(angular.module('uniko.guest.checkout'));