Loads of changes in this one:

- customer and sales order are updated with new workflow for details
 - invoice has yet to be updated to the new workflow
 - added a settings tab and put service types and logout on there
 - updated homepage and nav-bar accordingly
This commit is contained in:
Akash Shah 2019-06-08 23:42:44 -04:00
parent 56fb6591b5
commit 350b854b8d
16 changed files with 1863 additions and 1288 deletions

View File

@ -7,8 +7,8 @@ import {InvoiceComponent} from './invoice/invoice.component';
import {HomepageComponent} from './homepage/homepage.component'; import {HomepageComponent} from './homepage/homepage.component';
import {InvoiceGenComponent} from './invoice-gen/invoice-gen.component'; import {InvoiceGenComponent} from './invoice-gen/invoice-gen.component';
import {InvoicePaymentComponent} from './invoice-payment/invoice-payment.component'; import {InvoicePaymentComponent} from './invoice-payment/invoice-payment.component';
import {ServiceTypeComponent} from './service-type/service-type.component';
import {LoginComponent} from './login/login.component'; import {LoginComponent} from './login/login.component';
import {SettingsComponent} from './settings/settings.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', redirectTo: 'login', pathMatch: 'full'}, { path: '', redirectTo: 'login', pathMatch: 'full'},
@ -19,8 +19,9 @@ const routes: Routes = [
{ path: 'invoice', component: InvoiceComponent }, { path: 'invoice', component: InvoiceComponent },
{ path: 'invoice-gen', component: InvoiceGenComponent }, { path: 'invoice-gen', component: InvoiceGenComponent },
{ path: 'invoice-payment', component: InvoicePaymentComponent }, { path: 'invoice-payment', component: InvoicePaymentComponent },
{ path: 'service-type', component: ServiceTypeComponent}, // { path: 'service-type', component: ServiceTypeComponent},
{ path: 'login', component: LoginComponent } { path: 'login', component: LoginComponent },
{ path: 'settings', component: SettingsComponent }
]; ];
@NgModule({ @NgModule({

View File

@ -21,7 +21,8 @@ import { InvoicePaymentComponent } from './invoice-payment/invoice-payment.compo
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { ReactiveFormsModule } from '@angular/forms'; import { ReactiveFormsModule } from '@angular/forms';
import { ServiceTypeComponent } from './service-type/service-type.component'; import { SettingsComponent } from './settings/settings.component';
// import { ServiceTypeComponent } from './service-type/service-type.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -36,7 +37,8 @@ import { ServiceTypeComponent } from './service-type/service-type.component';
InvoiceGenComponent, InvoiceGenComponent,
LoginComponent, LoginComponent,
InvoicePaymentComponent, InvoicePaymentComponent,
ServiceTypeComponent SettingsComponent// ,
// ServiceTypeComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

View File

@ -5,27 +5,34 @@
<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"
[enableColResize]="true"
[enableSorting]="true" [enableSorting]="true"
[enableFilter]="true" [enableFilter]="true"
[rowData]="rowData | async" [rowData]="rowData | async"
[columnDefs]="columnDefs" [columnDefs]="columnDefs"
(cellEditingStopped)="updateRow($event)"
(gridReady)="onGridReady($event)"
(rowClicked)="setSelectedRow($event)"
(rowDataChanged)="resizeColumns($event)"
rowSelection="single" rowSelection="single"
rowDeselection="true" rowDeselection="true"
></ag-grid-angular> ></ag-grid-angular>
</div> </div>
</div> </div>
<div class="row justify-content-center mt-2"> <div class="row justify-content-center mt-2">
<div class="col-4"> <div class="col-3">
<button class="btn btn-success" style="width: 100%" (click)="open(new)">Add Customer</button> <button class="btn btn-success" style="width: 100%" (click)="open(new)">Add Customer</button>
</div> </div>
<div class="col-4"> <div class="col-3">
<button class="btn btn-info" style="width: 100%" (click)="open(edit)">Edit Customer</button> <button class="btn btn-info" style="width: 100%" (click)="open(edit)" [disabled]="!selected">Edit Customer</button>
</div> </div>
<div class="col-4"> <div class="col-3">
<button class="btn btn-danger" style="width: 100%" (click)="deleteCustomer(selected.customerId)">Delete Customer</button> <button class="btn btn-primary" style="width: 100%" (click)="open(contacts)" [disabled]="!selected">Contact Book</button>
</div>
<div class="col-3">
<button class="btn btn-danger" style="width: 100%" (click)="deleteCustomer(selected.customerId)" [disabled]="!selected">Delete Customer</button>
</div> </div>
</div> </div>
</div> </div>
@ -244,16 +251,13 @@
<td style="width: 1%"> <td style="width: 1%">
<span class="input-group-text">Phone*</span> <span class="input-group-text">Phone*</span>
</td> </td>
<td colspan="7"> <td colspan="3">
<input type="tel" class="form-control" placeholder="(123) 456-7890" [textMask]="{mask: usPhoneMask, guide: false}" #inPhone [value]="selected.phone"> <input type="tel" class="form-control" placeholder="(123) 456-7890" [textMask]="{mask: usPhoneMask, guide: false}" #inPhone [value]="selected.phone">
</td> </td>
</tr>
<tr>
<td style="width: 1%"> <td style="width: 1%">
<span class="input-group-text">Ext*</span> <span class="input-group-text">Ext*</span>
</td> </td>
<td colspan="3"> <td colspan="2">
<input type="tel" class="form-control" placeholder="123456" #inPhExt [value]="selected.phExt"> <input type="tel" class="form-control" placeholder="123456" #inPhExt [value]="selected.phExt">
</td> </td>
</tr> </tr>
@ -292,3 +296,58 @@
</div> </div>
</div> </div>
</app-modal-form> </app-modal-form>
<!--MODAL: customer contacts-->
<app-modal-form [title]="'Contact Book'" #contacts>
<div *ngIf="selected">
<div class="container-fluid">
<div class="row">
<div class="col-12">
<ag-grid-angular
style="height: 500px;"
class="ag-theme-balham"
[enableColResize]="true"
[enableSorting]="true"
[enableFilter]="true"
[rowData]="contactsData | async"
[columnDefs]="contactsColDef"
(cellEditingStopped)="updateContactRow($event)"
(gridReady)="onContactGridReady($event)"
(rowDataChanged)="resizeColumns($event)"
rowSelection="single"
rowDeselection="true"
></ag-grid-angular>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-danger" type="button"
(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>
</app-modal-form>

View File

@ -1,4 +1,4 @@
import {Component, OnInit, ViewChild} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {AstuteClientService} from '../services/astute-client-service'; import {AstuteClientService} from '../services/astute-client-service';
@Component({ @Component({
@ -7,23 +7,27 @@ import {AstuteClientService} from '../services/astute-client-service';
styleUrls: ['./customer.component.css'] styleUrls: ['./customer.component.css']
}) })
export class CustomerComponent implements OnInit { export class CustomerComponent implements OnInit {
@ViewChild('agGrid') agGrid; // @ViewChild('agGrid') agGrid;
gridApi;
gridColumnApi;
contactGridApi;
contactColumnApi;
selected = null; selected = null;
customers; customers;
columnDefs = [ columnDefs = [
{headerName: 'Customer ID', field: 'customerId', checkboxSelection: true}, {headerName: 'ID', field: 'customerId'},
{headerName: 'Customer Name', field: 'customerName'}, {headerName: 'Name', field: 'customerName', editable: true},
{headerName: 'Bill To Department', field: 'billToDept'}, {headerName: 'Bill To', field: 'billToDept', editable: true},
{headerName: 'Address 1', field: 'add1'}, {headerName: 'Address 1', field: 'add1', editable: true},
{headerName: 'Address 2', field: 'add2'}, {headerName: 'Address 2', field: 'add2', editable: true},
{headerName: 'City', field: 'city'}, {headerName: 'City', field: 'city', editable: true},
{headerName: 'Email', field: 'email'}, {headerName: 'Email', field: 'email', editable: true},
{headerName: 'Fax', field: 'fax'}, {headerName: 'Fax', field: 'fax', editable: true},
{headerName: 'Phone', field: 'phone'}, {headerName: 'Phone', field: 'phone', editable: true},
{headerName: 'phExt', field: 'phExt'}, {headerName: 'Ext.', field: 'phExt', editable: true},
{headerName: 'State', field: 'state'}, {headerName: 'State', field: 'state', editable: true},
{headerName: 'ZIP', field: 'zip'}, {headerName: 'ZIP', field: 'zip', editable: true},
{headerName: 'ZIP-4', field: 'ziplast4'} {headerName: 'ZIP-4', field: 'ziplast4', editable: true}
]; ];
rowData: any; rowData: any;
states = [ states = [
@ -81,6 +85,30 @@ export class CustomerComponent implements OnInit {
]; ];
usPhoneMask = ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]; usPhoneMask = ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
contactsData: any;
contactsColDef = [
{headerName: 'ID', field: 'contactId', checkboxSelection: true},
{headerName: 'Name', field: 'name', editable: true},
{headerName: 'Title', field: 'title', editable: true},
{headerName: 'Email', field: 'email', editable: true},
{headerName: 'Work', field: 'workPhone', editable: true},
{headerName: 'Phone', field: 'mobile', editable: true},
{headerName: 'Ext.', field: 'phExt', editable: true},
{headerName: 'Fax', field: 'fax', editable: true},
{headerName: 'Address', field: 'address', editable: true}
];
// address: "123 Test Drive"
// contactId: 1
// customerId: "MDOT"
// email: "Test@Test.com"
// fax: 234123344
// mobile: 1232343455
// name: "John Shaw"
// phExt: 1233
// title: "Manager"
// workPhone: 1231231233
constructor(protected astuteClientService: AstuteClientService) { constructor(protected astuteClientService: AstuteClientService) {
} }
@ -88,74 +116,70 @@ export class CustomerComponent implements OnInit {
this.refreshData(); this.refreshData();
} }
getSelectedRows() { // callback for grid selection
const selectedNodes = this.agGrid.api.getSelectedNodes(); setSelectedRow(event) {
if (selectedNodes.length) { this.selected = event.data;
this.selected = selectedNodes.map(node => node.data)[0];
} else {
this.selected = null;
}
} }
// inName.value, inBillToDept.value, inAdd1.value, inAdd2.value, inCity.value, inState.value, inZIP.value, inZIP4.value, inEmail.value, inPhone.value, inFax.value // wrappers for customer service methods
addCustomer(customerId, name, billTo, add1, add2, city, state, zip, zip4, email, phone, phExt, fax, ref) { addCustomer(customerId, name, billTo, add1, add2, city, state, zip, zip4, email, phone, phExt, fax, ref) {
if (fax.length > 0 && fax.length < 14) { if (fax.length > 0 && fax.length < 14) {
alert('Invalid fax.'); alert('Invalid fax.');
} else if (phone.length > 0 && phone.length < 14) { } else if (phone.length > 0 && phone.length < 14) {
alert('Invalid phone.'); alert('Invalid phone.');
} else if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email) == false) { } else if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email) === false) {
alert("You have entered an invalid email address!") alert('You have entered an invalid email address!');
} else { } else {
let customerData = { const customerData = {
"customerId": customerId, 'customerId': customerId,
"customerName": name, 'customerName': name,
"billToDept": billTo, 'billToDept': billTo,
"add1": add1, 'add1': add1,
"add2": add2, 'add2': add2,
"city": city, 'city': city,
"state": state, 'state': state,
"zip": zip, 'zip': zip,
"ziplast4": zip4, 'ziplast4': zip4,
"email": email, 'email': email,
"phone": phone, 'phone': phone,
"phExt": phExt, 'phExt': phExt,
"fax": fax 'fax': fax
}; };
this.astuteClientService.createCustomer(customerData).then((data) => { this.astuteClientService.createCustomer(customerData).then((data) => {
if (data) { if (data) {
this.refreshData(); this.refreshData();
ref.close(); ref.close();
} else { } else {
alert("Customer Creation Failed, Check Input Fields") alert('Customer Creation Failed, Check Input Fields');
} }
}, (reason) => { }, (reason) => {
alert("add customer failed for " + reason); alert('Add customer failed: ' + reason);
}); });
}} }
}
editCustomer(id, name, billTo, add1, add2, city, state, zip, zip4, email, phone, phExt, fax, ref) { editCustomer(id, name, billTo, add1, add2, city, state, zip, zip4, email, phone, phExt, fax, ref) {
if (fax.length > 0 && fax.length < 14) { if (fax.length > 0 && fax.length < 14) {
alert('Invalid fax.'); alert('Invalid fax.');
} else if (phone.length > 0 && phone.length < 14) { } else if (phone.length > 0 && phone.length < 14) {
alert('Invalid phone.'); alert('Invalid phone.');
} else if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email) == false) { } else if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email) === false) {
alert("You have entered an invalid email address!") alert('You have entered an invalid email address!');
} else { } else {
const customerData = { const customerData = {
"customerId": id, 'customerId': id,
"customerName": name, 'customerName': name,
"billToDept": billTo, 'billToDept': billTo,
"add1": add1, 'add1': add1,
"add2": add2, 'add2': add2,
"city": city, 'city': city,
"state": state, 'state': state,
"zip": zip, 'zip': zip,
"ziplast4": zip4, 'ziplast4': zip4,
"email": email, 'email': email,
"phone": phone, 'phone': phone,
"phExt": phExt, 'phExt': phExt,
"fax": fax 'fax': fax
}; };
this.astuteClientService.updateCustomer(id, customerData).then((data) => { this.astuteClientService.updateCustomer(id, customerData).then((data) => {
@ -163,29 +187,133 @@ export class CustomerComponent implements OnInit {
this.refreshData(); this.refreshData();
ref.close(); ref.close();
} else { } else {
alert("Customer Updating Failed, Check Input Fields") alert('Customer Updating Failed, Check Input Fields');
} }
}, (reason) => { }, (reason) => {
alert("update customer failed for " + reason); alert('Update customer failed: ' + reason);
}); });
}} }
}
deleteCustomer (customerId) { deleteCustomer(customerId) {
if (customerId) {
if (confirm('Are you sure you want to delete customer, ' + customerId)) { if (confirm('Are you sure you want to delete customer, ' + customerId)) {
this.astuteClientService.deleteCustomer(customerId).then((data) => { this.astuteClientService.deleteCustomer(customerId).then((data) => {
if (data) { if (data) {
console.log('Customer, ' + customerId + ' successfully deleted'); console.log('Customer, ' + customerId + ' successfully deleted');
this.refreshData(); this.refreshData();
} else { } else {
alert ('Error in deleting; Customer, ' + customerId + ' has not been deleted'); alert('Error in deleting; Customer, ' + customerId + ' has not been deleted');
} }
}); });
} }
} else {
alert('Choose a customer first!');
}
} }
// wrappers for contact service methods (only inline editing)
createEmptyContact() {
const newContactData = {
address: '',
customerId: this.selected.customerId,
email: 'example@email.com',
fax: null,
mobile: null,
name: '',
phExt: null,
title: '',
workPhone: null
};
console.log(newContactData);
this.astuteClientService.createCustomerContact(newContactData).then ((data) => {
if (!data) {
alert('Contact Creation Failed, Check Input Fields');
} else {
this.refreshContactData(this.selected.customerId);
}
}, (reason) => {
alert('Create customer failed: ' + reason);
});
}
deleteContact() {
const selectedNodes = this.contactGridApi.getSelectedNodes();
if (selectedNodes.length > 0) {
if (confirm('Are you sure?')) {
const selec = selectedNodes.map(node => node.data)[0];
this.astuteClientService.deleteCustomerContact(selec.customerId, selec.contactId).then((data) => {
if (data) {
this.refreshContactData(selec.customerId);
} else {
alert('Contact Deletion Failed, Check Input Fields');
}
}, (reason) => {
alert('Delete customer failed: ' + reason);
});
}
} else {
alert('Choose a contact first!');
}
}
// for inline updating
updateRow(event) {
const eventData = event.data;
console.log(eventData);
if (eventData.fax.length > 0 && eventData.fax.length < 14) {
alert('Invalid fax.');
} else if (eventData.phone.length > 0 && eventData.phone.length < 14) {
alert('Invalid phone.');
} else if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(eventData.email) === false) {
alert('You have entered an invalid email address!');
} else {
this.astuteClientService.updateCustomer(eventData.customerId, eventData).then((data) => {
if (data) {
this.refreshData();
} else {
alert('Customer Updating Failed, Check Input Fields');
}
}, (reason) => {
alert('Update customer failed: ' + reason);
});
}
this.refreshData();
}
updateContactRow(event) {
console.log(event);
const eventData = event.data;
// if (eventData.fax % 10 < 14) {
// alert('Invalid fax.');
// } else if (eventData.mobile % 10 < 14) {
// alert('Invalid phone.');
// } else if (eventData.workPhone % 10 < 14) {
// alert('Invalid work phone.');
// } else
if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(eventData.email) === false) {
alert('You have entered an invalid email address!');
} else {
this.astuteClientService.updateCustomerContact(eventData.customerId, eventData).then((data) => {
if (!data) {
alert('Customer Updating Failed, Check Input Fields');
} else {
this.contactsData = this.astuteClientService.getCustomerContacts(eventData.customerId);
}
}, (reason) => {
alert('Update customer failed: ' + reason);
});
}
this.contactsData = this.astuteClientService.getCustomerContacts(eventData.customerId);
}
// opening and closing modal-form components
open(ref) { open(ref) {
this.getSelectedRows(); // this.getSelectedRows();
if (this.selected) {
this.contactsData = this.astuteClientService.getCustomerContacts(this.selected.customerId);
}
ref.open(); ref.open();
} }
@ -193,10 +321,32 @@ export class CustomerComponent implements OnInit {
ref.close(); ref.close();
} }
// refreshes corresponding data
refreshData() { refreshData() {
this.rowData = this.astuteClientService.getCustomers(); this.rowData = this.astuteClientService.getCustomers();
this.selected = null;
this.astuteClientService.getCustomers().then((data) => { this.astuteClientService.getCustomers().then((data) => {
this.customers = data; this.customers = data;
}); });
} }
refreshContactData(customerId) {
this.contactsData = this.astuteClientService.getCustomerContacts(customerId);
}
// on each grid ready: sets api's and enable auto-resizing
onGridReady(evt) {
this.gridApi = evt.api;
this.gridColumnApi = evt.columnApi;
}
onContactGridReady(evt) {
this.contactGridApi = evt.api;
this.contactColumnApi = evt.columnApi;
}
resizeColumns(evt) {
evt.columnApi.autoSizeAllColumns();
}
} }

