import {Component, OnInit, ViewChild} from '@angular/core'; import {AstuteClientService} from '../services/astute-client-service'; import {formatCurrency} from '@angular/common'; @Component({ selector: 'app-sales-order', templateUrl: './sales-order.component.html', styleUrls: ['./sales-order.component.css'] }) export class SalesOrderComponent implements OnInit { // both of the grid api's gridApi; gridColumnApi; detailGridApi; detailColumnApi; // one time fetch meta-data customers; serviceTypes; serviceNames = []; rateTypes = []; rateNames = []; // data for SO grid rowData: any; columnDefs = [ {headerName: 'Project Number', field: 'astuteProjectNumber', editable: true}, {headerName: 'SO Number', field: 'ponum'}, // {headerName: 'Customer ID', field: 'customerId'}, {headerName: 'Customer Name', field: 'customerName'}, {headerName: 'Contract Number', field: 'contractNum', editable: true}, {headerName: 'SO Title', field: 'title', editable: true}, {headerName: 'Contract Amount', field: 'contractAmtString'}, // {headerName: 'Contract Amount', field: 'contractAmt'}, {headerName: 'SO Date', field: 'podate', editable: true}, {headerName: '# of Invoice', field: 'invoiceSequence'}, {headerName: 'notes', field: 'notes', editable: true, cellEditor: 'agLargeTextCellEditor'} // {headerName: 'oneInvInDraft', field: 'oneInvInDraft'} ]; selected = null; // the selected SO row // data for SO detail grid selectedPODetail; detailColumnDefs = [ {headerName: '#', field: 'lineItemNo'}, {headerName: 'Description', field: 'serviceDesc', editable: true}, {headerName: 'Rate Type', field: 'rateTypeName', editable: true, cellEditor: 'agSelectCellEditor', cellEditorParams: {values: this.rateNames}}, {headerName: 'Service Type', field: 'serviceTypeName', editable: true, cellEditor: 'agSelectCellEditor', cellEditorParams: {values: this.serviceNames}}, {headerName: 'Qty or Hours', field: 'qty', editable: true}, {headerName: 'Rate ($)', field: 'fee', editable: true} ]; contractAmount = 0; // used to show total amount constructor(private astuteClientService: AstuteClientService) { } ngOnInit() { this.astuteClientService.getServiceTypes().then((d) => { if (d) { this.serviceTypes = d; this.serviceTypes.forEach((type) => { this.serviceNames.push(type.serviceTypeDesc); }); // console.log(this.serviceNames); } else { alert ('Get service types failed'); } }, reason => { alert('Get service type failed: ' + reason); }); this.astuteClientService.getRateTypes().then((d) => { if (d) { this.rateTypes = d; this.rateTypes.forEach((type) => { this.rateNames.push(type.feeTypeDesc); }); } else { alert ('Get rate types failed'); } }, reason => { alert('Get rate type failed: ' + reason); }); this.astuteClientService.getCustomers().then((customers) => { if (customers) { this.customers = customers; this.refreshData(); } else { alert('Get Customers Failed!'); } }, (reason) => { alert('Get Customers Failed: ' + reason); }); } // callback for grid selection setSelectedRow(event) { if (event) { this.selected = event.data; } this.selectedPODetail = this.astuteClientService.getPODetail(this.selected.ponum).then((data) => { if (data) { data.forEach((row) => { row.poNum = row.ponum; row.serviceTypeName = this.serviceNames[row.serviceTypeId - 1]; row.rateTypeName = this.rateNames[row.feeTypeId - 1]; }); // console.log(this.selectedPODetail); this.updateContractAmt(); if (this.gridColumnApi) { this.gridColumnApi.autoSizeAllColumns(); } if (this.detailColumnApi) { this.detailColumnApi.autoSizeAllColumns(); } return data; } else { alert('Get SO detail failed!'); } }, (reason) => { alert('Get SO detail failed: ' + reason); }); } // for inline updating updateRow(event) { const eventData = event.data; // console.log(eventData); this.astuteClientService.updatePO(eventData.poNum, eventData).then((data) => { if (!data) { alert('SO updating failed, check input fields'); } this.refreshData(); }, (reason) => { alert('Update SO failed: ' + reason); }); // this.refreshData(); } updateDetailRow(event) { const eventData = event.data; // console.log(eventData); event.data.serviceTypeId = this.getServiceIdFromName(event.data.serviceTypeName); event.data.feeTypeId = this.getFeeIdFromName(event.data.rateTypeName); if (event.data.feeTypeId === 1 && event.data.qty > 1) { // fixed fee and qty > 1 alert('Cannot have a quantity greater than 1 for fixed fee rate type.'); this.refreshDetailsOfSelected(); } else { // console.log(event.data.serviceTypeId); this.astuteClientService.updatePODetail(eventData.poNum, eventData.lineItemNo, eventData).then((data) => { if (!data) { alert('SO Detail updating failed, check input fields'); } this.refreshDetailsOfSelected(); }, (reason) => { alert('Update SO Detail failed: ' + reason); }); // this.refreshData(); } } // wrappers for PO service methods addPo(projNum, ponum, podate, customerid, contractnum, contractamt, title, notes, ref) { const poData = { 'astuteProjectNumber': projNum, 'poNum': ponum, 'podate': podate, 'customerId': customerid, 'contractNum': contractnum, 'contractAmt': contractamt, 'title': title, 'notes': notes }; // console.log(poData); this.astuteClientService.createPO(poData).then((data) => { if (data) { this.refreshData(); // this.addPODetail(this.newPODetail); ref.close(); } else { alert('SO Creation failed, check input fields'); } }, (reason) => { alert('Add SO failed for ' + reason); }); } editPo(projNum, ponum, podate, contractnum, contractamt, title, notes, ref) { const poData = { 'astuteProjectNumber': projNum, 'poNum': ponum, 'podate': podate, 'contractNum': contractnum, 'contractAmt': contractamt, 'title': title, 'notes': notes, }; // console.log(poData); this.astuteClientService.updatePO(ponum, poData).then((data) => { if (data) { this.refreshData(); // this.editPODetail(this.selectedPODetail); ref.close(); } else { alert('SO updating failed, check input fields'); } }, (reason) => { alert('Update SO failed for ' + reason); }); } finalizePO(ponum) { this.astuteClientService.finalizePO(ponum).then((data) => { if (data) { this.refreshData(); alert('SO is now final and ready to be used, you can\'t delete it anymore!'); } else { alert('Finalizing SO failed, check input fields'); } }, reason => { alert('Finalizing SO failed: ' + reason); }); } deletePO(ponum) { if (confirm('Are you sure?')) { this.astuteClientService.deletePO(ponum).then((data) => { if (data) { this.refreshData(); } else { alert('Deleting SO failed, check input fields'); } }, (reason) => { alert('Deleting SO failed: ' + reason); }); } } // wrappers for SO detail service methods addEmptyDetail() { const emptyData = { fee: 0, feeTypeId: 1, // lineItemNo: 7, poNum: this.selected.poNum, qty: 1, remainingQty: 1, serviceDesc: '', serviceTypeId: 1 }; // String poNum; // int lineItemNo; // String serviceDesc; // int feeTypeId; // Double qty; // Double fee; // int serviceTypeId; // Double remainingQuantity; this.astuteClientService.createPODetail(emptyData).then((data) => { if (!data) { alert('Creating SO detailed failed!'); } this.refreshDetailsOfSelected(); }, (reason) => { alert('Creating SO detailed failed: ' + reason); }); } // open and closing modal-form components open(ref) { // this.getSelectedRows(); this.gridColumnApi.autoSizeAllColumns(); this.detailColumnApi.autoSizeAllColumns(); ref.open(); } close(ref) { // this.newPODetail = []; // this.selectedPODetail = []; ref.close(); } // refreshing data methods refreshData() { // this.astuteClientService.getPOs().then((data) => { // if (data) { // // this.pos = data; // this.rowData = data; // this.rowData.forEach((row) => { // row.customerName = this.getCustomerNameFromId(row.customerId); // row.contractAmtString = formatCurrency(row.contractAmt, 'en-US', '$', 'USD'); // row.poNum = row.ponum; // }); // this.selected = null; // this.updateNewContractAmt(); // this.updateEditContractAmt(); // } else { // alert('Get SO\'s Failed!'); // } // }, (reason) => { // alert('Get SO\'s Failed: ' + reason); // }); this.rowData = this.astuteClientService.getPOs().then((data) => { if (data) { // this.pos = data; data.forEach((row) => { row.customerName = this.getCustomerNameFromId(row.customerId); row.contractAmtString = formatCurrency(row.contractAmt, 'en-US', '$', 'USD'); row.poNum = row.ponum; }); this.selected = null; this.contractAmount = 0; return data; } else { alert('Get SO\'s Failed!'); } }, (reason) => { alert('Get SO\'s Failed: ' + reason); }); } refreshDetailsOfSelected() { this.setSelectedRow(null); } updateContractAmt() { this.contractAmount = 0; if (this.selectedPODetail) { this.selectedPODetail.then((detail) => { detail.forEach((d) => { this.contractAmount += +d.qty * +d.fee; }); }); } } // helper methods getCurrDate() { const d = new Date(); return this.formatDate(d); } formatDate(d: Date) { let month = '' + (d.getMonth() + 1), day = '' + d.getDate(), year = d.getFullYear(); if (month.length < 2) { month = '0' + month; } if (day.length < 2) { day = '0' + day; } return [year, month, day].join('-'); } getCustomerNameFromId(customerId) { let name = ''; this.customers.forEach((customer) => { if (customer.customerId === customerId) { name = customer.customerName; } }); return name; } getServiceIdFromName(name) { let id = -1; this.serviceTypes.forEach((type) => { console.log(type.serviceTypeDesc + ' ' + name); if (type.serviceTypeDesc === name) { id = type.serviceTypeId; } }); return id; } getFeeIdFromName(name: any) { let id = -1; this.rateTypes.forEach((type) => { if (type.feeTypeDesc === name) { id = type.feeTypeId; } }); return id; } // ag grid callbacks onGridReady(evt) { this.gridApi = evt.api; this.gridColumnApi = evt.columnApi; } onDetailGridReady(evt) { this.detailGridApi = evt.api; this.detailColumnApi = evt.columnApi; } resizeColumns(evt) { evt.columnApi.autoSizeAllColumns(); } }