shonubijerry/quick-credit

View on GitHub
server/model/repaymentsModel.js

Summary

Maintainability
A
0 mins
Test Coverage
import uuid from 'uuid';
import Model from './model';
import LoansModel from './loansModel';

/**
* @fileOverview - class manages all users data storage
* @class - RepaymentsModel
* @exports - repaymentsModel.js
* @requires - ./loansModel
* @requires - ../dummy/repayments
* @requires - ../helpers/utils
* */

const loansModel = new LoansModel('loans');

class RepaymentsModel extends Model {
  /**
     * Get a single loan repayments
     * @param {object} loanId
     * @returns {object} an object with loan repayments
     */

  async getLoanRepayments(loanId) {
    try {
      const user = await loansModel.selectWithJoin(
        'amount, tenor, balance, createdon loandate, paymentinstallment monthlyinstallment, loanuser, firstname, lastname, address',
        'loans.id=$1',
        'JOIN users ON (loans.loanuser = users.email)',
        [loanId],
      );
      if (user.rows.length < 1) {
        return 'no-loan';
      }
      const [result] = user.rows;
      const { rows } = await this.selectWhere('*', 'loanid=$1', [loanId]);
      result.repayments = rows;
      return result;
    } catch (error) {
      throw error;
    }
  }

  /**
     * Create a new loan repayment
     * @param {object} loanId id of affected loan
     * @param {object} amount amount to be repaid
     * @returns {object} return object with loan repayment
     */

  async createRepayment(loanId, loan, amount, tenor) {
    try {
      const validationError = RepaymentsModel.validateRepayment(loan, amount, tenor);
      if (validationError) {
        return validationError;
      }
      const paidAmount = amount * tenor;
      const { rows } = await this.insert('id, loanid, amount', '$1, $2, $3', [uuid(), loanId, paidAmount]);
      const update = await loansModel.updateLoanAfterRepayment(loanId, paidAmount, loan.balance);

      const user = await loansModel.selectWithJoin(
        'amount, tenor, balance, createdon loandate, paymentinstallment monthlyinstallment, loanuser, firstname, lastname, address',
        'loans.id=$1',
        'JOIN users ON (loans.loanuser = users.email)',
        [update.id],
      );

      const result = user.rows[0];
      [result.repayment] = rows;
      return result;
    } catch (error) {
      throw error;
    }
  }

  static validateRepayment(loan, amount, tenor) {
    if (!loan) {
      return 'no-loan';
    }
    const expectedAmount = Number.parseFloat(loan.paymentinstallment);
    const paidAmount = Number.parseFloat(amount);
    if (loan.status !== 'approved') {
      return 'not-approved';
    }
    if (expectedAmount !== paidAmount) {
      return 'not-amount';
    }
    if (loan.repaid) {
      return 'loan-repaid';
    }
    if ((amount * tenor) > loan.balance) {
      return 'over-payment';
    }
    return '';
  }
}

export default RepaymentsModel;