From dae8ca061658f17c3c6b2a9ef3ddab068c3698cb Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 5 Jul 2019 20:46:55 -0600 Subject: [PATCH] Working Transactions --- .../add-transaction-page.component.ts | 8 ++- .../src/app/services/transaction.service.ts | 9 +++ Server/src/database/connectionasync.js | 72 ++++++++++++++++++- Server/src/database/transactions.js | 29 +++++++- Server/src/routes/api/require-auth.js | 2 +- Server/src/routes/api/transactions.js | 23 ++---- 6 files changed, 120 insertions(+), 23 deletions(-) diff --git a/Client/src/app/components/add-transaction-page/add-transaction-page.component.ts b/Client/src/app/components/add-transaction-page/add-transaction-page.component.ts index 2bc76eb..74cca79 100644 --- a/Client/src/app/components/add-transaction-page/add-transaction-page.component.ts +++ b/Client/src/app/components/add-transaction-page/add-transaction-page.component.ts @@ -5,6 +5,7 @@ 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 'src/app/services/transaction.service'; @Component({ selector: 'app-add-transaction-page', @@ -26,7 +27,7 @@ export class AddTransactionPageComponent implements OnInit { - constructor(private userService: UserService, private formBuilder: FormBuilder) { + constructor(private userService: UserService, private formBuilder: FormBuilder, private transactionService: TransactionService) { this.form = this.formBuilder.group({ contributions: this.formBuilder.array([this.getContribution()]) }); @@ -148,7 +149,10 @@ export class AddTransactionPageComponent implements OnInit { } } console.log(transactions); - + this.transactionService.createFromArray(transactions).subscribe(x =>{ + this.submitButtonText = 'Submit'; + this.submitButtonDisabled = false; + }, e => console.log(e)); } } diff --git a/Client/src/app/services/transaction.service.ts b/Client/src/app/services/transaction.service.ts index 69c7a00..f4b528d 100644 --- a/Client/src/app/services/transaction.service.ts +++ b/Client/src/app/services/transaction.service.ts @@ -5,6 +5,7 @@ import { Observable, Subject, throwError, of } from 'rxjs'; import { catchError, map, tap, first } from 'rxjs/operators'; import { TRANSACTION_CREATE_URL } from '../constants/urls'; +import { Transaction } from '../components/add-transaction-page/transaction'; @Injectable() export class TransactionService { @@ -17,6 +18,14 @@ export class TransactionService { }; } + createFromArray(transactions: Transaction[]) { + const body = { + transactions: transactions + }; + return this.httpClient.post(TRANSACTION_CREATE_URL, body, this.options) + .pipe(tap(res => console.log(res)), catchError(this.handleError)); + } + create(date: Date, typeId: number, fundId: number, contributorId: number, description: string, amount: number, taxYear: number) { const body = { date: date, diff --git a/Server/src/database/connectionasync.js b/Server/src/database/connectionasync.js index 0a72fa5..cfd9198 100644 --- a/Server/src/database/connectionasync.js +++ b/Server/src/database/connectionasync.js @@ -1,5 +1,7 @@ var connection = require('./connection'); +let inTransaction = false; + exports.query = function(sql, args) { return new Promise(function(resolve, reject){ connection.query(sql,args,function(error,rows,fields){ @@ -22,4 +24,72 @@ exports.nonQuery = function(sql, args) { } }); }); -} \ No newline at end of file +} + +exports.beginTransaction = function() { + const self = this; + if (self.inTransaction === true) { + throw 'Already in a transaction'; + } + self.inTransaction = true; + return new Promise(function(resolve, reject){ + connection.beginTransaction(function(err){ + if (err) { + self.inTransaction = false; + reject(err); + } else { + resolve(self); + } + }) + }); +} + +exports.rollback = function() { + const self = this; + return new Promise(function(resolve, reject){ + if (self.inTransaction === true) { + resolve(); + return; + } + connection.rollback(function(err){ + self.inTransaction = false; + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); +} + +exports.commit = function() { + const self = this; + return new Promise(function(resolve, reject){ + if (self.inTransaction === false) { + resolve(); + return; + } + connection.commit(function(err){ + self.inTransaction = false; + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); +} + +exports.end = function(){ + return new Promise(function(resolve, reject){ + connection.end(function(err){ + if (err) { + reject(err); + } else { + resolve(); + } + + }); + }); +} + diff --git a/Server/src/database/transactions.js b/Server/src/database/transactions.js index eb612be..8f405bd 100644 --- a/Server/src/database/transactions.js +++ b/Server/src/database/transactions.js @@ -22,7 +22,29 @@ exports.getAll = async function() { return result; } -exports.add = async function(date, typeId, check, contributorId, fundId, description, amount, taxYear) { +exports.addArray = async function(transactions) { + let conn = null; + try { + conn = await connectionAsync.beginTransaction(); + } catch (ex) { + throw ex; + } + const results = []; + 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 result = await conn.nonQuery('INSERT INTO Transactions Set ?', newTrans); + results.push(result); + } + await conn.commit(); + } catch (ex) { + throw ex; + } + return results; +} + +function getTransaction(date, typeId, check, contributorId, fundId, description, amount, taxYear) { const newTrans = { Date: date, TypeId: typeId, @@ -33,6 +55,11 @@ exports.add = async function(date, typeId, check, contributorId, fundId, descrip Amount: amount, TaxYear: taxYear }; + 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); const newTransResult = await connectionAsync.nonQuery('INSERT INTO Transactions Set ?', newTrans); return newTransResult; } diff --git a/Server/src/routes/api/require-auth.js b/Server/src/routes/api/require-auth.js index 51a7170..9a3ceea 100644 --- a/Server/src/routes/api/require-auth.js +++ b/Server/src/routes/api/require-auth.js @@ -45,7 +45,7 @@ router.use(upload.single('file'),function(req,res,next){ token.id = +req.signedCookies.tokenId; token.value = req.signedCookies.tokenValue; - auth.verifyToken(token,function(error,isValid){ + auth.verifyToken(token,function(error,isValid,user){ if (error){ removeFile(filename); res.status(400).json({"status":400,"message":"error validating token"}); diff --git a/Server/src/routes/api/transactions.js b/Server/src/routes/api/transactions.js index d45fd24..b04680e 100644 --- a/Server/src/routes/api/transactions.js +++ b/Server/src/routes/api/transactions.js @@ -3,28 +3,15 @@ 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')) { + 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 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}); + if (!req.body.transactions || !req.body.transactions.length || req.body.transactions.length === 0) { + res.status(400).json({"status":400,"message":"must pass an array of transactions in the body"}); } + const result = await dbTransactions.addArray(req.body.transactions); + res.status(200).json({"status":200,"message":"transactions added","result":result}); }); module.exports = router; \ No newline at end of file