update transactions layout

MissionaryForm
dan 2019-07-07 00:36:49 -06:00
parent 219120fe71
commit 46b4e1dcd0
12 changed files with 382 additions and 268 deletions

View File

@ -68,6 +68,7 @@ import { AddUserPopupComponent } from './components/popups/add-user-popup/add-us
import { UserService } from './services/user.service'; import { UserService } from './services/user.service';
import { TransactionService } from './services/transaction.service'; import { TransactionService } from './services/transaction.service';
import { AddTransactionPageComponent } from './components/add-transaction-page/add-transaction-page.component'; import { AddTransactionPageComponent } from './components/add-transaction-page/add-transaction-page.component';
import { AddTransactionPopupComponent } from './components/add-transaction-page/add-transaction-popup/add-transaction-popup.component';
@ -111,7 +112,8 @@ import { AddTransactionPageComponent } from './components/add-transaction-page/a
CampPageComponent, CampPageComponent,
MembersPageComponent, MembersPageComponent,
AddUserPopupComponent, AddUserPopupComponent,
AddTransactionPageComponent AddTransactionPageComponent,
AddTransactionPopupComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
@ -140,7 +142,8 @@ import { AddTransactionPageComponent } from './components/add-transaction-page/a
SharePopupComponent, SharePopupComponent,
AddEventPopupComponent, AddEventPopupComponent,
AddUserPopupComponent, AddUserPopupComponent,
VideoPopupComponent], VideoPopupComponent,
AddTransactionPopupComponent],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })
export class AppModule { } export class AppModule { }

View File

@ -1,85 +1,73 @@
.d-inline-block { .b-0 {
display: inline-block; border: 0;
} }
.d-none { .fab-buttons{
display: none; display: none;
} }
.w-40px {
width: 40px;
}
.w-25less10px {
width: calc(25% - 10px);
}
.w-33less13px {
width: calc(33% - 13px);
}
.w-100less40px {
width: calc(100% - 40px);
}
.w-130px {
width: 130px;
}
.w-100less130px {
width: calc(100% - 130px);
}
.fw-bold { .fw-bold {
font-weight: bold; font-weight: bold;
} }
.fs-1-2-5 {
font-size: 1.25rem;
}
.highlight {
background-color: #F3FAFF;
}
.highlight-yellow {
background-color: lightyellow;
}
.ml-1 { .ml-1 {
margin-left: 1rem; margin-left: 1rem;
} }
.mt-1 { .p-0 {
margin-top: 1rem; padding: 0;
}
.mt-2 {
margin-top: 2rem;
}
.pt-1 {
padding-top: 1rem;
} }
.bb-1 { .bb-1 {
border-bottom: 1px solid #ff4081; border-bottom: 1px solid #ff4081;
} }
.bb-double {
border-bottom: 1px solid #ff4081;
border-style: double;
}
table { table {
border-collapse: collapse; border-collapse: collapse;
width: 100%;
} }
td, th { td, th {
padding: 5px; padding: 5px;
border: 1px solid #ff4081; border: 1px solid lightslategray;
}
.remove-top-border {
border-top: 0;
}
.remove-border {
border: 0;
}
.side-bar > button {
margin: 20px;
width: calc(100% - 40px);
}
#audio-player-filler{
height: 60px;
background-color: inherit;
} }
@media(max-width:800px){ @media(max-width:800px){
table { .fab-buttons{
width: 100%;
}
}
@media(max-width: 600px) {
.md-inline-block {
display: inline-block; display: inline-block;
} position: fixed;
bottom: 20px;
.mw-50less20px { right: 20px;
width: calc(50% - 20px);
} }
} }

View File

