mirror of
https://github.com/dyiop/astute.git
synced 2025-04-17 02:30:17 -04:00
487 lines
16 KiB
TypeScript
487 lines
16 KiB
TypeScript
import {Component, OnInit, ViewChild} from '@angular/core';
|
|
import {AstuteClientService} from '../services/astute-client-service';
|
|
|
|
declare var $: any;
|
|
|
|
@Component({
|
|
selector: 'app-invoice',
|
|
templateUrl: './invoice.component.html',
|
|
styleUrls: ['./invoice.component.css']
|
|
})
|
|
export class InvoiceComponent implements OnInit {
|
|
@ViewChild('agGrid') agGrid;
|
|
chosenCustomerID: any = 0;
|
|
chosenInv: any = 0;
|
|
source;
|
|
customers;
|
|
pos = [];
|
|
chosenPo;
|
|
correspondingPos = [];
|
|
generatedInvoiceNumber = '';
|
|
feeTypes = ['Fixed Fee', 'Hourly'];
|
|
serviceTypes = ['Study', 'Design', 'Peer Review', 'Cost Investigation', 'Forensic Investigation'];
|
|
columnDefs = [
|
|
{headerName: 'Invoice Number', field: 'invoiceNumber'},
|
|
{headerName: 'Date', field: 'invoiceDate'},
|
|
{headerName: 'Sales Order Number', field: 'poNum'},
|
|
{headerName: 'Change Order Number', field: 'changeOrderNum'},
|
|
{headerName: 'Paid', field: 'pmtStatus'},
|
|
{headerName: 'Bll Amount', field: 'billAmt'}
|
|
];
|
|
newInDetails = [];
|
|
newBillAmt = 0;
|
|
selectedInDetails = [];
|
|
selectedPO;
|
|
selectedBillAmt = 0;
|
|
poDetails = [];
|
|
selectedPODetails = [];
|
|
|
|
gridOptions = {
|
|
|
|
// PROPERTIES - object properties, myRowData and myColDefs are created somewhere in your application
|
|
rowData: this.source,
|
|
columnDefs: this.columnDefs,
|
|
|
|
// PROPERTIES - simple boolean / string / number properties
|
|
enableColResize: true,
|
|
rowSelection: 'single',
|
|
|
|
// EVENTS - add event callback handlers
|
|
onRowClicked: (event) => {
|
|
this.getSelectedRows()
|
|
},
|
|
onColumnResized: function (event) {
|
|
console.log('a column was resized');
|
|
},
|
|
onGridReady: (event) => {
|
|
},
|
|
// this.agGrid.sizeColumnsToFit();
|
|
// 1: draft
|
|
// 2: submitted
|
|
// 3: void
|
|
|
|
// getRowStyle: function(params) {
|
|
// if (params.data.invoiceStatus === 1) {
|
|
// return { 'color': 'red' }
|
|
// } else if (params.data.invoiceStatus === 3) {
|
|
// return { 'text-decoration': 'line-through'}
|
|
// }
|
|
// }
|
|
|
|
rowClassRules: {
|
|
// apply green to 2008
|
|
// 'bg-red': true,
|
|
|
|
// apply amber 2004
|
|
'text-danger': function (params) {
|
|
return params.data.invoiceStatus === 1;
|
|
},
|
|
'text-primary': function (params) {
|
|
return params.data.invoiceStatus === 2;
|
|
},
|
|
'text-warning': function (params) {
|
|
return params.data.invoiceStatus === 3;
|
|
},
|
|
|
|
// apply red to 2000
|
|
// 'rag-red-outer': function(params) { return params.data.year === 2000}
|
|
}
|
|
}
|
|
|
|
constructor(protected astuteClientService: AstuteClientService) {
|
|
}
|
|
|
|
customerDropdownChange(index) {
|
|
this.chosenCustomerID = this.customers[index].customerId;
|
|
this.setCorrespondingPos();
|
|
}
|
|
|
|
poDropdownChange(ponum) {
|
|
this.pos.forEach((po) => {
|
|
if (po.ponum === ponum) {
|
|
this.chosenPo = po;
|
|
}
|
|
})
|
|
this.astuteClientService.getPODetail(ponum).then((data) => {
|
|
if (data) {
|
|
// fee
|
|
// feeTypeId
|
|
// lineItemNo
|
|
// ponum
|
|
// qty
|
|
// remainingQty
|
|
// serviceDesc
|
|
// serviceTypeId
|
|
|
|
// lineItemNo, feeTypeId, serviceTypeId, serviceDesc, fee, remainingQty
|
|
this.poDetails = data;
|
|
this.poDetails[-1] = {
|
|
'lineItemNo': -1,
|
|
'feeTypeId': 1,
|
|
'serviceTypeId': 1,
|
|
'serviceDesc': 'Out of Pocket Expenses',
|
|
'fee': 0,
|
|
'remainingQty': 0
|
|
};
|
|
} else {
|
|
alert("get PO detail failed!");
|
|
}
|
|
});
|
|
this.astuteClientService.generateInvoiceNumber(ponum).then((data) => {
|
|
if (data) {
|
|
this.generatedInvoiceNumber = data;
|
|
} else {
|
|
alert('gen inv num failed!');
|
|
}
|
|
});
|
|
}
|
|
|
|
ngOnInit() {
|
|
this.refreshData();
|
|
}
|
|
|
|
refreshData() {
|
|
this.astuteClientService.getInvoices().then((data) => {
|
|
this.source = data;
|
|
});
|
|
|
|
this.astuteClientService.getCustomers().then((data) => {
|
|
this.customers = data;
|
|
});
|
|
|
|
this.astuteClientService.getPOs().then((data) => {
|
|
this.pos = data;
|
|
});
|
|
}
|
|
|
|
getPODetails(poIndex) {
|
|
let ponum = this.pos[poIndex].ponum;
|
|
this.astuteClientService.getPODetail(ponum).then((data) => {
|
|
this.selectedInDetails = data;
|
|
console.log("inDetails:");
|
|
console.log(this.selectedInDetails);
|
|
});
|
|
}
|
|
|
|
onSelectedCellChange(row: number, col: string, value) {
|
|
this.selectedInDetails[row][col] = value;
|
|
console.log(this.selectedInDetails);
|
|
}
|
|
|
|
onNewCellChange(row: number, col: string, value) {
|
|
this.newInDetails[row][col] = value;
|
|
console.log(this.newInDetails);
|
|
}
|
|
|
|
pushOntoSelectedDetail(invoiceNum, lineItemNum, poLineItemNum, serviceTypeId, desc, qty, fee) {
|
|
this.selectedInDetails.push({
|
|
'invoiceNum': invoiceNum,
|
|
'lineItemNum': lineItemNum,
|
|
'poLineItemNum': poLineItemNum,
|
|
'serviceTypeId': serviceTypeId,
|
|
'desc': desc,
|
|
'qty': +qty,
|
|
'fee': +fee
|
|
});
|
|
}
|
|
|
|
pushOntoNewDetail(invoiceNum, lineItemNum, poLineItemNum, feeTypeId, serviceTypeId, desc, qty, fee, remainingQty, poNum) {
|
|
this.newInDetails.push({
|
|
'invoiceNum': invoiceNum,
|
|
'lineItemNum': lineItemNum,
|
|
'poLineItemNum': poLineItemNum,
|
|
'feeTypeId': feeTypeId,
|
|
'serviceTypeId': serviceTypeId,
|
|
'desc': desc,
|
|
'qty': +qty,
|
|
'fee': +fee,
|
|
'remainingQty': +remainingQty,
|
|
'poNum': poNum
|
|
});
|
|
console.log(this.newInDetails);
|
|
}
|
|
|
|
updateNewBillAmt() {
|
|
let tot = 0;
|
|
this.newInDetails.forEach((d) => {
|
|
tot += +d.qty * +d.fee;
|
|
});
|
|
this.newBillAmt = tot;
|
|
}
|
|
|
|
updateSelectedBillAmt() {
|
|
let tot = 0;
|
|
this.selectedInDetails.forEach((d) => {
|
|
tot += +d.qty * +d.fee;
|
|
});
|
|
this.selectedBillAmt = tot;
|
|
}
|
|
|
|
|
|
assignActity(): void {
|
|
window.open('/invoice-gen');
|
|
}
|
|
|
|
getSelectedRows() {
|
|
const selectedNodes = this.agGrid.api.getSelectedNodes();
|
|
if (selectedNodes.length) {
|
|
this.chosenInv = selectedNodes.map(node => node.data)[0];
|
|
// console.log (this.chosenInv);
|
|
this.selectedBillAmt = +this.chosenInv.billAmt;
|
|
this.astuteClientService.getPODetail(this.chosenInv.poNum).then((poDetails) => {
|
|
if (poDetails) {
|
|
this.selectedPODetails = poDetails;
|
|
this.astuteClientService.getInvoiceDetail(this.chosenInv.invoiceNumber).then((invoiceDetails) => {
|
|
if (invoiceDetails) {
|
|
this.selectedInDetails = invoiceDetails;
|
|
this.selectedInDetails.forEach((invDetail) => {
|
|
const tempPo = this.selectedPODetails.filter((po) => {
|
|
// console.log (po.lineItemNo + " and " + invDetail.poLineItemNum);
|
|
return po.lineItemNo === invDetail.poLineItemNum;
|
|
})[0];
|
|
if (tempPo) {
|
|
invDetail.remainingQty = tempPo.remainingQty;
|
|
}
|
|
});
|
|
} else {
|
|
alert("get Inv detail failed!");
|
|
}
|
|
});
|
|
} else {
|
|
alert("get PO detail failed!")
|
|
}
|
|
});
|
|
this.pos.forEach((po) => {
|
|
if (po.ponum === this.chosenInv.poNum) {
|
|
this.selectedPO = po;
|
|
}
|
|
});
|
|
} else {
|
|
this.chosenInv = null;
|
|
this.selectedPODetails = [];
|
|
}
|
|
}
|
|
|
|
open(content, indexPO, indexINV) {
|
|
content.open();
|
|
// this.detailDescription = ViewChild('detailDescription');
|
|
// this.detailAmount = ViewChild('detailAmount');
|
|
// this.detailRate = ViewChild('detailRate');
|
|
// this.detailTotal = ViewChild('detailTotal');
|
|
// if (indexINV) {
|
|
// this.chosenInv = indexINV;
|
|
// }
|
|
// if (indexPO) {
|
|
// this.chosenPo = indexPO;
|
|
// this.getPODetails(this.chosenPo);
|
|
// }
|
|
// this.modalService.open(content, { size: 'lg' }).result.then((result) => {
|
|
// this.closeResult = `Closed with: ${result}`;
|
|
// }, (reason) => {
|
|
// this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
|
|
// });
|
|
}
|
|
|
|
close(content) {
|
|
content.close();
|
|
}
|
|
|
|
getCurrDate() {
|
|
let d = new Date(),
|
|
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('-');
|
|
}
|
|
|
|
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('-');
|
|
}
|
|
|
|
deleteInvoice (invoiceNum) {
|
|
if (confirm('Are you sure you want to delete invoice, ' + invoiceNum)) {
|
|
this.astuteClientService.deleteInvoice(invoiceNum).then((data) => {
|
|
if (data) {
|
|
console.log('Invoice, ' + invoiceNum + ' successfully deleted');
|
|
this.refreshData();
|
|
} else {
|
|
alert ('Error in deleting; Invoice, ' + invoiceNum + ' has not been deleted');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
addInvoice(invoiceNumber, poNum, changeOrderNum, pmtStatus, billAmt, specialNotes, certification, status, ref) {
|
|
// String invoiceNumber;
|
|
// Date invoiceDate;
|
|
// String poNum;
|
|
// String changeOrderNum;
|
|
// int pmtStatus;
|
|
// Double billAmt;
|
|
// String specialNotes;
|
|
// String certification;
|
|
// Date pmtReceivedDate;
|
|
const invData = {
|
|
"invoiceNumber": invoiceNumber,
|
|
"invoiceDate": this.formatDate(new Date()),
|
|
"poNum": poNum,
|
|
"changeOrderNum": changeOrderNum,
|
|
"pmtStatus": +pmtStatus,
|
|
"billAmt": +billAmt,
|
|
"specialNotes": specialNotes,
|
|
"certification": certification,
|
|
"pmtReceivedDate": this.formatDate(new Date()),
|
|
'invoiceStatus': status
|
|
};
|
|
console.log(invData);
|
|
|
|
this.astuteClientService.createInvoice(invData)
|
|
.catch((response) => {
|
|
console.log("rejected: " + response);
|
|
})
|
|
.then((data) => {
|
|
if (data) {
|
|
this.refreshData();
|
|
this.addInvoiceDetail(this.newInDetails);
|
|
ref.close();
|
|
} else {
|
|
alert('Invoice Creation Failed, Check Input Fields');
|
|
}
|
|
});
|
|
}
|
|
|
|
addInvoiceDetail(details) {
|
|
if (details.length) {
|
|
// console.log(details[0]);
|
|
// if (details[0].poLineItemNum !== -1) {
|
|
this.astuteClientService.createInvoiceDetail(details[0]).then((data) => {
|
|
if (data) {
|
|
details.splice(0, 1);
|
|
this.addInvoiceDetail(details);
|
|
} else {
|
|
alert('add inv detail failed');
|
|
}
|
|
});
|
|
// } else {
|
|
// desc
|
|
// fee
|
|
// feeTypeId
|
|
// invoiceNum
|
|
// lineItemNum
|
|
// poLineItemNum
|
|
// qty
|
|
// remainingQty
|
|
// serviceTypeId
|
|
// poNum
|
|
|
|
// const data = {
|
|
// // 'lineItemNo': details[0].,
|
|
// 'poNum': details[0].poNum,
|
|
// 'serviceDesc': details[0].desc,
|
|
// 'feeTypeId': details[0].feeTypeId,
|
|
// 'serviceTypeId': details[0].serviceTypeId,
|
|
// 'qty': +details[0].qty,
|
|
// 'fee': +details[0].fee,
|
|
// 'remainingQty': +details[0].fee * +details[0].qty
|
|
// };
|
|
// this.astuteClientService.createPODetail(data).then((d) => {
|
|
// if (d) {
|
|
// console.log (d);
|
|
// } else {
|
|
// alert('create custom PO failed.');
|
|
// }
|
|
// });
|
|
// }
|
|
} else {
|
|
this.newInDetails = [];
|
|
}
|
|
}
|
|
|
|
editInvoice(invoiceNumber, poNum, changeOrderNum, pmtStatus, billAmt, specialNotes, certification) {
|
|
// String invoiceNumber;
|
|
// Date invoiceDate;
|
|
// String poNum;
|
|
// String changeOrderNum;
|
|
// int pmtStatus;
|
|
// Double billAmt;
|
|
// String specialNotes;
|
|
// String certification;
|
|
// Date pmtReceivedDate;
|
|
const invData = {
|
|
"invoiceNumber": invoiceNumber,
|
|
"invoiceDate": new Date(),
|
|
"poNum": poNum,
|
|
"changeOrderNum": changeOrderNum,
|
|
"pmtStatus": +pmtStatus,
|
|
"billAmt": +billAmt,
|
|
"specialNotes": specialNotes,
|
|
"certification": certification,
|
|
"pmtReceivedDate": new Date()
|
|
};
|
|
|
|
this.astuteClientService.updateInvoice(invoiceNumber, invData)
|
|
.catch((response) => {
|
|
console.log("rejected: " + response);
|
|
})
|
|
.then((data) => {
|
|
if (data) {
|
|
alert("invoice " + invoiceNumber + " updated!");
|
|
console.log("fulfilled: " + data);
|
|
// this.source[this.chosenInv] = invData;
|
|
this.refreshData();
|
|
} else {
|
|
alert("Invoice Update Failed, Check Input Fields")
|
|
}
|
|
});
|
|
}
|
|
|
|
voidInvoice(invoiceNumber) {
|
|
this.astuteClientService.voidInvoice(invoiceNumber).then((data) => {
|
|
if (data) {
|
|
this.refreshData();
|
|
} else {
|
|
alert('void invoice failed.');
|
|
}
|
|
});
|
|
}
|
|
|
|
submitInvoice(invoiceNumber) {
|
|
this.astuteClientService.submitInvoice(invoiceNumber).then((data) => {
|
|
if (data) {
|
|
this.refreshData();
|
|
} else {
|
|
alert('submit invoice failed.');
|
|
}
|
|
});
|
|
}
|
|
|
|
getPerc(amt, total): number {
|
|
return Math.floor(((amt) / total) * 100);
|
|
}
|
|
|
|
getRangeMax(total, num) {
|
|
return Math.floor(total / num);
|
|
}
|
|
|
|
setCorrespondingPos() {
|
|
this.correspondingPos = this.pos.filter((po, index, array) => {
|
|
return po.customerId === this.chosenCustomerID;
|
|
});
|
|
}
|
|
}
|