View File

@ -21,19 +21,23 @@
</div> </div>
<div class="row"> <div class="row">
<app-app-box class="m-3" [color]="'#00bcd4'" [name]="'Customer'" [symbol]="'supervised_user_circle'" routerLink="/customer"> <app-app-box class="m-3" [color]="'#00bcd4'" [name]="'Customer'" [symbol]="'supervised_user_circle'" routerLink="/customer">
<h6 class="card-subtitle mb-2 text-muted">Go here to add or edit customers</h6> <h6 class="card-subtitle mb-2 text-muted">Add or edit customers!</h6>
<!--<i class="material-icons text-info">info</i> --> <!--<i class="material-icons text-info">info</i> -->
</app-app-box> </app-app-box>
<app-app-box class="m-3" [color]="'#f44336'" [name]="'Sales Order'" [symbol]="'assignment'" routerLink="/sales-order"> <app-app-box class="m-3" [color]="'#f44336'" [name]="'Sales Order'" [symbol]="'assignment'" routerLink="/sales-order">
<h6 class="card-subtitle mb-2 text-muted">Go here to add sales orders or make change orders</h6> <h6 class="card-subtitle mb-2 text-muted">Add sales orders or make change orders!</h6>
<!--<i class="material-icons text-info">info</i> Medical Records Application--> <!--<i class="material-icons text-info">info</i> Medical Records Application-->
</app-app-box> </app-app-box>
<app-app-box class="m-3" [color]="'#4caf50'" [name]="'Invoice'" [symbol]="'view_headline'" routerLink="/invoice"> <app-app-box class="m-3" [color]="'#4fd581'" [name]="'Invoice'" [symbol]="'view_headline'" routerLink="/invoice">
<h6 class="card-subtitle mb-2 text-muted">Go here to interact with invoices</h6> <h6 class="card-subtitle mb-2 text-muted">Interact with invoices!</h6>
<!--<i class="material-icons text-danger">info</i> Not yet implemented--> <!--<i class="material-icons text-danger">info</i> Not yet implemented-->
</app-app-box> </app-app-box>
<app-app-box class="m-3" [name]="'Invoice Payment'" [symbol]="'attach_money'" routerLink="/invoice-payment"> <app-app-box class="m-3" [color]="'#a5e076'" [name]="'Invoice Payment'" [symbol]="'attach_money'" routerLink="/invoice-payment">
<h6 class="card-subtitle mb-2 text-muted">Go here to enter payments received</h6> <h6 class="card-subtitle mb-2 text-muted">Enter payments received!</h6>
<!--<i class="material-icons text-danger">info</i> Not yet implemented-->
</app-app-box>
<app-app-box class="m-3" [color]="'#feaa6a'" [name]="'Settings'" [symbol]="'settings'" routerLink="/settings">
<h6 class="card-subtitle mb-2 text-muted">Change your settings!</h6>
<!--<i class="material-icons text-danger">info</i> Not yet implemented--> <!--<i class="material-icons text-danger">info</i> Not yet implemented-->
</app-app-box> </app-app-box>
</div> </div>

View File

