update transactions layout
parent
219120fe71
commit
46b4e1dcd0
|
|
@ -68,6 +68,7 @@ import { AddUserPopupComponent } from './components/popups/add-user-popup/add-us
|
|||
import { UserService } from './services/user.service';
|
||||
import { TransactionService } from './services/transaction.service';
|
||||
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,
|
||||
MembersPageComponent,
|
||||
AddUserPopupComponent,
|
||||
AddTransactionPageComponent
|
||||
AddTransactionPageComponent,
|
||||
AddTransactionPopupComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
|
@ -140,7 +142,8 @@ import { AddTransactionPageComponent } from './components/add-transaction-page/a
|
|||
SharePopupComponent,
|
||||
AddEventPopupComponent,
|
||||
AddUserPopupComponent,
|
||||
VideoPopupComponent],
|
||||
VideoPopupComponent,
|
||||
AddTransactionPopupComponent],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
|
|
|||
|
|
@ -1,85 +1,73 @@
|
|||
.d-inline-block {
|
||||
display: inline-block;
|
||||
.b-0 {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.d-none {
|
||||
.fab-buttons{
|
||||
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 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fs-1-2-5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
background-color: #F3FAFF;
|
||||
}
|
||||
|
||||
.highlight-yellow {
|
||||
background-color: lightyellow;
|
||||
}
|
||||
|
||||
.ml-1 {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.mt-1 {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.mt-2 {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.pt-1 {
|
||||
padding-top: 1rem;
|
||||
.p-0 {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.bb-1 {
|
||||
border-bottom: 1px solid #ff4081;
|
||||
}
|
||||
|
||||
.bb-double {
|
||||
border-bottom: 1px solid #ff4081;
|
||||
border-style: double;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
td, th {
|
||||
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){
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media(max-width: 600px) {
|
||||
.md-inline-block {
|
||||
.fab-buttons{
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mw-50less20px {
|
||||
width: calc(50% - 20px);
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,119 +3,81 @@
|
|||
|
||||
<secondary-page-component [fixedSideBar]="true" >
|
||||
<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"> </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>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>General</th>
|
||||
<th>Missions</th>
|
||||
<th>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<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>
|
||||
<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>
|
||||
<td>{{contributorTotal(i, 1) | currency}}</td>
|
||||
<td>{{contributorTotal(i, 2) | currency}}</td>
|
||||
<td>{{contributorTotal(i, 0) | currency}}</td>
|
||||
<td></td>
|
||||
<td class="fw-bold">Type</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>
|
||||
</ng-container>
|
||||
<tr>
|
||||
<td colspan="3" class="pt-1">
|
||||
Total
|
||||
</td>
|
||||
<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>{{contributorTotal(c.contributorId, 1) | currency}}</td>
|
||||
<td>{{contributorTotal(c.contributorId, 2) | currency}}</td>
|
||||
<td>{{contributorTotal(c.contributorId, 0) | currency}}</td>
|
||||
</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(2) | currency}}</td>
|
||||
<td>{{combinedTotal(0) | currency}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</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>
|
||||
</secondary-page-component>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ import { Component, OnInit } from '@angular/core';
|
|||
import { Transaction } from './transaction';
|
||||
import { UserService } from '../../services/user.service';
|
||||
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 { 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({
|
||||
selector: 'app-add-transaction-page',
|
||||
|
|
@ -16,120 +17,98 @@ export class AddTransactionPageComponent implements OnInit {
|
|||
|
||||
errorMessages = [];
|
||||
|
||||
form: FormGroup;
|
||||
contributions: Contribution[] = [];
|
||||
|
||||
submitButtonDisabled: boolean = false;
|
||||
submitButtonText: string = "Submit";
|
||||
types: {value:number,display:string}[] = [];
|
||||
funds: {value:number,display:string}[] = [];
|
||||
submitButtonText: string = "Submit Transactions";
|
||||
transactionType = TransactionType;
|
||||
fund = Fund;
|
||||
transactionTypes: ValDisplay[] = [];
|
||||
funds: ValDisplay[] = [];
|
||||
contributors: {value:number,display:string}[] = [];
|
||||
filteredContributors: {value:number,display:string}[]
|
||||
|
||||
|
||||
|
||||
constructor(private userService: UserService, private formBuilder: FormBuilder, private transactionService: TransactionService) {
|
||||
this.form = this.formBuilder.group({
|
||||
contributions: this.formBuilder.array([this.getContribution()])
|
||||
});
|
||||
constructor(private dialogService: MatDialog, private userService: UserService, private transactionService: TransactionService) {
|
||||
for(let m in TransactionType) {
|
||||
if (typeof TransactionType[m] === 'number') {
|
||||
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() {
|
||||
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);
|
||||
}
|
||||
|
||||
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 {
|
||||
return this.formBuilder.group({
|
||||
amount: [null, Validators.required],
|
||||
checkNumber: [''],
|
||||
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'});
|
||||
deleteContributor(contributorId: number) {
|
||||
const contrib = this.contributions.findIndex(c => c.contributorId === contributorId);
|
||||
if (contrib >= 0) {
|
||||
this.contributions.splice(contrib, 1);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
addTransaction(contributorPosition: number) {
|
||||
const contributors = this.form.get('contributions') as FormArray;
|
||||
const transactions = contributors.controls[contributorPosition].get('transactions') as FormArray;
|
||||
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);
|
||||
}
|
||||
contributorTotal(contributorId: number, fundId: number) {
|
||||
const contrib = this.contributions.find(c => c.contributorId === contributorId);
|
||||
if (!contrib) return 0;
|
||||
|
||||
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;
|
||||
transactions.forEach(e => {
|
||||
contrib.transactions.forEach(e => {
|
||||
if (e.fundId === fundId || fundId === 0) {
|
||||
sum += e.amount;
|
||||
}
|
||||
|
|
@ -138,9 +117,8 @@ export class AddTransactionPageComponent implements OnInit {
|
|||
}
|
||||
|
||||
combinedTotal(fundId: number) {
|
||||
const contributors = this.form.get('contributions').value;
|
||||
var sum = 0;
|
||||
contributors.forEach(c => {
|
||||
this.contributions.forEach(c => {
|
||||
c.transactions.forEach(t => {
|
||||
if (t.fundId === fundId || fundId === 0) {
|
||||
sum += +t.amount;
|
||||
|
|
@ -150,23 +128,20 @@ export class AddTransactionPageComponent implements OnInit {
|
|||
return sum;
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
submit() {
|
||||
this.submitButtonText = 'Submitting...';
|
||||
this.submitButtonDisabled = true;
|
||||
var data = this.form.value;
|
||||
|
||||
const transactions: Transaction[] = [];
|
||||
for(let c = 0; c < data.contributions.length; c++) {
|
||||
const contribution = data.contributions[c] as Contribution;
|
||||
for(let t = 0; t < contribution.transactions.length; t++) {
|
||||
const transaction = contribution.transactions[t] as Transaction;
|
||||
transaction.contributorId = (<any>contribution.contributorId).value;
|
||||
transaction.date = contribution.date;
|
||||
transactions.push(transaction);
|
||||
for(let c = 0; c < this.contributions.length; c++) {
|
||||
for(let t = 0; t < this.contributions[c].transactions.length; t++) {
|
||||
transactions.push(this.contributions[c].transactions[t]);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(transactions);
|
||||
this.transactionService.createFromArray(transactions).subscribe(x =>{
|
||||
this.submitButtonText = 'Submit';
|
||||
this.submitButtonText = 'Submit Transactions';
|
||||
this.submitButtonDisabled = false;
|
||||
}, e => console.log(e));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
.w-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
import { ValidatorFn, ValidationErrors, AbstractControl } from '@angular/forms';
|
||||
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 => {
|
||||
const val = control.value;
|
||||
const error = {'invalidName':{value: val}};
|
||||
if (!val || !val.value) {
|
||||
return error;
|
||||
}
|
||||
const contributor = comp.contributors.findIndex(c => c.value === val.value);
|
||||
const contributor = contributors.findIndex(c => c.value === val.value);
|
||||
if (contributor >= 0) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
export enum Fund {
|
||||
General = 1,
|
||||
Missions = 2
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
export enum TransactionType {
|
||||
Cash = 1,
|
||||
Check = 2
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ exports.addArray = async function(transactions) {
|
|||
try {
|
||||
for(let i = 0; i < transactions.length; 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);
|
||||
results.push(result);
|
||||
}
|
||||
|
|
@ -44,11 +44,11 @@ exports.addArray = async function(transactions) {
|
|||
return results;
|
||||
}
|
||||
|
||||
function getTransaction(date, typeId, check, contributorId, fundId, description, amount, taxYear) {
|
||||
function getTransaction(date, typeId, checkNumber, contributorId, fundId, description, amount, taxYear) {
|
||||
const newTrans = {
|
||||
Date: date,
|
||||
TypeId: typeId,
|
||||
CheckNumber: check,
|
||||
CheckNumber: checkNumber,
|
||||
ContributorId: contributorId,
|
||||
FundId: fundId,
|
||||
Description: description,
|
||||
|
|
@ -58,8 +58,8 @@ function getTransaction(date, typeId, check, contributorId, fundId, description,
|
|||
return newTrans;
|
||||
}
|
||||
|
||||
exports.add = async function(date, typeId, check, contributorId, fundId, description, amount, taxYear) {
|
||||
const newTrans = getTransaction(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, checkNumber, contributorId, fundId, description, amount, taxYear);
|
||||
const newTransResult = await connectionAsync.nonQuery('INSERT INTO Transactions Set ?', newTrans);
|
||||
return newTransResult;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue