From 22d345cfc175f3e757c4779941cb909de561d2e9 Mon Sep 17 00:00:00 2001 From: Akash Shah Date: Tue, 16 Jul 2019 11:13:27 -0400 Subject: [PATCH] added first input validation (phone), added delete buttons at each detail section --- .../number-formatter.component.spec.ts | 25 ++++++++ .../number-formatter.component.ts | 15 +++++ .../phone-editor.component.spec.ts | 25 ++++++++ .../phone-editor/phone-editor.component.ts | 44 ++++++++++++++ .../phone-formatter.component.spec.ts | 25 ++++++++ .../phone-formatter.component.ts | 20 +++++++ AstuteClient2/src/app/app.module.ts | 16 ++++- .../src/app/customer/customer.component.html | 53 +++++++---------- .../src/app/customer/customer.component.ts | 59 ++++++++++--------- .../src/app/invoice/invoice.component.html | 24 ++++++-- .../src/app/invoice/invoice.component.ts | 57 ++++++++++++------ .../src/app/nav-bar/nav-bar.component.ts | 5 +- .../sales-order/sales-order.component.html | 21 ++++++- .../app/sales-order/sales-order.component.ts | 40 ++++++++----- .../src/app/services/astute-client-service.ts | 23 ++++++++ 15 files changed, 347 insertions(+), 105 deletions(-) create mode 100644 AstuteClient2/src/app/ag-grid-components/number-formatter/number-formatter.component.spec.ts create mode 100644 AstuteClient2/src/app/ag-grid-components/number-formatter/number-formatter.component.ts create mode 100644 AstuteClient2/src/app/ag-grid-components/phone-editor/phone-editor.component.spec.ts create mode 100644 AstuteClient2/src/app/ag-grid-components/phone-editor/phone-editor.component.ts create mode 100644 AstuteClient2/src/app/ag-grid-components/phone-formatter/phone-formatter.component.spec.ts create mode 100644 AstuteClient2/src/app/ag-grid-components/phone-formatter/phone-formatter.component.ts diff --git a/AstuteClient2/src/app/ag-grid-components/number-formatter/number-formatter.component.spec.ts b/AstuteClient2/src/app/ag-grid-components/number-formatter/number-formatter.component.spec.ts new file mode 100644 index 0000000..ae6f743 --- /dev/null +++ b/AstuteClient2/src/app/ag-grid-components/number-formatter/number-formatter.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NumberFormatterComponent } from './number-formatter.component'; + +describe('NumberFormatterComponent', () => { + let component: NumberFormatterComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ NumberFormatterComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NumberFormatterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/AstuteClient2/src/app/ag-grid-components/number-formatter/number-formatter.component.ts b/AstuteClient2/src/app/ag-grid-components/number-formatter/number-formatter.component.ts new file mode 100644 index 0000000..ed3a456 --- /dev/null +++ b/AstuteClient2/src/app/ag-grid-components/number-formatter/number-formatter.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-number-formatter-cell', + template: ` + {{params.value | currency:'USD'}} + ` +}) +export class NumberFormatterComponent { + params: any; + + agInit(params: any): void { + this.params = params; + } +} diff --git a/AstuteClient2/src/app/ag-grid-components/phone-editor/phone-editor.component.spec.ts b/AstuteClient2/src/app/ag-grid-components/phone-editor/phone-editor.component.spec.ts new file mode 100644 index 0000000..dac22be --- /dev/null +++ b/AstuteClient2/src/app/ag-grid-components/phone-editor/phone-editor.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PhoneEditorComponent } from './phone-editor.component'; + +describe('PhoneEditorComponent', () => { + let component: PhoneEditorComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PhoneEditorComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PhoneEditorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/AstuteClient2/src/app/ag-grid-components/phone-editor/phone-editor.component.ts b/AstuteClient2/src/app/ag-grid-components/phone-editor/phone-editor.component.ts new file mode 100644 index 0000000..1c213ab --- /dev/null +++ b/AstuteClient2/src/app/ag-grid-components/phone-editor/phone-editor.component.ts @@ -0,0 +1,44 @@ +import {AfterViewInit, Component, ViewChild} from '@angular/core'; +import {ToastManagerService} from '../../services/toast-manager/toast-service.service'; + +@Component({ + selector: 'app-phone-editor-cell', + template: ` + + ` +}) +export class PhoneEditorComponent implements AfterViewInit { + @ViewChild('i', {'static': false}) textInput; + usPhoneMask = ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]; + params; + + constructor(protected toastService: ToastManagerService) {} + + ngAfterViewInit() { + setTimeout(() => { + this.textInput.nativeElement.focus(); + }); + } + + agInit(params: any): void { + this.params = params; + } + + getValue() { + return this.textInput.nativeElement.value; + } + + onKeyDown(event) { + if (event.keyCode === 9 || event.keyCode === 13) { + if (this.textInput.nativeElement.value.length < 14) { + event.stopPropagation(); + this.notif('Phone number\'s should have 10 digits'); + } + } + } + + // ** toast notification method + notif(text: string) { + this.toastService.show(text, {classname: 'bg-warning'}); + } +} diff --git a/AstuteClient2/src/app/ag-grid-components/phone-formatter/phone-formatter.component.spec.ts b/AstuteClient2/src/app/ag-grid-components/phone-formatter/phone-formatter.component.spec.ts new file mode 100644 index 0000000..c756b18 --- /dev/null +++ b/AstuteClient2/src/app/ag-grid-components/phone-formatter/phone-formatter.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PhoneFormatterComponent } from './phone-formatter.component'; + +describe('PhoneFormatterComponent', () => { + let component: PhoneFormatterComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PhoneFormatterComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PhoneFormatterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/AstuteClient2/src/app/ag-grid-components/phone-formatter/phone-formatter.component.ts b/AstuteClient2/src/app/ag-grid-components/phone-formatter/phone-formatter.component.ts new file mode 100644 index 0000000..7c3aa9d --- /dev/null +++ b/AstuteClient2/src/app/ag-grid-components/phone-formatter/phone-formatter.component.ts @@ -0,0 +1,20 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-phone-formatter-cell', + template: ` + ({{firstThree}}) {{secondThree}}-{{lastFour}} + ` +}) +export class PhoneFormatterComponent { + firstThree: string; + secondThree: string; + lastFour: string; + + agInit(params: any): void { + const whole: string = params.value; + this.firstThree = whole.substr(0, 3); + this.secondThree = whole.substr(3, 3); + this.lastFour = whole.substr(6, 4); + } +} diff --git a/AstuteClient2/src/app/app.module.ts b/AstuteClient2/src/app/app.module.ts index ac5fb7d..e109b3c 100644 --- a/AstuteClient2/src/app/app.module.ts +++ b/AstuteClient2/src/app/app.module.ts @@ -7,7 +7,7 @@ import { AstuteClientService } from './services/astute-client-service'; import { AgGridModule } from 'ag-grid-angular'; import { ModalFormComponent } from './modal-form/modal-form.component'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; -import {HttpClientModule} from '@angular/common/http'; +import { HttpClientModule } from '@angular/common/http'; import { AppRoutingModule } from './app-routing.module'; import { NavBarComponent } from './nav-bar/nav-bar.component'; import { SalesOrderComponent } from './sales-order/sales-order.component'; @@ -23,6 +23,9 @@ import { FormsModule } from '@angular/forms'; import { ReactiveFormsModule } from '@angular/forms'; import { SettingsComponent } from './settings/settings.component'; import { ToastsContainerComponent } from './services/toast-manager/toasts-container/toasts-container.component'; +import { NumberFormatterComponent } from './ag-grid-components/number-formatter/number-formatter.component'; +import { PhoneFormatterComponent } from './ag-grid-components/phone-formatter/phone-formatter.component'; +import { PhoneEditorComponent } from './ag-grid-components/phone-editor/phone-editor.component'; // import { ServiceTypeComponent } from './service-type/service-type.component'; @NgModule({ @@ -39,12 +42,19 @@ import { ToastsContainerComponent } from './services/toast-manager/toasts-contai LoginComponent, InvoicePaymentComponent, SettingsComponent, - ToastsContainerComponent// , + ToastsContainerComponent, + NumberFormatterComponent, + PhoneFormatterComponent, + PhoneEditorComponent// , // ServiceTypeComponent ], imports: [ BrowserModule, - AgGridModule.withComponents([]), + AgGridModule.withComponents([ + NumberFormatterComponent, + PhoneFormatterComponent, + PhoneEditorComponent + ]), NgbModule, HttpClientModule, AppRoutingModule, diff --git a/AstuteClient2/src/app/customer/customer.component.html b/AstuteClient2/src/app/customer/customer.component.html index bffabd7..bcb2e17 100644 --- a/AstuteClient2/src/app/customer/customer.component.html +++ b/AstuteClient2/src/app/customer/customer.component.html @@ -12,6 +12,7 @@ [enableFilter]="true" [rowData]="rowData | async" [columnDefs]="columnDefs" + [frameworkComponents]="frameworkComponents" (cellEditingStopped)="updateRow($event)" (gridReady)="onGridReady($event)" (rowClicked)="setSelectedRow($event)" @@ -307,6 +308,7 @@ [enableFilter]="true" [rowData]="contactsData | async" [columnDefs]="contactsColDef" + [frameworkComponents]="frameworkComponents" (cellEditingStopped)="updateContactRow($event)" (gridReady)="onContactGridReady($event)" (rowDataChanged)="resizeColumns($event)" @@ -317,23 +319,20 @@
-
- - +
+ +
+ + +
- - - - - -
@@ -341,20 +340,12 @@ - - - - - - - - - - - - - - - - +
+ + +
\ No newline at end of file diff --git a/AstuteClient2/src/app/customer/customer.component.ts b/AstuteClient2/src/app/customer/customer.component.ts index 308d17a..c051f94 100644 --- a/AstuteClient2/src/app/customer/customer.component.ts +++ b/AstuteClient2/src/app/customer/customer.component.ts @@ -1,6 +1,8 @@ import {Component, OnInit} from '@angular/core'; import {AstuteClientService} from '../services/astute-client-service'; import {ToastManagerService} from '../services/toast-manager/toast-service.service'; +import {PhoneFormatterComponent} from '../ag-grid-components/phone-formatter/phone-formatter.component'; +import {PhoneEditorComponent} from '../ag-grid-components/phone-editor/phone-editor.component'; @Component({ selector: 'app-customer', @@ -17,19 +19,23 @@ export class CustomerComponent implements OnInit { customers; columnDefs = [ {headerName: 'ID', field: 'customerId'}, - {headerName: 'Name', field: 'customerName', editable: true}, - {headerName: 'Bill To', field: 'billToDept', editable: true}, - {headerName: 'Address 1', field: 'add1', editable: true}, - {headerName: 'Address 2', field: 'add2', editable: true}, - {headerName: 'City', field: 'city', editable: true}, - {headerName: 'Email', field: 'email', editable: true}, - {headerName: 'Fax', field: 'fax', editable: true}, - {headerName: 'Phone', field: 'phone', editable: true}, - {headerName: 'Ext.', field: 'phExt', editable: true}, - {headerName: 'State', field: 'state', editable: true}, - {headerName: 'ZIP', field: 'zip', editable: true}, - {headerName: 'ZIP-4', field: 'ziplast4', editable: true} + {headerName: 'Name ✎', field: 'customerName', editable: true}, + {headerName: 'Bill To ✎', field: 'billToDept', editable: true}, + {headerName: 'Address 1 ✎', field: 'add1', editable: true}, + {headerName: 'Address 2 ✎', field: 'add2', editable: true}, + {headerName: 'City ✎', field: 'city', editable: true}, + {headerName: 'Email ✎', field: 'email', editable: true}, + {headerName: 'Fax ✎', field: 'fax', editable: true, cellEditor: 'phoneEditorComponent'}, + {headerName: 'Phone ✎', field: 'phone', editable: true, cellEditor: 'phoneEditorComponent'}, + {headerName: 'Ext. ✎', field: 'phExt', editable: true}, + {headerName: 'State ✎', field: 'state', editable: true}, + {headerName: 'ZIP ✎', field: 'zip', editable: true}, + {headerName: 'ZIP-4 ✎', field: 'ziplast4', editable: true} ]; + frameworkComponents = { + phoneFormatterComponent: PhoneFormatterComponent, + phoneEditorComponent: PhoneEditorComponent + }; rowData: any; states = [ 'AL', @@ -88,15 +94,14 @@ export class CustomerComponent implements OnInit { 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} + {headerName: 'Name ✎', field: 'name', editable: true}, + {headerName: 'Title ✎', field: 'title', editable: true}, + {headerName: 'Email ✎', field: 'email', editable: true}, + {headerName: 'Work ✎', field: 'workPhone', editable: true, cellEditor: 'phoneEditorComponent'}, + {headerName: 'Phone ✎', field: 'mobile', editable: true, cellEditor: 'phoneEditorComponent'}, + {headerName: 'Ext. ✎', field: 'phExt', editable: true}, + {headerName: 'Fax ✎', field: 'fax', editable: true, cellEditor: 'phoneEditorComponent'}, + {headerName: 'Address ✎', field: 'address', editable: true} ]; // address: "123 Test Drive" @@ -211,17 +216,17 @@ export class CustomerComponent implements OnInit { } // wrappers for contact service methods (only inline editing) - createEmptyContact() { + createEmptyContact(name: string) { const newContactData = { address: '', customerId: this.selected.customerId, email: '', - fax: null, - mobile: null, - name: '', - phExt: null, + fax: '', + mobile: '', + name: name, + phExt: '', title: '', - workPhone: null + workPhone: '' }; console.log(newContactData); this.astuteClientService.createCustomerContact(newContactData).then ((data) => { diff --git a/AstuteClient2/src/app/invoice/invoice.component.html b/AstuteClient2/src/app/invoice/invoice.component.html index 4694123..520bb1f 100644 --- a/AstuteClient2/src/app/invoice/invoice.component.html +++ b/AstuteClient2/src/app/invoice/invoice.component.html @@ -12,6 +12,7 @@ [enableFilter]="true" [rowData]="source" [columnDefs]="columnDefs" + [frameworkComponents]="frameworkComponents" (cellEditingStopped)="updateRow($event)" (gridReady)="onGridReady($event)" (rowDataChanged)="resizeColumns($event)" @@ -679,22 +680,33 @@ [enableFilter]="true" [rowData]="selectedInDetails | async" [columnDefs]="detailColumnDefs" + [frameworkComponents]="frameworkComponents" (cellEditingStopped)="updateDetailRow($event)" (gridReady)="onDetailGridReady($event)" (rowDataChanged)="resizeColumns($event)" rowSelection="single" >
- -
- +
+ +
+
diff --git a/AstuteClient2/src/app/invoice/invoice.component.ts b/AstuteClient2/src/app/invoice/invoice.component.ts index a42861f..4f11329 100644 --- a/AstuteClient2/src/app/invoice/invoice.component.ts +++ b/AstuteClient2/src/app/invoice/invoice.component.ts @@ -1,8 +1,9 @@ import {Component, OnInit, ViewChild} from '@angular/core'; import {AstuteClientService} from '../services/astute-client-service'; -import {formatCurrency} from "@angular/common"; +import {formatCurrency} from '@angular/common'; import {PrintInvoiceService} from '../services/print-invoice.service'; -import {ToastManagerService} from "../services/toast-manager/toast-service.service"; +import {ToastManagerService} from '../services/toast-manager/toast-service.service'; +import {NumberFormatterComponent} from '../ag-grid-components/number-formatter/number-formatter.component'; declare var $: any; @@ -49,8 +50,8 @@ export class InvoiceComponent implements OnInit { {headerName: 'Sales Order Number', field: 'poNum'}, {headerName: 'Change Order Number', field: 'changeOrderNum'}, {headerName: 'Outstanding Balance', field: 'outstandingBalanceString'}, - {headerName: 'Bill Amount', field: 'billAmtString'}, - {headerName: 'Notes', field: 'specialNotes', + {headerName: 'Bill Amount', field: 'billAmt', cellRenderer: 'numberFormatterComponent'}, + {headerName: 'Notes ✎', field: 'specialNotes', editable: (node => node.data.invoiceStatus === 1), cellEditor: 'agLargeTextCellEditor'} ]; gridOptions = { @@ -60,18 +61,21 @@ export class InvoiceComponent implements OnInit { 'text-warning': (node => node.data.invoiceStatus === 3) } }; + frameworkComponents = { + numberFormatterComponent: NumberFormatterComponent + }; detailColumnDefs = [ {headerName: '#', field: 'lineItemNum'}, {headerName: 'PO Detail', field: 'poDetailName'}, - {headerName: 'Description', field: 'desc', + {headerName: 'Description ✎', field: 'desc', editable: (_ => (this.chosenInv && this.chosenInv.invoiceStatus === 1)), cellEditor: 'agLargeTextCellEditor'}, {headerName: 'Fee Type', field: 'rateTypeName'}, {headerName: 'Service Type', field: 'serviceTypeName'}, - {headerName: 'Qty or Hours', field: 'qty', + {headerName: 'Qty or Hours ✎', field: 'qty', editable: (_ => (this.chosenInv && this.chosenInv.invoiceStatus === 1))}, {headerName: '(/Remaining)', field: 'remainingQty'}, {headerName: 'Fee', field: 'fee', - editable: (_ => (this.chosenInv && this.chosenInv.invoiceStatus === 1))} + cellRenderer: 'numberFormatterComponent'} ]; @@ -261,7 +265,7 @@ export class InvoiceComponent implements OnInit { } else { const temp = this.selectedPODetails[invDetail.poLineItemNum - 1]; if (temp) { - invDetail.poDetailName = this.selectedPODetails[invDetail.poLineItemNum - 1].desc; + invDetail.poDetailName = this.selectedPODetails[invDetail.poLineItemNum - 1].serviceDesc; } else { invDetail.poDetailName = ''; } @@ -550,17 +554,32 @@ export class InvoiceComponent implements OnInit { // creates empty line item detail addEmptyDetail(poLineItemNum) { - const emptyData = { - desc: '', - fee: 0, - feeTypeId: 1, - invoiceNum: this.chosenInv.invoiceNumber, - // lineItemNum: 1, - poLineItemNum: poLineItemNum, - qty: 1, - remainingQty: 1, - serviceTypeId: 1 - }; + let emptyData; + if (poLineItemNum === -1) { + emptyData = { + desc: this.selectedPODetails[poLineItemNum - 1].serviceDesc, + fee: this.selectedPODetails[poLineItemNum - 1].fee, + feeTypeId: this.selectedPODetails[poLineItemNum - 1].feeTypeId, + invoiceNum: this.chosenInv.invoiceNumber, + // lineItemNum: 1, + poLineItemNum: poLineItemNum, + qty: 1, + remainingQty: this.selectedPODetails[poLineItemNum - 1].remainingQty, + serviceTypeId: this.selectedPODetails[poLineItemNum - 1].serviceTypeId + }; + } else { + emptyData = { + desc: 'Out of Pocket Expenses', + fee: this.selectedPODetails[poLineItemNum - 1].fee, + feeTypeId: this.selectedPODetails[poLineItemNum - 1].feeTypeId, + invoiceNum: this.chosenInv.invoiceNumber, + // lineItemNum: 1, + poLineItemNum: poLineItemNum, + qty: 1, + remainingQty: this.selectedPODetails[poLineItemNum - 1].remainingQty, + serviceTypeId: this.selectedPODetails[poLineItemNum - 1].serviceTypeId + }; + } // desc: "Design Somethign" // fee: 2500 diff --git a/AstuteClient2/src/app/nav-bar/nav-bar.component.ts b/AstuteClient2/src/app/nav-bar/nav-bar.component.ts index 383bc23..7378382 100644 --- a/AstuteClient2/src/app/nav-bar/nav-bar.component.ts +++ b/AstuteClient2/src/app/nav-bar/nav-bar.component.ts @@ -25,12 +25,13 @@ export class NavBarComponent implements OnInit { } logout() { + this.notif('Logging Out...'); this.astuteClientService.logout().then((data) => { if (data) { this.router.navigate(['/login']); - this.notif('Logout successful'); + this.notif('Logout Successful'); } else { - this.notif('Logout unsuccessful'); + this.notif('Logout Unsuccessful'); } }); } diff --git a/AstuteClient2/src/app/sales-order/sales-order.component.html b/AstuteClient2/src/app/sales-order/sales-order.component.html index 76b9fa2..2fa1168 100644 --- a/AstuteClient2/src/app/sales-order/sales-order.component.html +++ b/AstuteClient2/src/app/sales-order/sales-order.component.html @@ -12,6 +12,7 @@ [enableFilter]="true" [rowData]="rowData | async" [columnDefs]="columnDefs" + [frameworkComponents]="frameworkComponents" (cellEditingStopped)="updateRow($event)" (gridReady)="onGridReady($event)" (rowClicked)="setSelectedRow($event)" @@ -415,12 +416,30 @@ [enableFilter]="true" [rowData]="selectedPODetail | async" [columnDefs]="detailColumnDefs" + [frameworkComponents]="frameworkComponents" (cellEditingStopped)="updateDetailRow($event)" (gridReady)="onDetailGridReady($event)" (rowDataChanged)="resizeColumns($event)" rowSelection="single" > - + + +
+
+
+ +
+ + +
+

diff --git a/AstuteClient2/src/app/sales-order/sales-order.component.ts b/AstuteClient2/src/app/sales-order/sales-order.component.ts index 659419e..f62dc7e 100644 --- a/AstuteClient2/src/app/sales-order/sales-order.component.ts +++ b/AstuteClient2/src/app/sales-order/sales-order.component.ts @@ -1,7 +1,8 @@ import {Component, OnInit, ViewChild} from '@angular/core'; import {AstuteClientService} from '../services/astute-client-service'; -import {formatCurrency} from '@angular/common'; -import {ToastManagerService} from "../services/toast-manager/toast-service.service"; +import {formatCurrency, formatNumber} from '@angular/common'; +import {ToastManagerService} from '../services/toast-manager/toast-service.service'; +import {NumberFormatterComponent} from '../ag-grid-components/number-formatter/number-formatter.component'; @Component({ selector: 'app-sales-order', @@ -25,19 +26,20 @@ export class SalesOrderComponent implements OnInit { // data for SO grid rowData: any; columnDefs = [ - {headerName: 'Project Number', field: 'astuteProjectNumber', editable: (node => !node.data.isFinal)}, + {headerName: 'Project Number ✎', field: 'astuteProjectNumber', editable: (node => !node.data.isFinal)}, {headerName: 'SO Number', field: 'ponum'}, // {headerName: 'Customer ID', field: 'customerId'}, {headerName: 'Customer Name', field: 'customerName'}, - {headerName: 'Contract Number', field: 'contractNum', editable: (node => !node.data.isFinal)}, - {headerName: 'SO Title', field: 'title', editable: (node => !node.data.isFinal)}, - {headerName: 'Contract Amount', field: 'contractAmtString'}, + {headerName: 'Contract Number ✎', field: 'contractNum', editable: (node => !node.data.isFinal)}, + {headerName: 'SO Title ✎', field: 'title', editable: (node => !node.data.isFinal)}, + {headerName: 'Contract Amount', field: 'contractAmt', cellRenderer: 'numberFormatterComponent'}, // {headerName: 'Contract Amount', field: 'contractAmt'}, - {headerName: 'SO Date', field: 'podate', editable: (node => !node.data.isFinal)}, + {headerName: 'SO Date ✎', field: 'podate', editable: (node => !node.data.isFinal)}, {headerName: '# of Invoices', field: 'invoiceSequence'}, - {headerName: 'notes', field: 'notes', editable: (node => !node.data.isFinal), cellEditor: 'agLargeTextCellEditor'} + {headerName: 'notes ✎', field: 'notes', editable: (node => !node.data.isFinal), cellEditor: 'agLargeTextCellEditor'} // {headerName: 'oneInvInDraft', field: 'oneInvInDraft'} ]; + gridOptions = { rowClassRules: { 'text-danger': function (params) { @@ -48,19 +50,25 @@ export class SalesOrderComponent implements OnInit { }, } }; + + frameworkComponents = { + numberFormatterComponent: NumberFormatterComponent + }; + selected = null; // the selected SO row // data for SO detail grid selectedPODetail; detailColumnDefs = [ {headerName: '#', field: 'lineItemNo'}, - {headerName: 'Description', field: 'serviceDesc', editable: (_ => (this.selected && !this.selected.isFinal))}, - {headerName: 'Rate Type', field: 'rateTypeName', editable: (_ => (this.selected && !this.selected.isFinal)), + {headerName: 'Description ✎', field: 'serviceDesc', editable: (_ => (this.selected && !this.selected.isFinal))}, + {headerName: 'Rate Type ✎', field: 'rateTypeName', editable: (_ => (this.selected && !this.selected.isFinal)), cellEditor: 'agSelectCellEditor', cellEditorParams: {values: this.rateNames}}, - {headerName: 'Service Type', field: 'serviceTypeName', editable: (_ => (this.selected && !this.selected.isFinal)), + {headerName: 'Service Type ✎', field: 'serviceTypeName', editable: (_ => (this.selected && !this.selected.isFinal)), cellEditor: 'agSelectCellEditor', cellEditorParams: {values: this.serviceNames}}, - {headerName: 'Qty or Hours', field: 'qty', editable: (_ => (this.selected && !this.selected.isFinal))}, - {headerName: 'Rate ($)', field: 'fee', editable: (_ => (this.selected && !this.selected.isFinal))} + {headerName: 'Qty or Hours ✎', field: 'qty', editable: (_ => (this.selected && !this.selected.isFinal))}, + {headerName: 'Rate ($) ✎', field: 'fee', editable: (_ => (this.selected && !this.selected.isFinal)), + cellRenderer: 'numberFormatterComponent'} ]; contractAmount = 0; // used to show total amount @@ -243,7 +251,7 @@ export class SalesOrderComponent implements OnInit { } // wrappers for SO detail service methods - addEmptyDetail() { + addEmptyDetail(desc: string) { const emptyData = { fee: 0, feeTypeId: 1, @@ -251,7 +259,7 @@ export class SalesOrderComponent implements OnInit { poNum: this.selected.poNum, qty: 1, remainingQty: 1, - serviceDesc: '', + serviceDesc: desc, serviceTypeId: 1 }; @@ -273,6 +281,7 @@ export class SalesOrderComponent implements OnInit { }); } + // open and closing modal-form components open(ref) { // this.getSelectedRows(); @@ -315,7 +324,6 @@ export class SalesOrderComponent implements OnInit { // 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; diff --git a/AstuteClient2/src/app/services/astute-client-service.ts b/AstuteClient2/src/app/services/astute-client-service.ts index c893470..2b19f2a 100644 --- a/AstuteClient2/src/app/services/astute-client-service.ts +++ b/AstuteClient2/src/app/services/astute-client-service.ts @@ -398,6 +398,29 @@ export class AstuteClientService { this.notif(error); }); } + // public deletePODetail(customerId) { + // console.log('*** In deleteCustomer()'); + // const url = `${this.customerUrl}/${customerId}/delete${this.sessionString}`; + // return this.http.put(url, {}) + // .toPromise() + // .then(response => { + // const code = response['code']; + // const message = response['message']; + // if (code === 9000) { + // console.log(response['entity']); + // return response['entity']; + // } else if (message.includes('login')) { + // this.notif('Please login again!'); + // } else { + // this.notif('Delete Customer Failed: ' + message); + // } + // }, (reason) => { + // this.notif('Delete Customer Failed: ' + reason); + // }) + // .catch( error => { + // this.notif(error); + // }); + // } public finalizePO(ponum: string) { console.log('*** In finalizePO()'); const url = `${this.POUrl}/${ponum}/finalize${this.sessionString}`;