@ -9,8 +9,9 @@
<a class="nav-link" [ngClass]="salesOrderActive ? 'active' : ''"routerLink="/sales-order" routerLinkActive="active">Sales Order</a> <a class="nav-link" [ngClass]="salesOrderActive ? 'active' : ''"routerLink="/sales-order" routerLinkActive="active">Sales Order</a>
<a class="nav-link" [ngClass]="invoiceActive ? 'active' : ''"routerLink="/invoice" routerLinkActive="active">Invoice</a> <a class="nav-link" [ngClass]="invoiceActive ? 'active' : ''"routerLink="/invoice" routerLinkActive="active">Invoice</a>
<a class="nav-link" [ngClass]="invoicePaymentActive ? 'active' : ''"routerLink="/invoice-payment" routerLinkActive="active">Invoice Payment</a> <a class="nav-link" [ngClass]="invoicePaymentActive ? 'active' : ''"routerLink="/invoice-payment" routerLinkActive="active">Invoice Payment</a>
<a class="nav-link" [ngClass]="serviceTypeActive ? 'active' : ''"routerLink="/service-type" routerLinkActive="active">Service Type</a> <!--<a class="nav-link" [ngClass]="serviceTypeActive ? 'active' : ''"routerLink="/service-type" routerLinkActive="active">Service Type</a>-->
<a class="nav-link" [ngClass]="logoffActive ? 'active' : ''"routerLink="/login" routerLinkActive="active">Log off</a> <!--<a class="nav-link" [ngClass]="logoffActive ? 'active' : ''"routerLink="/login" (click)="logout()" routerLinkActive="active">Log off</a>-->
<a class="nav-link" [ngClass]="settingsActive ? 'active' : ''"routerLink="/settings" routerLinkActive="active">Settings</a>
</div> </div>
</div> </div>
</nav> </nav>

View File

