server/dummyControllers/TransactionController.js
import dotenv from 'dotenv';
import nodemailer from 'nodemailer';
import Debug from 'debug';
import Transaction from '../dummyModels/Transaction';
import Mail from '../utils/Mail';
import dummyData from '../utils/dummyData';
import { isEmpty } from '../validation/authValidation';
dotenv.config();
const debug = Debug('dev');
const { transactions, accounts, users } = dummyData;
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.USER_EMAIL,
pass: process.env.USER_PASSWORD
}
});
export default class TransactionController {
/**
* @description Credit an account
* @param {Object} req The request object
* @param {Object} res The response object
* @route POST /api/v1/transactions/<account-number>/credit
* @returns {Object} status code, data and message properties
* @access private Admin or staff only
*/
static creditAccount(req, res) {
const { accountNumber } = req.params;
const { creditAmount } = req.body;
if (req.decoded.type !== 'staff') {
return res.status(401).json({
status: 401,
error: 'You are not authorized to carry out that action'
});
}
const accountToCredit = accounts.find(
account => account.accountNumber === parseInt(accountNumber, 10)
);
if (isEmpty(accountToCredit)) {
return res.status(404).json({
status: 404,
error: 'Account does not exist'
});
}
const { balance, owner } = accountToCredit;
const accountOwner = users.find(user => user.id === owner);
const transactionsLastID = transactions[transactions.length - 1].id;
const newID = transactionsLastID + 1;
const transaction = new Transaction();
transaction.id = newID;
transaction.cashier = req.decoded.id;
transaction.createdOn = new Date();
transaction.type = 'credit';
transaction.amount = parseFloat(creditAmount);
transaction.accountNumber = accountNumber;
transaction.owner = owner;
transaction.oldBalance = balance;
transaction.newBalance = balance + parseFloat(creditAmount);
// update the balance of the old account
accountToCredit.balance = transaction.newBalance;
transactions.push(transaction);
// send notification to account owner
const emailNotif = new Mail(transaction, accountOwner, accountNumber, accountToCredit);
transporter.sendMail(emailNotif.getMailOptions(), (err, info) => {
if (err) {
debug(err);
}
debug(info);
});
const data = {
transactionId: transaction.id,
accountNumber,
amount: transaction.amount,
cashier: transaction.cashier,
transactionType: transaction.type,
accountBalance: accountToCredit.balance
};
return res.status(200).json({
status: 200,
data,
message: 'Account credited successfully'
});
}
/**
* @description Credit an account
* @param {Object} req The request object
* @param {Object} res The response object
* @route POST /api/v1/transactions/<account-number>/credit
* @returns {Object} status code, data and message properties
* @access private Admin or staff only
*/
static debitAccount(req, res) {
const { accountNumber } = req.params;
const { debitAmount } = req.body;
if (req.decoded.type !== 'staff') {
return res.status(401).json({
status: 401,
error: 'You are not authorized to carry out that action'
});
}
const accountToDebit = accounts.find(
account => account.accountNumber === parseInt(accountNumber, 10)
);
if (isEmpty(accountToDebit)) {
return res.status(404).json({
status: 404,
error: 'Account does not exist'
});
}
const { balance, owner } = accountToDebit;
if (debitAmount > balance) {
return res.status(400).json({
status: 400,
error: `Insufficient funds, your account balance is ${balance}`
});
}
const accountOwner = users.find(user => user.id === owner);
const transactionsLastID = transactions[transactions.length - 1].id;
const newID = transactionsLastID + 1;
const transaction = new Transaction();
transaction.id = newID;
transaction.cashier = req.decoded.id;
transaction.createdOn = new Date();
transaction.type = 'debit';
transaction.amount = parseFloat(debitAmount);
transaction.accountNumber = accountNumber;
transaction.owner = owner;
transaction.oldBalance = balance;
transaction.newBalance = balance - parseFloat(debitAmount);
// update the balance of the old account
accountToDebit.balance = transaction.newBalance;
transactions.push(transaction);
// send notification to account owner
const emailNotif = new Mail(transaction, accountOwner, accountNumber, accountToDebit);
transporter.sendMail(emailNotif.getMailOptions(), (err, info) => {
if (err) {
debug(err);
}
debug(info);
});
const data = {
transactionId: transaction.id,
accountNumber,
amount: transaction.amount,
cashier: transaction.cashier,
transactionType: transaction.type,
accountBalance: accountToDebit.balance
};
return res.status(200).json({
status: 200,
data,
message: 'Account debited successfully'
});
}
}