timi-codes/Banka

View on GitHub
API/services/transaction.service.js

Summary

Maintainability
D
2 days
Test Coverage
import TransactionModel from '../models/transaction.model';
import AccountModel from '../models/account.model';
import UserModel from '../models/user.model';
 
import mailer from '../utils/mailer';
 
 
const Account = new AccountModel('accounts');
const Transaction = new TransactionModel('transactions');
const User = new UserModel('users');
 
 
/** service that allows cashier perform transaction of user's account */
class TransactionService {
/**
* @description debit user account
* @param {object} a new transaction object
*/
 
Function `debitAccount` has 34 lines of code (exceeds 30 allowed). Consider refactoring.
static async debitAccount(cashierId, accountNumber, amount) {
try {
const account = await Account.findByAccountNumber(Number(accountNumber));
 
if (account) {
if (account.status === 'dormant') {
throw new Error('You can\'t perform a transaction on a dormant account');
}
Similar blocks of code found in 2 locations. Consider refactoring.
if (account.balance >= amount) {
const user = await User.findUserById(Number(account.owner));
 
const transaction = await Transaction.debit(account, amount, cashierId);
 
const mailData = {
subject: 'A transaction occured on your Banka💸💵🏦 account',
text: 'A debit transaction occured on your bank account',
to: user.email,
html: `<b>Amount: ₦${amount}<br/><br/>
Transaction type: debit<br/><br/>
Account Balance: ₦${transaction.newbalance}<br/><br/>
Visit <a href='https://banka-timi.herokuapp.com/'>Banka App</a> today</b>`,
};
 
await mailer(mailData);
 
return {
transactionId: transaction.id,
accountNumber: Number(transaction.accountnumber),
amount,
cashier: transaction.cashier,
transactionType: transaction.transactiontype,
accountBalance: transaction.newbalance,
};
}
throw new Error('account balance is not sufficient');
}
throw new Error('account number doesn\'t exist');
} catch (error) {
throw error;
}
}
 
/**
* @description credit user account
* @param {object} a new transaction object
*/
 
static async creditAccount(cashierId, accountNumber, amount) {
try {
const account = await Account.findByAccountNumber(accountNumber);
 
Similar blocks of code found in 2 locations. Consider refactoring.
if (account) {
const user = await User.findUserById(Number(account.owner));
 
const transaction = await Transaction.credit(account, amount, cashierId);
 
const mailData = {
subject: 'A transaction occured on your Banka💸💵🏦 account',
text: 'A credit transaction occured on your bank account',
to: user.email,
html: `<b>Amount: ₦${amount}<br/><br/>
Transaction type: credit<br/><br/>
Account Balance: ₦${transaction.newbalance}<br/><br/>
Visit <a href='https://banka-timi.herokuapp.com/'>Banka App</a> today</b>`,
};
 
await mailer(mailData);
 
return {
transactionId: transaction.id,
accountNumber: Number(transaction.accountnumber),
amount,
cashier: transaction.cashier,
transactionType: transaction.transactiontype,
accountBalance: transaction.newbalance,
};
}
throw new Error('account number doesn\'t exist');
} catch (error) {
throw error;
}
}
 
/**
* @description this function fetches a user account's account transactions
* @param {object} response
*/
static async getAllTransactions(accountNumber) {
try {
const foundAccount = await Account.findByAccountNumber(accountNumber);
 
if (foundAccount) {
const transactions = await Transaction.getTransactions(Number(foundAccount.accountnumber));
 
Identical blocks of code found in 2 locations. Consider refactoring.
return transactions.map((transaction) => {
const {
id, transactiontype, accountnumber, createdon, oldbalance, newbalance, ...data
} = transaction;
 
return {
transactionId: id,
createdOn: createdon,
type: transactiontype,
accountNumber: accountnumber,
...data,
oldBalance: oldbalance,
newBalance: newbalance,
};
});
}
throw new Error('account number doesn\'t exist');
} catch (error) {
throw error;
}
}
 
/**
* @description this function fetches a single user transaction
* @param {object} response
*/
static async getTransaction(transactionId) {
try {
const transaction = await Transaction.getTransactionById(transactionId);
 
Identical blocks of code found in 2 locations. Consider refactoring.
if (transaction) {
const {
id, transactiontype, accountnumber, createdon, oldbalance, newbalance, ...data
} = transaction;
 
return {
transactionId: id,
createdOn: createdon,
type: transactiontype,
accountNumber: accountnumber,
...data,
oldBalance: oldbalance,
newBalance: newbalance,
};
}
throw new Error('transaction id doesn\'t exist');
} catch (error) {
throw error;
}
}
}
export default TransactionService;