@ -1,4 +1,5 @@
import {Component, Input, OnInit} from '@angular/core'; import {Component, Input, OnInit} from '@angular/core';
import {AstuteClientService} from '../services/astute-client-service';
@Component({ @Component({
selector: 'app-nav-bar', selector: 'app-nav-bar',
@ -10,13 +11,25 @@ export class NavBarComponent implements OnInit {
@Input() salesOrderActive: boolean; @Input() salesOrderActive: boolean;
@Input() invoiceActive: boolean; @Input() invoiceActive: boolean;
@Input() invoicePaymentActive: boolean; @Input() invoicePaymentActive: boolean;
@Input() serviceTypeActive: boolean; // @Input() serviceTypeActive: boolean;
@Input() logoffActive: boolean; // @Input() logoffActive: boolean;
@Input() settingsActive: boolean;
constructor() { } constructor(private astuteClientService: AstuteClientService) {
}
ngOnInit() { ngOnInit() {
} }
// logout() {
// this.astuteClientService.logout().then((data) => {
// if (data) {
// alert('Logout successful');
// } else {
// alert('Logout unsuccessful');
// }
// });
// }
} }

View File

@ -7,25 +7,33 @@
#agGrid #agGrid
style="height: 500px;" style="height: 500px;"
class="ag-theme-balham" class="ag-theme-balham"
[enableColResize]="true"
[enableSorting]="true" [enableSorting]="true"
[enableFilter]="true" [enableFilter]="true"
[rowData]="rowData" [rowData]="rowData | async"
[columnDefs]="columnDefs" [columnDefs]="columnDefs"
(cellEditingStopped)="updateRow($event)"
(gridReady)="onGridReady($event)"
(rowClicked)="setSelectedRow($event)"
(rowDataChanged)="resizeColumns($event)"
rowSelection="single" rowSelection="single"
></ag-grid-angular> ></ag-grid-angular>
</div> </div>
</div> </div>
<div class="row justify-content-center mt-2"> <div class="row justify-content-center mt-2">
<div class="col-3"> <div class="col-2">
<button class="btn btn-success" style="width: 100%" (click)="open(new)">Add</button> <button class="btn btn-success" style="width: 100%" (click)="open(new)">Add</button>
</div> </div>
<div class="col-3"> <div class="col-2">
<button class="btn btn-info" style="width: 100%" (click)="open(edit)">Edit</button> <button class="btn btn-info" style="width: 100%" (click)="open(edit)">Edit</button>
</div> </div>
<div class="col-3"> <div class="col-2">
<button class="btn btn-primary" style="width: 100%" (click)="finalizePO(selected.ponum)" [disabled]="!selected?true:selected.final === 1">Finalize</button> <button class="btn btn-primary" style="width: 100%" (click)="open(editDetails)" [disabled]="!selected">Details</button>
</div> </div>
<div class="col-3"> <div class="col-2">
<button class="btn btn-success" style="width: 100%" (click)="finalizePO(selected.ponum)" [disabled]="!selected?true:selected.final === 1">Finalize</button>
</div>
<div class="col-2">
<button class="btn btn-danger" style="width: 100%" (click)="deletePO(selected.ponum)" [disabled]="!selected?true:selected.final === 0">Delete</button> <button class="btn btn-danger" style="width: 100%" (click)="deletePO(selected.ponum)" [disabled]="!selected?true:selected.final === 0">Delete</button>
</div> </div>
</div> </div>
@ -59,13 +67,13 @@
<td style="width: 20%"><span class="input-group-text">SO Number</span></td> <td style="width: 20%"><span class="input-group-text">SO Number</span></td>
<td style="width: 30%"><input type="text" class="form-control" placeholder="Internal SO Number" maxlength="40" #ponum></td> <td style="width: 30%"><input type="text" class="form-control" placeholder="Internal SO Number" maxlength="40" #ponum></td>
<td style="width: 20%"><span class="input-group-text">SO Date</span></td> <td style="width: 20%"><span class="input-group-text">SO Date</span></td>
<td style="width: 30%"><input type="date" class="form-control" [value]="getCurrDate()" (change)="printValue(podate.value)" #podate></td> <td style="width: 30%"><input type="date" class="form-control" [value]="getCurrDate()" #podate></td>
</tr> </tr>
<tr> <tr>
<td style="width: 20%"><span class="input-group-text">Contract Number</span></td> <td style="width: 20%"><span class="input-group-text">Contract Number</span></td>
<td style="width: 30%"><input type="text" class="form-control" placeholder="External Contract Number" #contractnum></td> <td style="width: 30%"><input type="text" class="form-control" placeholder="External Contract Number" #contractnum></td>
<td style="width: 20%"><span class="input-group-text">Contract Amount</span></td> <td style="width: 20%"><span class="input-group-text">Contract Amount</span></td>
<td style="width: 30%"><input type="text" class="form-control" placeholder="Derived From Details" [value]="newContractAmount | currency" #contractamt disabled></td> <td style="width: 30%"><input type="text" class="form-control" placeholder="Derived From Details" [value]="0 | currency" #contractamt disabled></td>
</tr> </tr>
<tr> <tr>
<td><span class="input-group-text">Notes</span></td> <td><span class="input-group-text">Notes</span></td>
@ -76,75 +84,42 @@
</div> </div>
<!--Detail--> <!--Detail-->
<div class="modal-body"> <!--<div class="modal-body">-->
<p class="h4 text-right">Detail</p> <!--<p class="h4 text-right">Detail</p>-->
<hr> <!--<hr>-->
<table class="table"> <!--<table class="table">-->
<thead> <!--<thead>-->
<tr> <!--<tr>-->
<th scope="col"></th> <!--<th scope="col"></th>-->
<th scope="col" style="width: 50px">#</th> <!--<th scope="col" style="width: 50px">#</th>-->
<th scope="col">Description</th> <!--<th scope="col">Description</th>-->
<th scope="col">Rate Type</th> <!--<th scope="col">Rate Type</th>-->
<th scope="col">Service Type</th> <!--<th scope="col">Service Type</th>-->
<th scope="col" style="width: 75px">Qty(#)</th> <!--<th scope="col" style="width: 75px">Qty(#)</th>-->
<th scope="col" style="width: 100px">Rate($)</th> <!--<th scope="col" style="width: 100px">Rate($)</th>-->
</tr> <!--</tr>-->
</thead> <!--</thead>-->
<tbody *ngFor="let poDetail of newPODetail; let i = index"> <!--<tbody *ngFor="let poDetail of newPODetail; let i = index">-->
<tr class="p-0 m-0"> <!--<tr class="p-0 m-0">-->
<td class="p-1 m-0"> <!--<td class="p-1 m-0">-->
<button class="btn btn-outline-danger" type="button" (click)="newPODetail.splice(i, 1);"> <!--<button class="btn btn-outline-danger" type="button" (click)="newPODetail.splice(i, 1);">-->
- <!-- - -->
</button> <!--</button>-->
</td>
<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="poDetail.lineItemNo" (change)="onNewCellChange(i, 'lineItemNo', lineItemNo.value)" #lineItemNo></td>
<td class="p-0 m-0">
<textarea style="height: 36px" class="form-control cell" [value]="poDetail.serviceDesc" (change)="onNewCellChange(i, 'serviceDesc', serviceDesc.value)" #serviceDesc></textarea>
<!--<input type="text" class="form-control cell" [value]="poDetail.serviceDesc" (change)="onNewCellChange(i, 'serviceDesc', serviceDesc.value)" #serviceDesc>-->
</td>
<td class="p-0 m-0">
<select class="form-control cell" [value]="poDetail.feeTypeId" (change)="onNewCellChange(i, 'feeTypeId', feeTypeId.value)" #feeTypeId>
<option value="1">Fixed Fee</option>
<option value="2">Hourly</option>
</select>
</td>
<td class="p-0 m-0">
<select class="form-control cell" [value]="poDetail.serviceTypeId" (change)="onNewCellChange(i, 'serviceTypeId', serviceTypeId.value)" #serviceTypeId>
<option value="1">Study</option>
<option value="2">Design</option>
<option value="3">Peer Review</option>
<option value="4">Cost Estimation</option>
<option value="5">Forensic Investigation</option>
</select>
</td>
<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="+poDetail.qty" (change)="onNewCellChange(i, 'qty', qty.value); onNewCellChange(i, 'remainingQty', qty.value * fee.value); updateNewContractAmt();" #qty></td>
<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="+poDetail.fee" (change)="onNewCellChange(i, 'fee', fee.value); onNewCellChange(i, 'remainingQty', qty.value * fee.value); updateNewContractAmt();" #fee></td>
<!--<td class="p-0 m-0"><input type="text" class="form-control cell" [value]="poDetail.remainingQty" [id]="'remainingQty' + i"></td>-->
</tr>
</tbody>
<tr class="p-0 m-0">
<td class="p-1 m-0">
<button class="btn btn-success" type="button"
[disabled]="!ponum.value"
(click)="pushOntoNewDetail(newPODetail.length + 1, ponum.value, '', '1', '1', 1, 0, 0)">
<!--(click)="pushOntoNewDetail((lineItemNo) ? lineItemNo.value + 1: 1, ponum.value, serviceDesc.value,-->
<!--feeTypeId.value, serviceTypeId.value, qty.value, fee.value, 0)">-->
+</button>
</td>
<!--<td class="p-0 m-0">-->
<!--<input type="number" class="form-control cell" [value]="(selectedPODetail.length) ? selectedPODetail[selectedPODetail.length-1].lineItemNo + 1: 1" #lineItemNo>-->
<!--</td>--> <!--</td>-->
<!--<td class="p-0 m-0"><input type="text" class="form-control cell" [value]="''" #serviceDesc></td>--> <!--<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="poDetail.lineItemNo" (change)="onNewCellChange(i, 'lineItemNo', lineItemNo.value)" #lineItemNo></td>-->
<!--<td class="p-0 m-0">--> <!--<td class="p-0 m-0">-->
<!--<select class="form-control cell" [value]="1" #feeTypeId>--> <!--<textarea style="height: 36px" class="form-control cell" [value]="poDetail.serviceDesc" (change)="onNewCellChange(i, 'serviceDesc', serviceDesc.value)" #serviceDesc></textarea>-->
<!--&lt;!&ndash;<input type="text" class="form-control cell" [value]="poDetail.serviceDesc" (change)="onNewCellChange(i, 'serviceDesc', serviceDesc.value)" #serviceDesc>&ndash;&gt;-->
<!--</td>-->
<!--<td class="p-0 m-0">-->
<!--<select class="form-control cell" [value]="poDetail.feeTypeId" (change)="onNewCellChange(i, 'feeTypeId', feeTypeId.value)" #feeTypeId>-->
<!--<option value="1">Fixed Fee</option>--> <!--<option value="1">Fixed Fee</option>-->
<!--<option value="2">Hourly</option>--> <!--<option value="2">Hourly</option>-->
<!--</select>--> <!--</select>-->
<!--</td>--> <!--</td>-->
<!--<td class="p-0 m-0">--> <!--<td class="p-0 m-0">-->
<!--<select class="form-control cell" [value]="1" #serviceTypeId>--> <!--<select class="form-control cell" [value]="poDetail.serviceTypeId" (change)="onNewCellChange(i, 'serviceTypeId', serviceTypeId.value)" #serviceTypeId>-->
<!--<option value="1">Study</option>--> <!--<option value="1">Study</option>-->
<!--<option value="2">Design</option>--> <!--<option value="2">Design</option>-->
<!--<option value="3">Peer Review</option>--> <!--<option value="3">Peer Review</option>-->
@ -152,13 +127,46 @@
<!--<option value="5">Forensic Investigation</option>--> <!--<option value="5">Forensic Investigation</option>-->
<!--</select>--> <!--</select>-->
<!--</td>--> <!--</td>-->
<!--<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="1" #qty></td>--> <!--<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="+poDetail.qty" (change)="onNewCellChange(i, 'qty', qty.value); onNewCellChange(i, 'remainingQty', qty.value * fee.value); updateNewContractAmt();" #qty></td>-->
<!--<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="0" #fee></td>--> <!--<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="+poDetail.fee" (change)="onNewCellChange(i, 'fee', fee.value); onNewCellChange(i, 'remainingQty', qty.value * fee.value); updateNewContractAmt();" #fee></td>-->
<!--&lt;!&ndash;<td class="p-0 m-0"><input type="number" class="form-control cell" #remainingQty></td>&ndash;&gt;--> <!--&lt;!&ndash;<td class="p-0 m-0"><input type="text" class="form-control cell" [value]="poDetail.remainingQty" [id]="'remainingQty' + i"></td>&ndash;&gt;-->
</tr> <!--</tr>-->
</tbody> <!--</tbody>-->
</table> <!--<tr class="p-0 m-0">-->
</div> <!--<td class="p-1 m-0">-->
<!--<button class="btn btn-success" type="button"-->
<!--[disabled]="!ponum.value"-->
<!--(click)="pushOntoNewDetail(newPODetail.length + 1, ponum.value, '', '1', '1', 1, 0, 0)">-->
<!--&lt;!&ndash;(click)="pushOntoNewDetail((lineItemNo) ? lineItemNo.value + 1: 1, ponum.value, serviceDesc.value,&ndash;&gt;-->
<!--&lt;!&ndash;feeTypeId.value, serviceTypeId.value, qty.value, fee.value, 0)">&ndash;&gt;-->
<!--+</button>-->
<!--</td>-->
<!--&lt;!&ndash;<td class="p-0 m-0">&ndash;&gt;-->
<!--&lt;!&ndash;<input type="number" class="form-control cell" [value]="(selectedPODetail.length) ? selectedPODetail[selectedPODetail.length-1].lineItemNo + 1: 1" #lineItemNo>&ndash;&gt;-->
<!--&lt;!&ndash;</td>&ndash;&gt;-->
<!--&lt;!&ndash;<td class="p-0 m-0"><input type="text" class="form-control cell" [value]="''" #serviceDesc></td>&ndash;&gt;-->
<!--&lt;!&ndash;<td class="p-0 m-0">&ndash;&gt;-->
<!--&lt;!&ndash;<select class="form-control cell" [value]="1" #feeTypeId>&ndash;&gt;-->
<!--&lt;!&ndash;<option value="1">Fixed Fee</option>&ndash;&gt;-->
<!--&lt;!&ndash;<option value="2">Hourly</option>&ndash;&gt;-->
<!--&lt;!&ndash;</select>&ndash;&gt;-->
<!--&lt;!&ndash;</td>&ndash;&gt;-->
<!--&lt;!&ndash;<td class="p-0 m-0">&ndash;&gt;-->
<!--&lt;!&ndash;<select class="form-control cell" [value]="1" #serviceTypeId>&ndash;&gt;-->
<!--&lt;!&ndash;<option value="1">Study</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="4">Cost Estimation</option>&ndash;&gt;-->
<!--&lt;!&ndash;<option value="5">Forensic Investigation</option>&ndash;&gt;-->
<!--&lt;!&ndash;</select>&ndash;&gt;-->
<!--&lt;!&ndash;</td>&ndash;&gt;-->
<!--&lt;!&ndash;<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="1" #qty></td>&ndash;&gt;-->
<!--&lt;!&ndash;<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="0" #fee></td>&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash;<td class="p-0 m-0"><input type="number" class="form-control cell" #remainingQty></td>&ndash;&gt;&ndash;&gt;-->
<!--</tr>-->
<!--</tbody>-->
<!--</table>-->
<!--</div>-->
<div class="modal-footer"> <div class="modal-footer">
<button class="btn btn-success" type="button" <button class="btn btn-success" type="button"
@ -206,7 +214,7 @@
<td style="width: 20%"><span class="input-group-text">Contract Number</span></td> <td style="width: 20%"><span class="input-group-text">Contract Number</span></td>
<td style="width: 30%"><input type="text" class="form-control" placeholder="Contract Number" [value]="selected.contractNum" #contractnum></td> <td style="width: 30%"><input type="text" class="form-control" placeholder="Contract Number" [value]="selected.contractNum" #contractnum></td>
<td style="width: 20%"><span class="input-group-text">Contract Amount</span></td> <td style="width: 20%"><span class="input-group-text">Contract Amount</span></td>
<td style="width: 30%"><input type="text" class="form-control" placeholder="Contract Amount" [value]="editContractAmount | currency" #contractamt disabled></td> <td style="width: 30%"><input type="text" class="form-control" placeholder="Contract Amount" [value]="selected.contractAmtString" #contractamt disabled></td>
</tr> </tr>
<tr> <tr>
<td><span class="input-group-text">Notes</span></td> <td><span class="input-group-text">Notes</span></td>
@ -276,89 +284,90 @@
<!--serviceTypeId--> <!--serviceTypeId-->
<!--Detail--> <!--Detail-->
<div class="modal-body" *ngIf="selectedPODetail"> <!--<div class="modal-body" *ngIf="selectedPODetail">-->
<p class="h4 text-right">Detail</p> <!--<p class="h4 text-right">Detail</p>-->
<hr> <!--<hr>-->
<table class="table">
<thead> <!--<table class="table">-->
<tr> <!--<thead>-->
<th scope="col" style="width: 50px">#</th> <!--<tr>-->
<!--<th scope="col">Purchase Order Number</th>--> <!--<th scope="col" style="width: 50px">#</th>-->
<th scope="col">Description</th> <!--&lt;!&ndash;<th scope="col">Purchase Order Number</th>&ndash;&gt;-->
<th scope="col">Rate Type</th> <!--<th scope="col">Description</th>-->
<th scope="col">Service Type</th> <!--<th scope="col">Rate Type</th>-->
<th scope="col" style="width: 75px">Quantity</th> <!--<th scope="col">Service Type</th>-->
<th scope="col" style="width: 100px">Rate</th> <!--<th scope="col" style="width: 75px">Quantity</th>-->
<!--<th scope="col">Remaining Quantity</th>--> <!--<th scope="col" style="width: 100px">Rate</th>-->
</tr> <!--&lt;!&ndash;<th scope="col">Remaining Quantity</th>&ndash;&gt;-->
</thead> <!--</tr>-->
<!--<tbody>--> <!--</thead>-->
<tbody *ngFor="let poDetail of selectedPODetail; let i = index"> <!--&lt;!&ndash;<tbody>&ndash;&gt;-->
<tr class="p-0 m-0"> <!--<tbody *ngFor="let poDetail of selectedPODetail; let i = index">-->
<!--<tr class="p-0 m-0">-->
<!--&lt;!&ndash;<td class="p-0 m-0">&ndash;&gt;-->
<!--&lt;!&ndash;<button class="btn btn-outline-danger" type="button" (click)="selectedPODetail.splice(i, 1);">&ndash;&gt;-->
<!--&lt;!&ndash; - &ndash;&gt;-->
<!--&lt;!&ndash;</button>&ndash;&gt;-->
<!--&lt;!&ndash;</td>&ndash;&gt;-->
<!--<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="poDetail.lineItemNo" (change)="onSelectedCellChange(i, 'lineItemNo', lineItemNo.value)" #lineItemNo></td>-->
<!--&lt;!&ndash;<td class="p-0"><input type="text" class="form-control cell" [value]="poDetail.ponum"></td>&ndash;&gt;-->
<!--<td class="p-0 m-0">--> <!--<td class="p-0 m-0">-->
<!--<button class="btn btn-outline-danger" type="button" (click)="selectedPODetail.splice(i, 1);">--> <!--<textarea style="height: 36px" class="form-control cell" [value]="poDetail.serviceDesc" (change)="onSelectedCellChange(i, 'serviceDesc', serviceDesc.value)" #serviceDesc></textarea>-->
<!-- - --> <!--&lt;!&ndash;<input type="text" class="form-control cell" [value]="poDetail.serviceDesc" (change)="onSelectedCellChange(i, 'serviceDesc', serviceDesc.value)" #serviceDesc>&ndash;&gt;-->
<!--</button>-->
<!--</td>--> <!--</td>-->
<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="poDetail.lineItemNo" (change)="onSelectedCellChange(i, 'lineItemNo', lineItemNo.value)" #lineItemNo></td>
<!--<td class="p-0"><input type="text" class="form-control cell" [value]="poDetail.ponum"></td>-->
<td class="p-0 m-0">
<textarea style="height: 36px" class="form-control cell" [value]="poDetail.serviceDesc" (change)="onSelectedCellChange(i, 'serviceDesc', serviceDesc.value)" #serviceDesc></textarea>
<!--<input type="text" class="form-control cell" [value]="poDetail.serviceDesc" (change)="onSelectedCellChange(i, 'serviceDesc', serviceDesc.value)" #serviceDesc>-->
</td>
<td class="p-0 m-0">
<select class="form-control cell" [value]="poDetail.feeTypeId" (change)="onSelectedCellChange(i, 'feeTypeId', feeTypeId.value)" #feeTypeId>
<option value="1">Fixed Fee</option>
<option value="2">Hourly</option>
</select>
<!--<input type="number" class="form-control cell" [value]="poDetail.feeTypeId">-->
</td>
<td class="p-0 m-0">
<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="">Study</option>-->
<!--<option value="2">Design</option>-->
<!--<option value="3">Peer Review</option>-->
<!--<option value="4">Cost Estimation</option>-->
<!--<option value="5">Forensic Investigation</option>-->
</select>
<!--<input type="number" class="form-control cell" [value]="poDetail.serviceTypeId" #serviceTypeId>-->
</td>
<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="+poDetail.qty" (change)="onSelectedCellChange(i, 'qty', qty.value); onSelectedCellChange(i, 'remainingQty', qty.value * fee.value); updateEditContractAmt();" #qty></td>
<td class="p-0 m-0"><input type="text" class="form-control cell" [value]="+poDetail.fee | currency" (change)="onSelectedCellChange(i, 'fee', fee.value); onSelectedCellChange(i, 'remainingQty', qty.value * fee.value); updateEditContractAmt();" #fee></td>
<!--<td class="p-0 m-0"><input type="text" class="form-control cell" [value]="poDetail.remainingQty" [id]="'remainingQty' + i"></td>-->
</tr>
</tbody>
<tr class="p-0 m-0">
<td class="p-1 m-0">
<button class="btn btn-success" type="button"
(click)="pushOntoSelectedDetail(selectedPODetail.length + 1, ponum.value, '', '1', '1', 1, 0, 0)">
<!--(click)="pushOntoSelectedDetail(selectedPODetail[selectedPODetail.length-1].lineItemNo + 1, selected.ponum, serviceDesc.value,-->
<!--feeTypeId.value, serviceTypeId.value, qty.value, fee.value, 0)">-->
+</button>
</td>
<!--<td class="p-0 m-0"><input type="text" class="form-control cell" [value]="''" #serviceDesc></td>-->
<!--<td class="p-0 m-0">--> <!--<td class="p-0 m-0">-->
<!--<select class="form-control cell" [value]="1" #feeTypeId>--> <!--<select class="form-control cell" [value]="poDetail.feeTypeId" (change)="onSelectedCellChange(i, 'feeTypeId', feeTypeId.value)" #feeTypeId>-->
<!--<option value="1">Fixed Fee</option>--> <!--<option value="1">Fixed Fee</option>-->
<!--<option value="2">Hourly</option>--> <!--<option value="2">Hourly</option>-->
<!--</select>--> <!--</select>-->
<!--&lt;!&ndash;<input type="number" class="form-control cell" [value]="poDetail.feeTypeId">&ndash;&gt;-->
<!--</td>--> <!--</td>-->
<!--<td class="p-0 m-0">--> <!--<td class="p-0 m-0">-->
<!--<select class="form-control cell" [value]="1" #serviceTypeId>--> <!--<select class="form-control cell" [value]="poDetail.serviceTypeId" (change)="onSelectedCellChange(i, 'serviceTypeId', serviceTypeId.value)" #serviceTypeId>-->
<!--<option value="1">Study</option>--> <!--<option [value]="serviceType.serviceTypeId" *ngFor="let serviceType of serviceTypes">{{serviceType.desc}}</option>-->
<!--<option value="2">Design</option>--> <!--&lt;!&ndash;<option value="">Study</option>&ndash;&gt;-->
<!--<option value="3">Peer Review</option>--> <!--&lt;!&ndash;<option value="2">Design</option>&ndash;&gt;-->
<!--<option value="4">Cost Estimation</option>--> <!--&lt;!&ndash;<option value="3">Peer Review</option>&ndash;&gt;-->
<!--<option value="5">Forensic Investigation</option>--> <!--&lt;!&ndash;<option value="4">Cost Estimation</option>&ndash;&gt;-->
<!--&lt;!&ndash;<option value="5">Forensic Investigation</option>&ndash;&gt;-->
<!--</select>--> <!--</select>-->
<!--&lt;!&ndash;<input type="number" class="form-control cell" [value]="poDetail.serviceTypeId" #serviceTypeId>&ndash;&gt;-->
<!--</td>--> <!--</td>-->
<!--<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="0" #qty></td>--> <!--<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="+poDetail.qty" (change)="onSelectedCellChange(i, 'qty', qty.value); onSelectedCellChange(i, 'remainingQty', qty.value * fee.value); updateEditContractAmt();" #qty></td>-->
<!--<td class="p-0 m-0"><input type="number" class="form-control cell" #remainingQty></td>--> <!--<td class="p-0 m-0"><input type="text" class="form-control cell" [value]="+poDetail.fee | currency" (change)="onSelectedCellChange(i, 'fee', fee.value); onSelectedCellChange(i, 'remainingQty', qty.value * fee.value); updateEditContractAmt();" #fee></td>-->
</tr> <!--&lt;!&ndash;<td class="p-0 m-0"><input type="text" class="form-control cell" [value]="poDetail.remainingQty" [id]="'remainingQty' + i"></td>&ndash;&gt;-->
</tbody> <!--</tr>-->
</table> <!--</tbody>-->
</div> <!--<tr class="p-0 m-0">-->
<!--<td class="p-1 m-0">-->
<!--<button class="btn btn-success" type="button"-->
<!--(click)="pushOntoSelectedDetail(selectedPODetail.length + 1, ponum.value, '', '1', '1', 1, 0, 0)">-->
<!--&lt;!&ndash;(click)="pushOntoSelectedDetail(selectedPODetail[selectedPODetail.length-1].lineItemNo + 1, selected.ponum, serviceDesc.value,&ndash;&gt;-->
<!--&lt;!&ndash;feeTypeId.value, serviceTypeId.value, qty.value, fee.value, 0)">&ndash;&gt;-->
<!--+</button>-->
<!--</td>-->
<!--&lt;!&ndash;<td class="p-0 m-0"><input type="text" class="form-control cell" [value]="''" #serviceDesc></td>&ndash;&gt;-->
<!--&lt;!&ndash;<td class="p-0 m-0">&ndash;&gt;-->
<!--&lt;!&ndash;<select class="form-control cell" [value]="1" #feeTypeId>&ndash;&gt;-->
<!--&lt;!&ndash;<option value="1">Fixed Fee</option>&ndash;&gt;-->
<!--&lt;!&ndash;<option value="2">Hourly</option>&ndash;&gt;-->
<!--&lt;!&ndash;</select>&ndash;&gt;-->
<!--&lt;!&ndash;</td>&ndash;&gt;-->
<!--&lt;!&ndash;<td class="p-0 m-0">&ndash;&gt;-->
<!--&lt;!&ndash;<select class="form-control cell" [value]="1" #serviceTypeId>&ndash;&gt;-->
<!--&lt;!&ndash;<option value="1">Study</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="4">Cost Estimation</option>&ndash;&gt;-->
<!--&lt;!&ndash;<option value="5">Forensic Investigation</option>&ndash;&gt;-->
<!--&lt;!&ndash;</select>&ndash;&gt;-->
<!--&lt;!&ndash;</td>&ndash;&gt;-->
<!--&lt;!&ndash;<td class="p-0 m-0"><input type="number" class="form-control cell" [value]="0" #qty></td>&ndash;&gt;-->
<!--&lt;!&ndash;<td class="p-0 m-0"><input type="number" class="form-control cell" #remainingQty></td>&ndash;&gt;-->
<!--</tr>-->
<!--</tbody>-->
<!--</table>-->
<!--</div>-->
<div class="modal-footer"> <div class="modal-footer">
<button class="btn btn-success" type="button" <button class="btn btn-success" type="button"
@ -385,3 +394,39 @@
</div> </div>
</div> </div>
</app-modal-form> </app-modal-form>
<!--MODAL: po details-->
<app-modal-form [title]="'Details of ' + (selected ? selected.ponum: '')" #editDetails>
<div class="modal-body">
<div class="container-fluid">
<div class="row">
<div class="col-12 align-items-end">
<ag-grid-angular
style="height: 350px;"
class="ag-theme-balham"
[enableColResize]="true"
[enableSorting]="true"
[enableFilter]="true"
[rowData]="selectedPODetail | async"
[columnDefs]="detailColumnDefs"
(cellEditingStopped)="updateDetailRow($event)"
(gridReady)="onDetailGridReady($event)"
(rowDataChanged)="resizeColumns($event)"
rowSelection="single"
></ag-grid-angular>
</div>
</div>
<hr>
<div class="row">
<div class="col-12">
<h4 align="end">Total Cost: {{contractAmount | currency}}</h4>
</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>

