import { ListItemModel } from './list-item.model'; import { BomItemService } from './item.service'; import * as momentImported from 'moment'; import { BomListColumn } from './common-models/list-models'; import { BomColumn, BomColumnType, BomQuantity, ViewBomColumn } from './bom/bom.interfaces'; import { BomColumnId } from './bom/bomColumn.enum'; import { AppInjector } from './locator.service'; const moment = momentImported; export class BomModel { id: string; rows: Array; name: string; parts: number; created: string; updated: string; warnings: boolean = false; totalPrice: number; paging: any; source: string; region: string; activeQuantity: string; // All colIds < 0 customColumns: Array; // Custom Columns map ccMap: Map = new Map(); // Fixed columns map fcMap: Map = new Map(); multiplier: number; exportableColumns: Array; edited: string; hasRows: boolean = false; progress: number = 0; owner: string; permissions: string; isShared: boolean; InStockCount: number; OutOfStockCount: number; StockErrorCount: number; bomColumns: Array; constructor(data?: any) { if (data && data.payload) { const payload = data.payload; this.id = payload._id; this.name = payload.bomName; this.rows = payload.bom.rows.map((row: any) => { return new ListItemModel({ data: null, rowId: row.rowId }); }); this.bomColumns = this.getBomViewTableColumns(payload.viewColumns); this.setRowPositions(); this.created = moment(payload.cdate).format('D MMM YYYY'); this.updated = moment(payload.lastModified).format('D MMM YYYY'); this.edited = moment(payload.lastEdited).format('D MMM YYYY'); this.paging = payload.bom.paging; this.source = payload.bomSource; this.warnings = this.anyWarnings(payload.bom.rows); this.region = payload.region; this.customColumns = this.getCustomColumns(); this.setFixedColumns(payload.columnInfo.inputOrder); this.multiplier = Number(payload.bom.multiplier) || 1; this.exportableColumns = payload.columnInfo.outputOrder; this.hasRows = !this.rows.length; if (payload.ownerEmail) { this.owner = payload.ownerEmail; } else { this.owner = payload.ownerinfo.email; } if (payload.bomQuantities) { this.activeQuantity = payload.bomQuantities .filter(col => col.isActive) .map(qty => { return qty.name; }); //TODO: change above condition to this one, to stop using payload.bomQuantities // if(this.bomColumns){ // const multipleQtyColumns: BomQuantity[] = this.bomColumns // .filter(col => col.type == BomColumnType.QUANTITY) as BomQuantity[]; // this.activeQuantity = multipleQtyColumns.filter(col => col.isActive) // .map(qty => { // return qty.name; // }); // this.addBomQuantitiesColumns(payload.bomQuantities); } } } setId(id: string) { this.id = id; } clearRows() { this.rows.forEach(row => (row.isLoading = true)); } anyWarnings(rows: Array) { let warnings: boolean = false; rows.map((item: any) => { if (item.row && item.row.partInfo && !item.row.partInfo.fullPart) { warnings = true; } }); return warnings; } setRowPositions(): void { for (let i = 0; i < this.rows.length; i++) { this.rows[i].positionOnPage = i; } } getCustomColumns(): Array { const customColumns = this.bomColumns.filter( item => item.type == BomColumnType.CUSTOM ); customColumns.map(col => this.ccMap.set(+col.id, col)); return customColumns; } setFixedColumns(mappedColumns: Array): void { const fixedColumns = mappedColumns.filter(item => { return BomListColumn.getFixedColumnIds().find(id => id === item.colId); }); fixedColumns.map(col => this.fcMap.set(col.colId, col)); } private addRowQuantityInfo(rowData: any): void { if (rowData.rowQuantities) { const quantityData = this.bomColumns.filter( x => x.type == BomColumnType.QUANTITY ) as BomQuantity[]; if (quantityData) { rowData.rowQuantities.forEach(row => { const value = quantityData.find(x => x.key === row.id); if(value){ row.isActive = value.isActive; } }); } } } /** * Find index of the item with the rowId in the bom.rows array, update that item with newRowData * @param rowId - item's row id * @param newRowData - row data object as we get it from BE response */ updateRow(rowId: string, newRowData: any): number { if (!this.rows) return; const itemIndex = this.rows.findIndex( (bomItem: ListItemModel) => bomItem.rowId === rowId ); if (itemIndex >= 0) { this.addRowQuantityInfo(newRowData); const newItem = new ListItemModel({ data: newRowData, rowId }); this.rows[itemIndex] = newItem; newItem.positionOnPage = itemIndex; this.rows[itemIndex].customColumns.map(customColumn => { const match = this.ccMap.get(customColumn.mapId); if (match) { customColumn.name = match.name; } return customColumn; }); return null; // don't redirect } else { // new row const bomItemService = AppInjector.get(BomItemService); bomItemService.newItemAdded(); return this.appendNewRow(newRowData); // null or page number } } /** * * @param rowId - item's row id * @param newRowInfo - row "info" data only */ updateRowInfo(rowId: string, newRowInfo: any): void { if (!this.rows) return; const itemIndex = this.rows.findIndex( (bomItem: ListItemModel) => bomItem.rowId === rowId ); if (itemIndex >= 0) { const bomItemService = AppInjector.get(BomItemService); this.rows[itemIndex].updateRowInfo(newRowInfo.partInfo, newRowInfo.input); bomItemService.toggleAlternates(rowId, true); } } /** * * @param rowId - item's row id * @param newRowPricing - row "pricing" data only */ updateRowPricing(rowId: string, newRowPricing: any): void { if (!this.rows) return; const itemIndex = this.rows.findIndex( (bomItem: ListItemModel) => bomItem.rowId === rowId ); if (itemIndex >= 0) { this.rows[itemIndex].updateRowPricing( newRowPricing.stockInfoGroups, newRowPricing.priceSources, newRowPricing.rowQuantities, newRowPricing.isUploadedPart ); } } /** * * @param rowId - item's row id * @param alts - row "alternates/crosses" data only */ updateRowAlts(rowId: string, alts: any): void { if (!this.rows) return; const itemIndex = this.rows.findIndex( (bomItem: ListItemModel) => bomItem.rowId === rowId ); if (itemIndex >= 0) { this.rows[itemIndex].updateAlternates(alts); } } /** * Find row in the bom.rows array and overwrite/add its properties from rowData * @param rowId - item's row id * @param rowData - row data to be overwritten/added to the original row object */ amendRow(rowId: string, rowData: Object) { if (!this.rows) return; const itemIndex = this.rows.findIndex( (bomItem: ListItemModel) => bomItem.rowId === rowId ); if (itemIndex >= 0) { Object.assign(this.rows[itemIndex], rowData); } } appendNewRow(newRowData: any): number { const updatedNumberOfPages = this.paging.itemsPerPage ? Math.ceil((this.parts + 1) / this.paging.itemsPerPage) : 1; if (this.paging.currentPage === updatedNumberOfPages) { this.rows.push( new ListItemModel({ data: newRowData, rowId: newRowData._id }) ); const rowIndex = this.rows.findIndex(r => r.rowId === newRowData._id); this.rows[rowIndex].positionOnPage = rowIndex; this.parts++; return null; // don't redirect } else { return updatedNumberOfPages; // page number to redirect } } private getBomViewTableColumns( viewColumnData: Array ): Array { let bomViewColumns: Array = []; if (viewColumnData) { viewColumnData.forEach(column => { let columnInfo: BomListColumn = this.getBaseBomColumn(column); if (columnInfo.type == BomColumnType.QUANTITY) { columnInfo = this.getBomQuantityData(column); } bomViewColumns.push(columnInfo); }); bomViewColumns.sort(x => x.position); } else { bomViewColumns = [ ...BomListColumn.getRightColumnHeaders(), ...BomListColumn.getLeftStickyColumnHeaders() ]; } return bomViewColumns; } private getBaseBomColumn(viewColumnData: ViewBomColumn): BomListColumn{ const multipleQtyColIds = [BomColumnId.QUANTITY_1, BomColumnId.QUANTITY_2, BomColumnId.QUANTITY_3]; const hardKey = BomListColumn.keyByColId.get(viewColumnData.colId); const key = hardKey ? hardKey : viewColumnData.colId.toString(); let columnInfo: BomListColumn = { id: viewColumnData.colId.toString(), name: viewColumnData.name, nameId: viewColumnData.nameId, position: viewColumnData.defaultOrder, key: key, type: viewColumnData.isCustom ? BomColumnType.CUSTOM : BomColumnType.SCROLLABLE }; if ( viewColumnData.colId === BomColumnId.PART_NUMBER || viewColumnData.colId === BomColumnId.USER_UPLOADED_DATA ) { columnInfo.type = BomColumnType.STICKY; } if (multipleQtyColIds.indexOf(viewColumnData.colId) !== -1) { columnInfo.type = BomColumnType.QUANTITY; } return columnInfo; } private getBomQuantityData(viewColumnData: ViewBomColumn): BomQuantity { return { type: BomColumnType.QUANTITY, key: viewColumnData.quantityId, name: viewColumnData.name, nameId: viewColumnData.nameId, isActive: viewColumnData.isActive, isDefault: viewColumnData.isDefault, openOptions: false, position: viewColumnData.defaultOrder }; } }