mirror of
https://github.com/dyiop/astute.git
synced 2025-04-06 21:30:20 -04:00
i cant even keep track anymore
This commit is contained in:
parent
12748b8035
commit
6f54177cad
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { EmptyErrorEditorComponent } from './empty-error-editor.component';
|
||||
|
||||
describe('EmptyErrorEditorComponent', () => {
|
||||
let component: EmptyErrorEditorComponent;
|
||||
let fixture: ComponentFixture<EmptyErrorEditorComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ EmptyErrorEditorComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(EmptyErrorEditorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,46 @@
|
|||
import {AfterViewInit, Component, ViewChild} from '@angular/core';
|
||||
import {ToastManagerService} from '../../services/toast-manager/toast-service.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-empty-error-editor',
|
||||
template: `
|
||||
<input #i class="w-100" [value]="params.value" (keydown)="onKeyDown($event)"/>
|
||||
`
|
||||
})
|
||||
export class EmptyErrorEditorComponent implements AfterViewInit {
|
||||
@ViewChild('i', {'static': false}) textInput;
|
||||
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) {
|
||||
event.stopPropagation();
|
||||
this.notif('Value should not be empty');
|
||||
setTimeout(() => {
|
||||
this.textInput.nativeElement.focus();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ** toast notification method
|
||||
notif(text: string) {
|
||||
this.toastService.show(text, {classname: 'bg-warning'});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { NumericEditorComponent } from './numeric-editor.component';
|
||||
|
||||
describe('NumericEditorComponent', () => {
|
||||
let component: NumericEditorComponent;
|
||||
let fixture: ComponentFixture<NumericEditorComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ NumericEditorComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NumericEditorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,51 @@
|
|||
import {AfterViewInit, Component, ViewChild} from '@angular/core';
|
||||
import {ToastManagerService} from '../../services/toast-manager/toast-service.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-numeric-editor',
|
||||
template: `
|
||||
<input #i type="number" class="w-100" [value]="params.value" (keydown)="onKeyDown($event)"/>
|
||||
`
|
||||
})
|
||||
export class NumericEditorComponent implements AfterViewInit {
|
||||
@ViewChild('i', {'static': false}) numberInput;
|
||||
params;
|
||||
canBeEmpty: boolean;
|
||||
|
||||
constructor(protected toastService: ToastManagerService) { }
|
||||
|
||||
ngAfterViewInit() {
|
||||
setTimeout(() => {
|
||||
this.numberInput.nativeElement.focus();
|
||||
});
|
||||
}
|
||||
|
||||
agInit(params: any): void {
|
||||
this.params = params;
|
||||
this.canBeEmpty = params.canBeEmpty;
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.numberInput.nativeElement.value;
|
||||
}
|
||||
|
||||
onKeyDown(event) {
|
||||
if (this.canBeEmpty) {
|
||||
if (event.keyCode === 9 || event.keyCode === 13) {
|
||||
if (!this.numberInput.nativeElement.value) {
|
||||
event.stopPropagation();
|
||||
this.notif('Value should not be empty');
|
||||
setTimeout(() => {
|
||||
this.numberInput.nativeElement.focus();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ** toast notification method
|
||||
notif(text: string) {
|
||||
this.toastService.show(text, {classname: 'bg-warning'});
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ import {ToastManagerService} from '../../services/toast-manager/toast-service.se
|
|||
@Component({
|
||||
selector: 'app-phone-editor-cell',
|
||||
template: `
|
||||
<input #i [value]="params.value" [textMask]="{mask: usPhoneMask, guide: false}" (keydown)="onKeyDown($event)"/>
|
||||
<input #i class="w-100" [value]="params.value" [textMask]="{mask: usPhoneMask, guide: false}" (keydown)="onKeyDown($event)"/>
|
||||
`
|
||||
})
|
||||
export class PhoneEditorComponent implements AfterViewInit {
|
||||
|
|
|
@ -26,6 +26,8 @@ import { ToastsContainerComponent } from './services/toast-manager/toasts-contai
|
|||
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 { EmptyErrorEditorComponent } from './ag-grid-components/empty-error-editor/empty-error-editor.component';
|
||||
import { NumericEditorComponent } from './ag-grid-components/numeric-editor/numeric-editor.component';
|
||||
// import { ServiceTypeComponent } from './service-type/service-type.component';
|
||||
|
||||
@NgModule({
|
||||
|
@ -45,7 +47,9 @@ import { PhoneEditorComponent } from './ag-grid-components/phone-editor/phone-ed
|
|||
ToastsContainerComponent,
|
||||
NumberFormatterComponent,
|
||||
PhoneFormatterComponent,
|
||||
PhoneEditorComponent// ,
|
||||
PhoneEditorComponent,
|
||||
EmptyErrorEditorComponent,
|
||||
NumericEditorComponent// ,
|
||||
// ServiceTypeComponent
|
||||
],
|
||||
imports: [
|
||||
|
@ -53,7 +57,9 @@ import { PhoneEditorComponent } from './ag-grid-components/phone-editor/phone-ed
|
|||
AgGridModule.withComponents([
|
||||
NumberFormatterComponent,
|
||||
PhoneFormatterComponent,
|
||||
PhoneEditorComponent
|
||||
PhoneEditorComponent,
|
||||
EmptyErrorEditorComponent,
|
||||
NumericEditorComponent
|
||||
]),
|
||||
NgbModule,
|
||||
HttpClientModule,
|
||||
|
|
|
@ -9,3 +9,11 @@
|
|||
::-ms-input-placeholder { /* Microsoft Edge */
|
||||
color: lightblue;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 10;
|
||||
background-color: rgba(0,0,0,0.5) !important;
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
<app-nav-bar [customerActive]="true"></app-nav-bar>
|
||||
<div *ngIf="loggedIn">
|
||||
<h1 align="center">Customers</h1>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
@ -349,3 +350,21 @@
|
|||
</div>
|
||||
</div>
|
||||
</app-modal-form>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!loggedIn">
|
||||
<div class="container mt-5">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="jumbotron">
|
||||
<h1 class="display-4">Please Log In First!</h1>
|
||||
<p class="lead">Once you do, you will be able to create new customers and edit existing ones to your hearts content!</p>
|
||||
<p class="lead">
|
||||
<a class="btn btn-success btn-lg" href="#" role="button">Log In</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ 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';
|
||||
import {EmptyErrorEditorComponent} from '../ag-grid-components/empty-error-editor/empty-error-editor.component';
|
||||
import {NumericEditorComponent} from "../ag-grid-components/numeric-editor/numeric-editor.component";
|
||||
|
||||
@Component({
|
||||
selector: 'app-customer',
|
||||
|
@ -11,6 +13,7 @@ import {PhoneEditorComponent} from '../ag-grid-components/phone-editor/phone-edi
|
|||
})
|
||||
export class CustomerComponent implements OnInit {
|
||||
// @ViewChild('agGrid') agGrid;
|
||||
loggedIn: boolean;
|
||||
gridApi;
|
||||
gridColumnApi;
|
||||
contactGridApi;
|
||||
|
@ -19,22 +22,24 @@ 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: 'Name ✎', field: 'customerName', editable: true, cellEditor: 'emptyErrorEditorComponent'},
|
||||
{headerName: 'Bill To ✎', field: 'billToDept', editable: true, cellEditor: 'emptyErrorEditorComponent'},
|
||||
{headerName: 'Email ✎', field: 'email', editable: true, cellEditor: 'emptyErrorEditorComponent'},
|
||||
{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}
|
||||
{headerName: 'Ext. ✎', field: 'phExt', editable: true, cellEditor: 'numericEditorComponent'},
|
||||
{headerName: 'Address 1 ✎', field: 'add1', editable: true, cellEditor: 'emptyErrorEditorComponent'},
|
||||
{headerName: 'Address 2 ✎', field: 'add2', editable: true, cellEditor: 'emptyErrorEditorComponent'},
|
||||
{headerName: 'City ✎', field: 'city', editable: true, cellEditor: 'emptyErrorEditorComponent'},
|
||||
{headerName: 'State ✎', field: 'state', editable: true, cellEditor: 'emptyErrorEditorComponent'},
|
||||
{headerName: 'ZIP ✎', field: 'zip', editable: true, cellEditor: 'emptyErrorEditorComponent'},
|
||||
{headerName: 'ZIP-4 ✎', field: 'ziplast4', editable: true, cellEditor: 'numericEditorComponent'}
|
||||
];
|
||||
frameworkComponents = {
|
||||
phoneFormatterComponent: PhoneFormatterComponent,
|
||||
phoneEditorComponent: PhoneEditorComponent
|
||||
phoneEditorComponent: PhoneEditorComponent,
|
||||
emptyErrorEditorComponent: EmptyErrorEditorComponent,
|
||||
numericEditorComponent: NumericEditorComponent
|
||||
};
|
||||
rowData: any;
|
||||
states = [
|
||||
|
@ -94,7 +99,7 @@ export class CustomerComponent implements OnInit {
|
|||
|
||||
contactsData: any;
|
||||
contactsColDef = [
|
||||
{headerName: 'Name ✎', field: 'name', editable: true},
|
||||
{headerName: 'Name ✎', field: 'name', editable: true, cellEditor: 'emptyErrorEditorComponent'},
|
||||
{headerName: 'Title ✎', field: 'title', editable: true},
|
||||
{headerName: 'Email ✎', field: 'email', editable: true},
|
||||
{headerName: 'Work ✎', field: 'workPhone', editable: true, cellEditor: 'phoneEditorComponent'},
|
||||
|
@ -119,7 +124,12 @@ export class CustomerComponent implements OnInit {
|
|||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (localStorage.getItem('SESSION_ID') && localStorage.getItem('SESSION_USER')) {
|
||||
this.loggedIn = true;
|
||||
this.refreshData();
|
||||
} else {
|
||||
this.loggedIn = false;
|
||||
}
|
||||
}
|
||||
|
||||
// callback for grid selection
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<app-nav-bar [invoicePaymentActive]="true"></app-nav-bar>
|
||||
<div *ngIf="loggedIn">
|
||||
<h1 align="center">Invoice Payments</h1>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
@ -204,3 +206,20 @@
|
|||
</div>
|
||||
</div>
|
||||
</app-modal-form>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!loggedIn">
|
||||
<div class="container mt-5">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="jumbotron">
|
||||
<h1 class="display-4">Please Log In First!</h1>
|
||||
<p class="lead">Once you do, you will be able to log payments to your hearts content!</p>
|
||||
<p class="lead">
|
||||
<a class="btn btn-success btn-lg" href="#" role="button">Log In</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -10,6 +10,8 @@ import {ToastManagerService} from "../services/toast-manager/toast-service.servi
|
|||
})
|
||||
export class InvoicePaymentComponent implements OnInit {
|
||||
@ViewChild('agGrid', {'static': false}) agGrid;
|
||||
|
||||
loggedIn: boolean;
|
||||
selected = null;
|
||||
chosenInv: any = 0;
|
||||
chosenPaymentType: any = 0;
|
||||
|
@ -25,14 +27,17 @@ export class InvoicePaymentComponent implements OnInit {
|
|||
{headerName: 'Payment Type', field: 'paymentType'},
|
||||
{headerName: 'Check / ACH #', field: 'checkNo'},
|
||||
{headerName: 'Transaction #', field: 'transactionNo'}
|
||||
|
||||
|
||||
];
|
||||
constructor(protected astuteClientService: AstuteClientService, protected toastService: ToastManagerService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (localStorage.getItem('SESSION_ID') && localStorage.getItem('SESSION_USER')) {
|
||||
this.loggedIn = true;
|
||||
this.refreshData();
|
||||
} else {
|
||||
this.loggedIn = false;
|
||||
}
|
||||
}
|
||||
|
||||
invoiceDropdownChange(index) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<app-nav-bar [invoiceActive]="true"></app-nav-bar>
|
||||
<div *ngIf="loggedIn">
|
||||
<h1 align="center">Invoices</h1>
|
||||
|
||||
<div class="container-fluid">
|
||||
<!--Table-->
|
||||
<div class="row">
|
||||
|
@ -723,3 +725,20 @@
|
|||
<!--<button class="btn btn-outline-danger" (click)="close(details)">Exit</button>-->
|
||||
<!--</div>-->
|
||||
</app-modal-form>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!loggedIn">
|
||||
<div class="container mt-5">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="jumbotron">
|
||||
<h1 class="display-4">Please Log In First!</h1>
|
||||
<p class="lead">Once you do, you will be able to create new invoices and edit existing ones to your hearts content!</p>
|
||||
<p class="lead">
|
||||
<a class="btn btn-success btn-lg" href="#" role="button">Log In</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -13,6 +13,8 @@ declare var $: any;
|
|||
styleUrls: ['./invoice.component.css']
|
||||
})
|
||||
export class InvoiceComponent implements OnInit {
|
||||
loggedIn: boolean;
|
||||
|
||||
gridApi;
|
||||
gridColumnApi;
|
||||
detailGridApi;
|
||||
|
@ -49,7 +51,7 @@ export class InvoiceComponent implements OnInit {
|
|||
{headerName: 'Date', field: 'invoiceDate'},
|
||||
{headerName: 'Sales Order Number', field: 'poNum'},
|
||||
{headerName: 'Change Order Number', field: 'changeOrderNum'},
|
||||
{headerName: 'Outstanding Balance', field: 'outstandingBalanceString'},
|
||||
{headerName: 'Outstanding Balance', field: 'outstandingBalance', cellRenderer: 'numberFormatterComponent'},
|
||||
{headerName: 'Bill Amount', field: 'billAmt', cellRenderer: 'numberFormatterComponent'},
|
||||
{headerName: 'Notes ✎', field: 'specialNotes',
|
||||
editable: (node => node.data.invoiceStatus === 1), cellEditor: 'agLargeTextCellEditor'}
|
||||
|
@ -67,15 +69,17 @@ export class InvoiceComponent implements OnInit {
|
|||
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: 'Fee Type *', field: 'rateTypeName',
|
||||
editable: (node => (node.data.poLineItemNum === -1 && this.chosenInv && this.chosenInv.invoiceStatus === 1)),
|
||||
cellEditor: 'agSelectCellEditor', cellEditorParams: {values: this.rateNames}},
|
||||
{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',
|
||||
cellRenderer: 'numberFormatterComponent'}
|
||||
{headerName: 'Remaining Qty', field: 'remainingQty'},
|
||||
{headerName: 'Fee *', field: 'fee',
|
||||
editable: (node => (node.data.poLineItemNum === -1 && this.chosenInv && this.chosenInv.invoiceStatus === 1)), cellRenderer: 'numberFormatterComponent'}
|
||||
];
|
||||
|
||||
|
||||
|
@ -124,6 +128,8 @@ export class InvoiceComponent implements OnInit {
|
|||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (localStorage.getItem('SESSION_ID') && localStorage.getItem('SESSION_USER')) {
|
||||
this.loggedIn = true;
|
||||
this.astuteClientService.getServiceTypes().then((d) => {
|
||||
if (d) {
|
||||
this.serviceTypes = d;
|
||||
|
@ -157,6 +163,14 @@ export class InvoiceComponent implements OnInit {
|
|||
}, (reason) => {
|
||||
this.notif('Get Customers Failed: ' + reason);
|
||||
});
|
||||
this.refreshPOs();
|
||||
this.refreshData();
|
||||
} else {
|
||||
this.loggedIn = false;
|
||||
}
|
||||
}
|
||||
|
||||
refreshPOs() {
|
||||
this.astuteClientService.getPOs().then((data) => {
|
||||
if (data) {
|
||||
this.pos = data;
|
||||
|
@ -164,6 +178,7 @@ export class InvoiceComponent implements OnInit {
|
|||
this.astuteClientService.getPODetail(po.ponum).then((details) => {
|
||||
if (details) {
|
||||
details.forEach((detail) => {
|
||||
detail.tempRemainingQty = detail.remainingQty;
|
||||
this.allPODetails.push(detail);
|
||||
});
|
||||
// console.log(this.allPODetails);
|
||||
|
@ -181,18 +196,12 @@ export class InvoiceComponent implements OnInit {
|
|||
}, (reason) => {
|
||||
this.notif('Get SOs Failed: ' + reason);
|
||||
});
|
||||
this.refreshData();
|
||||
}
|
||||
|
||||
refreshData() {
|
||||
this.astuteClientService.getInvoices().then((data) => {
|
||||
if (data) {
|
||||
this.source = data;
|
||||
// console.log(data);
|
||||
this.source.forEach((row) => {
|
||||
row.billAmtString = formatCurrency(row.billAmt, 'en-US', '$', 'USD');
|
||||
row.outstandingBalanceString = formatCurrency(row.outstandingBalance, 'en-US', '$', 'USD');
|
||||
});
|
||||
} else {
|
||||
this.notif('Get Invoices failed!');
|
||||
}
|
||||
|
@ -221,15 +230,16 @@ export class InvoiceComponent implements OnInit {
|
|||
// this.refreshData();
|
||||
}
|
||||
updateDetailRow(event) {
|
||||
const eventData = event.data;
|
||||
// console.log(eventData);
|
||||
event.data.feeTypeId = this.getFeeIdFromName(event.data.rateTypeName);
|
||||
const eventData = event.data;
|
||||
this.astuteClientService.updateInvoiceDetail(eventData.invoiceNum, eventData.lineItemNum, eventData).then((data) => {
|
||||
if (!data) {
|
||||
this.refreshDetailsOfSelected();
|
||||
this.notif('Detail Updating Failed, Check Input Fields');
|
||||
} else {
|
||||
this.updateSelectedBillAmt();
|
||||
}
|
||||
this.refreshDetailsOfSelected();
|
||||
}, (reason) => {
|
||||
this.notif('Update Detail failed: ' + reason);
|
||||
});
|
||||
|
@ -251,18 +261,21 @@ export class InvoiceComponent implements OnInit {
|
|||
this.selectedInDetails = this.astuteClientService.getInvoiceDetail(this.chosenInv.invoiceNumber).then((data) => {
|
||||
if (data) {
|
||||
data.forEach((invDetail) => {
|
||||
const tempPo = this.selectedPODetails.filter((po) => {
|
||||
return po.lineItemNo === invDetail.poLineItemNum;
|
||||
})[0];
|
||||
if (tempPo) {
|
||||
invDetail.remainingQty = tempPo.remainingQty;
|
||||
}
|
||||
|
||||
invDetail.serviceTypeName = this.serviceNames[invDetail.serviceTypeId - 1];
|
||||
invDetail.rateTypeName = this.rateNames[invDetail.feeTypeId - 1];
|
||||
if (invDetail.poLineItemNum === -1) {
|
||||
invDetail.remainingQty = '-';
|
||||
invDetail.poDetailName = 'Out of Pocket Expenses';
|
||||
} else {
|
||||
if (this.chosenInv.invoiceStatus === 1) {
|
||||
invDetail.remainingQty = invDetail.draftRemainingQty;
|
||||
} else {
|
||||
const tempPo = this.selectedPODetails[invDetail.poLineItemNum - 1];
|
||||
if (tempPo) {
|
||||
invDetail.remainingQty = tempPo.remainingQty;
|
||||
} else {
|
||||
invDetail.remainingQty = '';
|
||||
}
|
||||
}
|
||||
|
||||
const temp = this.selectedPODetails[invDetail.poLineItemNum - 1];
|
||||
if (temp) {
|
||||
invDetail.poDetailName = this.selectedPODetails[invDetail.poLineItemNum - 1].serviceDesc;
|
||||
|
@ -270,6 +283,9 @@ export class InvoiceComponent implements OnInit {
|
|||
invDetail.poDetailName = '';
|
||||
}
|
||||
}
|
||||
|
||||
invDetail.serviceTypeName = this.serviceNames[invDetail.serviceTypeId - 1];
|
||||
invDetail.rateTypeName = this.rateNames[invDetail.feeTypeId - 1];
|
||||
});
|
||||
this.updateSelectedBillAmt();
|
||||
return data;
|
||||
|
@ -339,7 +355,19 @@ export class InvoiceComponent implements OnInit {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
// updateSelectedDetailRemainingQty(poLineItemNum: number) {
|
||||
// this.selectedInDetails.then((data) => {
|
||||
// if (data) {
|
||||
// let newRemainingQty = this.selectedPODetails[poLineItemNum - 1].remainingQty;
|
||||
// data.forEach(invDetail => {
|
||||
// if (invDetail.poLineItemNum.toString() === poLineItemNum.toString()) {
|
||||
// newRemainingQty = newRemainingQty - invDetail.qty;
|
||||
// }
|
||||
// });
|
||||
// this.selectedPODetails[poLineItemNum - 1].tempRemainingQty = newRemainingQty;
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
printInvoice() {
|
||||
this.printService.printPDF (this.chosenInv.invoiceNumber);
|
||||
|
@ -555,7 +583,19 @@ export class InvoiceComponent implements OnInit {
|
|||
// creates empty line item detail
|
||||
addEmptyDetail(poLineItemNum) {
|
||||
let emptyData;
|
||||
if (poLineItemNum === -1) {
|
||||
if (poLineItemNum === '-1') {
|
||||
emptyData = {
|
||||
desc: 'Out of Pocket Expenses',
|
||||
fee: 0,
|
||||
feeTypeId: 1,
|
||||
invoiceNum: this.chosenInv.invoiceNumber,
|
||||
// lineItemNum: 1,
|
||||
poLineItemNum: poLineItemNum,
|
||||
qty: 0,
|
||||
// remainingQty: 1,
|
||||
serviceTypeId: 6
|
||||
};
|
||||
} else {
|
||||
emptyData = {
|
||||
desc: this.selectedPODetails[poLineItemNum - 1].serviceDesc,
|
||||
fee: this.selectedPODetails[poLineItemNum - 1].fee,
|
||||
|
@ -563,20 +603,8 @@ export class InvoiceComponent implements OnInit {
|
|||
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,
|
||||
qty: 0,
|
||||
// remainingQty: this.selectedPODetails[poLineItemNum - 1].remainingQty,
|
||||
serviceTypeId: this.selectedPODetails[poLineItemNum - 1].serviceTypeId
|
||||
};
|
||||
}
|
||||
|
@ -709,5 +737,4 @@ export class InvoiceComponent implements OnInit {
|
|||
notif(text: string) {
|
||||
this.toastService.show(text, {classname: 'bg-danger text-light'});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,11 +8,15 @@
|
|||
</div>
|
||||
|
||||
<label for="username" class="sr-only">Username</label>
|
||||
<input class="form-control" type="text" id="username" name="username" ngModel placeholder="Username">
|
||||
<input class="form-control"
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
ngModel
|
||||
placeholder="Username">
|
||||
|
||||
<label for="password" class="sr-only">Password</label>
|
||||
<input
|
||||
class="form-control"
|
||||
<input class="form-control"
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
|
|
|
@ -30,7 +30,7 @@ export class LoginComponent implements OnInit {
|
|||
} else {
|
||||
this.notif('login failed, checked credentials');
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// ** toast notification method
|
||||
|
|
|
@ -21,10 +21,11 @@
|
|||
<span class="nav-item">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" [ngClass]="settingsActive ? 'active' : ''"routerLink="/settings" routerLinkActive="active">Settings</a>
|
||||
<a *ngIf="loggedIn" class="nav-link" [ngClass]="settingsActive ? 'active' : ''"routerLink="/settings" routerLinkActive="active">Settings</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="btn" style="color: red" (click)="logout()">Logout</button>
|
||||
<button *ngIf="loggedIn" class="btn" style="color: red" (click)="logout()">Logout</button>
|
||||
<a *ngIf="!loggedIn" class="btn" style="color: lawngreen" href="#" role="button">Log In</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
|
|
|
@ -17,11 +17,17 @@ export class NavBarComponent implements OnInit {
|
|||
// @Input() logoffActive: boolean;
|
||||
@Input() settingsActive: boolean;
|
||||
|
||||
loggedIn: boolean;
|
||||
|
||||
constructor(private astuteClientService: AstuteClientService, private router: Router, private toastService: ToastManagerService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (localStorage.getItem('SESSION_ID') && localStorage.getItem('SESSION_USER')) {
|
||||
this.loggedIn = true;
|
||||
} else {
|
||||
this.loggedIn = false;
|
||||
}
|
||||
}
|
||||
|
||||
logout() {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<app-nav-bar [salesOrderActive]="true"></app-nav-bar>
|
||||
<div *ngIf="loggedIn">
|
||||
<h1 align="center">Sales Orders</h1>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
@ -427,7 +429,8 @@
|
|||
<div class="row justify-content-center mt-2">
|
||||
<div class="col">
|
||||
<div class="input-group mb-3 mt-2">
|
||||
<input type="text" class="form-control input-group-sm" placeholder="Descrpition" #poDescription>
|
||||
<input type="text" class="form-control input-group-sm" placeholder="Descrpition"
|
||||
[disabled]="selected ? selected.isFinal : false" #poDescription>
|
||||
<div class="input-group-append w-25">
|
||||
<button class="btn btn-success w-50 input-group-sm" type="button"
|
||||
(click)="addEmptyDetail(poDescription.value); poDescription.value = '';"
|
||||
|
@ -451,3 +454,20 @@
|
|||
</div>
|
||||
</div>
|
||||
</app-modal-form>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!loggedIn">
|
||||
<div class="container mt-5">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="jumbotron">
|
||||
<h1 class="display-4">Please Log In First!</h1>
|
||||
<p class="lead">Once you do, you will be able to create new sales orders and edit existing ones to your hearts content!</p>
|
||||
<p class="lead">
|
||||
<a class="btn btn-success btn-lg" href="#" role="button">Log In</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -3,6 +3,7 @@ import {AstuteClientService} from '../services/astute-client-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';
|
||||
import {EmptyErrorEditorComponent} from "../ag-grid-components/empty-error-editor/empty-error-editor.component";
|
||||
|
||||
@Component({
|
||||
selector: 'app-sales-order',
|
||||
|
@ -10,6 +11,8 @@ import {NumberFormatterComponent} from '../ag-grid-components/number-formatter/n
|
|||
styleUrls: ['./sales-order.component.css']
|
||||
})
|
||||
export class SalesOrderComponent implements OnInit {
|
||||
loggedIn: boolean;
|
||||
|
||||
// both of the grid api's
|
||||
gridApi;
|
||||
gridColumnApi;
|
||||
|
@ -26,15 +29,15 @@ 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), cellEditor: 'emptyErrorEditorComponent'},
|
||||
{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 Number ✎', field: 'contractNum', editable: (node => !node.data.isFinal), cellEditor: 'emptyErrorEditorComponent'},
|
||||
{headerName: 'SO Title ✎', field: 'title', editable: (node => !node.data.isFinal), cellEditor: 'emptyErrorEditorComponent'},
|
||||
{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), cellEditor: 'emptyErrorEditorComponent'},
|
||||
{headerName: '# of Invoices', field: 'invoiceSequence'},
|
||||
{headerName: 'notes ✎', field: 'notes', editable: (node => !node.data.isFinal), cellEditor: 'agLargeTextCellEditor'}
|
||||
// {headerName: 'oneInvInDraft', field: 'oneInvInDraft'}
|
||||
|
@ -52,6 +55,7 @@ export class SalesOrderComponent implements OnInit {
|
|||
};
|
||||
|
||||
frameworkComponents = {
|
||||
emptyErrorEditorComponent: EmptyErrorEditorComponent,
|
||||
numberFormatterComponent: NumberFormatterComponent
|
||||
};
|
||||
|
||||
|
@ -61,7 +65,8 @@ export class SalesOrderComponent implements OnInit {
|
|||
selectedPODetail;
|
||||
detailColumnDefs = [
|
||||
{headerName: '#', field: 'lineItemNo'},
|
||||
{headerName: 'Description ✎', field: 'serviceDesc', editable: (_ => (this.selected && !this.selected.isFinal))},
|
||||
{headerName: 'Description ✎', field: 'serviceDesc', editable: (_ => (this.selected && !this.selected.isFinal)),
|
||||
cellEditor: 'emptyErrorEditorComponent'},
|
||||
{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)),
|
||||
|
@ -76,6 +81,8 @@ export class SalesOrderComponent implements OnInit {
|
|||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (localStorage.getItem('SESSION_ID') && localStorage.getItem('SESSION_USER')) {
|
||||
this.loggedIn = true;
|
||||
this.astuteClientService.getServiceTypes().then((d) => {
|
||||
if (d) {
|
||||
this.serviceTypes = d;
|
||||
|
@ -111,6 +118,9 @@ export class SalesOrderComponent implements OnInit {
|
|||
this.notif('Get Customers Failed: ' + reason);
|
||||
});
|
||||
this.refreshData();
|
||||
} else {
|
||||
this.loggedIn = false;
|
||||
}
|
||||
}
|
||||
|
||||
// callback for grid selection
|
||||
|
|
Loading…
Reference in New Issue
Block a user