View File

@ -1,6 +1,6 @@
import {Component, OnInit, ViewChild} from '@angular/core'; import {Component, OnInit, ViewChild} from '@angular/core';
import {AstuteClientService} from '../services/astute-client-service'; import {AstuteClientService} from '../services/astute-client-service';
import {formatCurrency} from "@angular/common"; import {formatCurrency} from '@angular/common';
@Component({ @Component({
selector: 'app-sales-order', selector: 'app-sales-order',
@ -8,225 +8,335 @@ import {formatCurrency} from "@angular/common";
styleUrls: ['./sales-order.component.css'] styleUrls: ['./sales-order.component.css']
}) })
export class SalesOrderComponent implements OnInit { export class SalesOrderComponent implements OnInit {
@ViewChild('agGrid') agGrid; // both of the grid api's
selected = null; gridApi;
selectedPODetail = []; gridColumnApi;
newPODetail = []; detailGridApi;
newContractAmount = 0; detailColumnApi;
editContractAmount = 0;
// one time fetch meta-data
customers; customers;
pos;
serviceTypes; serviceTypes;
serviceNames = [];
rateTypes = [];
rateNames = [];
// data for SO grid
rowData: any;
columnDefs = [ columnDefs = [
{headerName: 'Project Number', field: 'astuteProjectNumber'}, {headerName: 'Project Number', field: 'astuteProjectNumber', editable: true},
{headerName: 'SO Number', field: 'ponum'}, {headerName: 'SO Number', field: 'ponum'},
// {headerName: 'Customer ID', field: 'customerId'}, // {headerName: 'Customer ID', field: 'customerId'},
{headerName: 'Customer Name', field: 'customerName'}, {headerName: 'Customer Name', field: 'customerName'},
{headerName: 'Contract Number', field: 'contractNum'}, {headerName: 'Contract Number', field: 'contractNum', editable: true},
{headerName: 'SO Title', field: 'title'}, {headerName: 'SO Title', field: 'title', editable: true},
{headerName: 'Contract Amount', field: 'contractAmt'}, {headerName: 'Contract Amount', field: 'contractAmtString'},
{headerName: 'SO Date', field: 'podate'}, // {headerName: 'Contract Amount', field: 'contractAmt'},
{headerName: 'SO Date', field: 'podate', editable: true},
{headerName: '# of Invoice', field: 'invoiceSequence'}, {headerName: '# of Invoice', field: 'invoiceSequence'},
{headerName: 'notes', field: 'notes'} {headerName: 'notes', field: 'notes', editable: true, cellEditor: 'agLargeTextCellEditor'}
// {headerName: 'oneInvInDraft', field: 'oneInvInDraft'} // {headerName: 'oneInvInDraft', field: 'oneInvInDraft'}
]; ];
rowData: any; 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) { constructor(private astuteClientService: AstuteClientService) {
} }
ngOnInit() { ngOnInit() {
this.refreshData();
this.astuteClientService.getServiceTypes().then((d) => { this.astuteClientService.getServiceTypes().then((d) => {
if (d) { if (d) {
this.serviceTypes = d; this.serviceTypes = d;
this.serviceTypes.forEach((type) => {
this.serviceNames.push(type.serviceTypeDesc);
});
// console.log(this.serviceNames);
} else { } else {
alert ('get service types failed'); 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);
}); });
} }
printValue(val) {
console.log(val); // callback for grid selection
setSelectedRow(event) {
if (event) {
this.selected = event.data;
} }
gridOptions = { this.selectedPODetail = this.astuteClientService.getPODetail(this.selected.ponum).then((data) => {
onRowClicked: (event) => { if (data) {
this.getSelectedRows(); 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) { addPo(projNum, ponum, podate, customerid, contractnum, contractamt, title, notes, ref) {
const poData = { const poData = {
"astuteProjectNumber": projNum, 'astuteProjectNumber': projNum,
"poNum": ponum, 'poNum': ponum,
"podate": podate, 'podate': podate,
"customerId": customerid, 'customerId': customerid,
"contractNum": contractnum, 'contractNum': contractnum,
"contractAmt": contractamt, 'contractAmt': contractamt,
"title": title, 'title': title,
"notes": notes, 'notes': notes
} };
console.log(poData); // console.log(poData);
this.astuteClientService.createPO(poData).then((data) => { this.astuteClientService.createPO(poData).then((data) => {
if (data) { if (data) {
this.refreshData(); this.refreshData();
this.addPODetail(this.newPODetail); // this.addPODetail(this.newPODetail);
ref.close(); ref.close();
} else { } else {
alert("PO Creation failed, check input fields"); alert('SO Creation failed, check input fields');
} }
}, (reason) => { }, (reason) => {
alert("add po failed for " + reason); alert('Add SO failed for ' + reason);
}); });
} }
addPODetail(details) {
if (details.length) {
console.log(details[0]);
this.astuteClientService.createPODetail(details[0]).then((data) => {
if (data) {
details.splice(0, 1);
this.addPODetail(details);
} else {
alert("add detail failed");
}
});
} else {
this.newPODetail = [];
}
}
editPo(projNum, ponum, podate, contractnum, contractamt, title, notes, ref) { editPo(projNum, ponum, podate, contractnum, contractamt, title, notes, ref) {
const poData = { const poData = {
"astuteProjectNumber": projNum, 'astuteProjectNumber': projNum,
"poNum": ponum, 'poNum': ponum,
"podate": podate, 'podate': podate,
"contractNum": contractnum, 'contractNum': contractnum,
"contractAmt": contractamt, 'contractAmt': contractamt,
"title": title, 'title': title,
"notes": notes, 'notes': notes,
} };
console.log(poData); // console.log(poData);
this.astuteClientService.updatePO(ponum, poData).then((data) => { this.astuteClientService.updatePO(ponum, poData).then((data) => {
if (data) { if (data) {
this.refreshData(); this.refreshData();
this.editPODetail(this.selectedPODetail); // this.editPODetail(this.selectedPODetail);
ref.close(); ref.close();
} else { } else {
alert("PO updating failed, check input fields"); alert('SO updating failed, check input fields');
} }
}, (reason) => { }, (reason) => {
alert("update po failed for " + reason); alert('Update SO failed for ' + reason);
}); });
} }
editPODetail(details) {
if (details.length) {
console.log(details[0]);
this.astuteClientService.updatePODetail(details[0].ponum, details[0].lineItemNo, details[0]).then((data) => {
if (data) {
details.splice(0, 1);
this.editPODetail(details);
} else {
alert('add detail failed');
}
});
} else {
this.newPODetail = [];
}
}
finalizePO(ponum) { finalizePO(ponum) {
this.astuteClientService.finalizePO(ponum).then((data) => { this.astuteClientService.finalizePO(ponum).then((data) => {
if (data) { if (data) {
this.refreshData(); this.refreshData();
alert("PO is now final and ready to be used, you can't delete it anymore!"); alert('SO is now final and ready to be used, you can\'t delete it anymore!');
} else { } else {
alert("Finalizing PO failed, check input fields"); alert('Finalizing SO failed, check input fields');
} }
}, reason => {
alert('Finalizing SO failed: ' + reason);
}); });
} }
deletePO(ponum) { deletePO(ponum) {
if (confirm('Are you sure?')) {
this.astuteClientService.deletePO(ponum).then((data) => { this.astuteClientService.deletePO(ponum).then((data) => {
if (data) { if (data) {
this.refreshData(); this.refreshData();
} else { } else {
alert("deleting PO failed, check input fields"); 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);
}); });
} }
pushOntoSelectedDetail(lineItemNo: number, ponum, serviceDesc, feeTypeId, serviceTypeId, qty, fee, remainingQty) { // open and closing modal-form components
this.selectedPODetail.push({
'lineItemNo': lineItemNo,
'ponum': ponum,
'serviceDesc': serviceDesc,
'feeTypeId': feeTypeId,
'serviceTypeId': serviceTypeId,
'qty': qty,
'fee': fee,
'remainingQty': remainingQty
});
}
pushOntoNewDetail(lineItemNo: number, ponum, serviceDesc, feeTypeId, serviceTypeId, qty, fee, remainingQty) {
this.newPODetail.push({
'lineItemNo': lineItemNo,
'poNum': ponum,
'serviceDesc': serviceDesc,
'feeTypeId': feeTypeId,
'serviceTypeId': serviceTypeId,
'qty': qty,
'fee': fee,
'remainingQty': remainingQty
});
}
updateNewContractAmt() {
let tot = 0;
this.newPODetail.forEach((d) => {
tot += +d.qty * +d.fee;
});
this.newContractAmount = tot;
}
updateEditContractAmt() {
let tot = 0;
this.selectedPODetail.forEach((d) => {
tot += +d.qty * +d.fee;
});
this.editContractAmount = tot;
}
open(ref) { open(ref) {
this.getSelectedRows(); // this.getSelectedRows();
this.gridColumnApi.autoSizeAllColumns();
this.detailColumnApi.autoSizeAllColumns();
ref.open(); ref.open();
} }
close(ref) { close(ref) {
this.newPODetail = []; // this.newPODetail = [];
this.selectedPODetail = []; // this.selectedPODetail = [];
ref.close(); ref.close();
} }
onSelectedCellChange(row: number, col: string, value) { // refreshing data methods
this.selectedPODetail[row][col] = value; refreshData() {
console.log(this.selectedPODetail); // this.astuteClientService.getPOs().then((data) => {
} // if (data) {
// // this.pos = data;
onNewCellChange(row: number, col: string, value) { // this.rowData = data;
this.newPODetail[row][col] = value; // this.rowData.forEach((row) => {
console.log(this.newPODetail); // 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() { getCurrDate() {
const d = new Date(); const d = new Date();
return this.formatDate(d); return this.formatDate(d);
} }
formatDate(d: Date) { formatDate(d: Date) {
let month = '' + (d.getMonth() + 1), let month = '' + (d.getMonth() + 1),
day = '' + d.getDate(), day = '' + d.getDate(),
@ -240,50 +350,7 @@ export class SalesOrderComponent implements OnInit {
} }
return [year, month, day].join('-'); return [year, month, day].join('-');
} }
getCustomerNameFromId(customerId) {
getSelectedRows() {
const selectedNodes = this.agGrid.api.getSelectedNodes();
if (selectedNodes.length) {
this.selected = selectedNodes.map(node => node.data)[0];
// this.editContractAmount = +this.selected.contractAmt;
console.log(this.selected.contractNum);
this.astuteClientService.getPODetail(this.selected.ponum).then((data) => {
if (data) {
this.selectedPODetail = data;
// console.log(this.selectedPODetail);
this.updateEditContractAmt();
} else {
alert('get PO detail failed!');
}
});
} else {
this.selected = null;
this.selectedPODetail = [];
}
}
refreshData() {
this.astuteClientService.getCustomers().then((customers) => {
if (customers) {
this.customers = customers;
this.astuteClientService.getPOs().then((data) => {
if (data) {
this.pos = data;
this.rowData = data;
this.rowData.forEach((row) => {
row.customerName = this.getCustomerName(row.customerId);
row.contractAmt = formatCurrency(row.contractAmt, 'en-US', '$', 'USD');
});
}
});
} else {
alert('get Customers Failed!');
}
});
// this.rowData = this.astuteClientService.getPOs();
}
getCustomerName(customerId) {
let name = ''; let name = '';
this.customers.forEach((customer) => { this.customers.forEach((customer) => {
if (customer.customerId === customerId) { if (customer.customerId === customerId) {
@ -292,4 +359,36 @@ export class SalesOrderComponent implements OnInit {
}); });
return name; 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();
}
} }

View File

@ -8,6 +8,7 @@ export class AstuteClientService {
}; };
private authUrl = 'http://localhost:8080/astutesystem/auth'; private authUrl = 'http://localhost:8080/astutesystem/auth';
private customerUrl = 'http://localhost:8080/astutesystem/customer'; private customerUrl = 'http://localhost:8080/astutesystem/customer';
private customerContactUrl = 'http://localhost:8080/astutesystem/customer/contact';
private POUrl = 'http://localhost:8080/astutesystem/po'; private POUrl = 'http://localhost:8080/astutesystem/po';
private POServiceTypesUrl = 'http://localhost:8080/astutesystem/po/serviceTypes'; private POServiceTypesUrl = 'http://localhost:8080/astutesystem/po/serviceTypes';
private PODetailUrl = 'http://localhost:8080/astutesystem/po/detail'; private PODetailUrl = 'http://localhost:8080/astutesystem/po/detail';
@ -16,19 +17,17 @@ export class AstuteClientService {
private invoiceGenUrl = 'http://localhost:8080/astutesystem/invoice/generatedInvoice'; private invoiceGenUrl = 'http://localhost:8080/astutesystem/invoice/generatedInvoice';
private invoicePaymentUrl = 'http://localhost:8080/astutesystem/invoicePayment'; private invoicePaymentUrl = 'http://localhost:8080/astutesystem/invoicePayment';
private serviceTypeUrl = 'http://localhost:8080/astutesystem/serviceType'; private serviceTypeUrl = 'http://localhost:8080/astutesystem/serviceType';
private sessionId = localStorage.getItem(''); private sessionString = `?sessionId=${localStorage.getItem('SESSION_ID')}`;
private sessionString = `?sessionId=${this.sessionId}`;
constructor(private http: HttpClient) { } constructor(private http: HttpClient) { }
// **************************************** AUTH Service methods // **************************************** AUTH Service methods
public login(username: string, password: string): Promise<string> { public login(username: string, password: string): Promise<string> {
const data = { const data = {
'username': username, 'username': username,
'password': password 'password': password
}; };
return this.http return this.http
.post(this.authUrl, data) .post(this.authUrl, data)
.toPromise() .toPromise()
@ -38,6 +37,8 @@ export class AstuteClientService {
const sessionId = response['entity'].sessionId; const sessionId = response['entity'].sessionId;
if (sessionId != null) { if (sessionId != null) {
localStorage.setItem('SESSION_ID', sessionId); localStorage.setItem('SESSION_ID', sessionId);
this.sessionString = `?sessionId=${localStorage.getItem('SESSION_ID')}`;
console.log(sessionId);
localStorage.setItem('SESSION_USER', name); localStorage.setItem('SESSION_USER', name);
return sessionId; return sessionId;
} else { } else {
@ -45,29 +46,30 @@ export class AstuteClientService {
} }
}); });
} }
public logout() { public logout() {
return this.http
.post(`${this.authUrl}/logout${this.sessionString}`, {})
.toPromise()
.then(response => {
localStorage.removeItem('SESSION_ID'); localStorage.removeItem('SESSION_ID');
localStorage.removeItem('SESSION_USER'); localStorage.removeItem('SESSION_USER');
console.log(localStorage.getItem('SESSION_ID')); return response['entity'];
});
} }
public getSessionId(): string { public getSessionId(): string {
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(localStorage.getItem('SESSION_USER')); console.log(localStorage.getItem('SESSION_USER'));
return localStorage.getItem('SESSION_USER'); return localStorage.getItem('SESSION_USER');
} }
// **************************************** Customer Service methods // **************************************** Customer Service methods
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 => {
@ -78,26 +80,23 @@ export class AstuteClientService {
alert(error); alert(error);
}); });
} }
public updateCustomer(customerId: number, data: any): Promise<any> { public updateCustomer(customerId: number, data: any): Promise<any> {
console.log("*** In updateCustomer()"); console.log('*** In updateCustomer()');
const url = `${this.customerUrl}/${customerId}`; //TODO send sessionId const url = `${this.customerUrl}/${customerId}${this.sessionString}`;
return this.http.put(url, data) return this.http.put(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
public createCustomer(data: any): Promise<any> { public createCustomer(data: any): Promise<any> {
console.log("*** In createCustomer()"); console.log('*** In createCustomer()');
const url = `${this.customerUrl}`; //TODO send sessionId const url = `${this.customerUrl}${this.sessionString}`;
return this.http.post(url, data) return this.http.post(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
public deleteCustomer(customerId) { public deleteCustomer(customerId) {
console.log("*** In deleteCustomer()"); console.log('*** In deleteCustomer()');
const url = `${this.customerUrl}/${customerId}/delete`; const url = `${this.customerUrl}/${customerId}/delete${this.sessionString}`;
return this.http.put(url, {}) return this.http.put(url, {})
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -106,23 +105,10 @@ export class AstuteClientService {
}); });
} }
// **************************************** PO Service methods // **************************************** Customer Contact Service methods
public getCustomerContacts(customerId): Promise<any> {
console.log('*** In getCustomerContacts()');
public getPOs(): Promise<any> { const url = `${this.customerContactUrl}?customerId=${customerId}&sessionId=${localStorage.getItem('SESSION_ID')}`;
console.log("*** In getPOs()");
const url = `${this.POUrl}`;
return this.http.get(url)
.toPromise()
.then(response => {
console.log(response['entity']);
return response['entity'];
});
}
public getPODetail(ponum): Promise<any> {
console.log("*** In getPODetails()");
const url = `${this.PODetailUrl}?PONum=${ponum}`;
console.log(url); console.log(url);
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
@ -131,63 +117,108 @@ export class AstuteClientService {
return response['entity']; return response['entity'];
}); });
} }
public updateCustomerContact(customerId: string, data: any): Promise<any> {
console.log('*** In updateCustomerContact()');
const url = `${this.customerContactUrl}/${customerId}${this.sessionString}`;
return this.http.put(url, data)
.toPromise()
.then(response => response['entity']);
}
public deleteCustomerContact(customerId: string, contactId: number): Promise<any> {
console.log('*** In deleteCustomerContact()');
const url = `${this.customerContactUrl}/${customerId}/${contactId}/delete${this.sessionString}`;
return this.http.put(url, {})
.toPromise()
.then(response => response['entity']);
}
public createCustomerContact(data: any): Promise<any> {
console.log('*** In createCustomerContact()');
const url = `${this.customerContactUrl}/${this.sessionString}`;
return this.http.post(url, data)
.toPromise()
.then(response => response['entity']);
}
// **************************************** PO Service methods
public getPOs(): Promise<any> {
console.log('*** In getPOs()');
const url = `${this.POUrl}${this.sessionString}`;
return this.http.get(url)
.toPromise()
.then(response => {
console.log(response['entity']);
return response['entity'];
});
}
public getPODetail(ponum): Promise<any> {
console.log('*** In getPODetails()');
const url = `${this.PODetailUrl}?PONum=${ponum}&sessionId=${localStorage.getItem('SESSION_ID')}`;
console.log(url);
return this.http.get(url)
.toPromise()
.then(response => {
console.log(response['entity']);
return response['entity'];
});
}
public updatePO(ponum: string, data: any): Promise<any> { public updatePO(ponum: string, data: any): Promise<any> {
console.log("*** In updatePO()"); console.log('*** In updatePO()');
const url = `${this.POUrl}/${ponum}`; //TODO send sessionId const url = `${this.POUrl}/${ponum}${this.sessionString}`;
return this.http.put(url, data) return this.http.put(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
public createPO(data: any): Promise<any> { public createPO(data: any): Promise<any> {
console.log("*** In createPO()"); console.log('*** In createPO()');
const url = `${this.POUrl}`; //TODO send sessionId const url = `${this.POUrl}${this.sessionString}`;
return this.http.post(url, data) return this.http.post(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
public updatePODetail(ponum, lineItemNo, data) { public updatePODetail(ponum, lineItemNo, data) {
console.log("*** In updatePODetail()"); console.log('*** In updatePODetail()');
const sessionId = localStorage.getItem('sessionId'); const sessionId = localStorage.getItem('sessionId');
const url = `${this.POUrl}/detail/${ponum}/${lineItemNo}`; //TODO send sessionId const url = `${this.POUrl}/detail/${ponum}/${lineItemNo}${this.sessionString}`;
return this.http.put(url, data) return this.http.put(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
public createPODetail(data) { public createPODetail(data) {
console.log("*** In createPODetail()"); console.log('*** In createPODetail()');
const url = `${this.POUrl}/detail`; //TODO send sessionId const url = `${this.POUrl}/detail${this.sessionString}`;
return this.http.post(url, data) return this.http.post(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
public finalizePO(ponum: string) {
public finalizePO(ponum: string){ console.log('*** In finalizePO()');
console.log("*** In finalizePO()"); const url = `${this.POUrl}/${ponum}/finalize${this.sessionString}`;
const url = `${this.POUrl}/${ponum}/finalize`; //TODO send sessionId
return this.http.put(url, {}) return this.http.put(url, {})
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
public deletePO(ponum: string) { public deletePO(ponum: string) {
console.log("*** In deletePO()"); console.log('*** In deletePO()');
const url = `${this.POUrl}/${ponum}/delete`; //TODO send sessionId const url = `${this.POUrl}/${ponum}/delete${this.sessionString}`;
return this.http.put(url, {}) return this.http.put(url, {})
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
public getRateTypes(): Promise<any> {
console.log('*** In getPOs()');
const url = `${this.POUrl}/feeTypes${this.sessionString}`;
return this.http.get(url)
.toPromise()
.then(response => {
console.log(response['entity']);
return response['entity'];
});
}
// **************************************** Invoice Service methods // **************************************** Invoice Service methods
// /{InvoiceNumber}/void
public submitInvoice (invoiceNumber) { public submitInvoice (invoiceNumber) {
console.log("*** In submitInvoice(), invoiceNumber" + invoiceNumber); console.log('*** In submitInvoice(), invoiceNumber' + invoiceNumber);
const url = `${this.invoiceUrl}/${invoiceNumber}/submit`; const url = `${this.invoiceUrl}/${invoiceNumber}/submit${this.sessionString}`;
return this.http.put(url, {}) return this.http.put(url, {})
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -195,10 +226,9 @@ export class AstuteClientService {
return response['entity']; return response['entity'];
}); });
} }
public voidInvoice (invoiceNumber) { public voidInvoice (invoiceNumber) {
console.log("*** In voidInvoice(), invoiceNumber" + invoiceNumber); console.log('*** In voidInvoice(), invoiceNumber' + invoiceNumber);
const url = `${this.invoiceUrl}/${invoiceNumber}/void`; const url = `${this.invoiceUrl}/${invoiceNumber}/void${this.sessionString}`;
return this.http.put(url, {}) return this.http.put(url, {})
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -206,10 +236,9 @@ export class AstuteClientService {
return response['entity']; return response['entity'];
}); });
} }
public deleteInvoice (invoiceNumber) { public deleteInvoice (invoiceNumber) {
console.log("*** In deleteInvoice(), invoiceNumber" + invoiceNumber); console.log('*** In deleteInvoice(), invoiceNumber' + invoiceNumber);
const url = `${this.invoiceUrl}/${invoiceNumber}/delete`; const url = `${this.invoiceUrl}/${invoiceNumber}/delete${this.sessionString}`;
return this.http.put(url, {}) return this.http.put(url, {})
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -217,21 +246,19 @@ export class AstuteClientService {
return response['entity']; return response['entity'];
}); });
} }
public generateInvoiceNumber (ponum) { public generateInvoiceNumber (ponum) {
console.log("*** In generateInvoiceNumber()"); console.log('*** In generateInvoiceNumber()');
const url = `${this.invoiceUrl}/generateInvoiceNumber/${ponum}`; const url = `${this.invoiceUrl}/generateInvoiceNumber/${ponum}${this.sessionString}`;
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
.then(response => { .then(response => {
console.log (response['entity']) console.log (response['entity']);
return response['entity']; return response['entity'];
}); });
} }
public getInvoices(): Promise<any> { public getInvoices(): Promise<any> {
console.log("*** In getInvoices()"); console.log('*** In getInvoices()');
const url = `${this.invoiceUrl}`; const url = `${this.invoiceUrl}${this.sessionString}`;
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -239,10 +266,9 @@ export class AstuteClientService {
return response['entity']; return response['entity'];
}); });
} }
public getInvoiceDetail(invoiceId: string): Promise<any> { public getInvoiceDetail(invoiceId: string): Promise<any> {
console.log("*** In getInvoiceDetail()"); console.log('*** In getInvoiceDetail()');
const url = `${this.invoiceDetailUrl}?invoiceNumber=${invoiceId}`; const url = `${this.invoiceDetailUrl}?invoiceNumber=${invoiceId}&sessionId=${localStorage.getItem('SESSION_ID')}`;
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -250,10 +276,9 @@ export class AstuteClientService {
return response['entity']; return response['entity'];
}); });
} }
public getInvoiceGen (invoiceId: string): Promise<any> { public getInvoiceGen (invoiceId: string): Promise<any> {
console.log("*** In getInvoiceGen()"); console.log('*** In getInvoiceGen()');
const url = `${this.invoiceGenUrl}/${invoiceId}`; const url = `${this.invoiceGenUrl}/${invoiceId}${this.sessionString}`;
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -261,34 +286,30 @@ export class AstuteClientService {
return response['entity']; return response['entity'];
}); });
} }
public updateInvoice(invoiceNumber: string, data: any): Promise<any> { public updateInvoice(invoiceNumber: string, data: any): Promise<any> {
console.log("*** In updateInvoice()"); console.log('*** In updateInvoice()');
const url = `${this.invoiceUrl}/${invoiceNumber}`; //TODO send sessionId const url = `${this.invoiceUrl}/${invoiceNumber}${this.sessionString}`;
return this.http.put(url, data) return this.http.put(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
public createInvoice(data: any): Promise<any> { public createInvoice(data: any): Promise<any> {
console.log("*** In createInvoice()"); console.log('*** In createInvoice()');
const url = `${this.invoiceUrl}`; //TODO send sessionId const url = `${this.invoiceUrl}${this.sessionString}`;
return this.http.post(url, data) return this.http.post(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
public updateInvoiceDetail(invNum, lineItemNo, data) { public updateInvoiceDetail(invNum, lineItemNo, data) {
console.log("*** In updateInvoiceDetail()"); console.log('*** In updateInvoiceDetail()');
const url = `${this.invoiceUrl}/detail/${invNum}/${lineItemNo}`; //TODO send sessionId const url = `${this.invoiceUrl}/detail/${invNum}/${lineItemNo}${this.sessionString}`;
return this.http.put(url, data) return this.http.put(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
public createInvoiceDetail(data) { public createInvoiceDetail(data) {
console.log("*** In createInvoiceDetail()"); console.log('*** In createInvoiceDetail()');
const url = `${this.invoiceUrl}/detail`; //TODO send sessionId const url = `${this.invoiceUrl}/detail${this.sessionString}`;
return this.http.post(url, data) return this.http.post(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
@ -296,10 +317,9 @@ export class AstuteClientService {
// **************************************** Invoice Payment Service methods // **************************************** Invoice Payment Service methods
public getSumittedInvoices(): Promise<any> { public getSumittedInvoices(): Promise<any> {
console.log("*** In getSumittedInvoices()"); console.log('*** In getSumittedInvoices()');
const url = `${this.invoiceUrl}/submitted`; const url = `${this.invoiceUrl}/submitted${this.sessionString}`;
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -307,10 +327,9 @@ export class AstuteClientService {
return response['entity']; return response['entity'];
}); });
} }
public getInvoiceTypes(): Promise<any> { public getInvoiceTypes(): Promise<any> {
const url = `${this.invoicePaymentUrl}/paymentTypes`; const url = `${this.invoicePaymentUrl}/paymentTypes${this.sessionString}`;
console.log("*** In getInvoiceTypes() ... calling " + url); console.log('*** In getInvoiceTypes() ... calling ' + url);
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -318,10 +337,9 @@ export class AstuteClientService {
return response['entity']; return response['entity'];
}); });
} }
public getInvoicePayments(): Promise<any> { public getInvoicePayments(): Promise<any> {
console.log("*** In getInvoicePayments()"); console.log('*** In getInvoicePayments()');
const url = `${this.invoicePaymentUrl}`; const url = `${this.invoicePaymentUrl}${this.sessionString}`;
return this.http.get(url) return this.http.get(url)
.toPromise() .toPromise()
.then(response => { .then(response => {
@ -329,29 +347,27 @@ export class AstuteClientService {
return response['entity']; return response['entity'];
}); });
} }
public updateInvoicePayment(invoiceNumber: string, invoicePaymentId: string, data: any): Promise<any> { public updateInvoicePayment(invoiceNumber: string, invoicePaymentId: string, data: any): Promise<any> {
console.log("*** In updateInvoicePayment()"); console.log('*** In updateInvoicePayment()');
const url = `${this.invoicePaymentUrl}/${invoiceNumber}/${invoicePaymentId}`; //TODO send sessionId const url = `${this.invoicePaymentUrl}/${invoiceNumber}/${invoicePaymentId}${this.sessionString}`;
console.log("*** invoicePaymentUrl is " + url); console.log('*** invoicePaymentUrl is ' + url);
return this.http.put(url, data) return this.http.put(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
public addInvoicePayment(data: any): Promise<any> { public addInvoicePayment(data: any): Promise<any> {
console.log("*** In addInvoicePayment()"); console.log('*** In addInvoicePayment()');
const url = `${this.invoicePaymentUrl}`; //TODO send sessionId const url = `${this.invoicePaymentUrl}${this.sessionString}`;
return this.http.post(url, data) return this.http.post(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
// **************************************** Service Type methods // **************************************** Service Type methods
public getServiceTypes(): Promise<any> { public getServiceTypes(): Promise<any> {
console.log("*** In getPOServiceTypes()"); console.log('*** In getPOServiceTypes()');
const url = `${this.serviceTypeUrl}`; 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 => {
@ -359,19 +375,17 @@ export class AstuteClientService {
return response['entity']; return response['entity'];
}); });
} }
public updateServiceType(serviceTypeId, data: any): Promise<any> {
public updateServiceType(serviceTypeId, serviceTypeDesc, data: any): Promise<any> { console.log('*** In updateServiceType()');
console.log("*** In updateServiceType()"); const url = `${this.serviceTypeUrl}/${serviceTypeId}${this.sessionString}`;
const url = `${this.serviceTypeUrl}/${serviceTypeId}/?desc=${serviceTypeDesc}`; //TODO send sessionId console.log('*** updateServiceType is ' + url);
console.log("*** updateServiceType is " + url);
return this.http.put(url, data) return this.http.put(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);
} }
public createServiceType(data: any): Promise<any> { public createServiceType(data: any): Promise<any> {
console.log("*** In createServiceType()"); console.log('*** In createServiceType()');
const url = `${this.serviceTypeUrl}`; //TODO send sessionId const url = `${this.serviceTypeUrl}${this.sessionString}`;
return this.http.post(url, data) return this.http.post(url, data)
.toPromise() .toPromise()
.then(response => response['entity']); .then(response => response['entity']);

View File

@ -0,0 +1,3 @@
.top-buffer {
margin-top:20px;
}

View File

@ -0,0 +1,75 @@
<app-nav-bar></app-nav-bar>
<div class="container p-2">
<div class="row top-buffer align-items-center">
<div class="col-lg-12">
<h1 class="display-4">Settings</h1>
<hr>
<h3 class="display-5">Configuration</h3>
<hr>
<div class="container-fluid m-1">
<div class="row m-1 align-content-center w-100">
<button class="btn btn-info" style="width: 100%" (click)="open(serviceTypes)">Edit Service Types</button>
</div>
<div class="row m-1 p-1 align-content-center w-100">
<div class="col-4">
<button class="btn btn-primary w-100" [disabled]="true">Export Customers</button>
</div>
<div class="col-4">
<button class="btn btn-primary w-100" style="width: 100%" [disabled]="true">Export Sales Orders</button>
</div>
<div class="col-4">
<button class="btn btn-info w-100" style="width: 100%" [disabled]="true">Export Invoices</button>
</div>
</div>
</div>
<h3 class="display-5">Configuration</h3>
<hr>
<div class="container-fluid m-1">
<div class="row m-1 align-content-center w-100">
<div class="col-12 m-1">
<div class="row p-1">
<button class="btn btn-primary" style="width: 100%" [disabled]="true">Edit Users</button>
</div>
<div class="row p-1">
<button class="btn btn-warning" style="width: 100%" [disabled]="true">Change Password</button>
</div>
<div class="row p-1">
<button class="btn btn-danger" style="width: 100%" (click)="logout()">Logout</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<app-modal-form [title]="'Service Types'" #serviceTypes>
<div class="modal-body">
<div class="container-fluid">
<div class="row">
<div class="col-12 align-items-end">
<ag-grid-angular
style="height: 350px;"
class="ag-theme-balham"
[enableColResize]="true"
[enableSorting]="true"
[enableFilter]="true"
[rowData]="serviceTypeData | async"
[columnDefs]="columnDefs"
(cellEditingStopped)="updateServiceTypeRow($event)"
(gridReady)="onGridReady($event)"
(rowDataChanged)="resizeColumns($event)"
rowSelection="single"
></ag-grid-angular>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" (click)="addEmptyServiceTypes()">Add</button>
<button class="btn btn-outline-danger" (click)="close(serviceTypes)">Exit</button>
</div>
</app-modal-form>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SettingsComponent } from './settings.component';
describe('SettingsComponent', () => {
let component: SettingsComponent;
let fixture: ComponentFixture<SettingsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SettingsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SettingsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,84 @@
import { Component, OnInit } from '@angular/core';
import {AstuteClientService} from '../services/astute-client-service';
import {Router} from '@angular/router';
@Component({
selector: 'app-settings',
templateUrl: './settings.component.html',
styleUrls: ['./settings.component.css']
})
export class SettingsComponent implements OnInit {
serviceTypeData: Promise<any>;
columnDefs = [
{headerName: 'Service Type ID', field: 'serviceTypeId'},
{headerName: 'Service Type Description', field: 'serviceTypeDesc', editable: true},
];
gridApi;
gridColumnApi;
constructor(private astuteClientService: AstuteClientService,
private router: Router) {
}
ngOnInit() {
this.refreshServiceTypeData();
}
updateServiceTypeRow(evt) {
const data = evt.data;
console.log(data);
this.astuteClientService.updateServiceType(data.serviceTypeId, data).then((d) => {
if (!d) {
alert('Service Type updating failed, check input fields');
}
this.refreshServiceTypeData();
}, (reason) => {
alert('Update Service Type failed: ' + reason);
});
}
addEmptyServiceTypes() {
const data = {'serviceTypeName': ''};
this.astuteClientService.createServiceType(data).then((d) => {
if (!d) {
alert('Create Service Type Failed!');
}
this.refreshServiceTypeData();
}, (reason) => {
alert('Create Service Type Failed: ' + reason);
});
}
open(ref) {
ref.open();
}
close(ref) {
this.refreshServiceTypeData();
ref.close();
}
refreshServiceTypeData() {
this.serviceTypeData = this.astuteClientService.getServiceTypes();
}
onGridReady(evt) {
this.gridApi = evt.api;
this.gridColumnApi = evt.columnApi;
}
resizeColumns(evt) {
evt.columnApi.autoSizeAllColumns();
}
logout() {
this.astuteClientService.logout().then((data) => {
if (data) {
this.router.navigate(['/login']);
alert('Logout successful');
} else {
alert('Logout unsuccessful');
}
});
}
}