Initial Transactions
parent
25f4b1d84c
commit
142c41ae8e
|
|
@ -12,6 +12,7 @@ import { ContactPageComponent } from './components/contact-page/contact-page.com
|
||||||
import { SalvationPageComponent } from './components/salvation-page/salvation-page.component';
|
import { SalvationPageComponent } from './components/salvation-page/salvation-page.component';
|
||||||
import { CampPageComponent } from './components/camp-page/camp-page.component';
|
import { CampPageComponent } from './components/camp-page/camp-page.component';
|
||||||
import { MembersPageComponent } from './components/members-page/members-page.component';
|
import { MembersPageComponent } from './components/members-page/members-page.component';
|
||||||
|
import { AddTransactionPageComponent } from './components/add-transaction-page/add-transaction-page.component';
|
||||||
|
|
||||||
const routes =
|
const routes =
|
||||||
[
|
[
|
||||||
|
|
@ -66,6 +67,10 @@ const routes =
|
||||||
{
|
{
|
||||||
path: 'camp',
|
path: 'camp',
|
||||||
component: CampPageComponent
|
component: CampPageComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'transactions/add',
|
||||||
|
component: AddTransactionPageComponent
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,18 @@ import { WindowRefService } from './services/window-ref.service';
|
||||||
import { EmailService } from './services/email.service';
|
import { EmailService } from './services/email.service';
|
||||||
import { SermonService } from './services/sermon.service';
|
import { SermonService } from './services/sermon.service';
|
||||||
import { LoginService } from './services/login.service';
|
import { LoginService } from './services/login.service';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
import { MatButtonModule,
|
import { MatButtonModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
MatSliderModule,
|
MatSliderModule,
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
MatDialogModule } from '@angular/material';
|
MatDialogModule,
|
||||||
|
MatSelectModule,
|
||||||
|
MatOptionModule,
|
||||||
|
MatAutocompleteModule} from '@angular/material';
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import 'hammerjs';
|
import 'hammerjs';
|
||||||
|
|
||||||
|
|
@ -63,6 +66,8 @@ import { CampPageComponent } from './components/camp-page/camp-page.component';
|
||||||
import { MembersPageComponent } from './components/members-page/members-page.component';
|
import { MembersPageComponent } from './components/members-page/members-page.component';
|
||||||
import { AddUserPopupComponent } from './components/popups/add-user-popup/add-user-popup.component';
|
import { AddUserPopupComponent } from './components/popups/add-user-popup/add-user-popup.component';
|
||||||
import { UserService } from './services/user.service';
|
import { UserService } from './services/user.service';
|
||||||
|
import { TransactionService } from './services/transaction.service';
|
||||||
|
import { AddTransactionPageComponent } from './components/add-transaction-page/add-transaction-page.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -105,22 +110,27 @@ import { UserService } from './services/user.service';
|
||||||
VideoPopupComponent,
|
VideoPopupComponent,
|
||||||
CampPageComponent,
|
CampPageComponent,
|
||||||
MembersPageComponent,
|
MembersPageComponent,
|
||||||
AddUserPopupComponent
|
AddUserPopupComponent,
|
||||||
|
AddTransactionPageComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
//Angular Material Components
|
//Angular Material Components
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
|
MatSelectModule,
|
||||||
|
MatOptionModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
MatSliderModule,
|
MatSliderModule,
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
MatDialogModule,
|
MatDialogModule,
|
||||||
|
MatAutocompleteModule
|
||||||
],
|
],
|
||||||
providers: [LoginService,UserService,GoogleAnalyticsService,SermonService,EventService,EmailService,WindowRefService],
|
providers: [LoginService,UserService,GoogleAnalyticsService,SermonService,TransactionService,EventService,EmailService,WindowRefService],
|
||||||
entryComponents: [AddSermonPopupComponent,
|
entryComponents: [AddSermonPopupComponent,
|
||||||
LoginPopupComponent,
|
LoginPopupComponent,
|
||||||
OkPopupComponent,
|
OkPopupComponent,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
.d-inline-block {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fw-b {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-5 {
|
||||||
|
width: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-15 {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-20 {
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-30 {
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-80 {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-1 {
|
||||||
|
margin: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-1 {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-2 {
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml-1 {
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml-2 {
|
||||||
|
margin-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mr-1 {
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bb-1 {
|
||||||
|
border-bottom: 1px solid #ff4081;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
<div> </div>
|
||||||
|
<h2 class="ml-1 mr-1 bb-1">Add Transactions</h2>
|
||||||
|
<form [formGroup]="form">
|
||||||
|
<div formArrayName="contributions" *ngFor="let item of form.get('contributions').controls; let i = index;">
|
||||||
|
<div class="m-1 mt-2 bb-1" [formGroupName]="i">
|
||||||
|
<button class="w-5" mat-icon-button (click)="deleteContributor(i)">
|
||||||
|
<i ofbicon>delete_forever</i>
|
||||||
|
</button>
|
||||||
|
<mat-form-field class="w-15">
|
||||||
|
<input matInput placeholder="Date" type="date" formControlName="date" >
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="w-80">
|
||||||
|
<input 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-5" mat-icon-button (click)="deleteTransaction(i,a)">
|
||||||
|
<i ofbicon>delete_forever</i>
|
||||||
|
</button>
|
||||||
|
<mat-form-field class="w-15">
|
||||||
|
<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-20">
|
||||||
|
<input matInput placeholder="Check Number" type="text" formControlName="checkNumber" >
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="w-20">
|
||||||
|
<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-20">
|
||||||
|
<input matInput placeholder="Amount" type="number" formControlName="amount" >
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="w-20">
|
||||||
|
<input matInput placeholder="Description" type="text" formControlName="description" >
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="w-15" mat-stroked-button (click)="addTransaction(i)">Add Transaction</button>
|
||||||
|
<div class="ml-1 w-20 d-inline-block">
|
||||||
|
{{contributorName(i)}}
|
||||||
|
</div>
|
||||||
|
<div class="ml-1 w-20 d-inline-block">
|
||||||
|
General: {{contributorTotal(i, 1)}}
|
||||||
|
</div>
|
||||||
|
<div class="w-15 d-inline-block">
|
||||||
|
Missions: {{contributorTotal(i, 2)}}
|
||||||
|
</div>
|
||||||
|
<div class="w-15 d-inline-block">
|
||||||
|
Total: {{contributorTotal(i, 0)}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button mat-stroked-button class="m-1 w-15" (click)="addContributor()">Add Contributor</button>
|
||||||
|
<div class="ml-1 w-20 d-inline-block">
|
||||||
|
Combined
|
||||||
|
</div>
|
||||||
|
<div class="ml-1 w-20 d-inline-block">
|
||||||
|
General: {{combinedTotal(1)}}
|
||||||
|
</div>
|
||||||
|
<div class="w-15 d-inline-block">
|
||||||
|
Missions: {{combinedTotal(2)}}
|
||||||
|
</div>
|
||||||
|
<div class="w-15 d-inline-block">
|
||||||
|
Total: {{combinedTotal(0)}}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AddTransactionPageComponent } from './add-transaction-page.component';
|
||||||
|
|
||||||
|
describe('AddTransactionPageComponent', () => {
|
||||||
|
let component: AddTransactionPageComponent;
|
||||||
|
let fixture: ComponentFixture<AddTransactionPageComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ AddTransactionPageComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(AddTransactionPageComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,137 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Transaction } from './transaction';
|
||||||
|
import { UserService } from 'src/app/services/user.service';
|
||||||
|
import { Contribution } from './contribution';
|
||||||
|
import { FormBuilder, FormGroup, Validators, FormArray } from '@angular/forms';
|
||||||
|
import { checkNumberValidator } from './check-number-validator';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-add-transaction-page',
|
||||||
|
templateUrl: './add-transaction-page.component.html',
|
||||||
|
styleUrls: ['./add-transaction-page.component.css']
|
||||||
|
})
|
||||||
|
export class AddTransactionPageComponent implements OnInit {
|
||||||
|
|
||||||
|
errorMessages = [];
|
||||||
|
|
||||||
|
form: FormGroup;
|
||||||
|
|
||||||
|
addTransactionButtonDisabled: boolean = true;
|
||||||
|
addTransactionButtonText: string = "Submit";
|
||||||
|
types: {value:number,display:string}[] = [];
|
||||||
|
funds: {value:number,display:string}[] = [];
|
||||||
|
contributors: {value:number,display:string}[] = [];
|
||||||
|
filteredContributors: {value:number,display:string}[]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
constructor(private userService: UserService, private formBuilder: FormBuilder) {
|
||||||
|
this.form = this.formBuilder.group({
|
||||||
|
contributions: this.formBuilder.array([this.getContribution()])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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],
|
||||||
|
transactions: this.formBuilder.array([this.getTransaction(), this.getTransaction()])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
console.log(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 {
|
||||||
|
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;
|
||||||
|
transactions.push(this.getTransaction());
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 => {
|
||||||
|
if (e.fundId === fundId || fundId === 0) {
|
||||||
|
sum += e.amount;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
combinedTotal(fundId: number) {
|
||||||
|
const contributors = this.form.get('contributions').value;
|
||||||
|
var sum = 0;
|
||||||
|
contributors.forEach(c => {
|
||||||
|
c.transactions.forEach(t => {
|
||||||
|
if (t.fundId === fundId || fundId === 0) {
|
||||||
|
sum += +t.amount;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { ValidatorFn, FormGroup, ValidationErrors } from '@angular/forms';
|
||||||
|
|
||||||
|
export const checkNumberValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
|
||||||
|
const type = control.get('typeId').value;
|
||||||
|
const numb = control.get('checkNumber').value;
|
||||||
|
if (type === 2 && (!numb || numb === '')) {
|
||||||
|
return { 'checkNumber': true };
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { Transaction } from './transaction';
|
||||||
|
|
||||||
|
export class Contribution {
|
||||||
|
date: string;
|
||||||
|
contributorId: number;
|
||||||
|
transactions: Transaction[] = [];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
export class Transaction {
|
||||||
|
date: string;
|
||||||
|
amount: number;
|
||||||
|
checkNumber: string;
|
||||||
|
contributorId: number;
|
||||||
|
description: string;
|
||||||
|
fundId: number;
|
||||||
|
taxYear: number;
|
||||||
|
typeId: number;
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,9 @@
|
||||||
<div *ngIf="canAddUser">
|
<div *ngIf="canAddUser">
|
||||||
<button (click)="addUserModal()">Add User</button>
|
<button (click)="addUserModal()">Add User</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<button [routerLink]="transactions/add">Add Transaction</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="!user || !user.userName">
|
<div *ngIf="!user || !user.userName">
|
||||||
<button>Login</button>
|
<button>Login</button>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import { UserRights } from 'src/app/constants/user-rights';
|
||||||
import { MatDialog } from '@angular/material';
|
import { MatDialog } from '@angular/material';
|
||||||
import { AddUserPopupComponent } from '../popups/add-user-popup/add-user-popup.component';
|
import { AddUserPopupComponent } from '../popups/add-user-popup/add-user-popup.component';
|
||||||
import { take } from 'rxjs/operators';
|
import { take } from 'rxjs/operators';
|
||||||
|
import { TransactionService } from 'src/app/services/transaction.service';
|
||||||
|
import { LoginPopupComponent } from '../popups/login-popup/login-popup.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-members-page',
|
selector: 'app-members-page',
|
||||||
|
|
@ -19,14 +21,14 @@ export class MembersPageComponent implements OnInit {
|
||||||
return this.user && this.user.canDo(UserRights.userAdd);
|
return this.user && this.user.canDo(UserRights.userAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private loginService: LoginService, private matDialog: MatDialog) { }
|
constructor(private loginService: LoginService, private matDialog: MatDialog, private tservice: TransactionService) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.loginService.isLoggedIn(true).pipe(take(1)).subscribe(r => {
|
this.loginService.isLoggedIn(true).pipe(take(1)).subscribe(r => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
console.log(r);
|
console.log(r);
|
||||||
if (r == false) {
|
if (r == false) {
|
||||||
this.addUserModal();
|
this.matDialog.open(LoginPopupComponent);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.loginService.user.subscribe(u => this.user = u);
|
this.loginService.user.subscribe(u => this.user = u);
|
||||||
|
|
@ -35,5 +37,4 @@ export class MembersPageComponent implements OnInit {
|
||||||
addUserModal() {
|
addUserModal() {
|
||||||
let dialog = this.matDialog.open(AddUserPopupComponent);
|
let dialog = this.matDialog.open(AddUserPopupComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@ export const SERMON_ADD_URL = environment.baseUrl + "/api2/sermons/a/";
|
||||||
export const SERMON_DELETE_URL = environment.baseUrl + "/api2/sermons/a/";
|
export const SERMON_DELETE_URL = environment.baseUrl + "/api2/sermons/a/";
|
||||||
export const SERMON_UPDATE_URL = environment.baseUrl + "/api2/sermons/a/";
|
export const SERMON_UPDATE_URL = environment.baseUrl + "/api2/sermons/a/";
|
||||||
export const SERMON_DOWNLOAD_URL = environment.baseUrl + "/api2/sermons/download/";
|
export const SERMON_DOWNLOAD_URL = environment.baseUrl + "/api2/sermons/download/";
|
||||||
|
export const TRANSACTION_CREATE_URL = environment.baseUrl + "/api2/transactions/a/";
|
||||||
export const USER_CREATE_URL = environment.baseUrl + "/api2/users/a/";
|
export const USER_CREATE_URL = environment.baseUrl + "/api2/users/a/";
|
||||||
|
export const USER_GET_ALL_URL = environment.baseUrl + "/api2/users/a";
|
||||||
export const LOGIN_URL = environment.baseUrl + '/api2/login';
|
export const LOGIN_URL = environment.baseUrl + '/api2/login';
|
||||||
export const LOGIN_VALIDATE_TOKEN = '';
|
export const LOGIN_VALIDATE_TOKEN = '';
|
||||||
export const EMAIL_URL = environment.baseUrl + "/api2/email";
|
export const EMAIL_URL = environment.baseUrl + "/api2/email";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||||
|
|
||||||
|
import { Observable, Subject, throwError, of } from 'rxjs';
|
||||||
|
import { catchError, map, tap, first } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { TRANSACTION_CREATE_URL } from '../constants/urls';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TransactionService {
|
||||||
|
|
||||||
|
private options: {};
|
||||||
|
|
||||||
|
constructor(private httpClient: HttpClient){
|
||||||
|
this.options = {
|
||||||
|
withCredentials: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
create(date: Date, typeId: number, fundId: number, contributorId: number, description: string, amount: number, taxYear: number) {
|
||||||
|
const body = {
|
||||||
|
date: date,
|
||||||
|
typeId: typeId,
|
||||||
|
fundId: fundId,
|
||||||
|
contributorId: contributorId,
|
||||||
|
description: description,
|
||||||
|
amount: amount,
|
||||||
|
taxYear: taxYear
|
||||||
|
};
|
||||||
|
console.log(body);
|
||||||
|
return this.httpClient.post(TRANSACTION_CREATE_URL, body, this.options)
|
||||||
|
.pipe(tap(res => console.log(res)), catchError(this.handleError));
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleError(error: HttpErrorResponse) {
|
||||||
|
if (error.error instanceof ErrorEvent) {
|
||||||
|
// A client-side or network error occurred. Handle it accordingly.
|
||||||
|
console.error('An error occurred:', error.error.message);
|
||||||
|
} else {
|
||||||
|
// The backend returned an unsuccessful response code.
|
||||||
|
// The response body may contain clues as to what went wrong,
|
||||||
|
console.error(
|
||||||
|
`Backend returned code ${error.status}, ` +
|
||||||
|
`body was: ${error.error}`);
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
// return an observable with a user-facing error message
|
||||||
|
return throwError((error && error.error && error.error.message) ? error.error.message :
|
||||||
|
'Something bad happened; please try again later.');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||||
import { Observable, Subject, throwError, of } from 'rxjs';
|
import { Observable, Subject, throwError, of } from 'rxjs';
|
||||||
import { catchError, map, tap, first } from 'rxjs/operators';
|
import { catchError, map, tap, first } from 'rxjs/operators';
|
||||||
|
|
||||||
import { LOGIN_URL, USER_CREATE_URL } from '../constants/urls';
|
import { LOGIN_URL, USER_CREATE_URL, USER_GET_ALL_URL } from '../constants/urls';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserService {
|
export class UserService {
|
||||||
|
|
@ -17,6 +17,11 @@ export class UserService {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAll(){
|
||||||
|
return this.httpClient.get(USER_GET_ALL_URL, this.options)
|
||||||
|
.pipe(tap(res => console.log(res)), catchError(this.handleError));
|
||||||
|
}
|
||||||
|
|
||||||
create(firstName: string, lastName: string, street: string, city: string, state: string, zip: string, country: string) {
|
create(firstName: string, lastName: string, street: string, city: string, state: string, zip: string, country: string) {
|
||||||
const body = {
|
const body = {
|
||||||
firstName: firstName,
|
firstName: firstName,
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,9 @@ function verifyToken(userId, tokenId, token, callback){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
user.rights = rights;
|
user.rights = rights;
|
||||||
|
user.canDo = function(activity) {
|
||||||
|
return this.rights.includes(activity);
|
||||||
|
}.bind(user);
|
||||||
callback(null, isValid, user);
|
callback(null, isValid, user);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
var connectionAsync = require("./connectionasync");
|
||||||
|
|
||||||
|
exports.getAll = async function() {
|
||||||
|
const queryResult = await connectionAsync.query('SELECT * FROM Transactions WHERE DeletedDate IS NULL;');
|
||||||
|
const result = [];
|
||||||
|
if (queryResult && queryResult.rows && queryResult.rows.length > 0) {
|
||||||
|
for(var i = 0 ; i < qqueryResult.rows.length; i++) {
|
||||||
|
const row = queryResult.rows[i];
|
||||||
|
const trans = {};
|
||||||
|
trans.id = row.Id;
|
||||||
|
trans.date = row.Date;
|
||||||
|
trans.typeId = row.TypeId;
|
||||||
|
trans.checkNumber = row.CheckNumber;
|
||||||
|
trans.contributorId = row.ContributorId;
|
||||||
|
trans.fundId = row.FundId;
|
||||||
|
trans.description = row.Description;
|
||||||
|
trans.amount = row.Amount;
|
||||||
|
trans.taxYear = row.TaxYear;
|
||||||
|
result.push(trans);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.add = async function(date, typeId, check, contributorId, fundId, description, amount, taxYear) {
|
||||||
|
const newTrans = {
|
||||||
|
Date: date,
|
||||||
|
TypeId: typeId,
|
||||||
|
CheckNumber: check,
|
||||||
|
ContributorId: contributorId,
|
||||||
|
FundId: fundId,
|
||||||
|
Description: description,
|
||||||
|
Amount: amount,
|
||||||
|
TaxYear: taxYear
|
||||||
|
};
|
||||||
|
const newTransResult = await connectionAsync.nonQuery('INSERT INTO Transactions Set ?', newTrans);
|
||||||
|
return newTransResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -37,31 +37,46 @@ exports.getUser = function(userIdOrUserName, callback){
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.getAll = async function() {
|
||||||
|
const queryResult = await connectionAsync.query('SELECT * FROM Users WHERE DeletedDate IS NULL;');
|
||||||
|
const users = [];
|
||||||
|
if (queryResult && queryResult.rows && queryResult.rows.length > 0) {
|
||||||
|
for(var i = 0; i < queryResult.rows.length; i++) {
|
||||||
|
users.push(rowToUser(queryResult.rows[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
exports.getUser2 = async function(email) {
|
exports.getUser2 = async function(email) {
|
||||||
const queryResult = await connectionAsync.query('SELECT * FROM Users WHERE UserName = ? AND DeletedDate IS NULL;', [email]);
|
const queryResult = await connectionAsync.query('SELECT * FROM Users WHERE UserName = ? AND DeletedDate IS NULL;', [email]);
|
||||||
if (queryResult && queryResult.rows && queryResult.rows.length > 0) {
|
if (queryResult && queryResult.rows && queryResult.rows.length > 0) {
|
||||||
const row = queryResult.rows[0];
|
const row = queryResult.rows[0];
|
||||||
const user = {};
|
return rowToUser(row);
|
||||||
user.id = row.Id;
|
|
||||||
user.userName = row.UserName;
|
|
||||||
user.password = row.Password;
|
|
||||||
user.firstName = row.FirstName;
|
|
||||||
user.lastName = row.LastName;
|
|
||||||
user.street = row.Street;
|
|
||||||
user.city = row.City;
|
|
||||||
user.state = row.State;
|
|
||||||
user.country = row.Country;
|
|
||||||
user.emailVerified = row.EmailVerified;
|
|
||||||
user.emailVerificationCode = row.EmailVerificationCode;
|
|
||||||
user.emailVerificationCodeDate = row.EmailVerificationCodeDate;
|
|
||||||
user.federated = row.Federated;
|
|
||||||
user.federationCode = row.federationCode;
|
|
||||||
return user;
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function rowToUser(row) {
|
||||||
|
const user = {};
|
||||||
|
user.id = row.Id;
|
||||||
|
user.userName = row.UserName;
|
||||||
|
user.password = row.Password;
|
||||||
|
user.firstName = row.FirstName;
|
||||||
|
user.lastName = row.LastName;
|
||||||
|
user.street = row.Street;
|
||||||
|
user.city = row.City;
|
||||||
|
user.state = row.State;
|
||||||
|
user.country = row.Country;
|
||||||
|
user.emailVerified = row.EmailVerified;
|
||||||
|
user.emailVerificationCode = row.EmailVerificationCode;
|
||||||
|
user.emailVerificationCodeDate = row.EmailVerificationCodeDate;
|
||||||
|
user.federated = row.Federated;
|
||||||
|
user.federationCode = row.federationCode;
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
exports.createUser = async function(firstName, lastName, street, city, state, zip, country) {
|
exports.createUser = async function(firstName, lastName, street, city, state, zip, country) {
|
||||||
// Check to see if email already exists
|
// Check to see if email already exists
|
||||||
const tempUserName = firstName + " " + lastName;
|
const tempUserName = firstName + " " + lastName;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ const fs = require('fs');
|
||||||
router.use("/users/a", require("./require-auth"));
|
router.use("/users/a", require("./require-auth"));
|
||||||
router.use("/sermons/a", require("./require-auth"));
|
router.use("/sermons/a", require("./require-auth"));
|
||||||
router.use("/events/a", require("./require-auth"));
|
router.use("/events/a", require("./require-auth"));
|
||||||
|
router.use("/transactions/a", require("./require-auth"));
|
||||||
|
|
||||||
// routes
|
// routes
|
||||||
router.use("/", require("./main"));
|
router.use("/", require("./main"));
|
||||||
|
|
@ -17,6 +18,7 @@ router.use("/sermons", require("./sermons"));
|
||||||
router.use("/events", require("./events"));
|
router.use("/events", require("./events"));
|
||||||
router.use("/login", require("./login"));
|
router.use("/login", require("./login"));
|
||||||
router.use("/email", require("./email"));
|
router.use("/email", require("./email"));
|
||||||
|
router.use("/transactions", require("./transactions"));
|
||||||
|
|
||||||
router.use('/share',require('./share'));
|
router.use('/share',require('./share'));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ router.use(upload.single('file'),function(req,res,next){
|
||||||
req.body.finalPath = finalStorage + req.file.filename;
|
req.body.finalPath = finalStorage + req.file.filename;
|
||||||
req.body.tmpPath = req.file.destination + req.file.filename;
|
req.body.tmpPath = req.file.destination + req.file.filename;
|
||||||
}
|
}
|
||||||
|
res.locals.user = user;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
var express = require('express');
|
||||||
|
var router = express.Router();
|
||||||
|
var dbTransactions = require("../../database/transactions");
|
||||||
|
|
||||||
|
router.post("/a/",async function(req,res) {
|
||||||
|
if (!res.locals.user || !res.locals.user.canDo || !res.locals.user.canDo('transactions_add')) {
|
||||||
|
res.status(401).json({"status":401,"message":"you are not authorized to add a transaction"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const result = await dbTransactions.add(req.body.date, req.body.typeId, req.body.check, req.body.contributorId, req.body.fundId, req.body.descriptions, req.body.amount, req.body.taxYear);
|
||||||
|
console.log(result);
|
||||||
|
console.log("new user");
|
||||||
|
console.log(req.body);
|
||||||
|
console.log(res.locals.user);
|
||||||
|
console.log(res.locals.user.canDo('sermons_add'));
|
||||||
|
console.log(res.locals.user.canDo('sermons_addd'));
|
||||||
|
return;
|
||||||
|
if (!req.body.lastName){
|
||||||
|
res.status(400).json({"status":400,"message":"last name is required fields in the body"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var newUser = await dbUsers.createUser(req.body.firstName, req.body.lastName, req.body.street, req.body.city, req.body.state, req.body.zip, req.body.country);
|
||||||
|
res.status(201).json({"status":201,"message":"user created","user":newUser});
|
||||||
|
} catch (ex) {
|
||||||
|
res.status(500).json({"status":500,"message":ex});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
|
|
@ -3,6 +3,23 @@ var router = express.Router();
|
||||||
var dbUsers = require("../../database/users");
|
var dbUsers = require("../../database/users");
|
||||||
|
|
||||||
|
|
||||||
|
router.get("/a/", async function(req, res) {
|
||||||
|
|
||||||
|
if (!res.locals.user || !res.locals.user.canDo || !res.locals.user.canDo('user_add')) {
|
||||||
|
res.status(401).json({"status":401,"message":"you are not authorized to add a transaction"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const users = await dbUsers.getAll();
|
||||||
|
const usersRes = users.map(x => {
|
||||||
|
return {
|
||||||
|
value: x.id,
|
||||||
|
display: `${x.lastName} ${x.firstName}`
|
||||||
|
};
|
||||||
|
});
|
||||||
|
res.status(201).json({"status":201,"message":"all users","users":usersRes});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
router.post("/a/",async function(req,res) {
|
router.post("/a/",async function(req,res) {
|
||||||
console.log("new user");
|
console.log("new user");
|
||||||
console.log(req.body);
|
console.log(req.body);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue