import { Component, Input, Output, EventEmitter, OnInit, OnChanges, OnDestroy, ViewChild } from '@angular/core'; import * as Constants from '../../../../shared/constants'; import Utils from '../../../../shared/utils'; import CartUtils from '../../../../shared/cart.utils'; import { ADJUST_PRICE_REASONS, INVENTORY_STATUS, TRADE_IN_ACCOUNTS } from '../../../../shared/form.constants'; import { IPackage, IDevice, IDeviceItem, IOrderItemDevice } from '../../../../shared/modal/common'; import { User } from '../../../../shared/modal/user'; import { IKeyValue } from '../../../../shared/modal/key.value'; import { Cart } from '../../../../shared/modal/cart'; import { Customer, ICreditProfile } from '../../../../shared/modal/customer'; import { SharedService } from '../../../../shared/shared.service'; import { UserService } from '../../../../services/user.service'; import { CartService } from '../../../../services/cart.service'; import { TradeinService } from '../../../../services/tradein.service'; @Component({ selector: 'device-cmp', moduleId: module.id, templateUrl: 'device.component.html' }) export class DeviceComponent implements OnInit, OnChanges, OnDestroy { private COMPONENT_NAME: string = 'DeviceComponent'; storeId: number; // update storeid rtStoreId: number = Constants.STORE_ID_RT; loanCrp: number = Constants.LOAN_CRP_DEFAULT; leaseCrp: number = Constants.LEASE_CRP_DEFAULT; financeTypeFull: string = Constants.FINANCE_TYPE_FRP; financeTypeLoan: string = Constants.FINANCE_TYPE_LOAN; financeTypeLease: string = Constants.FINANCE_TYPE_LEASE; tradeinOfferDisplay: string = Constants.TRADE_IN_OFFER_DISPLAY; refTypeExchange: string = Constants.REF_TYPE_EXCHANGE; imageBaseUrl: string = Constants.IMAGE_BASE_URL; primaryLine: string = ''; digitsMappingList: any = {}; KarmaTestResult: any = {}; orderItem: IOrderItemDevice; device: IDevice; deviceItem: IDeviceItem; isFinanceOrder: boolean = false; isNCFPlanInCart: boolean = false; financeType: string; options: any = []; tradeinInfo: any = {}; declineTradein: string = ''; isExchangeOrder: boolean = false; isAALOrder: boolean = false; canFinance: boolean = true; dormantFlag: any; user: User; @Input() cart: Cart; @Input() package: IPackage; @Output() onItemChange = new EventEmitter(false); @ViewChild('tradeinModal') tradeinModal: any; @ViewChild('removeTradeInModel') removeTradeInModel: any; constructor( public tradeinService: TradeinService, public sharedService: SharedService, public userService: UserService, public cartService: CartService) { } /** * 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. * @returns void */ ngOnInit(): void { const METHOD_NAME: string = 'ngOnInit()'; // tradein flow init this.tradeinInfo.allTradeInfoList = []; this.tradeinInfo.isTradein = this.package.device.isTradein ? true : false; this.tradeinInfo.allTradeInfoList = this.tradeinService.getTradeInInfo(); if (this.tradeinInfo && this.tradeinInfo.isTradein) { // checking for tradeinfo list whether we have it or not on reload of the page we are lossing the data // so we are making an API cal for get ALLtradein if (this.tradeinInfo.allTradeInfoList.length === 0) { this.getAllTradeInfoList(); } else { this.setTradeinInfoForPackage(Utils.getTradeInInfoOrder(this.orderItem.orderItemId, this.tradeinInfo.allTradeInfoList)); } } } /** * This function is called whenever one or more data-bound input properties change * @returns void */ ngOnChanges(): void { const METHOD_NAME: string = 'ngOnChanges()'; this.sharedService.storeId.subscribe((val: number) => { this.storeId = val; }); this.dormantFlag = this.sharedService.getDormantProperties(); // getting user info this.user = this.userService.getUser(); if (this.cart) { // checking cart is available if (this.cart.customer && this.cart.customer.creditProfile) { const creditProfile: ICreditProfile = this.cart.customer.creditProfile; this.loanCrp = creditProfile.loanCrp ? creditProfile.loanCrp : Constants.LOAN_CRP_DEFAULT; this.leaseCrp = creditProfile.leaseCrp ? creditProfile.leaseCrp : Constants.LEASE_CRP_DEFAULT; this.isExchangeOrder = this.cart.refType === Constants.REF_TYPE_EXCHANGE ? true : false; if (!this.isExchangeOrder && this.cart.customer.creditProfile.accountNumber) { this.isAALOrder = this.cart.customer.creditProfile.accountNumber ? true : false; this.canFinance = (!this.cart.customer.creditProfile.isExtendedPaySchedule && !creditProfile.hideFinance) ? true : false; } } } if (this.package && this.package.device) { // make sure device is available this.orderItem = this.package.device; this.financeType = this.orderItem.financeType; this.isNCFPlanInCart = CartUtils.isNCFPlanInCart(this.cart); this.isFinanceOrder = CartUtils.isFinanceOrder(this.cart); this.device = Utils.getDeviceParent(this.orderItem.deviceSKU); // // tradein flow init // this.tradeinInfo.allTradeInfoList = []; // this.tradeinInfo.isTradein = this.package.device.isTradein ? true : false; // this.tradeinInfo.allTradeInfoList = this.tradeinService.getTradeInInfo(); // if (this.tradeinInfo && this.tradeinInfo.isTradein) { // // checking for tradeinfo list whether we have it or not on reload of the page we are lossing the data // // so we are making an API cal for get ALLtradein // if (this.tradeinInfo.allTradeInfoList.length === 0) { // this.getAllTradeInfoList(); // } else { // this.setTradeinInfoForPackage(Utils.getTradeInInfoOrder(this.orderItem.orderItemId, this.tradeinInfo.allTradeInfoList)); // } // } if (this.device) { // make sure device is available in master list const items: any = this.device.items.filter((item) => { return item.deviceSKU === this.orderItem.deviceSKU; }); if (items && items.length > 0) { this.options = new Array(); this.deviceItem = items[0]; this.options.push({ key: Constants.FINANCE_TYPE_FRP, value: Constants.FULL_PRICE }); if (!this.isFinanceOrder) { if (this.deviceItem.loan != null && this.deviceItem.loan.length > 0) { this.options.push({ key: Constants.FINANCE_TYPE_LOAN, value: Constants.PRICING_OPTION }); } if (this.deviceItem.lease != null && this.deviceItem.lease.length > 0) { this.options.push({ key: Constants.FINANCE_TYPE_LEASE, value: Constants.JUMP_ON_DEMAND }); } } else { if (CartUtils.isEIPOnlyOrder(this.cart)) { if (this.deviceItem.loan != null && this.deviceItem.loan.length > 0) { this.options.push({ key: Constants.FINANCE_TYPE_LOAN, value: Constants.PRICING_OPTION }); } } else if (CartUtils.isJUMPOnlyOrder(this.cart)) { if (this.deviceItem.lease != null && this.deviceItem.lease.length > 0) { this.options.push({ key: Constants.FINANCE_TYPE_LEASE, value: Constants.JUMP_ON_DEMAND }); } } } } } } // digita mapping this.primaryLine = this.package.primaryLine ? this.package.primaryLine.toString() : ''; if (this.cart && this.cart.packages) { this.digitsMappingList = new Array(); let i = 0; // to get the index of voice line for (const packagee of this.cart.packages) { if (packagee.packageType === Constants.PACKAGE_TYPE_VOICE) { if (packagee.device) { this.digitsMappingList.push({ line: packagee.device.orderItemId.toString(), lineName: Constants.PRIMARY_VOICE_LINE + (++i), lineType: Constants.ORDER_ITEM_ID, isDisabled: false }); } } } } if (this.cart && this.cart.customer && this.cart && this.cart.customer.subscribers) { for (const subscriber of this.cart.customer.subscribers) { if (subscriber.isGSM) { if (subscriber.duplicateLineMappingCount || !subscriber.duplicateLineMappingCount) { this.digitsMappingList.push({ line: subscriber.phoneNumber.toString(), lineName: subscriber.phoneNumber.toString(), lineType: Constants.MSISDN, isDisabled: (subscriber.duplicateLineMappingCount < Constants.MAX_DUPLICATE_MAPPING) ? false : true }); } } } } } /** * Cleanup just before Angular destroys the directive/component. * Unsubscribe Observables and detach event handlers to avoid memory leaks. * @returns void */ ngOnDestroy(): void { const METHOD_NAME: string = 'ngOnDestroy()'; this.orderItem = null; this.device = null; this.deviceItem = null; this.digitsMappingList = null; this.KarmaTestResult = null; this.tradeinInfo = null; this.options = null; this.user = null; this.cart = null; this.package = null; } /** * This function is used to check if trad-in option is available for a device. * @returns boolean */ checkForTradeinDetailsExits(): boolean { let tradeInExists = false; if (this.tradeinInfo.allTradeInfoList[this.orderItem.orderItemId]) { (this.tradeinInfo.responses) ? '' : this.tradeinInfo.responses = {}; this.tradeinInfo.responses.getItemTradeinInfo = this.tradeinInfo.allTradeInfoList[this.orderItem.orderItemId]; // this.package.device.tradeInInfo = this.tradeinInfo.allTradeInfoList[this.orderItem.orderItemId]; tradeInExists = true; } return tradeInExists; } /** * This function is used to switch finance type by calling switchDeviceFinanceInput function. * @returns void */ switchDeviceFinance(): void { const METHOD_NAME: string = 'switchDeviceFinance()'; console.log('switchDeviceFinance:' + this.financeType); if (this.orderItem.financeType !== this.financeType) { this.sharedService.addLogging(this.COMPONENT_NAME, METHOD_NAME, 'Switching device finance in shopping cart'); const packageType: string = this.package.packageType; const crp: number = this.financeType && this.financeType === Constants.FINANCE_TYPE_LOAN ? this.loanCrp : this.leaseCrp; const inputData: any = CartUtils.switchDeviceFinanceInput(packageType, this.deviceItem, this.financeType, crp); // setting original order item# inputData.orderItemId = this.orderItem.orderItemId; this.sharedService.showSpinner(true); // spinner this.cartService.updateDevice(this.storeId, this.cart.orderId, this.package.packageId, this.package.lineId, this.orderItem.orderItemId, inputData ).subscribe(result => { this.sharedService.showSpinner(false); // spinner console.log('Successfully updated the device.'); // deleting the tradein when chnaging the finance type. // needs to be revisit // if(this.package && this.package.device && this.package.device.isTradein){ (this.orderItem.isTradein) ? this.deleteTradeIn() : ''; this.getCartSummary(); // } }, error => { this.financeType = this.orderItem.financeType; this.sharedService.showSpinner(false); // spinner this.sharedService.showErrorMessage(error, true); console.error('error=>' + error); }); } } /** * This function is used to switch device color by making updateDevice api call. * @param {string} deviceSKU - SKU of a device whose color has to be changed * @returns void */ switchDeviceColor(deviceSKU: string): void { const METHOD_NAME: string = 'switchDeviceColor()'; console.log('switchDeviceColor:' + deviceSKU); if (this.orderItem.deviceSKU !== deviceSKU) { this.sharedService.addLogging(this.COMPONENT_NAME, METHOD_NAME, 'Switching device color'); const items: any = this.device.items.filter((item) => { return item.deviceSKU === deviceSKU; }); if (items && items.length > 0) { const deviceItem: IDeviceItem = items[0]; if (deviceItem.status !== Constants.DEVICE_ITEM_STATUS) { const packageType: string = this.package.packageType; const crp: number = this.financeType && this.financeType === Constants.FINANCE_TYPE_LOAN ? this.loanCrp : this.leaseCrp; const inputData: any = CartUtils.switchDeviceFinanceInput(packageType, deviceItem, this.financeType, crp); // setting original order item# inputData.orderItemId = this.orderItem.orderItemId; this.sharedService.showSpinner(true); // spinner this.cartService.updateDevice(this.storeId, this.cart.orderId, this.package.packageId, this.package.lineId, this.orderItem.orderItemId, inputData ).subscribe(result => { this.sharedService.showSpinner(false); // spinner console.log('Successfully updated the device.'); // deleting the tradein when chnaging the finance type. // needs to be revisit // if(this.package && this.package.device && this.package.device.isTradein){ (this.orderItem.isTradein) ? this.deleteTradeIn() : ''; this.getCartSummary(); }, error => { this.sharedService.showSpinner(false); // spinner console.error('error=>' + error); this.sharedService.showErrorMessage(error, true); }); } else { this.sharedService.showErrorMessage('_ERR_OUT_OF_STOCK', false); } } } console.log('evt>>>>' + this.financeType); } updateDigitsMapping(): void { const METHOD_NAME: string = 'updateDigitsMapping()'; if (this.primaryLine) { let mappingLine: any = null; for (const item of this.digitsMappingList) { if (item.line === this.primaryLine) { mappingLine = item; break; } } if (mappingLine) { const inputData: any = { digitsMapping: [{ duplicateOrderItemId: this.orderItem.orderItemId, primaryLine: mappingLine.line, type: mappingLine.lineType }] }; this.sharedService.addLogging(this.COMPONENT_NAME, METHOD_NAME, 'Updating digits mapping'); this.sharedService.showSpinner(true); // spinner this.cartService.saveDigitsMapping(this.storeId, this.cart.orderId, inputData).subscribe(result => { this.KarmaTestResult = result; this.sharedService.showSpinner(false); // spinner this.primaryLine = mappingLine.line; this.getCartSummary(); console.log('Successfully updated the device.'); }, error => { this.primaryLine = ''; this.sharedService.showSpinner(false); // spinner console.error('error=>' + error); this.sharedService.showErrorMessage(error, true); }); } } else { this.sharedService.showErrorMessage('_ERR_PRIMARY_LINE', false); } } /** * This function is used to get the inventory status * @param {string} status - variable contains the item status * @return {string} */ getInventoryStatus(status: string): string { const METHOD_NAME: string = 'getInventoryStatus()'; const statusItems: IKeyValue[] = INVENTORY_STATUS.filter((item) => { return item.key === status; }); if (statusItems && statusItems.length > 0) { return statusItems[0].value; } return Constants.OUT_OF_STOCK; } /** * This function is used to show trade-in details through a popup * @returns void */ tradeinDevice(): void { const METHOD_NAME: string = 'tradeinDevice()'; console.log('showing tradein model.'); this.tradeinModal.show(); } /** * This function is used to edit trade-in details. * @returns void */ editTradeIn(): void { const METHOD_NAME: string = 'editTradeIn()'; this.sharedService.addLogging(this.COMPONENT_NAME, METHOD_NAME, 'Edit tradein'); if (this.tradeinInfo && this.tradeinInfo.responses) { this.tradeinModal.show(); } } /** * This function is used to delete trade-in option availed. * @returns void */ deleteTradeIn(): void { const METHOD_NAME: string = 'deleteTradeIn()'; this.sharedService.addLogging(this.COMPONENT_NAME, METHOD_NAME, 'Delete tradein'); this.sharedService.showSpinner(true); this.rmaCancel(); this.tradeinService.deleteTradeIn(this.storeId, this.cart.orderId, this.orderItem.orderItemId).subscribe(result => { this.tradeinService.saveTradeInInfo(this.orderItem.orderItemId, null); this.sharedService.showSpinner(false); this.tradeinInfo = {}; this.updateDeletePromo(); this.sharedService.updateErrorMessage(null); }, error => { this.sharedService.showSpinner(false); // spinner this.sharedService.showErrorMessage(error, true); }); } rmaCancel(): void { const METHOD_NAME: string = 'rmaCancel()'; if (this.tradeinInfo && this.tradeinInfo.responses && this.tradeinInfo.responses.getItemTradeinInfo) { let inputData: any = {}; const input = { lineId: this.package.lineId, lineOrderId: this.orderItem.orderItemId, orderId: this.package.packageId, phoneNumber: (this.cart.customer && this.cart.customer.phone1) ? this.cart.customer.phone1 : Constants.DEFAULT_PHONE_NUMBER, programType: Constants.PROGRAM_TYPE_DRP, quotationId: this.tradeinInfo.responses.getItemTradeinInfo.quoteId, tradeInIntent: (this.tradeinInfo.responses.getItemTradeinInfo.promotionId) ? '' : Constants.TRADEIN_INTENT, status: { statusCode: Constants.TRADEIN_STATUS_CODE, reasonCode: Constants.BUY_BACK_OFFER } }; inputData = { 'tradeInQuotes': [input] }; this.tradeinService.rmaCancel(this.storeId, this.cart.orderId, this.orderItem.orderItemId, inputData).subscribe(result => { }, error => { this.sharedService.showSpinner(false); // spinner this.sharedService.showErrorMessage(error, true); }); } } /** * This function is used to get cart details * @param {number} orderId - orderId * @returns void */ getCartSummary(): void { this.sharedService.showSpinner(true); // spinner this.cartService.getCartSummary(this.storeId, this.cart.orderId).subscribe(result => { this.sharedService.showSpinner(false); // spinner this.cart = CartUtils.replaceRequired(this.cart, result); // this.errorMessage = this.sharedService.showErrorDownPaymentAdjusted(this.cart.isDownPaymentAdjusted); this.cartService.setCart(this.cart); if (CartUtils.isFinanceOrder(this.cart)) { this.onItemChange.emit(true); } }, error => { this.sharedService.showSpinner(false); // spinner this.sharedService.showErrorMessage(error, true); }); } onSelectedPromo(selectedPromo: any) { const METHOD_NAME: string = 'onSelectedPromo()'; this.tradeinInfo = selectedPromo; this.tradeinInfo.isTradein = true; this.getTradeinInfo(); } getTradeinInfo(): void { const METHOD_NAME: string = 'getTradeinInfo()'; this.sharedService.addLogging(this.COMPONENT_NAME, METHOD_NAME, 'Getting tradein information'); this.sharedService.showSpinner(true); this.tradeinService.getItemTradeinInfo(this.storeId, this.cart.orderId, this.orderItem.orderItemId).subscribe(result => { this.KarmaTestResult = result; this.sharedService.showSpinner(false); this.setTradeinInfoForPackage(result); this.tradeinService.saveTradeInInfo(this.orderItem.orderItemId, [result]); }, error => { this.sharedService.showSpinner(false); // spinner this.sharedService.showErrorMessage(error, true); }); } getAllTradeInfoList(): any { this.tradeinInfo.allTradeInfoList = {}; this.tradeinService.getAllTradeinInfo(this.storeId, this.cart.orderId).subscribe(result => { this.KarmaTestResult = result; this.tradeinService.saveTradeInInfo(null, result.tradeInInfo); this.tradeinInfo.allTradeInfoList = this.tradeinService.getTradeInInfo(); this.setTradeinInfoForPackage(Utils.getTradeInInfoOrder(this.orderItem.orderItemId, result.tradeInInfo)); }, error => { console.error('error=>' + error); }); } setTradeinInfoForPackage(result: any): void { if (result) { if (this.tradeinInfo.responses) { this.tradeinInfo.responses.getItemTradeinInfo = result; } else { this.tradeinInfo.responses = {}; this.tradeinInfo.responses.getItemTradeinInfo = result; } if (!this.tradeinInfo.responses.checkEligibility) { // no need to call these api for edit flow as we get only existed promos. // this.basicPromo(); // this.searchQuotation(); } } else { this.tradeinInfo.isTradein = false; } } updateDeletePromo(): any { let lists = this.sharedService.getAllPromoAndQuoteLists(); if (lists.length > 0) { this.sharedService.updateTradeInList(lists.filter(ls => ls.itemId !== this.orderItem.itemId) ); } } }