/** * @Component Name: CustomerInfoComponent * @Module: Checkout * @Module Functionality : To display the customer info section * @Creation Date: August 12,2017 * @Author: sbaireddy * @Version: 1.0 */ import { Component, Input, ViewChild, OnInit, OnDestroy } from '@angular/core'; import { Router } from '@angular/router'; import { NgForm } from '@angular/forms'; import * as Constants from '../../shared/constants' import Utils from '../../shared/utils'; import CheckoutUtils from '../../shared/checkout.utils'; import { IPackage, IShipping, IUsableShipping, IShippingMode, IZipMarket, IDormantProperties } from '../../shared/modal/common'; import { User } from '../../shared/modal/user'; import { Cart } from '../../shared/modal/cart'; import { Customer } from '../../shared/modal/customer'; import { SharedService } from '../../shared/shared.service'; import { CartService } from '../../services/cart.service'; import { CustomerService } from '../../services/customer.service'; import { CheckoutService } from '../../services/checkout.service'; import { UserService } from '../../services/user.service'; import { LookupService } from '../../services/lookup.service'; import { ORDER_STATUS } from '../../shared/form.constants'; @Component( { selector: 'customer-info-cmp', moduleId: module.id, templateUrl: 'customer-info.component.html', styleUrls: ['customer-info.component.css'] }) export class CustomerInfoComponent implements OnInit, OnDestroy { private COMPONENT_NAME: string = 'CustomerInfoComponent'; packageTypes: string[] = [ Constants.PACKAGE_TYPE_VOICE, Constants.PACKAGE_TYPE_DATA, Constants.PACKAGE_TYPE_PREPAID, Constants.PACKAGE_TYPE_ACCESSORY ]; refTypeExchange: string = Constants.REF_TYPE_EXCHANGE; billingForm: NgForm; shippingForm: NgForm; user: User; cart: any; customerInfo: any = {}; storeId: number; // update storeid usableShipping: IUsableShipping; isOnlyAccCart: boolean = false; isBYOSOnlyOrder: boolean = false; npaNxxList: IZipMarket[]; isAutoEnrolled: boolean = false; autoEnrolledTermsUrl = Constants.AUTO_ENROLLED_TERMS_URL; enableShopify: boolean = false; enabledShipModeId: number; karmaTestResult: any = {}; isAALOrder: boolean = false; isExchangeOrder: boolean = false; resendShippingLabelEmail: string; isPAHNumberSelected:boolean = false; customer: Customer; languageModel: any = {isEnglish: false}; pahNumber:any; dormantProperties: IDormantProperties; subscribersList: any[]; PAHserviceFailed : boolean = false; cartSummary: any; submittedCart: boolean = false; selectedMsisdn: any = null; showNotification: boolean = false; pahNumberWithFormat: any; constructor( public router: Router, public sharedService: SharedService, public cartService: CartService, public customerService: CustomerService, public checkoutService: CheckoutService, public userService: UserService, public lookupService: LookupService ) { } /** * This function is used to initialize the directive/component after Angular * first displays the data-bound properties.It is invoked only once when the * directive is instantiated.Here it is initializing the user profile, cart and customer information * @return {void} */ ngOnInit(): void { const METHOD_NAME: string = 'ngOnInit()'; this.sharedService.updateErrorMessage(null); this.sharedService.storeId.subscribe((val: number) => { this.storeId = val; }); // getting the customer info updates // this.checkoutService.setCustomerInfo(null); // saving the Customer Info device address when it got updated. this.customerInfo = this.checkoutService.getCustomerInfo(); this.user = this.userService.getUser(); this.cart = this.lookupService.getOrder(); this.cart = this.cartService.getCart(); this.isOnlyAccCart = CheckoutUtils.isAccOnlyOrder(this.cart); this.isBYOSOnlyOrder = CheckoutUtils.isBYOSOnlyOrder(this.cart); // getting updated cart information // this.sharedService.showSpinner(true); //spinner // this.cartService.getCartDeatils(this.storeId, this.cart.orderId).subscribe(result => { // this.sharedService.showSpinner(false); //spinner // this.cart = Object.assign(this.cart, result); // }, error => { // this.sharedService.showSpinner(false); //spinner // this.sharedService.showErrorMessage(error, null); // console.error('error=>' + error) // }); this.isExchangeOrder = (this.cart.refType === this.refTypeExchange) ? true : false; if (!this.isExchangeOrder && this.cart && this.cart.customer && this.cart.customer.creditProfile && this.cart.customer.creditProfile.accountNumber) { this.isAALOrder = this.cart.customer.creditProfile.accountNumber ? true : false; } if (this.cart && this.cart.packages) { this.customerInfo.orderId = this.cart.orderId; // getting cart summary this.getCartSummary(this.cart.orderId); } if (!(this.user.permissions.isSupervisor || this.user.permissions.isWTS)) { this.customerInfo.validDealerCode = true; } else if (this.cart.dealerCode || this.isAALOrder || this.isExchangeOrder) { this.customerInfo.validDealerCode = true; } else { this.customerInfo.validDealerCode = false; } //added for notification preferences in the exchange flow this.dormantProperties = this.sharedService.getDormantProperties(); if (this.cart && this.cart.customer && this.cart.customer.email2) { this.resendShippingLabelEmail = this.cart.customer.email2; }else if (this.cart && this.cart.customer && this.cart.customer.email1) { this.resendShippingLabelEmail = this.cart.customer.email1; } let orderItemId = []; if (this.cart.packages[0].device) { orderItemId.push(this.cart.packages[0].device.originalOrderItemId); } if (this.cart.packages[0].accessories) { this.cart.packages[0].accessories.forEach(eachAccessory => { orderItemId.push(eachAccessory.originalOrderItemId); }); } let exchangeItemSpecs = this.cartService.returnableItems.filter((eachItem) => { return orderItemId.indexOf(eachItem.orderItemId) !== -1; }); // We need to make sure that exchangeItemSpecs is not empty or else showNotification will be set to true. if(exchangeItemSpecs.length>0){ this.showNotification = exchangeItemSpecs.every((eachItem) => { return eachItem.isReturnable && eachItem.isExchangeable; }); } if (this.isExchangeOrder && this.dormantProperties && this.dormantProperties.isProjectOne && this.showNotification) { this.lookupCustomer(); } } /** * Cleanup just before Angular destroys the directive/component * Unsubscribe Observables and detach event handlers to avoid memory leaks. * @return {void} */ ngOnDestroy(): void { const METHOD_NAME: string = 'ngOnDestroy()'; this.cart = null; this.usableShipping = null; this.customerInfo = null; this.user = null; this.karmaTestResult = null; this.npaNxxList = null; this.packageTypes = null; } /** * This function is used to get the cart summary through * getCartSummary function in cart service * @param {number} orderId - order id to refer the order details * @return {void} */ getCartSummary(orderId: number): void { const METHOD_NAME: string = 'getCartSummary()'; // getting current cart updates this.sharedService.showSpinner(true); // spinner this.cartService.getCartSummary(this.storeId, this.cart.orderId).subscribe(result => { this.sharedService.showSpinner(false); // spinner this.cart = Object.assign(this.cart, result); for (const pkg of this.cart.packages) { if (!pkg.showPackage) { pkg.showPackage = false; } } // expanding the first package this.cart.packages[0].showPackage = true; // getting the customer profile this.getCustomerProfile(this.cart.orderId); // checking shopify option if (this.user.permissions.isShopifyAgent && this.cart.isShopifyOrder) { this.enableShopify = true; } }, error => { this.sharedService.showSpinner(false); // spinner this.sharedService.showErrorMessage(error, true); // console.error('error=>' + error) }); } /** * This function is used to get the customer profile through * getCustomerProfile function in customer service * @param {number} orderId - order id to refer the order details * @return {void} */ getCustomerProfile(orderId: number): void { const METHOD_NAME: string = 'getCustomerProfile()'; console.log('CustomerInfoComponent.getCustomerProfile()>>Start.'); this.sharedService.showSpinner(true); // spinner this.customerService.getCustomerProfile(this.storeId, orderId, null).subscribe(result => { this.sharedService.showSpinner(false); // spinner // this.cart.customer = result ; if (result && !result.subscribers && this.cart.customer && this.cart.customer.subscribers) { result.subscribers = this.cart.customer.subscribers; } /* cart.customer does not pre-exist for Accessory only flow until billing address is entered in customer info page. hence bind result object */ this.cart.customer = this.cart && this.cart.customer ? Object.assign(this.cart.customer, result) : result; // this.cart = Object.assign(this.cart.customer, result); // getting npa nxx details if (!this.isOnlyAccCart && this.cart.refType !== Constants.REF_TYPE_EXCHANGE) { if (this.cart && this.cart.customer && this.cart.customer.zipCode) { if (!this.isAALOrder) { this.lookupNpaNxx(this.cart.customer.zipCode); } this.getPaperlessBilling(this.cart.customer.zipCode); } } }, error => { this.sharedService.showSpinner(false); // spinner this.sharedService.showErrorMessage(error, true); // console.error('error=>' + error); }); } /** * This function is used to get the npanxx type through * lookupNpaNxx function in checkout service * @param {string} zipCode - Zipcode of the customer * @return {void} */ lookupNpaNxx(zipCode: string): void { const METHOD_NAME: string = 'lookupNpaNxx()'; this.npaNxxList = CheckoutUtils.createNpaNxx(this.cart); if(!this.npaNxxList) { // getting current cart updates this.sharedService.showSpinner(true); // spinner this.cartService.lookupNpaList(this.storeId, this.cart.orderId, Utils.trimZipCode(zipCode)).subscribe(result => { this.karmaTestResult = result; this.sharedService.showSpinner(false); // spinner if (result && !result.hasOwnProperty('errorCode')) { this.npaNxxList = result } else { this.sharedService.showErrorMessage('_ERR_NPA_SERVICE_NOT_FOUND', false); } }, error => { this.sharedService.showSpinner(false); // spinner //this.sharedService.showErrorMessage(error, true); this.sharedService.showErrorMessage('_ERR_NPA_SERVICE_NOT_FOUND', false); // console.error('error=>' + error); }); } } /** * This function is used to get the paperless bill information * through getPaperlessBilling function in checkout service * @param {string} zipCode - Zipcode of the customer * @return {void} */ getPaperlessBilling(zipCode: string): void { const METHOD_NAME: string = 'getPaperlessBilling()'; let accountNumber: number; let accountType: string; let accountSubType: string; if (this.cart && this.cart.customer && this.cart.customer.creditProfile) { accountNumber = this.cart.customer.creditProfile.accountNumber; accountType = this.cart.customer.creditProfile.accountType; accountSubType = this.cart.customer.creditProfile.accountSubType; } // getting current cart updates this.sharedService.showSpinner(true); // spinner this.checkoutService.getPaperlessBilling(this.storeId, this.cart.orderId, zipCode, accountNumber, accountType, accountSubType, null ).subscribe(result => { this.karmaTestResult = result; this.sharedService.showSpinner(false); // spinner this.isAutoEnrolled = result.isAutoEnrolled; }, error => { this.sharedService.showSpinner(false); // spinner this.sharedService.showErrorMessage(error, true); // console.error('error=>' + error); }); } /** * This function is used to update the usable shipping modes * @param {IShippingMode} shippingMode - Object contains the ship mode id * @return {void} */ updateShipMode(shippingMode: IShippingMode): void { const METHOD_NAME: string = 'updateShipMode()'; console.log('CustomerInfoComponent.updateShipMode()>>Start.'); if (this.usableShipping && this.usableShipping.usableShippingMode) { for (const shipMode of this.usableShipping.usableShippingMode) { if (this.enableShopify) { if (shipMode.orderType === Constants.SHIP_MODE_SHOPIFY || shipMode.orderType === Constants.SHIP_MODE_BOTH) { if (shipMode.shipModeId === shippingMode.shipModeId) { shipMode.defaultShippingEnabled = true; } else { shipMode.defaultShippingEnabled = false; } } } else { if (!shipMode.orderType || (shipMode.orderType && shipMode.orderType === Constants.SHIP_MODE_BOTH)) { if (shipMode.shipModeId === shippingMode.shipModeId) { shipMode.defaultShippingEnabled = true; } else { shipMode.defaultShippingEnabled = false; } } } } } console.log('CustomerInfoComponent.updateShipMode()>>End.'); } /** * This function is used to get the ship mode id based on the order type * @return {number} */ getSelectedShipModeId(): number { const METHOD_NAME: string = 'getSelectedShipModeId()'; let shipModeId: number; if (this.usableShipping && this.usableShipping.usableShippingMode) { for (const shipMode of this.usableShipping.usableShippingMode) { if (this.enableShopify) { if (shipMode.orderType === Constants.SHIP_MODE_SHOPIFY || shipMode.orderType === Constants.SHIP_MODE_BOTH) { if (shipMode.defaultShippingEnabled) { shipModeId = shipMode.shipModeId; } } } else { if (!shipMode.orderType || (shipMode.orderType && shipMode.orderType === Constants.SHIP_MODE_BOTH)) { if (shipMode.defaultShippingEnabled) { shipModeId = shipMode.shipModeId; } } } } } return shipModeId; } /** * This function is used to update the shipping methods * @param {any} usableShipping - Object contains the shipping method * @return {void} */ onShipModesUpdate(usableShipping: any): void { const METHOD_NAME: string = 'onShipModesUpdate()'; console.log('updating usable shipping methods..'); this.usableShipping = CheckoutUtils.updateUsableShipping(usableShipping); } /** * This function is used to update the shipping modes * @return {void} */ updateShipModeId(): void { const METHOD_NAME: string = 'updateShipModeInfo()'; const inputData: any = {shipModeId: this.getSelectedShipModeId()}; // updating the ship mode information if (inputData && inputData.shipModeId) { this.sharedService.showSpinner(true); // spinner this.checkoutService.updateShippingMode(this.storeId, this.cart.orderId, inputData).subscribe(result => { this.karmaTestResult = result; this.sharedService.showSpinner(false); // spinner this.shippingCalculate(); }, error => { this.sharedService.showSpinner(false); // spinner // this.sharedService.showErrorMessage(error, null); // console.error('error=>' + error); }); } else { this.shippingCalculate(); } } /** * This function is used to update the cart details through * updateCartDetails function in cart service * @param {any} inputData - Contains the cart details to update * @return {void} */ updateCartDetails(inputData: any): void { const METHOD_NAME: string = 'updateCartDetails()'; if (inputData.hasOwnProperty(Constants.CUSTOMER)) {inputData.customer = undefined} this.sharedService.showSpinner(true); // spinner this.cartService.updateCartDetails(this.storeId, this.cart.orderId, inputData).subscribe(result => { this.karmaTestResult = result; const cart = Object.assign( {}, this.cart , result); this.cartService.setCart(cart); // weborder Id is not updated in payment info page drop down before it gets loaded. this.sharedService.showSpinner(false); // spinner this.shippingCalculate(); }, error => { this.sharedService.showSpinner(false); // spinner this.sharedService.showErrorMessage(error, null); console.error('error=>' + error); }); } /** * This function is used to update the customer details through * updateCustomerInfo function in checkout service * @param {any} inputData - Contains the customer details to update * @return {void} */ updateCustomerDetails(inputData: any): void { if (!inputData.hasOwnProperty(Constants.CUSTOMER)) { this.updateCartDetails(inputData); } else { const billing: any = { billingAddress: inputData.customer }; if (billing.billingAddress.phone1) { billing.billingAddress.phone1 = Utils.nonFormatPhoneNumber(this.customerInfo.billingAddress.phone1); } this.sharedService.showSpinner(true); // spinner this.checkoutService.updateCustomerInfo(this.storeId, this.cart.orderId, billing).subscribe(result => { this.karmaTestResult = result; this.sharedService.showSpinner(false); // spinner this.updateCartDetails(inputData); }, error => { this.sharedService.showSpinner(false); // spinner this.sharedService.showErrorMessage(error, true); console.error('error=>' + error); }); } } /** * This function is used to verify/validate all the information are * correct before navigating to pay and review * @return {void} */ readyForPayReview(): void { const METHOD_NAME: string = 'readyForPayReview()'; this.sharedService.addLogging(this.COMPONENT_NAME,  METHOD_NAME,  'Navigating to Pay Review: '); // applying the minimum rules before going to pay and review page const cust = CheckoutUtils.isValidCustomerInfo(this.cart, this.customerInfo); if (!this.customerInfo.validDealerCode) { // verifying the dealer code this.sharedService.showErrorMessage('_ERR_DEALER_CODE_NOT_FOUND', false); } else if (!cust.isValid) { if (cust.section === 'Billing') { this.sharedService.showErrorMessage('_ERR_INVALID_BILLING', false); } if (cust.section === 'Shipping') { this.sharedService.showErrorMessage('_ERR_INVALID_SHIPPING_ADDRESS', false); } if (cust.section === 'e911') { this.sharedService.showErrorMessage('_ERR_INVALID_E911_ADDRESS', false); } if (cust.section === 'PPU') { this.sharedService.showErrorMessage('_ERR_INVALID_PPU_ADDRESS', false); } if (cust.section === 'Porting') { this.sharedService.showErrorMessage('_ERR_INVALID_PORTING', false); } } else{ if(this.billingForm.valid){ const inputData: any = CheckoutUtils.createCartUpdateInput(this.cart, this.customerInfo, this.npaNxxList); if (inputData) { this.customerInfo.billingAddress.phone1 = Utils.nonFormatPhoneNumber(this.customerInfo.billingAddress.phone1); if(inputData.packages){ inputData.packages.forEach(function(pkg){ if(pkg.numberPorting && pkg.numberPorting.phoneNumber !== null && pkg.numberPorting.phoneNumber != undefined){ pkg.numberPorting.phoneNumber = Utils.nonFormatPhoneNumber(pkg.numberPorting.phoneNumber); } }); } // update ship mode information inputData.shipModeId = this.getSelectedShipModeId(); if (this.isOnlyAccCart || this.cart.refType === Constants.REF_TYPE_EXCHANGE) { // call cart update for only accessorries order or exchange order this.updateCustomerDetails(inputData); } else { if ( !inputData.packages && !this.isAALOrder ) { // making sure there is service found customer zip code. this.sharedService.showErrorMessage('_ERR_NPA_SERVICE_NOT_FOUND', null); } else if (CheckoutUtils.hasLineLinkPlan(this.cart) && !CheckoutUtils.acceptE911Disclaimer(this.cart, inputData)) { // making sure terms and conditions accepted for line link plan this.sharedService.showErrorMessage('_E911_ADDRESS_DISCLAIMER', null); } else { // make sure t-mobile service for each voice/data line let hasService: boolean = this.isAALOrder? true: CheckoutUtils.hasServiceCoverage(inputData); if (!hasService) { this.sharedService.showErrorMessage('_ERR_NPA_SERVICE_NOT_FOUND', null); } else { this.updateCustomerDetails(inputData); } } } } else { if (this.cart.customer && this.cart.customer.addressId) { if (!this.isBYOSOnlyOrder) { this.updateShipModeId(); } else { this.shippingCalculate(); } } else { this.sharedService.showErrorMessage('_ERR_INVALID_BILLING', false); } } } } } /** * This function used to calculate the shipping charges * @return {void} */ shippingCalculate(): void { this.sharedService.notificationModel = {pahMsisdn: Utils.nonFormatPhoneNumber(this.pahNumber), languagePref: (this.languageModel.isEnglish == 'true') ? 'EN' : 'ES', additionalMsisdn: this.selectedMsisdn , pahNumberSelected:this.isPAHNumberSelected }; const METHOD_NAME: string = 'shippingCalculate()'; if(this.isBYOSOnlyOrder){ this.router.navigate(['checkout/pay-review']); }else{ const inputData: any = {calculationUsageId: '-1,-2,-3,-4,-5,-6,-7'}; if (!this.enableShopify) { inputData.actions = 'SETADDRESSDEFAULT,OOBORDERPREPARE'; } else { inputData.actions = 'SETADDRESSDEFAULT,SHOPIFYORDERUPDATE,OOBORDERPREPARE'; } // calling the tax calculation this.sharedService.showSpinner(true); // spinner this.cartService.calculate(this.storeId, this.cart.orderId, inputData).subscribe(result => { this.karmaTestResult = result; this.sharedService.showSpinner(false); // spinner this.router.navigate(['checkout/pay-review']); }, error => { this.sharedService.showSpinner(false); // spinner this.sharedService.showErrorMessage(error, true); // console.error('error=>' + error); }); } } get canDisableContinue(): boolean { const METHOD_NAME: string = 'canDisableContinue()'; if ((this.billingForm && !this.billingForm.valid) || (this.shippingForm && !this.shippingForm.valid) || !this.customerInfo.validDealerCode) { return true; } return false; } /** * This function is used to find the customer using Account number. * @returns void */ lookupCustomer(): void { const METHOD_NAME: string = "lookupCustomer()"; let cartSummary = this.cartService.getCart(); let accountNumber = (cartSummary.customer.creditProfile.accountNumber) ? cartSummary.customer.creditProfile.accountNumber : (cartSummary.customer && cartSummary.customer.creditProfile && cartSummary.customer.creditProfile.tentativeBAN) ? cartSummary.customer.creditProfile.tentativeBAN : null; // let accountNumber = 110005622 if (accountNumber) { this.sharedService.showSpinner(true); // spinner this.customerService .profileByBAN( this.storeId, String(accountNumber), "OTP_SUMMARY" ) .subscribe( result => { this.sharedService.showSpinner(false); // spinner this.customer = Object.assign({}, result); this.formatdropDown(); }, error => { this.sharedService.showSpinner(false); // spinner this.sharedService.showErrorMessage(error, true); this.PAHserviceFailed = true; console.error("error=>" + error); } ); } } /** * The function formats the check box data. * @returns void */ formatdropDown(): void { const METHOD_NAME = "formatdropDown()"; if (this.customer && this.customer.subscribers) { this.subscribersList = new Array(); console.log("this is subscriber list ->>", this.subscribersList); // setting first primary account holder for (const sub of this.customer.subscribers) { if (sub && sub.isPAH) { this.pahNumber = Utils.formatPhoneNumber(sub.phoneNumber.toString()); this.pahNumberWithFormat = this.pahNumber.toString(); this.pahNumberWithFormat = '('+this.pahNumberWithFormat.substring(0,3)+')'+this.pahNumberWithFormat.substring(3,12); console.log(this.pahNumberWithFormat); } } // setting authorized customers for (const sub of this.customer.subscribers) { if (sub && sub.isAuthorized && !sub.isPAH) { let customerName: string = Utils.formatPhoneNumber(sub.phoneNumber.toString()) + " : "; if (sub.firstName && sub.lastName) { customerName += sub.firstName + " " + sub.lastName; } else if (sub.firstName) { customerName += sub.firstName; } else if (sub.lastName) { customerName += sub.lastName; } this.subscribersList.push({ phoneNumber: sub.phoneNumber, customerName: customerName }); } } } } }