Lots of changes:

- Added separate grid for details in each section
 - Enabled inline editing for items

TODO:
 - Fix alert messages
 - Make editing follow buisness rules
This commit is contained in:
Akash Shah 2019-06-20 10:48:10 -04:00
parent ac46e2eb75
commit 91e41b501e
7 changed files with 73 additions and 68 deletions

View File

@ -302,7 +302,7 @@
<div *ngIf="selected"> <div *ngIf="selected">
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12 align-items-end">
<ag-grid-angular <ag-grid-angular
style="height: 500px;" style="height: 500px;"
class="ag-theme-balham" class="ag-theme-balham"
@ -319,35 +319,40 @@
></ag-grid-angular> ></ag-grid-angular>
</div> </div>
</div> </div>
<div class="row">
<div class="col-6">
<button class="btn btn-primary btn-sm w-100 mt-2 mb-2" type="button"
(click)="createEmptyContact()">
Add Contact
</button>
</div>
<div class="col-6">
<button class="btn btn-danger btn-sm w-100 mt-2 mb-2" type="button"
(click)="deleteContact()">
Delete Contact
</button>
</div>
</div>
</div> </div>
<!--<div class="modal-footer">-->
<div class="modal-footer"> <!--<button type="button" class="btn btn-info" (click)="close(contacts)">Exit</button>-->
<button class="btn btn-danger" type="button" <!--</div>-->
(click)="deleteContact()">
Delete Contact
</button>
<button class="btn btn-primary" type="button"
(click)="createEmptyContact()">
Add Contact
</button>
<button type="button" class="btn btn-info" (click)="close(contacts)">Exit</button>
</div>
</div>
<div *ngIf="!selected">
<div class="modal-body">
Choose a Customer First!
</div>
<div class="modal-footer">
<button class="btn btn-danger" type="button"
[disabled]="true">
Delete Contact
</button>
<button class="btn btn-primary" type="button"
[disabled]="true">
Add Contact
</button>
<button type="button" class="btn btn-info" (click)="close(contacts)">Exit</button>
</div>
</div> </div>
<!--<div *ngIf="!selected">-->
<!--<div class="modal-body">-->
<!--Choose a Customer First!-->
<!--</div>-->
<!--<div class="modal-footer">-->
<!--<button class="btn btn-danger" type="button"-->
<!--[disabled]="true">-->
<!--Delete Contact-->
<!--</button>-->
<!--<button class="btn btn-primary" type="button"-->
<!--[disabled]="true">-->
<!--Add Contact-->
<!--</button>-->
<!--<button type="button" class="btn btn-info" (click)="close(contacts)">Exit</button>-->
<!--</div>-->
<!--</div>-->
</app-modal-form> </app-modal-form>

View File

