import { Component, Directive, OnInit, Inject, Input, ViewEncapsulation, HostListener } from '@angular/core'; import { WPT_DIALOG_DATA, WptDialogRef, WptDialog } from '@arrow/warpaint/dialog'; import { AnalyticsEvent, AnalyticsService, SocketsService, UserService2 } from '@arrow/bom/core'; import { CPN, EndCustomer, Row } from '../../ORM/types/custom/row.interface'; import { LoggerService } from '@arrow/bom/logger'; import { throwError } from 'rxjs'; import { catchError, take } from 'rxjs/operators'; interface SelectedCpnData{ cpn:CPN; endCustomer?: EndCustomer; } @Directive({ selector: '[bomCpnEdit], [bom-cpn-edit]' }) export class BomCpnEditDirective { @Input() row: Row; @Input() customerType: string; @Input() ECList: any[]; private isCpnDataValid(cpnData: SelectedCpnData): boolean{ return (cpnData != null && cpnData.cpn != null && cpnData.cpn.endCustomers.length > 0); } private getEndCustomer(cpnData: SelectedCpnData): EndCustomer{ if(!this.isCpnDataValid(cpnData)) return {id: -1, name: ''}; const ownEc = cpnData.endCustomer != null ? cpnData.cpn.endCustomers.findIndex(x => x.name === cpnData.endCustomer.name) !== -1 : false; return cpnData.endCustomer && ownEc ? cpnData.endCustomer : {id: -1, name: ''}; } @HostListener('editCpn') onEditCpn = () => { this.wptDialog .open(CreateCpnComponent, { // Ensure modal window content is scrollable on smaller screen resolutions (i.e. 320px) panelClass: 'bom-create-cpn-cdk-overlay-pane', // See _normalize.scss data: { row: this.row, ECList: this.ECList, customerType: this.customerType } }) .afterClosed() .pipe(take(1)) .subscribe(result => { if (!result) return; const cpnData: SelectedCpnData = result; this.row.item.isLoading = true; //Temporary patch this.row.errorCode = 0; const endCustomerData = this.getEndCustomer(cpnData); this.sockets.emitAction('setCPN', { bomId: this.row.bomId, rowId: this.row.id, cpn: cpnData.cpn ? cpnData.cpn.cpn : '', custId: endCustomerData.id, custName: endCustomerData.name }); }); }; constructor(private wptDialog: WptDialog, private sockets: SocketsService) {} } @Component({ templateUrl: 'create-cpn.component.html', styleUrls: [ '../../../../core/src/style/modal.scss', './create-cpn.component.scss' ], encapsulation: ViewEncapsulation.None }) export class CreateCpnComponent implements OnInit { isShowModal: boolean = true; isCreateButtonClicked: boolean = false; isSubmitButtonClicked: boolean = false; isInvalidCPN: boolean = false; selectedCPN: string; selectedEC: string; selectedInfo: SelectedCpnData; newCpn: string; appliedCPN: string; appliedEC: string; customerType: any; selectedOptions: any[] = []; stringTyped: string; endCustomerList: any[] = []; maxedECSelected: boolean = false; createLoading: boolean = false; public approvedCPNs: CPN[] = []; constructor( @Inject(WPT_DIALOG_DATA) public data: any, private _analyticsService: AnalyticsService, private _log: LoggerService, public userService: UserService2, public dialogRef: WptDialogRef ) {} ngOnInit() { this.approvedCPNs = this.data.row.cpnToEcRel.approvedCPNs; this.customerType = this.data.customerType; this.endCustomerList = this.data.ECList.map(this.addSelectedProperty); if (this.data.row.pricing) { this.selectedInfo = this._getCpnAndEcData(this.data.row.pricing.appliedCPN, this.data.row.pricing.appliedEC); this.selectedCPN = this.selectedInfo.cpn.cpn; this.selectedEC = this.selectedInfo.endCustomer ? this.selectedInfo.endCustomer.name : ''; } else { this.selectedCPN = ''; this.selectedEC = ''; } this._sortByRank(this.approvedCPNs); } private _getCpnAndEcData(appliedCPN:string, appliedEC: EndCustomer): SelectedCpnData { return { cpn:{ approved: true, cpn: appliedCPN ? appliedCPN : '', endCustomers: appliedCPN ? this.approvedCPNs.filter(x => x.cpn === appliedCPN)[0].endCustomers : {} }, endCustomer: appliedEC ? appliedEC : null } // let selectedCpnInfo: SelectedCpnData = {}; // if(appliedCPN){ // selectedCpnInfo.cpn.cpn = appliedCPN; // } // if(appliedEC){ // selectedCpnInfo.endCustomer = appliedEC; // } // return selectedCpnInfo; } private _handleError(error: any): any { this._log.warn(error); return throwError(error.error || 'Server error'); } private _sortByRank(array) { array.sort((a, b) => (a.rank > b.rank ? 1 : -1)); } cancel(): void { this.dialogRef.close(); } updateSelectedCPN(value, selectedInfo:SelectedCpnData) { selectedInfo.cpn = value; this._analyticsService.googleTrackEvent(AnalyticsEvent.CLICK, { category: 'BOM', action: 'Change CPN', label: value.cpn }); } updateSelectedEC(value, selectedInfo:SelectedCpnData) { selectedInfo.endCustomer = value; this._analyticsService.googleTrackEvent(AnalyticsEvent.CLICK, { category: 'BOM', action: 'Change EC', label: value.name }); } clearSelectedCPN(selectedInfo:SelectedCpnData) { selectedInfo.cpn = null; selectedInfo.endCustomer = null; this._analyticsService.googleTrackEvent(AnalyticsEvent.CLICK, { category: 'BOM', action: 'Change CPN', label: '' }); } checkDuplicateCPN(array, newCPN): void { array.forEach(value => { if (value.cpn.toLowerCase() === newCPN.toLowerCase()) { this.isInvalidCPN = true; } }); } checkValidCPN(value, approvedCPNs: CPN[]) { const asciiRegex = /^[\000-\177]*$/; this.isInvalidCPN = false; this.checkDuplicateCPN(approvedCPNs, value); if (!asciiRegex.test(value) || value.length > 50) this.isInvalidCPN = true; } onCreateClick( data: any, selectedOptions: any[], endCustomerList: any[], approvedCPNs: CPN[] ) { const bomId = data.row.bomId, partId = data.row.part.id, cpn = this.newCpn, ecs = []; this.createLoading = true; for (let i = 0; i < selectedOptions.length; i++) { const selectedEndCustomer = endCustomerList.find( endCustomer => endCustomer.name === selectedOptions[i] ); const cleanEndCustomer = { type: selectedEndCustomer.type, id: selectedEndCustomer.id, name: selectedEndCustomer.name }; ecs.push(cleanEndCustomer); } this.userService .createCPN(bomId, partId, cpn, ecs) .pipe(catchError((error: any) => this._handleError(error))) .subscribe((response: any) => { if (response.success) { approvedCPNs.push(response.userCpn); this._sortByRank(approvedCPNs); this._analyticsService.googleTrackEvent(AnalyticsEvent.CLICK, { category: 'BOM', action: 'Create CPN', label: 1, value: 1 }); this.newCpn = ''; } else { this._handleError(response.message); } this.createLoading = false; }); } inputSearch(stringTyped: string) { this.stringTyped = stringTyped; } updateEndCustomerState(selectedEndCustomer, selectedOptions: any[]) { if ( selectedOptions.indexOf(selectedEndCustomer.name) !== -1 || selectedEndCustomer.selected ) { selectedEndCustomer.selected = !selectedEndCustomer.selected; } } clickDeselectItems(selectedOptions: any[], endCustomerList: any[]) { for (let i = 0; i < selectedOptions.length; i++) { const selectedEndCustomer = endCustomerList.find( endCustomer => endCustomer.name === selectedOptions[i] ); this.updateEndCustomerState(selectedEndCustomer, selectedOptions); } selectedOptions = []; } addSelectedProperty(value) { return { ...value, selected: false }; } }