@ -3,119 +3,81 @@
<secondary-page-component [fixedSideBar]="true" > <secondary-page-component [fixedSideBar]="true" >
<div mainContent> <div mainContent>
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<div formArrayName="contributions" *ngFor="let item of getContributionsFormArray().controls; let i = index;">
<div class="mt-2 bb-1" [formGroupName]="i">
<mat-form-field class="w-130px">
<input class="fw-bold" matInput placeholder="Date" type="date" formControlName="date" >
</mat-form-field>
<mat-form-field class="w-100less130px">
<input class="fw-bold" type="text" placeholder="Contributor" aria-label="Contributor" matInput formControlName="contributorId" (ngModelChange)="onContributorChange($event)" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="contirbutorDisplayFn">
<mat-option *ngFor="let option of filteredContributors" [value]="option">
{{option.display}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div formArrayName="transactions" *ngFor="let trans of item.get('transactions').controls; let a = index;">
<div [formGroupName]="a">
<button class="w-40px" type="button" mat-icon-button (click)="deleteTransaction(i,a)">
<i ofbicon>delete_forever</i>
</button>
<mat-form-field class="w-25less10px mw-50less20px">
<mat-select formControlName="typeId">
<mat-option *ngFor="let type of types" [value]="type.value" >
{{type.display}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="w-25less10px mw-50less20px">
<input matInput placeholder="Check Number" type="text" formControlName="checkNumber" >
</mat-form-field>
<div class="w-40px d-none md-inline-block"></div>
<mat-form-field class="w-25less10px mw-50less20px">
<mat-select formControlName="fundId">
<mat-option *ngFor="let fund of funds" [value]="fund.value">
{{fund.display}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="w-25less10px mw-50less20px">
<input matInput placeholder="Amount" type="number" formControlName="amount" >
</mat-form-field>
<div class="w-40px d-inline-block"></div>
<mat-form-field class="w-100less40px">
<input matInput placeholder="Description" type="text" formControlName="description" >
</mat-form-field>
</div>
</div>
<button class="w-40px" type="button" mat-icon-button (click)="addTransaction(i)">
<i ofbicon>add</i>
</button>
<div class="w-100less40px d-inline-block">
{{contributorName(i)}}
</div>
<div class="w-40px d-inline-block"></div>
<div class="w-33less13px d-inline-block">
General: {{contributorTotal(i, 1) | currency}}
</div>
<div class="w-33less13px d-inline-block">
Missions: {{contributorTotal(i, 2) | currency}}
</div>
<div class="w-33less13px d-inline-block">
Total: {{contributorTotal(i, 0) | currency}}
</div>
</div>
</div>
<div class="mt-2 w-40px d-inline-block">&nbsp;</div>
<div class="w-33less13px d-inline-block">
General: {{combinedTotal(1) | currency}}
</div>
<div class="w-33less13px d-inline-block">
Missions: {{combinedTotal(2) | currency}}
</div>
<div class="w-33less13px d-inline-block">
Total: {{combinedTotal(0) | currency}}
</div>
<div class="bb-double"></div>
<button mat-stroked-button class="mt-2" type="button" (click)="addContributor()">Add Contributor</button>
<button mat-raised-button class="mt-2 ml-1" type="submit" [disabled]="!form.valid || submitButtonDisabled">{{ submitButtonText }}</button>
</form>
</div>
<div sideBar class="side-bar">
<table> <table>
<thead>
<tr>
<th>General</th>
<th>Missions</th>
<th>Total</th>
</tr>
</thead>
<tbody> <tbody>
<ng-container *ngFor="let c of form.get('contributions').value; let i = index"> <ng-container *ngFor="let c of contributions; let ci = index">
<tr> <tr>
<td colspan="3" class="pt-1">{{contributorName(i)}}</td> <td colspan="2" class="fw-bold fs-1-2-5">{{c.date}}</td>
<td colspan="3" class="fw-bold fs-1-2-5">{{contributorName(c.contributorId)}}</td>
</tr> </tr>
<tr> <tr>
<td>{{contributorTotal(i, 1) | currency}}</td> <td></td>
<td>{{contributorTotal(i, 2) | currency}}</td> <td class="fw-bold">Type</td>
<td>{{contributorTotal(i, 0) | currency}}</td> <td class="fw-bold">Check</td>
<td class="fw-bold">Fund</td>
<td class="fw-bold">Amount</td>
</tr>
<ng-container *ngFor="let t of c.transactions; let ti = index">
<tr [class.highlight]="ti % 2">
<td rowspan="2" style="width: 30px;">
<button mat-icon-button (click)="deleteTransaction(t.contributorId, ti)"><i ofbicon>delete_forever</i></button>
</td>
<td colspan="4" *ngIf="t.description && t.description.length > 0">{{t.description}}</td>
<td colspan="4" *ngIf="!t.description || t.description.length === 0" class="b-0 p-0"></td>
</tr>
<tr [class.highlight]="ti % 2">
<td [class.remove-top-border]="!t.description || t.description.length === 0">{{transactionType[t.typeId]}}</td>
<td [class.remove-top-border]="!t.description || t.description.length === 0">{{t.checkNumber}}</td>
<td [class.remove-top-border]="!t.description || t.description.length === 0">{{fund[t.fundId]}}</td>
<td [class.remove-top-border]="!t.description || t.description.length === 0">{{t.amount | currency}}</td>
</tr> </tr>
</ng-container> </ng-container>
<tr> <tr>
<td colspan="3" class="pt-1"> <td></td>
Total <td></td>
</td> <td class="fw-bold">General</td>
<td class="fw-bold">Missions</td>
<td class="fw-bold">Total</td>
</tr>
<tr class="highlight-yellow">
<td></td>
<td></td>
<td>{{contributorTotal(c.contributorId, 1) | currency}}</td>
<td>{{contributorTotal(c.contributorId, 2) | currency}}</td>
<td>{{contributorTotal(c.contributorId, 0) | currency}}</td>
</tr> </tr>
<tr> <tr>
<td colspan="5">
<button mat-raised-button (click)="addTransaction(c.contributorId)" >Add Transaction to {{contributorName(c.contributorId)}}</button>
</td>
</tr>
</ng-container>
<tr>
<td colspan="5" class="fw-bold fs-1-2-5">Grand Totals</td>
</tr>
<tr>
<td></td>
<td></td>
<td class="fw-bold">General</td>
<td class="fw-bold">Missions</td>
<td class="fw-bold">Total</td>
</tr>
<tr class="highlight-yellow">
<td></td>
<td></td>
<td>{{combinedTotal(1) | currency}}</td> <td>{{combinedTotal(1) | currency}}</td>
<td>{{combinedTotal(2) | currency}}</td> <td>{{combinedTotal(2) | currency}}</td>
<td>{{combinedTotal(0) | currency}}</td> <td>{{combinedTotal(0) | currency}}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div class="fab-buttons" >
<button mat-fab (click)="addTransaction(-1)"><i ofbicon>add</i></button>
</div>
</div>
<div sideBar class="side-bar">
<button mat-raised-button (click)="addTransaction(-1)" >Add Transaction</button>
<button mat-raised-button (click)="submit()" [disabled]="contributions.length === 0 || submitButtonDisabled" >{{submitButtonText}}</button>
</div> </div>
</secondary-page-component> </secondary-page-component>

View File

@ -2,10 +2,11 @@ import { Component, OnInit } from '@angular/core';
import { Transaction } from './transaction'; import { Transaction } from './transaction';
import { UserService } from '../../services/user.service'; import { UserService } from '../../services/user.service';
import { Contribution } from './contribution'; import { Contribution } from './contribution';
import { FormBuilder, FormGroup, Validators, FormArray } from '@angular/forms';
import { checkNumberValidator } from './check-number-validator';
import { contributorValidator } from './contributor-validator';
import { TransactionService } from '../../services/transaction.service'; import { TransactionService } from '../../services/transaction.service';
import { MatDialog } from '@angular/material';
import { AddTransactionPopupComponent, ValDisplay } from './add-transaction-popup/add-transaction-popup.component';
import { TransactionType } from './transaction-type';
import { Fund } from './fund';
@Component({ @Component({
selector: 'app-add-transaction-page', selector: 'app-add-transaction-page',
@ -16,120 +17,98 @@ export class AddTransactionPageComponent implements OnInit {
errorMessages = []; errorMessages = [];
form: FormGroup; contributions: Contribution[] = [];
submitButtonDisabled: boolean = false; submitButtonDisabled: boolean = false;
submitButtonText: string = "Submit"; submitButtonText: string = "Submit Transactions";
types: {value:number,display:string}[] = []; transactionType = TransactionType;
funds: {value:number,display:string}[] = []; fund = Fund;
transactionTypes: ValDisplay[] = [];
funds: ValDisplay[] = [];
contributors: {value:number,display:string}[] = []; contributors: {value:number,display:string}[] = [];
filteredContributors: {value:number,display:string}[]
constructor(private dialogService: MatDialog, private userService: UserService, private transactionService: TransactionService) {
constructor(private userService: UserService, private formBuilder: FormBuilder, private transactionService: TransactionService) { for(let m in TransactionType) {
this.form = this.formBuilder.group({ if (typeof TransactionType[m] === 'number') {
contributions: this.formBuilder.array([this.getContribution()]) this.transactionTypes.push({value:<any>TransactionType[m], display: m});
}); }
}
for(let m in Fund) {
if (typeof Fund[m] === 'number') {
this.funds.push({value:<any>Fund[m], display: m});
}
}
} }
ngOnInit() { ngOnInit() {
this.types = [{value:1, display: 'Cash'},{value:2, display: 'Check'}];
this.funds = [{value:1, display: 'General'},{value:2, display: 'Missions'}];
this.userService.getAll().subscribe(res => this.contributors = (<any>res).users); this.userService.getAll().subscribe(res => this.contributors = (<any>res).users);
} }
getContributionsFormArray(): FormArray {
return this.form.get('contributions') as FormArray;
addTransaction(contributorId: number) {
const contrib = this.contributors.find(c => c.value === contributorId);
const contributor = this.contributions.find(c => c.contributorId === contributorId);
const lastTransaction = contributor && contributor.transactions.length > 0 ? contributor.transactions[contributor.transactions.length-1] : null;
const ref = this.dialogService.open(AddTransactionPopupComponent, {
data: {
contributors: this.contributors,
funds: this.funds,
types: this.transactionTypes,
contributor: contrib ? contrib : undefined,
typeId: lastTransaction ? lastTransaction.typeId : TransactionType.Cash,
fundId: lastTransaction ? (lastTransaction.fundId === Fund.General ? Fund.Missions : Fund.General) : Fund.General,
checkNumber: lastTransaction ? lastTransaction.checkNumber : ''
} }
getContribution(): FormGroup {
const date = new Date();
const dte = date.getFullYear() + "-" + (date.getMonth()<10?'0':'') + (date.getMonth() + 1) + "-" + (date.getDate()<10?'0':'') + date.getDate();
return this.formBuilder.group({
date: [dte, Validators.required],
contributorId: [0, [Validators.required, contributorValidator(this)]],
transactions: this.formBuilder.array([this.getTransaction()])
}); });
ref.afterClosed().subscribe((trans: Transaction) => {
if (trans) {
let contrib = this.contributions.find(c => c.contributorId === trans.contributorId);
if (!contrib) {
contrib = new Contribution();
contrib.contributorId = trans.contributorId;
contrib.date = trans.date;
contrib.transactions = [];
this.contributions.push(contrib);
}
contrib.transactions.push(trans);
}
});
} }
getTransaction(): FormGroup { deleteContributor(contributorId: number) {
return this.formBuilder.group({ const contrib = this.contributions.findIndex(c => c.contributorId === contributorId);
amount: [null, Validators.required], if (contrib >= 0) {
checkNumber: [''], this.contributions.splice(contrib, 1);
description: [''],
fundId: [1, [Validators.required, Validators.min(1), Validators.max(2)]],
taxYear: [(new Date()).getFullYear(), Validators.required],
typeId: [1, [Validators.required, Validators.min(1), Validators.max(2)]],
}, { validators: checkNumberValidator });
}
onContributorChange(event) {
if (event && event.value) {
if (event.value === -1) {
// Open new user dialog
}
event = event.display;
}
const filterValue = event.toLowerCase();
this.filteredContributors = this.contributors.filter(option => option.display.toLowerCase().indexOf(filterValue) >= 0);
if (this.filteredContributors.length === 0) {
this.filteredContributors.push({value:-1, display:'Add New Contributor'});
} }
} }
contirbutorDisplayFn(contributor?: {value:number,display:string}): string | undefined { deleteTransaction(contributorId: number, transactionIndex: number) {
const contrib = this.contributions.find(c => c.contributorId === contributorId);
if (contrib) {
contrib.transactions.splice(transactionIndex, 1);
}
if (contrib.transactions.length === 0) {
this.deleteContributor(contributorId);
}
}
contributorName(id: number) {
const contributor = this.contributors.find(c => c.value === id);
return contributor ? contributor.display : undefined; return contributor ? contributor.display : undefined;
} }
addTransaction(contributorPosition: number) { contributorTotal(contributorId: number, fundId: number) {
const contributors = this.form.get('contributions') as FormArray; const contrib = this.contributions.find(c => c.contributorId === contributorId);
const transactions = contributors.controls[contributorPosition].get('transactions') as FormArray; if (!contrib) return 0;
const lastTransaction = transactions.value.length > 0 ? transactions.value[transactions.value.length-1] : undefined;
const newTransaction = this.getTransaction();
if (lastTransaction) {
newTransaction.patchValue({
"typeId": lastTransaction.typeId,
"checkNumber": lastTransaction.checkNumber,
"fundId": lastTransaction.fundId === 1 ? 2 : 1
});
}
transactions.push(newTransaction);
}
addContributor() {
const contributors = this.form.get('contributions') as FormArray;
contributors.push(this.getContribution());
}
deleteContributor(index: number) {
const contributors = this.form.get('contributions') as FormArray;
contributors.removeAt(index);
}
deleteTransaction(contributorIndex: number, transactionIndex: number) {
const contributors = this.form.get('contributions') as FormArray;
const transactions = contributors.controls[contributorIndex].get('transactions') as FormArray;
transactions.removeAt(transactionIndex);
if (transactions.length === 0) {
this.deleteContributor(contributorIndex);
}
}
contributorName(index: number) {
const contributors = this.form.get('contributions') as FormArray;
const contributor = contributors.controls[index].get('contributorId');
if (contributor && contributor.value.display) {
return contributor.value.display;
}
}
contributorTotal(index: number, fundId: number) {
const contributors = this.form.get('contributions') as FormArray;
const transactions = contributors.controls[index].get('transactions').value;
var sum = 0; var sum = 0;
transactions.forEach(e => { contrib.transactions.forEach(e => {
if (e.fundId === fundId || fundId === 0) { if (e.fundId === fundId || fundId === 0) {
sum += e.amount; sum += e.amount;
} }
@ -138,9 +117,8 @@ export class AddTransactionPageComponent implements OnInit {
} }
combinedTotal(fundId: number) { combinedTotal(fundId: number) {
const contributors = this.form.get('contributions').value;
var sum = 0; var sum = 0;
contributors.forEach(c => { this.contributions.forEach(c => {
c.transactions.forEach(t => { c.transactions.forEach(t => {
if (t.fundId === fundId || fundId === 0) { if (t.fundId === fundId || fundId === 0) {
sum += +t.amount; sum += +t.amount;
@ -150,23 +128,20 @@ export class AddTransactionPageComponent implements OnInit {
return sum; return sum;
} }
onSubmit() { submit() {
this.submitButtonText = 'Submitting...'; this.submitButtonText = 'Submitting...';
this.submitButtonDisabled = true; this.submitButtonDisabled = true;
var data = this.form.value;
const transactions: Transaction[] = []; const transactions: Transaction[] = [];
for(let c = 0; c < data.contributions.length; c++) { for(let c = 0; c < this.contributions.length; c++) {
const contribution = data.contributions[c] as Contribution; for(let t = 0; t < this.contributions[c].transactions.length; t++) {
for(let t = 0; t < contribution.transactions.length; t++) { transactions.push(this.contributions[c].transactions[t]);
const transaction = contribution.transactions[t] as Transaction;
transaction.contributorId = (<any>contribution.contributorId).value;
transaction.date = contribution.date;
transactions.push(transaction);
} }
} }
console.log(transactions); console.log(transactions);
this.transactionService.createFromArray(transactions).subscribe(x =>{ this.transactionService.createFromArray(transactions).subscribe(x =>{
this.submitButtonText = 'Submit'; this.submitButtonText = 'Submit Transactions';
this.submitButtonDisabled = false; this.submitButtonDisabled = false;
}, e => console.log(e)); }, e => console.log(e));
} }

View File

@ -0,0 +1,49 @@
<div md-dialog-title>
<p>Add Event</p>
</div>
<div md-dialog-content>
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<mat-form-field>
<input matInput placeholder="Date" type="date" formControlName="date" >
</mat-form-field>
<mat-form-field>
<input type="text" placeholder="Contributor" aria-label="Contributor" matInput formControlName="contributor" (ngModelChange)="onContributorChange($event)" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="contributorDisplayFn">
<mat-option *ngFor="let option of filteredContributors" [value]="option">
{{option.display}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<br>
<mat-form-field>
<mat-select formControlName="typeId">
<mat-option *ngFor="let type of types" [value]="type.value" >
{{type.display}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Check Number" type="text" formControlName="checkNumber" >
</mat-form-field>
<div></div>
<mat-form-field class="w-25less10px mw-50less20px">
<mat-select formControlName="fundId">
<mat-option *ngFor="let fund of funds" [value]="fund.value">
{{fund.display}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Amount" type="number" formControlName="amount" >
</mat-form-field>
<br>
<mat-form-field class="w-100">
<input matInput placeholder="Description" type="text" formControlName="description" >
</mat-form-field>
<br>
<button mat-raised-button type="button" (click)="cancel()" >Cancel</button>
<button mat-raised-button type="submit" [disabled]="!form.valid || saveBtnDisabled">{{ saveBtnTxt }}</button>
</form>
</div>

View File

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

View File

@ -0,0 +1,101 @@
import { Component, OnInit, Inject } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormArray } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material';
import { contributorValidator } from '../contributor-validator';
import { Transaction } from '../transaction';
export interface ValDisplay {
value: number;
display: string;
}
export interface DialogData {
contributors: ValDisplay[],
funds: ValDisplay[],
types: ValDisplay[],
contributor: ValDisplay,
date: string,
typeId: number,
fundId: number,
checkNumber: string,
description: string,
taxYear: number
}
@Component({
selector: 'app-add-transaction-popup',
templateUrl: './add-transaction-popup.component.html',
styleUrls: ['./add-transaction-popup.component.css']
})
export class AddTransactionPopupComponent implements OnInit {
form: FormGroup;
saveBtnDisabled: boolean = false;
saveBtnTxt: string = 'Save';
contributors: ValDisplay[] = [];
filteredContributors: ValDisplay[]
funds: ValDisplay[];
types: ValDisplay[];
constructor(private formBuilder: FormBuilder, @Inject(MAT_DIALOG_DATA) public data: DialogData, private dialogRef:MatDialogRef<AddTransactionPopupComponent>) {
this.contributors = this.data.contributors || [];
this.funds = this.data.funds || [];
this.types = this.data.types || [];
const date = new Date();
const dte = date.getFullYear() + "-" + (date.getMonth()<10?'0':'') + (date.getMonth() + 1) + "-" + (date.getDate()<10?'0':'') + date.getDate();
this.form = this.formBuilder.group({
date: [this.data.date || dte, [Validators.required]],
contributor: [this.data.contributor, [Validators.required, contributorValidator(this.contributors)]],
typeId: [this.data.typeId || 1, [Validators.required]],
fundId: [this.data.fundId || 1, [Validators.required]],
checkNumber: [this.data.checkNumber],
description: [this.data.description],
amount: ['', [Validators.required]],
taxYear: [this.data.taxYear || new Date().getFullYear(), [Validators.required]]
});
}
ngOnInit() {
}
contributorDisplayFn(contributor?: {value:number,display:string}): string | undefined {
console.log(contributor);
return contributor ? contributor.display : undefined;
}
onContributorChange(event) {
if (event && event.value) {
if (event.value === -1) {
// Open new user dialog
}
event = event.display;
}
const filterValue = event.toLowerCase();
this.filteredContributors = this.contributors.filter(option => option.display.toLowerCase().indexOf(filterValue) >= 0);
if (this.filteredContributors.length === 0) {
this.filteredContributors.push({value:-1, display:'Add New Contributor'});
}
}
onSubmit() {
const trans = new Transaction();
trans.amount = this.form.value.amount;
trans.checkNumber = this.form.value.checkNumber;
trans.contributorId = this.form.value.contributor.value;
trans.date = this.form.value.date;
trans.description = this.form.value.description;
trans.fundId = this.form.value.fundId;
trans.taxYear = this.form.value.taxYear;
trans.typeId = this.form.value.typeId;
this.dialogRef.close(trans);
}
cancel() {
this.dialogRef.close();
}
}

View File

@ -1,14 +1,14 @@
import { ValidatorFn, ValidationErrors, AbstractControl } from '@angular/forms'; import { ValidatorFn, ValidationErrors, AbstractControl } from '@angular/forms';
import { AddTransactionPageComponent } from './add-transaction-page.component'; import { AddTransactionPageComponent } from './add-transaction-page.component';
export function contributorValidator(comp: AddTransactionPageComponent): ValidatorFn { export function contributorValidator(contributors: {value:number,display:string}[]): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => { return (control: AbstractControl): ValidationErrors | null => {
const val = control.value; const val = control.value;
const error = {'invalidName':{value: val}}; const error = {'invalidName':{value: val}};
if (!val || !val.value) { if (!val || !val.value) {
return error; return error;
} }
const contributor = comp.contributors.findIndex(c => c.value === val.value); const contributor = contributors.findIndex(c => c.value === val.value);
if (contributor >= 0) { if (contributor >= 0) {
return null; return null;
} }

View File

@ -0,0 +1,4 @@
export enum Fund {
General = 1,
Missions = 2
}

View File

@ -0,0 +1,4 @@
export enum TransactionType {
Cash = 1,
Check = 2
}

View File

@ -33,7 +33,7 @@ exports.addArray = async function(transactions) {
try { try {
for(let i = 0; i < transactions.length; i++) { for(let i = 0; i < transactions.length; i++) {
const t = transactions[i]; const t = transactions[i];
const newTrans = getTransaction(t.date, t.typeId, t.check, t.contributorId, t.fundId, t.description, t.amount, t.taxYear); const newTrans = getTransaction(t.date, t.typeId, t.checkNumber, t.contributorId, t.fundId, t.description, t.amount, t.taxYear);
const result = await conn.nonQuery('INSERT INTO Transactions Set ?', newTrans); const result = await conn.nonQuery('INSERT INTO Transactions Set ?', newTrans);
results.push(result); results.push(result);
} }
@ -44,11 +44,11 @@ exports.addArray = async function(transactions) {
return results; return results;
} }
function getTransaction(date, typeId, check, contributorId, fundId, description, amount, taxYear) { function getTransaction(date, typeId, checkNumber, contributorId, fundId, description, amount, taxYear) {
const newTrans = { const newTrans = {
Date: date, Date: date,
TypeId: typeId, TypeId: typeId,
CheckNumber: check, CheckNumber: checkNumber,
ContributorId: contributorId, ContributorId: contributorId,
FundId: fundId, FundId: fundId,
Description: description, Description: description,
@ -58,8 +58,8 @@ function getTransaction(date, typeId, check, contributorId, fundId, description,
return newTrans; return newTrans;
} }
exports.add = async function(date, typeId, check, contributorId, fundId, description, amount, taxYear) { exports.add = async function(date, typeId, checkNumber, contributorId, fundId, description, amount, taxYear) {
const newTrans = getTransaction(date, typeId, check, contributorId, fundId, description, amount, taxYear); const newTrans = getTransaction(date, typeId, checkNumber, contributorId, fundId, description, amount, taxYear);
const newTransResult = await connectionAsync.nonQuery('INSERT INTO Transactions Set ?', newTrans); const newTransResult = await connectionAsync.nonQuery('INSERT INTO Transactions Set ?', newTrans);
return newTransResult; return newTransResult;
} }