@ -109,7 +109,7 @@ export class InvoicePaymentComponent implements OnInit {
this.astuteClientService.getSumittedInvoices().then((data) => { this.astuteClientService.getSumittedInvoices().then((data) => {
this.invoices = data; this.invoices = data;
}); });
this.astuteClientService.getInvoiceTypes().then((data) => { this.astuteClientService.getInvoicePaymentTypes().then((data) => {
this.paymentTypes = data; this.paymentTypes = data;
}); });

View File

@ -659,7 +659,7 @@
<!--Modal Footer--> <!--Modal Footer-->
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-success" <button type="button" class="btn btn-success"
(click)="addInvoice(inNumIn.value, poNumIn.value, coNumIn.value, pmtStatusIn.value, newBillAmt, notesIn.value, certIn.value, 1, new)" (click)="addInvoice(inNumIn.value, poNumIn.value, coNumIn.value, pmtStatusIn.value, 0, notesIn.value, certIn.value, 1, new)"
[disabled]="!(inNumIn.value && poNumIn.value)"> [disabled]="!(inNumIn.value && poNumIn.value)">
<!--[disabled]="!(inNumIn.value && poNumIn.value && newBillAmt && certIn.value)">--> <!--[disabled]="!(inNumIn.value && poNumIn.value && newBillAmt && certIn.value)">-->
Confirm Confirm
@ -689,14 +689,15 @@
rowSelection="single" rowSelection="single"
></ag-grid-angular> ></ag-grid-angular>
<div class="input-group mt-2"> <div class="input-group mt-2">
<select class="custom-select" <select class="custom-select" #poDetailSelec
[disabled]="!selectedPODetails.length" [disabled]="!selectedPODetails.length || (chosenInv ? chosenInv.invoiceStatus === 2 || chosenInv.invoiceStatus === 3: false)"
#poDetSelec> #poDetSelec>
<option *ngFor="let po of selectedPODetails" [value]="po.lineItemNo">{{po.serviceDesc}}</option> <option *ngFor="let po of selectedPODetails" [value]="po.lineItemNo">{{po.serviceDesc}}</option>
<option [value]="-1">Out of Pocket Expenses</option> <option [value]="-1">Out of Pocket Expenses</option>
</select> </select>
<div class="input-group-append"> <div class="input-group-append">
<button class="btn btn-primary btn-sm" type="button" (click)="addEmptyDetail()">Add</button> <button class="btn btn-primary btn-sm" type="button" (click)="addEmptyDetail(poDetailSelec.value)"
[disabled]="(chosenInv ? chosenInv.invoiceStatus === 2 || chosenInv.invoiceStatus === 3: false)">Add</button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -43,7 +43,7 @@ export class InvoiceComponent implements OnInit {
{headerName: '#', field: 'lineItemNum'}, {headerName: '#', field: 'lineItemNum'},
{headerName: 'PO Detail', field: 'poDetailName'}, {headerName: 'PO Detail', field: 'poDetailName'},
{headerName: 'Description', field: 'desc', editable: true, cellEditor: 'agLargeTextCellEditor'}, {headerName: 'Description', field: 'desc', editable: true, cellEditor: 'agLargeTextCellEditor'},
{headerName: 'Fee Type', field: 'feeTypeName'}, {headerName: 'Fee Type', field: 'rateTypeName'},
{headerName: 'Service Type', field: 'serviceTypeName'}, {headerName: 'Service Type', field: 'serviceTypeName'},
{headerName: 'Qty or Hours', field: 'qty', editable: true}, {headerName: 'Qty or Hours', field: 'qty', editable: true},
{headerName: '(/Remaining)', field: 'remainingQty'}, {headerName: '(/Remaining)', field: 'remainingQty'},
@ -67,7 +67,6 @@ export class InvoiceComponent implements OnInit {
allPODetails = []; allPODetails = [];
newInDetails = []; newInDetails = [];
newBillAmt = 0;
selectedInDetails; selectedInDetails;
selectedPO; selectedPO;
@ -192,6 +191,7 @@ export class InvoiceComponent implements OnInit {
} }
}); });
} }
refreshDetailsOfSelected() { refreshDetailsOfSelected() {
this.setSelectedRow(null); this.setSelectedRow(null);
} }
@ -216,11 +216,13 @@ export class InvoiceComponent implements OnInit {
} }
updateDetailRow(event) { updateDetailRow(event) {
const eventData = event.data; const eventData = event.data;
console.log(eventData); // console.log(eventData);
this.astuteClientService.updateInvoiceDetail(eventData.invoiceNumber, eventData.lineItemNum, eventData).then((data) => { this.astuteClientService.updateInvoiceDetail(eventData.invoiceNum, eventData.lineItemNum, eventData).then((data) => {
if (!data) { if (!data) {
this.refreshDetailsOfSelected(); this.refreshDetailsOfSelected();
alert('Detail Updating Failed, Check Input Fields'); alert('Detail Updating Failed, Check Input Fields');
} else {
this.updateSelectedBillAmt();
} }
}, (reason) => { }, (reason) => {
alert('Update Detail failed: ' + reason); alert('Update Detail failed: ' + reason);
@ -235,6 +237,7 @@ export class InvoiceComponent implements OnInit {
this.selectedPODetails = this.allPODetails.filter((detail) => { this.selectedPODetails = this.allPODetails.filter((detail) => {
return (detail.ponum === this.chosenInv.poNum); return (detail.ponum === this.chosenInv.poNum);
}); });
this.selectedInDetails = null;
this.selectedInDetails = this.astuteClientService.getInvoiceDetail(this.chosenInv.invoiceNumber).then((data) => { this.selectedInDetails = this.astuteClientService.getInvoiceDetail(this.chosenInv.invoiceNumber).then((data) => {
if (data) { if (data) {
data.forEach((invDetail) => { data.forEach((invDetail) => {
@ -253,6 +256,7 @@ export class InvoiceComponent implements OnInit {
invDetail.poDetailName = this.selectedPODetails[invDetail.poLineItemNum - 1].serviceDesc; invDetail.poDetailName = this.selectedPODetails[invDetail.poLineItemNum - 1].serviceDesc;
} }
}); });
this.updateSelectedBillAmt();
return data; return data;
} else { } else {
alert('get Inv detail failed!'); alert('get Inv detail failed!');
@ -308,14 +312,17 @@ export class InvoiceComponent implements OnInit {
this.newInDetails.forEach((d) => { this.newInDetails.forEach((d) => {
tot += +d.qty * +d.fee; tot += +d.qty * +d.fee;
}); });
this.newBillAmt = tot; // this.newBillAmt = tot;
} }
updateSelectedBillAmt() { updateSelectedBillAmt() {
// let tot = 0; this.selectedBillAmt = 0;
// this.selectedInDetails.forEach((d) => { if (this.selectedInDetails) {
// tot += +d.qty * +d.fee; this.selectedInDetails.then((data) => {
// }); data.forEach((d) => {
// this.selectedBillAmt = tot; this.selectedBillAmt += +d.qty * +d.fee;
});
});
}
} }
@ -532,6 +539,7 @@ export class InvoiceComponent implements OnInit {
// creates empty line item detail // creates empty line item detail
addEmptyDetail(poLineItemNum) { addEmptyDetail(poLineItemNum) {
console.log(this.chosenInv.invoiceNumber);
const emptyData = { const emptyData = {
desc: '', desc: '',
fee: 0, fee: 0,

View File

@ -4,9 +4,9 @@
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<ag-grid-angular <ag-grid-angular
#agGrid
style="height: 500px;" style="height: 500px;"
class="ag-theme-balham" class="ag-theme-balham"
[gridOptions]="gridOptions"
[enableColResize]="true" [enableColResize]="true"
[enableSorting]="true" [enableSorting]="true"
[enableFilter]="true" [enableFilter]="true"
@ -324,7 +324,7 @@
<!--</td>--> <!--</td>-->
<!--<td class="p-0 m-0">--> <!--<td class="p-0 m-0">-->
<!--<select class="form-control cell" [value]="poDetail.serviceTypeId" (change)="onSelectedCellChange(i, 'serviceTypeId', serviceTypeId.value)" #serviceTypeId>--> <!--<select class="form-control cell" [value]="poDetail.serviceTypeId" (change)="onSelectedCellChange(i, 'serviceTypeId', serviceTypeId.value)" #serviceTypeId>-->
<!--<option [value]="serviceType.serviceTypeId" *ngFor="let serviceType of serviceTypes">{{serviceType.desc}}</option>--> <!--<option [value]="serviceType.serviceTypeId" *ngFor="let serviceType of serviceNames">{{serviceType.desc}}</option>-->
<!--&lt;!&ndash;<option value="">Study</option>&ndash;&gt;--> <!--&lt;!&ndash;<option value="">Study</option>&ndash;&gt;-->
<!--&lt;!&ndash;<option value="2">Design</option>&ndash;&gt;--> <!--&lt;!&ndash;<option value="2">Design</option>&ndash;&gt;-->
<!--&lt;!&ndash;<option value="3">Peer Review</option>&ndash;&gt;--> <!--&lt;!&ndash;<option value="3">Peer Review</option>&ndash;&gt;-->
@ -414,19 +414,15 @@
(rowDataChanged)="resizeColumns($event)" (rowDataChanged)="resizeColumns($event)"
rowSelection="single" rowSelection="single"
></ag-grid-angular> ></ag-grid-angular>
<button class="btn btn-primary btn-sm w-100 mt-2" type="button" (click)="addEmptyDetail()" [disabled]="(selected ? selected.isFinal : false)">Add</button>
</div> </div>
</div> </div>
<hr> <hr>
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12 justify-content-start">
<h4 align="end">Total Cost: {{contractAmount | currency}}</h4> <h4 align="end">Total Cost: {{contractAmount | currency}}</h4>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" (click)="addEmptyDetail()">Add</button>
<button class="btn btn-outline-danger" (click)="close(editDetails)">Exit</button>
</div>
</app-modal-form> </app-modal-form>

View File

@ -117,14 +117,7 @@ export class SalesOrderComponent implements OnInit {
row.serviceTypeName = this.serviceNames[row.serviceTypeId - 1]; row.serviceTypeName = this.serviceNames[row.serviceTypeId - 1];
row.rateTypeName = this.rateNames[row.feeTypeId - 1]; row.rateTypeName = this.rateNames[row.feeTypeId - 1];
}); });
// console.log(this.selectedPODetail);
this.updateContractAmt(); this.updateContractAmt();
// if (this.gridColumnApi) {
// this.gridColumnApi.autoSizeAllColumns();
// }
// if (this.detailColumnApi) {
// this.detailColumnApi.autoSizeAllColumns();
// }
return data; return data;
} else { } else {
alert('Get SO detail failed!'); alert('Get SO detail failed!');
@ -163,6 +156,8 @@ export class SalesOrderComponent implements OnInit {
if (!data) { if (!data) {
alert('SO Detail updating failed, check input fields'); alert('SO Detail updating failed, check input fields');
this.refreshDetailsOfSelected(); this.refreshDetailsOfSelected();
} else {
this.updateContractAmt();
} }
}, (reason) => { }, (reason) => {
alert('Update SO Detail failed: ' + reason); alert('Update SO Detail failed: ' + reason);

View File

@ -24,6 +24,7 @@ export class AstuteClientService {
// **************************************** AUTH Service methods // **************************************** AUTH Service methods
public login(username: string, password: string): Promise<string> { public login(username: string, password: string): Promise<string> {
console.log('*** In login()');
const data = { const data = {
'username': username, 'username': username,
'password': password 'password': password
@ -47,6 +48,7 @@ export class AstuteClientService {
}); });
} }
public logout() { public logout() {
console.log('*** In logout()');
return this.http return this.http
.post(`${this.authUrl}/logout${this.sessionString}`, {}) .post(`${this.authUrl}/logout${this.sessionString}`, {})
.toPromise() .toPromise()
@ -57,10 +59,12 @@ export class AstuteClientService {
}); });
} }
public getSessionId(): string { public getSessionId(): string {
console.log('*** In getSessionId()');
console.log(localStorage.getItem('SESSION_ID')); console.log(localStorage.getItem('SESSION_ID'));
return localStorage.getItem('SESSION_ID'); return localStorage.getItem('SESSION_ID');
} }
public getSessionUser(): string { public getSessionUser(): string {
console.log('*** In getSessionUser()');
console.log(localStorage.getItem('SESSION_USER')); console.log(localStorage.getItem('SESSION_USER'));
return localStorage.getItem('SESSION_USER'); return localStorage.getItem('SESSION_USER');
} }
@ -69,7 +73,6 @@ export class AstuteClientService {
public getCustomers(): Promise<any> { public getCustomers(): Promise<any> {
console.log('*** In getCustomers()'); console.log('*** In getCustomers()');
const url = `${this.customerUrl}${this.sessionString}`; const url = `${this.customerUrl}${this.sessionString}`;
console.log(url);
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -118,7 +121,6 @@ export class AstuteClientService {
public getCustomerContacts(customerId): Promise<any> { public getCustomerContacts(customerId): Promise<any> {
console.log('*** In getCustomerContacts()'); console.log('*** In getCustomerContacts()');
const url = `${this.customerContactUrl}?customerId=${customerId}&sessionId=${localStorage.getItem('SESSION_ID')}`; const url = `${this.customerContactUrl}?customerId=${customerId}&sessionId=${localStorage.getItem('SESSION_ID')}`;
console.log(url);
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -160,9 +162,8 @@ export class AstuteClientService {
}); });
} }
public getPODetail(ponum): Promise<any> { public getPODetail(ponum): Promise<any> {
console.log('*** In getPODetails()'); console.log('*** In getPODetail()');
const url = `${this.PODetailUrl}?PONum=${ponum}&sessionId=${localStorage.getItem('SESSION_ID')}`; const url = `${this.PODetailUrl}?PONum=${ponum}&sessionId=${localStorage.getItem('SESSION_ID')}`;
console.log(url);
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -214,7 +215,7 @@ export class AstuteClientService {
.then(response => response['entity']); .then(response => response['entity']);
} }
public getRateTypes(): Promise<any> { public getRateTypes(): Promise<any> {
console.log('*** In getPOs()'); console.log('*** In getRateTypes()');
const url = `${this.POUrl}/feeTypes${this.sessionString}`; const url = `${this.POUrl}/feeTypes${this.sessionString}`;
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
@ -336,9 +337,9 @@ export class AstuteClientService {
return response['entity']; return response['entity'];
}); });
} }
public getInvoiceTypes(): Promise<any> { public getInvoicePaymentTypes(): Promise<any> {
console.log('*** In getInvoicePaymentTypes()');
const url = `${this.invoicePaymentUrl}/paymentTypes${this.sessionString}`; const url = `${this.invoicePaymentUrl}/paymentTypes${this.sessionString}`;
console.log('*** In getInvoiceTypes() ... calling ' + url);
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -374,9 +375,8 @@ export class AstuteClientService {
// **************************************** Service Type methods // **************************************** Service Type methods
public getServiceTypes(): Promise<any> { public getServiceTypes(): Promise<any> {
console.log('*** In getPOServiceTypes()'); console.log('*** In getServiceTypes()');
const url = `${this.serviceTypeUrl}${this.sessionString}`; const url = `${this.serviceTypeUrl}${this.sessionString}`;
// console.log(url);
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
.then(response => { .then(response => {