| Path : /var/www/html/usd_loan_system/app/Http/Controllers/ |
|
B-Con CMD Config cPanel C-Rdp D-Log Info Jump Mass Ransom Symlink vHost Zone-H |
| Current File : /var/www/html/usd_loan_system/app/Http/Controllers/LoanController.php |
<?php
namespace App\Http\Controllers;
use Carbon\Carbon;
use App\Events\InterestWaived;
use App\Events\LoanTransactionUpdated;
use App\Events\RepaymentCreated;
use App\Events\RepaymentReversed;
use App\Events\PayOffReversed;
use App\Events\RepaymentUpdated;
use App\Helpers\GeneralHelper;
use App\Models\Capital;
use App\Models\CustomField;
use App\Models\CustomFieldMeta;
use App\Models\Email;
use App\Models\Guarantor;
use App\Models\JournalEntry;
use App\Models\Loan;
use App\Models\LoanApplication;
use App\Models\LoanCharge;
use App\Models\LoanFee;
use App\Models\LoanGuarantor;
use App\Models\LoanOverduePenalty;
use App\Models\LoanProduct;
use App\Models\LoanProductCharge;
use App\Models\LoanRepayment;
use App\Models\LoanRepaymentMethod;
use App\Models\LoanDisbursedBy;
use App\Models\Borrower;
use App\Models\LoanSchedule;
use App\Models\LoanTransaction;
use App\Models\Setting;
use App\Models\User;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\View;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;
use Laracasts\Flash\Flash;
class LoanController extends Controller
{
public function __construct()
{
$this->middleware(['sentinel', 'branch']);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
if (!Sentinel::hasAccess('loans')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$q = $request->q;
if($q){
$data = Loan::query()
->whereHas('borrower', function($query){
return $query->search();
})
->loan_total_penalty()
->loan_total_fees()
->loan_total_interest()
->loan_total_principal()
->loan_total_interest_waived()
->loan_total_pay_off()
->loan_total_paid()
->where('branch_id', session('branch_id'))
->with(['loan_product:id,name', 'borrower:id,first_name,last_name'])
->orderBy('id', 'desc')
->when($request->status, function ($query) use ($request) {
$query->where(function ($query) use ($request) {
$query->where('status', '=', $request->status);
});
})
->paginate(default_paginate());
}
else{
$data = Loan::query()
->loan_total_penalty()
->loan_total_fees()
->loan_total_interest()
->loan_total_principal()
->loan_total_interest_waived()
->loan_total_pay_off()
->loan_total_paid()
->where('branch_id', session('branch_id'))
->with(['loan_product:id,name', 'borrower:id,first_name,last_name'])
->orderBy('id', 'desc')
->when($request->status, function ($query) use ($request) {
$query->where(function ($query) use ($request) {
$query->where('status', '=', $request->status);
});
})
->paginate(default_paginate());
}
return view('loan.data', compact('data'));
}
public function pending_approval(Request $request)
{
if (!Sentinel::hasAccess('loans')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
if (empty($request->status)) {
$data = Loan::all();
} else {
$data = Loan::where('branch_id', session('branch_id'))->where('status', $request->status)->get();
}
return view('loan.data', compact('data'));
}
public function create(Request $request)
{
if (!Sentinel::hasAccess('loans.create')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$borrowers = array();
foreach (Borrower::all() as $key) {
$borrowers[$key->id] = $key->first_name . ' ' . $key->last_name . '(' . $key->unique_number . ')';
}
$users = [];
foreach (User::all() as $key) {
$users[$key->id] = $key->first_name . ' ' . $key->last_name;
}
$loan_products = array();
foreach (LoanProduct::all() as $key) {
$loan_products[$key->id] = $key->name;
}
$loan_disbursed_by = array();
foreach (LoanDisbursedBy::all() as $key) {
$loan_disbursed_by[$key->id] = $key->name;
}
if (isset($request->product_id)) {
$loan_product = LoanProduct::find($request->product_id);
} else {
$loan_product = LoanProduct::first();
}
if (isset($request->borrower_id)) {
$borrower_id = $request->borrower_id;
} else {
$borrower_id = '';
}
if (empty($loan_product)) {
Flash::warning("No loan product set. You must first set a loan product");
return redirect()->back();
}
$charges = array();
foreach (LoanProductCharge::where('loan_product_id', $loan_product->id)->get() as $key) {
if (!empty($key->charge)) {
$charges[$key->id] = $key->charge->name;
}
}
//get custom fields
$custom_fields = CustomField::where('category', 'loans')->get();
return view(
'loan.create',
compact(
'borrowers',
'loan_disbursed_by',
'loan_products',
'loan_product',
'borrower_id',
'custom_fields',
'charges',
'users'
)
);
}
public function reschedule(Request $request, $id)
{
if (!Sentinel::hasAccess('loans.reschedule')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();
}
$loan = Loan::find($id);
$loan_products = array();
foreach (LoanProduct::all() as $key) {
$loan_products[$key->id] = $key->name;
}
$loan_disbursed_by = array();
foreach (LoanDisbursedBy::all() as $key) {
$loan_disbursed_by[$key->id] = $key->name;
}
if (isset($request->product_id)) {
$loan_product = LoanProduct::find($request->product_id);
} else {
if (empty($loan->product)) {
$loan_product = LoanProduct::first();
} else {
$loan_product = $loan->product;
}
}
if (isset($request->borrower_id)) {
$borrower_id = $request->borrower_id;
} else {
$borrower_id = '';
}
if (empty($loan_product)) {
Flash::warning("No loan product set. You must first set a loan product");
return redirect()->back();
}
$loan_due_items = GeneralHelper::loan_due_items($loan->id);
$paid_items = GeneralHelper::loan_paid_items($loan->id);
if ($request->type == 1) {
$principal = $loan_due_items["principal"] + $loan_due_items["interest"] - $paid_items['principal'] - $paid_items['interest'];
}
if ($request->type == 2) {
$principal = $loan_due_items["principal"] + $loan_due_items["interest"] + $loan_due_items["fees"] - $paid_items['principal'] - $paid_items['interest'] - $paid_items['fees'];
}
if ($request->type == 3) {
$principal = GeneralHelper::loan_total_balance($id);
}
if ($request->type == 0) {
$principal = $loan_due_items["principal"] - $paid_items['principal'];
}
$charges = array();
foreach (LoanProductCharge::where('loan_product_id', $loan_product->id)->get() as $key) {
if (!empty($key->charge)) {
$charges[$key->id] = $key->charge->name;
}
}
//get custom fields
$custom_fields = CustomField::where('category', 'loans')->get();
return view(
'loan.reschedule',
compact(
'loan_disbursed_by',
'loan_products',
'loan_product',
'borrower_id',
'custom_fields',
'charges',
'principal',
'loan'
)
);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
if (!Sentinel::hasAccess('loans.create')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan_product = LoanProduct::find($request->loan_product_id);
if ($request->principal > $loan_product->maximum_principal) {
Flash::warning(translate('principle_greater_than_maximum') . "(" . $loan_product->maximum_principal . ")");
return redirect()->back()->withInput();
}
if ($request->principal < $loan_product->minimum_principal) {
Flash::warning(translate('principle_less_than_minimum') . "(" . $loan_product->minimum_principal . ")");
return redirect()->back()->withInput();
}
if ($request->interest_rate > $loan_product->maximum_interest_rate) {
Flash::warning(translate('interest_greater_than_maximum') . "(" . $loan_product->maximum_interest_rate . ")");
return redirect()->back()->withInput();
}
if ($request->interest_rate < $loan_product->minimum_interest_rate) {
Flash::warning(translate('interest_less_than_minimum') . "(" . $loan_product->minimum_interest_rate . ")");
return redirect()->back()->withInput();
}
/*
if ($request->pay_off_interest_rate > $loan_product->maximum_interest_rate) {
Flash::warning(translate('interest_greater_than_maximum') . "(" . $loan_product->maximum_interest_rate . ")");
return redirect()->back()->withInput();
}
if ($request->pay_off_interest_rate < $loan_product->minimum_interest_rate) {
Flash::warning(translate('interest_less_than_minimum') . "(" . $loan_product->minimum_interest_rate . ")");
return redirect()->back()->withInput();
}
*/
$loan = new Loan();
$loan->principal = $request->principal;
$loan->interest_method = $request->interest_method;
$loan->interest_rate = $request->interest_rate;
$loan->pay_off_interest_rate = $request->pay_off_interest_rate != 0 ? $request->pay_off_interest_rate : $request->interest_rate;
$loan->branch_id = session('branch_id');
$loan->interest_period = $request->interest_period;
$loan->loan_duration = $request->loan_duration;
$loan->loan_duration_type = $request->loan_duration_type;
$loan->repayment_cycle = $request->repayment_cycle;
$loan->decimal_places = $request->decimal_places;
$loan->override_interest = isset($request->override_interest) ? $request->override_interest : 0;
$loan->override_interest_amount = isset($request->override_interest_amount) ? $request->override_interest_amount : 0;
$loan->grace_on_interest_charged = isset($request->grace_on_interest_charged) ? $request->grace_on_interest_charged : 0;
$loan->borrower_id = $request->borrower_id;
$loan->applied_amount = $request->principal;
$loan->loan_officer_id = $request->loan_officer_id;
$loan->user_id = Sentinel::getUser()->id;
$loan->loan_product_id = $request->loan_product_id;
$loan->release_date = $request->release_date;
$date = explode('-', $request->release_date);
$loan->month = $date[1];
$loan->year = $date[0];
if (!empty($request->first_payment_date)) {
$loan->first_payment_date = $request->first_payment_date;
}
$loan->description = $request->description;
$files = array();
if (!empty($request->file('files'))) {
$count = 0;
foreach ($request->file('files') as $key) {
$file = array('files' => $key);
$rules = array('files' => 'required|mimes:jpeg,jpg,bmp,png,pdf,docx,xlsx');
$validator = Validator::make($file, $rules);
if ($validator->fails()) {
Flash::warning(translate('validation_error'));
return redirect()->back()->withInput()->withErrors($validator);
} else {
$fname = "loan_" . uniqid() . '.' . $key->guessExtension();
$files[$count] = $fname;
$key->move(
public_path() . '/uploads',
$fname
);
}
$count++;
}
}
$loan->files = serialize($files);
$loan->save();
//save custom meta
$custom_fields = CustomField::where('category', 'loans')->get();
foreach ($custom_fields as $key) {
$custom_field = new CustomFieldMeta();
$id = $key->id;
$custom_field->name = $request->$id;
$custom_field->parent_id = $loan->id;
$custom_field->custom_field_id = $key->id;
$custom_field->category = "loans";
$custom_field->save();
}
if (!empty($request->charges)) {
//loop through the array
foreach ($request->charges as $key) {
$amount = "charge_amount_" . $key;
$date = "charge_date_" . $key;
$loan_charge = new LoanCharge();
$loan_charge->loan_id = $loan->id;
$loan_charge->user_id = Sentinel::getUser()->id;
$loan_charge->charge_id = $key;
$loan_charge->amount = $request->$amount;
if (!empty($request->$date)) {
$loan_charge->date = $request->$date;
}
$loan_charge->save();
}
}
$period = GeneralHelper::loan_period($loan->id);
$loan = Loan::find($loan->id);
if ($loan->repayment_cycle == 'daily') {
$repayment_cycle = 'day';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' days')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'weekly') {
$repayment_cycle = 'week';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' weeks')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'monthly') {
$repayment_cycle = 'month';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'bi_monthly') {
$repayment_cycle = 'month';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'quarterly') {
$repayment_cycle = 'month';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'semi_annually') {
$repayment_cycle = 'month';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'yearly') {
$repayment_cycle = 'year';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' years')
),
'Y-m-d'
);
}
$loan->save();
GeneralHelper::audit_trail("Added loan with id:" . $loan->id);
Flash::success(translate('successfully_saved'));
return redirect('loan/data');
}
public function show($loan)
{
$this->penalty();
if (!Sentinel::hasAccess('loans.view')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan_disbursed_by = array();
foreach (LoanDisbursedBy::all() as $key) {
$loan_disbursed_by[$key->id] = $key->name;
}
$guarantors = array();
foreach (Guarantor::all() as $key) {
$guarantors[$key->id] = $key->first_name . ' ' . $key->last_name . '(' . $key->unique_number . ')';
}
foreach (LoanGuarantor::where('loan_id', $loan->id)->get() as $key) {
$guarantors = array_except($guarantors, $key->id);
}
$schedules = LoanSchedule::where('loan_id', $loan->id)->orderBy('due_date', 'asc')->get();
$loanCharges = LoanCharge::where('loan_id', $loan->id)->first();
$loanChargesType = null;
if($loanCharges){
$loanChargesType = $loanCharges->charge?$loanCharges->charge->charge_option:null;
}
$custom_fields = CustomFieldMeta::where('category', 'loans')->where('parent_id', $loan->id)->get();
return view(
'loan.show',
compact('loan', 'schedules', 'custom_fields', 'loan_disbursed_by', 'guarantors', 'loanCharges','loanChargesType')
);
}
public function penalty()
{
//check for penalties
//missed payment penalty
$loans = Loan::where('status', 'disbursed')->get();
foreach ($loans as $loan) {
if (!empty($loan->loan_product)) {
if ($loan->loan_product->enable_late_repayment_penalty == 1) {
$schedules = LoanSchedule::where('loan_id', $loan->id)->where(
'missed_penalty_applied',
0
)->orderBy('due_date', 'asc')->get();
foreach ($schedules as $schedule) {
if ($loan->loan_product->late_repayment_penalty_grace_period > 0) {
$date = date_format(
date_add(
date_create($schedule->due_date),
date_interval_create_from_date_string($loan->loan_product->late_repayment_penalty_grace_period . ' days')
),
'Y-m-d'
);
} else {
$date = date("Y-m-d");
}
if ($date < date("Y-m-d")) {
if (
GeneralHelper::loan_total_due_period(
$loan->id,
$schedule->due_date
) > GeneralHelper::loan_total_paid_period(
$loan->id,
$schedule->due_date
)
) {
$sch = LoanSchedule::find($schedule->id);
$sch->missed_penalty_applied = 1;
//determine which amount to use
if ($loan->loan_product->late_repayment_penalty_type == "fixed") {
$sch->penalty = $sch->penalty + $loan->loan_product->late_repayment_penalty_amount;
} else {
if ($loan->loan_product->late_repayment_penalty_calculate == 'overdue_principal') {
$principal = (GeneralHelper::loan_total_principal(
$loan->id,
$schedule->due_date
) - GeneralHelper::loan_paid_item(
$loan->id,
'principal',
$schedule->due_date
));
$sch->penalty = $sch->penalty + (($loan->loan_product->late_repayment_penalty_amount / 100) * $principal);
}
if ($loan->loan_product->late_repayment_penalty_calculate == 'overdue_principal_interest') {
$principal = (GeneralHelper::loan_total_principal(
$loan->id,
$schedule->due_date
) + GeneralHelper::loan_total_interest(
$loan->id,
$schedule->due_date
) - GeneralHelper::loan_paid_item(
$loan->id,
'principal',
$schedule->due_date
) - GeneralHelper::loan_paid_item(
$loan->id,
'interest',
$schedule->due_date
));
$sch->penalty = $sch->penalty + (($loan->loan_product->late_repayment_penalty_amount / 100) * $principal);
}
if ($loan->loan_product->late_repayment_penalty_calculate == 'overdue_principal_interest_fees') {
$principal = (GeneralHelper::loan_total_principal(
$loan->id,
$schedule->due_date
) + GeneralHelper::loan_total_interest(
$loan->id,
$schedule->due_date
) + GeneralHelper::loan_total_fees(
$loan->id,
$schedule->due_date
) - GeneralHelper::loan_paid_item(
$loan->id,
'principal',
$schedule->due_date
) - GeneralHelper::loan_paid_item(
$loan->id,
'interest',
$schedule->due_date
) - GeneralHelper::loan_paid_item(
$loan->id,
'fees',
$schedule->due_date
));
$sch->penalty = $sch->penalty + (($loan->loan_product->late_repayment_penalty_amount / 100) * $principal);
}
if ($loan->loan_product->late_repayment_penalty_calculate == 'total_overdue') {
$principal = (GeneralHelper::loan_total_due_amount(
$loan->id,
$schedule->due_date
) - GeneralHelper::loan_total_paid(
$loan->id,
$schedule->due_date
));
$sch->penalty = $sch->penalty + (($loan->loan_product->late_repayment_penalty_amount / 100) * $principal);
}
}
$sch->save();
}
}
}
}
}
}
}
public function approve(Request $request, $id)
{
if (!Sentinel::hasAccess('loans.approve')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan = Loan::find($id);
if (Sentinel::getUser()->max_approval < $loan->principal) {
Flash::warning(translate('max_approval_exceed'));
return redirect()->back();
}
$loan->status = 'approved';
$loan->approved_date = $request->approved_date;
$loan->approved_notes = $request->approved_notes;
$loan->approved_by_id = Sentinel::getUser()->id;
$loan->approved_amount = $request->approved_amount;
$loan->principal = $request->approved_amount;
$loan->save();
GeneralHelper::audit_trail("Approved loan with id:" . $loan->id);
Flash::success(translate('successfully_saved'));
return redirect('loan/' . $id . '/show');
}
public function unapprove($id)
{
if (!Sentinel::hasAccess('loans.approve')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan = Loan::find($id);
if (Sentinel::getUser()->max_approval < $loan->principal) {
Flash::warning(translate('max_approval_exceed'));
return redirect()->back();;
}
$loan->status = 'pending';
$loan->save();
GeneralHelper::audit_trail("Unapproved loan with id:" . $loan->id);
Flash::success(translate('successfully_saved'));
return redirect('loan/' . $id . '/show');
}
public function disburse(Request $request, $loan)
{
if (!Sentinel::hasAccess('loans.disburse')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan = Loan::find($loan->id);
if (Sentinel::getUser()->max_approval < $loan->principal) {
Flash::warning(translate('max_approval_exceed'));
return redirect()->back();;
}
if ($request->first_payment_date < $request->disbursed_date) {
Flash::warning(translate('disburse_date_greater_than_first_payment'));
return redirect()->back()->withInput();
}
//delete previously created schedules and payments
LoanRepayment::where('loan_id', $loan->id)->delete();
LoanSchedule::where('loan_id', $loan->id)->delete();
$interest_rate = GeneralHelper::determine_interest_rate($loan->id);
$period = GeneralHelper::loan_period($loan->id);
if ($loan->repayment_cycle == 'daily') {
$repayment_cycle = '1 days';
$repayment_type = 'days';
}
if ($loan->repayment_cycle == 'weekly') {
$repayment_cycle = '1 weeks';
$repayment_type = 'weeks';
}
if ($loan->repayment_cycle == 'monthly') {
$repayment_cycle = 'month';
$repayment_type = 'months';
}
if ($loan->repayment_cycle == 'bi_monthly') {
$repayment_cycle = '2 months';
$repayment_type = 'months';
}
if ($loan->repayment_cycle == 'quarterly') {
$repayment_cycle = '4 months';
$repayment_type = 'months';
}
if ($loan->repayment_cycle == 'semi_annually') {
$repayment_cycle = '6 months';
$repayment_type = 'months';
}
if ($loan->repayment_cycle == 'yearly') {
$repayment_cycle = '1 years';
$repayment_type = 'years';
}
if (empty($request->first_payment_date)) {
$first_payment_date = date_format(
date_add(
date_create($request->disbursed_date),
date_interval_create_from_date_string($repayment_cycle)
),
'Y-m-d'
);
} else {
$first_payment_date = $request->first_payment_date;
}
$loan->maturity_date = date_format(
date_add(
date_create($first_payment_date),
date_interval_create_from_date_string($period . ' ' . $repayment_type)
),
'Y-m-d'
);
$loan->status = 'disbursed';
$loan->loan_disbursed_by_id = $request->loan_disbursed_by_id;
$loan->disbursed_notes = $request->disbursed_notes;
$loan->first_payment_date = $first_payment_date;
$loan->disbursed_by_id = Sentinel::getUser()->id;
$loan->disbursed_date = $request->disbursed_date;
$loan->release_date = $request->disbursed_date;
$dateDisbursed = explode('-', $request->disbursed_date);
$loan->month = $dateDisbursed[1];
$loan->year = $dateDisbursed[0];
$loan->save();
//generate schedules until period finished
$next_payment = $first_payment_date;
$balance = $loan->principal;
$total_interest = 0;
$isFullMonth = false;
$isOverMonth = false;
$amortizedPrincipal = $loan->principal;
for ($i = 1; $i <= $period; $i++) {
$loan_schedule = new LoanSchedule();
$loan_schedule->loan_id = $loan->id;
$loan_schedule->branch_id = session('branch_id');
$loan_schedule->borrower_id = $loan->borrower_id;
$loan_schedule->description = "Repayment";
$loan_schedule->due_date = $next_payment;
$datePayment = explode('-', $next_payment);
$loan_schedule->month = $datePayment[1];
$loan_schedule->year = $datePayment[0];
//determine which method to use
$due = 0;
//reducing balance equal installments
// if ($dateDisbursed[2] >= 16 && $dateDisbursed[2] != $datePayment[2]) {
if ($dateDisbursed[2] != $datePayment[2]) {
$diffDays = Carbon::parse($loan->disbursed_date)->diffInDays($first_payment_date);
$days_of_first_month = Carbon::parse($first_payment_date)->daysInMonth;
} else {
$isFullMonth = true;
}
if ($loan->interest_method == 'declining_balance_equal_installments') {
if ($i == 1 && !$isFullMonth) {
$principal = $balance / $period;
$interest = $balance * $interest_rate / $days_of_first_month * $diffDays;
$due = $principal + $interest;
$amortizedPrincipal = $balance - $principal;
} else {
//$isFullMonth = $isOverMonth;
$due = GeneralHelper::amortized_monthly_payment($loan->id, $amortizedPrincipal, $isFullMonth);
$interest = ($interest_rate * $balance);
$principal = ($due - $interest);
}
$loan_schedule->principal = $principal;
if ($loan->grace_on_interest_charged >= $i) {
$loan_schedule->interest = 0;
} else {
$loan_schedule->interest = $interest;
}
$loan_schedule->due = $due;
//determine next balance
$balance = ($balance - ($due - $interest));
$loan_schedule->principal_balance = $balance;
}
//reducing balance equal principle
if ($loan->interest_method == 'declining_balance_equal_principal') {
$principal = $loan->principal / $period;
$loan_schedule->principal = ($principal);
// $interest = ($interest_rate * ($balance));
if ($i == 1 && !$isFullMonth) {
$interest = ((($interest_rate / $days_of_first_month) * $diffDays) * $balance);
} else {
$interest = ($interest_rate * $balance);
}
if ($loan->grace_on_interest_charged >= $i) {
$loan_schedule->interest = 0;
} else {
$loan_schedule->interest = $interest;
}
$loan_schedule->due = $principal + $interest;
//determine next balance
//$balance = ($balance - ($principal + $interest));
$balance = ($balance - ($principal));
$loan_schedule->principal_balance = $balance;
}
//flat method
if ($loan->interest_method == 'flat_rate') {
$principal = $loan->principal / $period;
// $interest = ($interest_rate * $loan->principal);
if ($i == 1 && !$isFullMonth) {
$interest = ((($interest_rate / $days_of_first_month) * $diffDays) * $loan->principal);
} else {
$interest = ($interest_rate * $loan->principal);
}
if ($loan->grace_on_interest_charged >= $i) {
$loan_schedule->interest = 0;
} else {
$loan_schedule->interest = $interest;
}
$loan_schedule->principal = $principal;
$loan_schedule->due = $principal + $interest;
//determine next balance
$balance = ($balance - $principal);
$loan_schedule->principal_balance = $balance;
}
//interest only method
if ($loan->interest_method == 'interest_only') {
if ($i == $period) {
$principal = $loan->principal;
} else {
$principal = 0;
}
// $interest = ($interest_rate * $loan->principal);
if ($i == 1 && !$isFullMonth) {
$interest = ((($interest_rate / $days_of_first_month) * $diffDays) * $loan->principal);
} else {
$interest = ($interest_rate * $loan->principal);
}
if ($loan->grace_on_interest_charged >= $i) {
$loan_schedule->interest = 0;
} else {
$loan_schedule->interest = $interest;
}
$loan_schedule->principal = $principal;
$loan_schedule->due = $principal + $interest;
//determine next balance
$balance = ($balance - $principal);
$loan_schedule->principal_balance = $balance;
}
$total_interest = $total_interest + $interest;
//determine next due date
if ($loan->repayment_cycle == 'daily') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('1 days')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'weekly') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('1 weeks')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'monthly') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('1 months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'bi_monthly') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('2 months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'quarterly') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('4 months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'semi_annually') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('6 months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'yearly') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('1 years')
),
'Y-m-d'
);
}
if ($i == $period) {
$loan_schedule->principal_balance = round($balance);
}
$loan_schedule->save();
}
$loan = Loan::find($loan->id);
$loan->maturity_date = $next_payment;
$loan->save();
$fees_disbursement = 0;
$fees_installment = 0;
$fees_due_date = [];
$fees_due_date_amount = 0;
foreach ($loan->charges as $key) {
if (!empty($key->charge)) {
if ($key->charge->charge_type == "disbursement") {
if ($key->charge->charge_option == "fixed") {
$fees_disbursement = $fees_disbursement + $key->amount;
} else {
if ($key->charge->charge_option == "principal_due") {
$fees_disbursement = $fees_disbursement + ($key->amount * $loan->principal) / 100;
}
if ($key->charge->charge_option == "principal_interest") {
$fees_disbursement = $fees_disbursement + ($key->amount * ($loan->principal + $total_interest)) / 100;
}
if ($key->charge->charge_option == "interest_due") {
$fees_disbursement = $fees_disbursement + ($key->amount * $total_interest) / 100;
}
if ($key->charge->charge_option == "original_principal") {
$fees_disbursement = $fees_disbursement + ($key->amount * $loan->principal) / 100;
}
if ($key->charge->charge_option == "total_due") {
$fees_disbursement = $fees_disbursement + ($key->amount * ($loan->principal + $total_interest)) / 100;
}
}
}
if ($key->charge->charge_type == "installment_fee") {
if ($key->charge->charge_option == "fixed") {
$fees_installment = $fees_installment + $key->amount;
} else {
if ($key->charge->charge_option == "principal_due") {
$fees_installment = $fees_installment + ($key->amount * $loan->principal) / 100;
}
if ($key->charge->charge_option == "principal_interest") {
$fees_installment = $fees_installment + ($key->amount * ($loan->principal + $total_interest)) / 100;
}
if ($key->charge->charge_option == "interest_due") {
$fees_installment = $fees_installment + ($key->amount * $total_interest) / 100;
}
if ($key->charge->charge_option == "original_principal") {
$fees_installment = $fees_installment + ($key->amount * $loan->principal) / 100;
}
if ($key->charge->charge_option == "total_due") {
$fees_installment = $fees_installment + ($key->amount * ($loan->principal + $total_interest)) / 100;
}
}
}
if ($key->charge->charge_type == "specified_due_date") {
if ($key->charge->charge_option == "fixed") {
$fees_due_date_amount = $fees_due_date_amount + $key->amount;
$fees_due_date[$key->charge->date] = $key->amount;
} else {
if ($key->charge->charge_option == "principal_due") {
$fees_due_date_amount = $fees_due_date_amount + ($key->amount * $loan->principal) / 100;
$fees_due_date[$key->charge->date] = ($key->amount * $loan->principal) / 100;
}
if ($key->charge->charge_option == "principal_interest") {
$fees_due_date_amount = $fees_due_date_amount + ($key->amount * ($loan->principal + $total_interest)) / 100;
$fees_due_date[$key->charge->date] = ($key->amount * ($loan->principal + $total_interest)) / 100;
}
if ($key->charge->charge_option == "interest_due") {
$fees_due_date_amount = $fees_due_date_amount + ($key->amount * $total_interest) / 100;
$fees_due_date[$key->charge->date] = ($key->amount * $total_interest) / 100;
}
if ($key->charge->charge_option == "original_principal") {
$fees_due_date_amount = $fees_due_date_amount + ($key->amount * $loan->principal) / 100;
$fees_due_date[$key->charge->date] = ($key->amount * $loan->principal) / 100;
}
if ($key->charge->charge_option == "total_due") {
$fees_due_date_amount = $fees_due_date_amount + ($key->amount * ($loan->principal + $total_interest)) / 100;
$fees_due_date[$key->charge->date] = ($key->amount * ($loan->principal + $total_interest)) / 100;
}
}
}
}
}
//add disbursal transaction
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "disbursement";
$loan_transaction->date = $request->disbursed_date;
$date = explode('-', $request->disbursed_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->debit = $loan->principal;
$loan_transaction->save();
//add interest transaction
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "interest";
$loan_transaction->date = $request->disbursed_date;
$date = explode('-', $request->disbursed_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->debit = $total_interest;
$loan_transaction->save();
//add fees transactions
if ($fees_disbursement > 0) {
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "disbursement_fee";
$loan_transaction->date = $request->disbursed_date;
$date = explode('-', $request->disbursed_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->debit = $fees_disbursement;
$loan_transaction->save();
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "repayment_disbursement";
$loan_transaction->date = $request->disbursed_date;
$date = explode('-', $request->disbursed_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->credit = $fees_disbursement;
$loan_transaction->save();
//add journal entry for payment and charge
if (!empty($loan->loan_product->chart_income_fee)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_income_fee->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->disbursed_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'fee';
$journal->name = "Fee Income";
$journal->loan_id = $loan->id;
$journal->credit = $fees_disbursement;
$journal->reference = $loan_transaction->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_fund_source)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_fund_source->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->disbursed_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'fee';
$journal->name = "Fee Income";
$journal->loan_id = $loan->id;
$journal->debit = $fees_disbursement;
$journal->reference = $loan_transaction->id;
$journal->save();
}
}
if ($fees_installment > 0) {
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "installment_fee";
$loan_transaction->reversible = 1;
$loan_transaction->date = $request->disbursed_date;
$date = explode('-', $request->disbursed_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->debit = $fees_installment;
$loan_transaction->save();
//add installment to schedules
foreach (LoanSchedule::where('loan_id', $loan->id)->get() as $key) {
$schedule = LoanSchedule::find($key->id);
$schedule->fees = $fees_installment;
$schedule->save();
}
}
if ($fees_due_date_amount > 0) {
foreach ($fees_due_date as $key => $value) {
$due_date = GeneralHelper::determine_due_date($loan->id, $key);
if (!empty($due_date)) {
$schedule = LoanSchedule::where('loan_id', $loan->id)->where('due_date', $due_date)->first();
$schedule->fees = $schedule->fees + $value;
$schedule->save();
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->loan_schedule_id = $schedule->id;
$loan_transaction->reversible = 1;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "specified_due_date_fee";
$loan_transaction->date = $due_date;
$date = explode('-', $due_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->debit = $value;
$loan_transaction->save();
}
}
}
//debit and credit the necessary accounts
if (!empty($loan->loan_product->chart_fund_source)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_fund_source->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->disbursed_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'disbursement';
$journal->name = "Loan Disbursement";
$journal->loan_id = $loan->id;
$journal->credit = $loan->principal;
$journal->reference = $loan->id;
$journal->save();
} else {
//alert admin that no account has been set
}
if (!empty($loan->loan_product->chart_loan_portfolio)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_loan_portfolio->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->disbursed_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'disbursement';
$journal->name = "Loan Disbursement";
$journal->loan_id = $loan->id;
$journal->debit = $loan->principal;
$journal->reference = $loan->id;
$journal->save();
} else {
//alert admin that no account has been set
}
if ($loan->loan_product->accounting_rule == "accrual_upfront") {
//we need to save the accrued interest in journal here
if (!empty($loan->loan_product->chart_receivable_interest)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_receivable_interest->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->disbursed_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'accrual';
$journal->name = "Accrued Interest";
$journal->loan_id = $loan->id;
$journal->debit = $total_interest;
$journal->reference = $loan->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_income_interest)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_income_interest->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->disbursed_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'accrual';
$journal->name = "Accrued Interest";
$journal->loan_id = $loan->id;
$journal->credit = $total_interest;
$journal->reference = $loan->id;
$journal->save();
}
}
GeneralHelper::audit_trail("Disbursed loan with id:" . $loan->id);
Flash::success(translate('successfully_saved'));
return redirect('loan/' . $loan->id . '/show');
}
public function rescheduleStore(Request $request, $id)
{
// dd($request);
if (!Sentinel::hasAccess('loans.reschedule')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$l = Loan::find($id);
$l->status = 'rescheduled';
$l->save();
$loan = new Loan();
$loan->principal = $request->principal;
$loan->status = "disbursed";
$loan->interest_method = $request->interest_method;
$loan->interest_rate = $request->interest_rate;
$loan->pay_off_interest_rate = $l->pay_off_interest_rate;
$loan->branch_id = session('branch_id');
$loan->interest_period = $request->interest_period;
$loan->loan_duration = $request->loan_duration;
$loan->loan_duration_type = $request->loan_duration_type;
$loan->repayment_cycle = $request->repayment_cycle;
$loan->decimal_places = $request->decimal_places;
$loan->override_interest = $request->override_interest;
$loan->override_interest_amount = $request->override_interest_amount;
$loan->grace_on_interest_charged = $request->grace_on_interest_charged;
$loan->borrower_id = $l->borrower_id;
$loan->applied_amount = $request->principal;
$loan->user_id = Sentinel::getUser()->id;
$loan->loan_product_id = $request->loan_product_id;
$loan->release_date = $request->release_date;
$dateDisbursed = explode('-', $request->release_date);
$loan->month = $dateDisbursed[1];
$loan->year = $dateDisbursed[0];
if (!empty($request->first_payment_date)) {
$loan->first_payment_date = $request->first_payment_date;
}
$loan->description = $request->description;
$files = array();
if (!empty($request->file('files'))) {
$count = 0;
foreach ($request->file('files') as $key) {
$file = array('files' => $key);
$rules = array('files' => 'required|mimes:jpeg,jpg,bmp,png,pdf,docx,xlsx');
$validator = Validator::make($file, $rules);
if ($validator->fails()) {
Flash::warning(translate('validation_error'));
return redirect()->back()->withInput()->withErrors($validator);
} else {
$files[$count] = $key->getClientOriginalName();
$key->move(
public_path() . '/uploads',
$key->getClientOriginalName()
);
}
$count++;
}
}
$loan->files = serialize($files);
$loan->save();
$interest_rate = GeneralHelper::determine_interest_rate($loan->id);
$period = GeneralHelper::loan_period($loan->id);
//save custom meta
$custom_fields = CustomField::where('category', 'loans')->get();
foreach ($custom_fields as $key) {
$custom_field = new CustomFieldMeta();
$id = $key->id;
$custom_field->name = $request->$id;
$custom_field->parent_id = $loan->id;
$custom_field->custom_field_id = $key->id;
$custom_field->category = "loans";
$custom_field->save();
}
if ($loan->repayment_cycle == 'daily') {
$repayment_cycle = '1 days';
$repayment_type = 'days';
}
if ($loan->repayment_cycle == 'weekly') {
$repayment_cycle = '1 weeks';
$repayment_type = 'weeks';
}
if ($loan->repayment_cycle == 'monthly') {
$repayment_cycle = 'month';
$repayment_type = 'months';
}
if ($loan->repayment_cycle == 'bi_monthly') {
$repayment_cycle = '2 months';
$repayment_type = 'months';
}
if ($loan->repayment_cycle == 'quarterly') {
$repayment_cycle = '4 months';
$repayment_type = 'months';
}
if ($loan->repayment_cycle == 'semi_annually') {
$repayment_cycle = '6 months';
$repayment_type = 'months';
}
if ($loan->repayment_cycle == 'yearly') {
$repayment_cycle = '1 years';
$repayment_type = 'years';
}
if (empty($request->first_payment_date)) {
$first_payment_date = date_format(
date_add(
date_create($request->disbursed_date),
date_interval_create_from_date_string($repayment_cycle)
),
'Y-m-d'
);
} else {
$first_payment_date = $request->first_payment_date;
}
$loan->maturity_date = date_format(
date_add(
date_create($first_payment_date),
date_interval_create_from_date_string($period . ' ' . $repayment_type)
),
'Y-m-d'
);
$loan->status = 'disbursed';
$loan->loan_disbursed_by_id = $request->loan_disbursed_by_id;
$loan->disbursed_notes = $request->disbursed_notes;
$loan->first_payment_date = $first_payment_date;
$loan->disbursed_by_id = Sentinel::getUser()->id;
$loan->disbursed_date = $request->disbursed_date;
$loan->release_date = $request->disbursed_date;
//$date = explode('-', $request->disbursed_date);
$date = explode('-', $request->release_date);
$loan->month = $date[1];
$loan->year = $date[0];
$loan->save();
//generate schedules until period finished
$next_payment = $first_payment_date;
$balance = $loan->principal;
$total_interest = 0;
$isFullMonth = false;
$isOverMonth = false;
$amortizedPrincipal = $loan->principal;
for ($i = 1; $i <= $period; $i++) {
$loan_schedule = new LoanSchedule();
$loan_schedule->loan_id = $loan->id;
$loan_schedule->branch_id = session('branch_id');
$loan_schedule->borrower_id = $loan->borrower_id;
$loan_schedule->description = "Repayment";
$loan_schedule->due_date = $next_payment;
$datePayment = explode('-', $next_payment);
$loan_schedule->month = $datePayment[1];
$loan_schedule->year = $datePayment[0];
//determine which method to use
$due = 0;
// if ($dateDisbursed[2] >= 16 && $dateDisbursed[2] != $datePayment[2]) {
if ($dateDisbursed[2] != $datePayment[2]) {
$diffDays = Carbon::parse($loan->disbursed_date)->diffInDays($first_payment_date);
$days_of_first_month = Carbon::parse($first_payment_date)->daysInMonth;
//$days_of_month = Carbon::parse($next_payment)->daysInMonth;
//if($diffDays - $days_of_first_month == 0 ) $isFullMonth = true;
//if($diffDays - $days_of_first_month > 0) $isOverMonth = true;
} else {
$isFullMonth = true;
}
// $diffDays = Carbon::parse($loan->disbursed_date)->diffInDays($first_payment_date);
// $days_of_first_month = Carbon::parse($first_payment_date)->daysInMonth;
// if($diffDays - $days_of_first_month == 0 ) $isFullMonth = true;
// if($diffDays - $days_of_first_month > 0) $isOverMonth = true;
//reducing balance equal installments
if ($loan->interest_method == 'declining_balance_equal_installments') {
if ($i == 1 && !$isFullMonth) {
$principal = $balance / $period;
$interest = $balance * $interest_rate / $days_of_first_month * $diffDays;
$due = $principal + $interest;
$amortizedPrincipal = $balance - $principal;
} else {
$due = GeneralHelper::amortized_monthly_payment($loan->id, $amortizedPrincipal, $isFullMonth);
$interest = ($interest_rate * $balance);
$principal = ($due - $interest);
}
$loan_schedule->principal = $principal;
if ($loan->grace_on_interest_charged >= $i) {
$loan_schedule->interest = 0;
} else {
$loan_schedule->interest = $interest;
}
$loan_schedule->due = $due;
//determine next balance
$balance = ($balance - ($due - $interest));
$loan_schedule->principal_balance = $balance;
}
//reducing balance equal principle
if ($loan->interest_method == 'declining_balance_equal_principal') {
$principal = $loan->principal / $period;
$loan_schedule->principal = ($principal);
//$interest = ($interest_rate * $balance);
if ($i == 1 && !$isFullMonth) {
$interest = ((($interest_rate / $days_of_first_month) * $diffDays) * $balance);
} else {
$interest = ($interest_rate * $balance);
}
if ($loan->grace_on_interest_charged >= $i) {
$loan_schedule->interest = 0;
} else {
$loan_schedule->interest = $interest;
}
$loan_schedule->due = $principal + $interest;
//determine next balance
//$balance = ($balance - ($principal + $interest));
$balance = $balance - $principal;
$loan_schedule->principal_balance = $balance;
}
//flat method
if ($loan->interest_method == 'flat_rate') {
$principal = $loan->principal / $period;
//$interest = ($interest_rate * $loan->principal);
if ($i == 1 && !$isFullMonth) {
$interest = ((($interest_rate / $days_of_first_month) * $diffDays) * $loan->principal);
} else {
$interest = ($interest_rate * $loan->principal);
}
if ($loan->grace_on_interest_charged >= $i) {
$loan_schedule->interest = 0;
} else {
$loan_schedule->interest = $interest;
}
$loan_schedule->principal = $principal;
$loan_schedule->due = $principal + $interest;
//determine next balance
$balance = ($balance - $principal);
$loan_schedule->principal_balance = $balance;
}
//interest only method
if ($loan->interest_method == 'interest_only') {
if ($i == $period) {
$principal = $loan->principal;
} else {
$principal = 0;
}
//$interest = ($interest_rate * $loan->principal);
if ($i == 1 && !$isFullMonth) {
$interest = ((($interest_rate / $days_of_first_month) * $diffDays) * $loan->principal);
} else {
$interest = ($interest_rate * $loan->principal);
}
if ($loan->grace_on_interest_charged >= $i) {
$loan_schedule->interest = 0;
} else {
$loan_schedule->interest = $interest;
}
$loan_schedule->principal = $principal;
$loan_schedule->due = $principal + $interest;
//determine next balance
$balance = ($balance - $principal);
$loan_schedule->principal_balance = $balance;
}
$total_interest = $total_interest + $interest;
//determine next due date
if ($loan->repayment_cycle == 'daily') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('1 days')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'weekly') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('1 weeks')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'monthly') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('1 months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'bi_monthly') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('2 months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'quarterly') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('4 months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'semi_annually') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('6 months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'yearly') {
$next_payment = date_format(
date_add(
date_create($next_payment),
date_interval_create_from_date_string('1 years')
),
'Y-m-d'
);
}
if ($i == $period) {
$loan_schedule->principal_balance = round($balance);
}
$loan_schedule->save();
}
$loan = Loan::find($loan->id);
$loan->maturity_date = $next_payment;
$loan->save();
$fees_disbursement = 0;
$fees_installment = 0;
$fees_due_date = [];
$fees_due_date_amount = 0;
foreach ($loan->charges as $key) {
if (!empty($key->charge)) {
if ($key->charge->charge_type == "disbursement") {
if ($key->charge->charge_option == "fixed") {
$fees_disbursement = $fees_disbursement + $key->amount;
} else {
if ($key->charge->charge_option == "principal_due") {
$fees_disbursement = $fees_disbursement + ($key->amount * $loan->principal) / 100;
}
if ($key->charge->charge_option == "principal_interest") {
$fees_disbursement = $fees_disbursement + ($key->amount * ($loan->principal + $total_interest)) / 100;
}
if ($key->charge->charge_option == "interest_due") {
$fees_disbursement = $fees_disbursement + ($key->amount * $total_interest) / 100;
}
if ($key->charge->charge_option == "original_principal") {
$fees_disbursement = $fees_disbursement + ($key->amount * $loan->principal) / 100;
}
if ($key->charge->charge_option == "total_due") {
$fees_disbursement = $fees_disbursement + ($key->amount * ($loan->principal + $total_interest)) / 100;
}
}
}
if ($key->charge->charge_type == "installment_fee") {
if ($key->charge->charge_option == "fixed") {
$fees_installment = $fees_installment + $key->amount;
} else {
if ($key->charge->charge_option == "principal_due") {
$fees_installment = $fees_installment + ($key->amount * $loan->principal) / 100;
}
if ($key->charge->charge_option == "principal_interest") {
$fees_installment = $fees_installment + ($key->amount * ($loan->principal + $total_interest)) / 100;
}
if ($key->charge->charge_option == "interest_due") {
$fees_installment = $fees_installment + ($key->amount * $total_interest) / 100;
}
if ($key->charge->charge_option == "original_principal") {
$fees_installment = $fees_installment + ($key->amount * $loan->principal) / 100;
}
if ($key->charge->charge_option == "total_due") {
$fees_installment = $fees_installment + ($key->amount * ($loan->principal + $total_interest)) / 100;
}
}
}
if ($key->charge->charge_type == "specified_due_date") {
if ($key->charge->charge_option == "fixed") {
$fees_due_date_amount = $fees_due_date_amount + $key->amount;
$fees_due_date[$key->charge->date] = $key->amount;
} else {
if ($key->charge->charge_option == "principal_due") {
$fees_due_date_amount = $fees_due_date_amount + ($key->amount * $loan->principal) / 100;
$fees_due_date[$key->charge->date] = ($key->amount * $loan->principal) / 100;
}
if ($key->charge->charge_option == "principal_interest") {
$fees_due_date_amount = $fees_due_date_amount + ($key->amount * ($loan->principal + $total_interest)) / 100;
$fees_due_date[$key->charge->date] = ($key->amount * ($loan->principal + $total_interest)) / 100;
}
if ($key->charge->charge_option == "interest_due") {
$fees_due_date_amount = $fees_due_date_amount + ($key->amount * $total_interest) / 100;
$fees_due_date[$key->charge->date] = ($key->amount * $total_interest) / 100;
}
if ($key->charge->charge_option == "original_principal") {
$fees_due_date_amount = $fees_due_date_amount + ($key->amount * $loan->principal) / 100;
$fees_due_date[$key->charge->date] = ($key->amount * $loan->principal) / 100;
}
if ($key->charge->charge_option == "total_due") {
$fees_due_date_amount = $fees_due_date_amount + ($key->amount * ($loan->principal + $total_interest)) / 100;
$fees_due_date[$key->charge->date] = ($key->amount * ($loan->principal + $total_interest)) / 100;
}
}
}
}
}
//add disbursal transaction
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "disbursement";
$loan_transaction->date = $request->disbursed_date;
//$date = explode('-', $request->disbursed_date);
$date = explode('-', $request->release_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->debit = $loan->principal;
$loan_transaction->save();
//add interest transaction
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "interest";
$loan_transaction->date = $request->disbursed_date;
//$date = explode('-', $request->disbursed_date);
$date = explode('-', $request->release_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->debit = $total_interest;
$loan_transaction->save();
//add fees transactions
if ($fees_disbursement > 0) {
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "disbursement_fee";
$loan_transaction->date = $request->disbursed_date;
//$date = explode('-', $request->disbursed_date);
$date = explode('-', $request->release_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->debit = $fees_disbursement;
$loan_transaction->save();
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "repayment_disbursement";
$loan_transaction->date = $request->disbursed_date;
//$date = explode('-', $request->disbursed_date);
$date = explode('-', $request->release_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->credit = $fees_disbursement;
$loan_transaction->save();
//add journal entry for payment and charge
if (!empty($loan->loan_product->chart_income_fee)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_income_fee->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->disbursed_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'fee';
$journal->name = "Fee Income";
$journal->loan_id = $loan->id;
$journal->credit = $fees_disbursement;
$journal->reference = $loan_transaction->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_fund_source)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_fund_source->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->disbursed_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'fee';
$journal->name = "Fee Income";
$journal->loan_id = $loan->id;
$journal->debit = $fees_disbursement;
$journal->reference = $loan_transaction->id;
$journal->save();
}
}
if ($fees_installment > 0) {
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "installment_fee";
$loan_transaction->reversible = 1;
$loan_transaction->date = $request->disbursed_date;
$date = explode('-', $request->disbursed_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->debit = $fees_installment;
$loan_transaction->save();
//add installment to schedules
foreach (LoanSchedule::where('loan_id', $loan->id)->get() as $key) {
$schedule = LoanSchedule::find($key->id);
$schedule->fees = $fees_installment;
$schedule->save();
}
}
if ($fees_due_date_amount > 0) {
foreach ($fees_due_date as $key => $value) {
$due_date = GeneralHelper::determine_due_date($loan->id, $key);
if (!empty($due_date)) {
$schedule = LoanSchedule::where('loan_id', $loan->id)->where('due_date', $due_date)->first();
$schedule->fees = $schedule->fees + $value;
$schedule->save();
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->loan_schedule_id = $schedule->id;
$loan_transaction->reversible = 1;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "specified_due_date_fee";
$loan_transaction->date = $due_date;
$date = explode('-', $due_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->debit = $value;
$loan_transaction->save();
}
}
}
//debit and credit the necessary accounts
if (!empty($loan->loan_product->chart_fund_source)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_fund_source->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->disbursed_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'disbursement';
$journal->name = "Loan Disbursement";
$journal->loan_id = $loan->id;
$journal->credit = $loan->principal;
$journal->reference = $loan->id;
$journal->save();
} else {
//alert admin that no account has been set
}
if (!empty($loan->loan_product->chart_loan_portfolio)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_loan_portfolio->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->disbursed_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'disbursement';
$journal->name = "Loan Disbursement";
$journal->loan_id = $loan->id;
$journal->debit = $loan->principal;
$journal->reference = $loan->id;
$journal->save();
} else {
//alert admin that no account has been set
}
if ($loan->loan_product->accounting_rule == "accrual_upfront") {
//we need to save the accrued interest in journal here
if (!empty($loan->loan_product->chart_receivable_interest)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_receivable_interest->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->disbursed_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'accrual';
$journal->name = "Accrued Interest";
$journal->loan_id = $loan->id;
$journal->debit = $total_interest;
$journal->reference = $loan->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_income_interest)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_income_interest->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->disbursed_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'accrual';
$journal->name = "Accrued Interest";
$journal->loan_id = $loan->id;
$journal->credit = $total_interest;
$journal->reference = $loan->id;
$journal->save();
}
}
GeneralHelper::audit_trail("Rescheduled loan with id:" . $l->id);
Flash::success(translate('successfully_saved'));
return redirect('loan/' . $loan->id . '/show');
}
public function undisburse($id)
{
if (!Sentinel::hasAccess('loans.disburse')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan = Loan::find($id);
if (Sentinel::getUser()->max_approval < $loan->principal) {
Flash::warning(translate('max_approval_exceed'));
return redirect()->back();;
}
//delete previously created schedules and payments
LoanSchedule::where('loan_id', $id)->delete();
LoanRepayment::where('loan_id', $id)->delete();
Capital::where('loan_id', $id)->delete();
$loan->status = 'approved';
$loan->save();
//lets reverse all transactions that have been made for this loan
foreach (LoanTransaction::where('loan_id', $id)->where('reversed', 0)->get() as $key) {
$loan_transaction = LoanTransaction::find($key->id);
if ($key->debit > $key->credit) {
$loan_transaction->credit = $loan_transaction->debit;
} else {
$loan_transaction->debit = $loan_transaction->credit;
}
$loan_transaction->reversible = 0;
$loan_transaction->reversed = 1;
$loan_transaction->reversal_type = 'system';
$loan_transaction->save();
//reverse journal transactions
foreach (JournalEntry::where('reference', $key->id)->where(
'loan_id',
$id
)->get() as $k) {
$journal = JournalEntry::find($k->id);
if ($k->debit > $k->credit) {
$journal->credit = $journal->debit;
} else {
$journal->debit = $journal->credit;
}
$journal->save();
}
}
GeneralHelper::audit_trail("Undisbursed loan with id:" . $loan->id);
Flash::success(translate('successfully_saved'));
return redirect('loan/' . $loan->id . '/show');
}
public function decline(Request $request, $id)
{
if (!Sentinel::hasAccess('loans.approve')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan = Loan::find($id);
$loan->status = 'declined';
$loan->declined_date = $request->declined_date;
$loan->declined_notes = $request->declined_notes;
$loan->declined_by_id = Sentinel::getUser()->id;
$loan->save();
GeneralHelper::audit_trail("Declined loan with id:" . $loan->id);
Flash::success(translate('successfully_saved'));
return redirect('loan/' . $id . '/show');
}
public function write_off(Request $request, $id)
{
if (!Sentinel::hasAccess('loans.writeoff')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan = Loan::find($id);
$loan->status = 'written_off';
$loan->written_off_date = $request->written_off_date;
$loan->written_off_notes = $request->written_off_notes;
$loan->written_off_by_id = Sentinel::getUser()->id;
$loan->save();
$amount = GeneralHelper::loan_due_items($loan->id)["principal"] - GeneralHelper::loan_paid_items($loan->id)["principal"];
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "write_off";
$loan_transaction->date = $request->written_off_date;
$loan_transaction->reversible = 1;
$date = explode('-', $request->written_off_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->credit = GeneralHelper::loan_total_balance($loan->id);
$loan_transaction->notes = $request->written_off_notes;
$loan_transaction->save();
//fire payment added event
//debit and credit the necessary accounts
//return $allocation;
//principal
if (!empty($loan->loan_product->chart_loan_portfolio)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_loan_portfolio->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'close_write_off';
$journal->name = "Loan Written Off";
$journal->loan_id = $loan->id;
$journal->loan_repayment_id = $loan_transaction->id;
$journal->credit = $amount;
$journal->reference = $loan_transaction->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_loans_written_off)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_fund_source->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'close_write_off';
$journal->name = "Loan Written Off";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->debit = $amount;
$journal->reference = $loan_transaction->id;
$journal->save();
}
GeneralHelper::audit_trail("Write off loan with id:" . $loan->id);
Flash::success(translate('successfully_saved'));
return redirect('loan/' . $id . '/show');
}
public function withdraw(Request $request, $id)
{
if (!Sentinel::hasAccess('loans.withdraw')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan = Loan::find($id);
$loan->status = 'withdrawn';
$loan->withdrawn_date = $request->withdrawn_date;
$loan->withdrawn_notes = $request->withdrawn_notes;
$loan->withdrawn_by_id = Sentinel::getUser()->id;
$loan->save();
GeneralHelper::audit_trail("Withdraw loan with id:" . $loan->id);
Flash::success(translate('successfully_saved'));
return redirect('loan/' . $id . '/show');
}
public function unwithdraw($id)
{
if (!Sentinel::hasAccess('loans.withdraw')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan = Loan::find($id);
$loan->status = 'disbursed';
$loan->save();
GeneralHelper::audit_trail("Unwithdraw loan with id:" . $loan->id);
Flash::success(translate('successfully_saved'));
return redirect('loan/' . $id . '/show');
}
public function unwrite_off($id)
{
if (!Sentinel::hasAccess('loans.writeoff')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan = Loan::find($id);
$loan->status = 'disbursed';
$loan->save();
GeneralHelper::audit_trail("Unwriteoff loan with id:" . $loan->id);
Flash::success(translate('successfully_saved'));
return redirect('loan/' . $id . '/show');
}
public function edit($loan)
{
if (!Sentinel::hasAccess('loans.update')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
if ($loan->status == 'disbursed') {
Flash::warning(translate('validation_error'));
return redirect('loan/data');
}
$borrowers = array();
foreach (Borrower::all() as $key) {
$borrowers[$key->id] = $key->first_name . ' ' . $key->last_name . '(' . $key->unique_number . ')';
}
$users = [];
foreach (User::all() as $key) {
$users[$key->id] = $key->first_name . ' ' . $key->last_name;
}
$loan_products = array();
foreach (LoanProduct::all() as $key) {
$loan_products[$key->id] = $key->name;
}
$loan_disbursed_by = array();
foreach (LoanDisbursedBy::all() as $key) {
$loan_disbursed_by[$key->id] = $key->name;
}
$loan_overdue_penalties = array();
foreach (LoanOverduePenalty::all() as $key) {
$loan_overdue_penalties[$key->id] = $key->name;
}
//get custom fields
$custom_fields = CustomField::where('category', 'loans')->get();
$loan_fees = LoanFee::all();
return view(
'loan.edit',
compact(
'loan',
'borrowers',
'loan_disbursed_by',
'loan_products',
'custom_fields',
'loan_fees',
'loan_overdue_penalties',
'users'
)
);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
if (!Sentinel::hasAccess('loans.update')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan = Loan::find($id);
$loan->principal = $request->principal;
$loan->applied_amount = $request->principal;
$loan->interest_method = $request->interest_method;
$loan->interest_rate = $request->interest_rate;
$loan->pay_off_interest_rate = $request->pay_off_interest_rate != 0 ? $request->pay_off_interest_rate : $request->interest_rate;
$loan->interest_period = $request->interest_period;
$loan->loan_duration = $request->loan_duration;
$loan->loan_duration_type = $request->loan_duration_type;
$loan->repayment_cycle = $request->repayment_cycle;
$loan->decimal_places = $request->decimal_places;
$loan->override_interest = isset($request->override_interest) ? $request->override_interest : 0;
$loan->override_interest_amount = isset($request->override_interest_amount) ? $request->override_interest_amount : 0;
$loan->grace_on_interest_charged = isset($request->grace_on_interest_charged) ? $request->grace_on_interest_charged : 0;
$loan->borrower_id = $request->borrower_id;
$loan->loan_product_id = $request->loan_product_id;
$loan->loan_officer_id = $request->loan_officer_id;
$loan->release_date = $request->release_date;
$date = explode('-', $request->release_date);
$loan->month = $date[1];
$loan->year = $date[0];
if (!empty($request->first_payment_date)) {
$loan->first_payment_date = $request->first_payment_date;
}
$loan->description = $request->description;
$files = unserialize($loan->files);
$count = count($files);
if (!empty($request->file('files'))) {
foreach ($request->file('files') as $key) {
$count++;
$file = array('files' => $key);
$rules = array('files' => 'required|mimes:jpeg,jpg,bmp,png,pdf,docx,xlsx');
$validator = Validator::make($file, $rules);
if ($validator->fails()) {
Flash::warning(translate('validation_error'));
return redirect()->back()->withInput()->withErrors($validator);
} else {
$fname = "loan_" . uniqid() . '.' . $key->guessExtension();
$files[$count] = $fname;
$key->move(
public_path() . '/uploads',
$fname
);
}
}
}
$loan->files = serialize($files);
$loan->save();
$custom_fields = CustomField::where('category', 'loans')->get();
foreach ($custom_fields as $key) {
if (!empty(CustomFieldMeta::where('custom_field_id', $key->id)->where('parent_id', $id)->where(
'category',
'loans'
)->first())) {
$custom_field = CustomFieldMeta::where('custom_field_id', $key->id)->where(
'parent_id',
$id
)->where('category', 'loans')->first();
} else {
$custom_field = new CustomFieldMeta();
}
$kid = $key->id;
$custom_field->name = $request->$kid;
$custom_field->parent_id = $id;
$custom_field->custom_field_id = $key->id;
$custom_field->category = "loans";
$custom_field->save();
}
LoanCharge::where('loan_id', $loan->id)->delete();
if (!empty($request->charges)) {
//loop through the array
foreach ($request->charges as $key) {
$amount = "charge_amount_" . $key;
$date = "charge_date_" . $key;
$loan_charge = new LoanCharge();
$loan_charge->loan_id = $loan->id;
$loan_charge->user_id = Sentinel::getUser()->id;
$loan_charge->charge_id = $key;
$loan_charge->amount = $request->$amount;
if (!empty($request->$date)) {
$loan_charge->date = $request->$date;
}
$loan_charge->save();
}
}
GeneralHelper::audit_trail("Updated loan with id:" . $loan->id);
Flash::success(translate('successfully_saved'));
return redirect('loan/data');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function delete($id)
{
if (!Sentinel::hasAccess('loans.delete')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
Loan::destroy($id);
LoanSchedule::where('loan_id', $id)->delete();
LoanRepayment::where('loan_id', $id)->delete();
Guarantor::where('loan_id', $id)->delete();
LoanCharge::where('loan_id', $id)->delete();
GeneralHelper::audit_trail("Deleted loan with id:" . $id);
Flash::success(translate('successfully_deleted'));
return redirect('loan/data');
}
public function deleteFile(Request $request, $id)
{
if (!Sentinel::hasAccess('loans.delete')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan = Loan::find($id);
$files = unserialize($loan->files);
@unlink(public_path() . '/uploads/' . $files[$request->id]);
$files = array_except($files, [$request->id]);
$loan->files = serialize($files);
$loan->save();
}
public function waiveInterest(Request $request, $loan)
{
if (!Sentinel::hasAccess('repayments.update')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$amount = GeneralHelper::loan_total_interest($loan->id) - GeneralHelper::loan_paid_items(
$loan->id,
$loan->release_date,
date("Y-m-d")
)["interest"];
if ($request->amount > round($amount, 2)) {
Flash::warning("Amount is more than the total interest(" . $amount . ')');
return redirect()->back()->withInput();
}
if ($request->date > date("Y-m-d")) {
Flash::warning(translate('future_date_error'));
return redirect()->back()->withInput();
}
if ($request->date < $loan->disbursed_date) {
Flash::warning(translate('early_date_error'));
return redirect()->back()->withInput();
}
//add interest transaction
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "waiver";
$loan_transaction->date = $request->date;
$loan_transaction->reversible = 0;
$date = explode('-', $request->date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->credit = $request->amount;
$loan_transaction->notes = $request->notes;
$loan_transaction->save();
event(new InterestWaived($loan_transaction));
GeneralHelper::audit_trail("Waived interest for loan with id " . $loan->id);
Flash::success("Waived interest successfully saved");
return redirect()->back();
}
public function waivePenalty(Request $request, $scheduleId)
{
if (!Sentinel::hasAccess('repayments.update')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
// $scheduleId = $request->schedule_id;
$loanSchedule = LoanSchedule::findOrFail($request->schedule_id);
$amount = $loanSchedule->penalty;
if ($request->amount > $amount) {
Flash::warning("Amount is more than the penalty (" . $amount . ')');
return redirect()->back()->withInput();
}
$loanSchedule->penalty = $loanSchedule->penalty - $request->amount;
$loanSchedule->penalty_waived = $request->amount;
// dd($loanSchedule,$request->schedule_id);
$loanSchedule->save();
// event(new InterestWaived($loan_transaction));
GeneralHelper::audit_trail("Waived penalty for loan schedule with id " . $loanSchedule->id);
Flash::success("Waive Penalty is successfully saved");
return redirect()->back();
}
public function indexRepayment(Request $request)
{
if (!Sentinel::hasAccess('repayments')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$date_range = $this->getDateRange($request->date_range);
$start_date = $date_range->start_date;
$end_date = $date_range->end_date;
$data = LoanTransaction::query()
->with(['borrower', 'user', 'loan_repayment_method:id,name'])
->whereIn('transaction_type', ['repayment', 'pay_off', 'overpay'])
->where('reversed', 0)
->where('branch_id', session('branch_id'))
// if($start_date && $end_date){
->whereBetween('date',[$start_date, $end_date]);
// }
$data = $data->orderBy('id','desc')->paginate(default_paginate());
return view('loan_repayment.data', compact('data','start_date','end_date'));
}
//loan repayments
public function createBulkRepayment()
{
if (!Sentinel::hasAccess('repayments.create')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loans = array();
foreach (Loan::all() as $key) {
$loans[$key->id] = $key->borrower->first_name . ' ' . $key->borrower->last_name . '(' . translate(
'loan',
1
) . '#' . $key->id . ',' . translate(
'due',
1
) . ':' . GeneralHelper::loan_total_balance($key->id) . ')';
}
$repayment_methods = array();
foreach (LoanRepaymentMethod::all() as $key) {
$repayment_methods[$key->id] = $key->name;
}
$custom_fields = CustomField::where('category', 'repayments')->get();
return view('loan_repayment.bulk', compact('loan', 'repayment_methods', 'custom_fields', 'loans'));
}
public function storeBulkRepayment(Request $request)
{
if (!Sentinel::hasAccess('repayments.create')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
for ($i = 1; $i <= 20; $i++) {
$amount = "repayment_amount" . $i;
$loan_id = "loan_id" . $i;
$repayment_method = "repayment_method_id" . $i;
$receipt = "receipt" . $i;
$collected_date = "repayment_collected_date" . $i;
$repayment_description = "repayment_description" . $i;
if (!empty($request->$amount && !empty($request->$loan_id))) {
$loan = Loan::find($request->$loan_id);
if ($request->$amount > round(GeneralHelper::loan_total_balance($loan->id), 2)) {
Flash::warning("Amount is more than the balance(" . GeneralHelper::loan_total_balance($loan->id) . ')');
return redirect()->back()->withInput();
} else {
$repayment = new LoanRepayment();
$repayment->user_id = Sentinel::getUser()->id;
$repayment->amount = $request->$amount;
$repayment->loan_id = $loan->id;
$repayment->borrower_id = $loan->borrower_id;
$repayment->branch_id = session('branch_id');
$repayment->collection_date = $request->$collected_date;
$repayment->receipt = $request->$receipt;
$repayment->repayment_method_id = $request->$repayment_method;
$repayment->notes = $request->$repayment_description;
$date = explode('-', $request->$collected_date);
$repayment->year = $date[0];
$repayment->month = $date[1];
//determine which schedule due date the payment applies too
$schedule = LoanSchedule::where('due_date', '>=', $request->$collected_date)->where(
'loan_id',
$loan->id
)->orderBy(
'due_date',
'asc'
)->first();
if (!empty($schedule)) {
$repayment->due_date = $schedule->due_date;
} else {
$schedule = LoanSchedule::where(
'loan_id',
$loan->id
)->orderBy(
'due_date',
'desc'
)->first();
if ($request->$collected_date > $schedule->due_date) {
$repayment->due_date = $schedule->due_date;
} else {
$schedule = LoanSchedule::where(
'due_date',
'>',
$request->$collected_date
)->where(
'loan_id',
$loan->id
)->orderBy(
'due_date',
'asc'
)->first();
$repayment->due_date = $schedule->due_date;
}
}
$repayment->save();
//update loan status if need be
if (round(GeneralHelper::loan_total_balance($loan->id), 2) == 0) {
$l = Loan::find($loan->id);
$l->status = "closed";
$l->save();
}
//check if late repayment is to be applied when adding payment
}
}
//notify borrower
}
GeneralHelper::audit_trail("Added bulk repayment");
Flash::success("Repayment successfully saved");
return redirect('repayment/data');
}
public function addRepayment()
{
if (!Sentinel::hasAccess('repayments.create')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loans = array();
foreach (Loan::whereIn(
'status',
['disbursed', 'closed', 'written_off']
)->get() as $key) {
if (!empty($key->borrower)) {
$borrower = ' (' . $key->borrower->first_name . ' ' . $key->borrower->last_name . ")";
} else {
$borrower = '';
}
$loans[$key->id] = "#" . $key->id . $borrower;
}
return view('loan_repayment.add', compact('loans'));
}
public function createRepayment($loan, $schedule_id)
{
if (!Sentinel::hasAccess('repayments.create')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$repayment_methods = array();
foreach (LoanRepaymentMethod::all() as $key) {
$repayment_methods[$key->id] = $key->name;
}
$schedule = LoanSchedule::findOrFail($schedule_id);
$custom_fields = CustomField::where('category', 'repayments')->get();
return view('loan_repayment.create', compact('loan', 'schedule_id', 'schedule', 'repayment_methods', 'custom_fields'));
}
public function createPayOff($loan)
{
if (!Sentinel::hasAccess('repayments.create')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$repayment_methods = array();
foreach (LoanRepaymentMethod::all() as $key) {
$repayment_methods[$key->id] = $key->name;
}
$payOffInterestRate = $this->getData($loan, "payOffInterestRate");
$principal = $this->getData($loan, 'principal');
$payOffAmount = $this->getData($loan, "payOffAmount");
$custom_fields = CustomField::where('category', 'repayments')->get();
return view('loan_repayment.payOff', compact('loan', 'repayment_methods', 'custom_fields', 'payOffAmount', 'payOffInterestRate', 'principal'));
}
private function getData($loan, $getType = "payOffAmount")
{
// $getType can be "interestToUncharge" or "payOffAmount" or "payOffInterestRate"
// dd(GeneralHelper::loan_total_balance($loan->id));
$alreadyPaid = 0;
$loanTransactions = LoanTransaction::where('loan_id', $loan->id)->whereIn('reversal_type', ['user', 'none'])->where('reversible', true)->get();
// $loan_total_balance = 0;
// $amountPaid = 0;
$repaymentCount = 0;
// $currentBalance= 0;
$mainBalanceRest = 0;
$interestToUncharge = 0;
$isFirstMonth = true;
$lastPaymentDate = $loan->first_payment_date;
foreach ($loanTransactions as $index => $loanTransaction) {
// $currentBalance = $currentBalance + ($loanTransaction->debit - $loanTransaction->credit);
if ($loanTransaction->transaction_type == "repayment" && $loanTransaction->credit > 0) {
$repaymentCount = $repaymentCount + 1;
$lastPaymentDate = $loanTransaction->date;
$isFirstMonth = false;
// $amountPaid = $amountPaid + ($loanTransaction->credit-$loanTransaction->debit);
} else if ($loanTransaction->transaction_type == "pay_off") {
$isFirstMonth = false;
return 0.0;
}
}
if ($loan->interest_method == "interest_only") {
if ($repaymentCount == 0) {
$mainBalanceRest = $loan->principal;
$interestToUncharge = LoanSchedule::where('loan_id', $loan->id)->sum("interest");;
} else {
$loanSchedules = LoanSchedule::where('loan_id', $loan->id)->orderBy('due_date', 'asc');
$mainBalanceRest = $loan->principal;
$interestToUncharge = $loanSchedules->get()->slice($repaymentCount)->sum("interest");
// dd($interestToUncharge,$repaymentCount, $mainBalanceRest, $amountPaid);
}
} else {
if ($repaymentCount == 0) {
$mainBalanceRest = $loan->principal;
$interestToUncharge = LoanSchedule::where('loan_id', $loan->id)->where("description", "Repayment")->sum("interest");
} else {
$loanSchedules = LoanSchedule::where('loan_id', $loan->id)->orderBy('due_date', 'asc');
$tmp = clone $loanSchedules;
$mainBalanceRest = $tmp->get()->slice($repaymentCount - 1)->first()->principal_balance;
$interestToUncharge = $tmp->get()->slice($repaymentCount)->sum("interest");
}
}
// what we have to know: total paid , Total interest for past duration only, rest amount that borrowed (not include interest) ,
// Total PayOffAmount = rest amount that borrow * pay off Rate
// $interestToUncharge = ( $loan_total_balance* ($loan->interest_rate/100) * ($loan->loan_duration-$repaymentCount) );
$today = Carbon::today();
$dayPassFromLastRepayment = Carbon::parse($lastPaymentDate)->diffInDays($today);
if ($dayPassFromLastRepayment > 15 || $isFirstMonth) {
// pay off interest full month
if ($getType == "payOffAmount") {
// $mainBalanceRest = $currentBalance-$interestToUncharge;
return $mainBalanceRest + ($mainBalanceRest * ($loan->pay_off_interest_rate / 100));
} else if ($getType == "payOffInterestRate") {
// $mainBalanceRest = $currentBalance;
return $mainBalanceRest * ($loan->pay_off_interest_rate / 100);
} else if ($getType == "principal") {
return $mainBalanceRest;
} else {
return $interestToUncharge;
}
} else {
if ($getType == "payOffAmount") {
// $mainBalanceRest = $currentBalance-$interestToUncharge;
return $mainBalanceRest + ($mainBalanceRest * ((($loan->pay_off_interest_rate / Carbon::today()->daysInMonth) * $dayPassFromLastRepayment) / 100));
} else if ($getType == "payOffInterestRate") {
// $mainBalanceRest = $currentBalance;
return $mainBalanceRest * ((($loan->pay_off_interest_rate / Carbon::today()->daysInMonth) * $dayPassFromLastRepayment) / 100);
} else if ($getType == "principal") {
return $mainBalanceRest;
} else {
return $interestToUncharge;
}
}
}
public function storeRepayment(Request $request, $loan)
{
if (!Sentinel::hasAccess('repayments.create')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$amount_to_pay = GeneralHelper::get_total_repayment_amount($request->schedule_id);
// if (round($request->amount) < round($amount_to_pay)) {
// Flash::warning("Amount (" . $request->amount . ") is less than schedule due amount (" . $amount_to_pay . ")");
// return redirect()->back()->withInput();
// }
if (round($request->amount) != round($amount_to_pay)) {
Flash::warning("Amount (" . $request->amount . ") is not equal schedule due amount (" . $amount_to_pay . ")");
return redirect()->back()->withInput();
} else if ($request->amount == 0) {
Flash::warning("Amount must be greater than 0");
return redirect()->back()->withInput();
}
// if ($request->collection_date > date("Y-m-d")) {
// Flash::warning(translate('future_date_error'));
// return redirect()->back()->withInput();
// }
// if ($request->collection_date < $loan->disbursed_date) {
// Flash::warning(translate('early_date_error'));
// return redirect()->back()->withInput();
// }
// is over pay?
// $is_overpay = false;
// $amt_overpay = 0;
// if (round($request->amount) > round($amount_to_pay)) {
// $amt_overpay = $request->amount - $amount_to_pay;
// $is_overpay = true;
// }
//add interest transaction
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->loan_schedule_id = $request->schedule_id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "repayment";
$loan_transaction->receipt = $request->receipt;
$loan_transaction->date = $request->collection_date;
$loan_transaction->reversible = 1;
$loan_transaction->repayment_method_id = $request->repayment_method_id;
$date = explode('-', $request->collection_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->credit = $request->amount; //$amount_to_pay;
$loan_transaction->notes = $request->notes;
$loan_transaction->save();
//fire payment added event
//debit and credit the necessary accounts
$allocation = GeneralHelper::loan_allocate_payment($loan_transaction);
//return $allocation;
//principal
// dd($allocation['principal'],$loan->loan_product);
if ($allocation['principal'] > 0) {
if (!empty($loan->loan_product->chart_loan_portfolio)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_loan_portfolio->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->transaction_sub_type = 'repayment_principal';
$journal->name = "Principal Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->credit = $allocation['principal'] + $request->overpay;
$journal->reference = $loan_transaction->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_fund_source)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_fund_source->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Principal Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->debit = $allocation['principal'] + $request->overpay;
$journal->reference = $loan_transaction->id;
$journal->save();
}
}
//interest
if ($allocation['interest'] > 0) {
if (!empty($loan->loan_product->chart_income_interest)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_income_interest->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->transaction_sub_type = 'repayment_interest';
$journal->name = "Interest Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->credit = $allocation['interest'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_receivable_interest)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_receivable_interest->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Interest Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->debit = $allocation['interest'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
}
//fees
if ($allocation['fees'] > 0) {
if (!empty($loan->loan_product->chart_income_fee)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_income_fee->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->transaction_sub_type = 'repayment_fees';
$journal->name = "Fees Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->credit = $allocation['fees'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_receivable_fee)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_receivable_fee->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Fees Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->debit = $allocation['fees'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
}
if ($allocation['penalty'] > 0) {
if (!empty($loan->loan_product->chart_income_penalty)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_income_penalty->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->transaction_sub_type = 'repayment_penalty';
$journal->name = "Penalty Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->credit = $allocation['penalty'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_receivable_penalty)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_receivable_penalty->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Penalty Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->debit = $allocation['penalty'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
}
//save custom meta
$custom_fields = CustomField::where('category', 'repayments')->get();
foreach ($custom_fields as $key) {
$custom_field = new CustomFieldMeta();
$id = $key->id;
$custom_field->name = $request->$id;
$custom_field->parent_id = $loan_transaction->id;
$custom_field->custom_field_id = $key->id;
$custom_field->category = "repayments";
$custom_field->save();
}
//update loan status if need be
if (round(GeneralHelper::loan_total_balance($loan->id)) <= 0) {
$l = Loan::find($loan->id);
$l->status = "closed";
$l->save();
}
if ($request->overpay > 0) {
$loan_transaction->credit = $request->amount + $request->overpay;
$loan_transaction->save();
$loanSchedule = LoanSchedule::where('id', $request->schedule_id)->first();
$principal_balance = $loanSchedule->principal_balance - $request->overpay;
$loanTransaction = LoanTransaction::where('loan_id', $loan->id)->where('transaction_type', 'repayment')->where('reversed', 0)->get();
// $loan_transaction = new LoanTransaction();
// $loan_transaction->user_id = Sentinel::getUser()->id;
// $loan_transaction->branch_id = session('branch_id');
// $loan_transaction->loan_id = $loan->id;
// $loan_transaction->loan_schedule_id = $request->schedule_id;
// $loan_transaction->borrower_id = $loan->borrower_id;
// $loan_transaction->transaction_type = "overpay";
// $loan_transaction->receipt = $request->receipt;
// $loan_transaction->date = $request->collection_date;
// $loan_transaction->reversible = 1;
// $loan_transaction->repayment_method_id = $request->repayment_method_id;
// $date = explode('-', $request->collection_date);
// $loan_transaction->year = $date[0];
// $loan_transaction->month = $date[1];
// $loan_transaction->credit = $amt_overpay;
// $loan_transaction->notes = $request->notes;
// $loan_transaction->save();
//TODO: Reschedule
$re = new Request();
$re->principal = $principal_balance;
$re->status = "disbursed";
$re->interest_method = $loan->interest_method;
$re->interest_rate = $loan->interest_rate;
$re->pay_off_interest_rate = $loan->pay_off_interest_rate;
$re->branch_id = session('branch_id');
$re->interest_period = $loan->interest_period;
$re->loan_duration = $loan->loan_duration - count($loanTransaction);
$re->loan_duration_type = $loan->loan_duration_type;
$re->repayment_cycle = $loan->repayment_cycle;
$re->decimal_places = $loan->decimal_places;
$re->override_interest = $loan->override_interest;
$re->override_interest_amount = $loan->override_interest_amount;
$re->grace_on_interest_charged = $loan->grace_on_interest_charged;
$re->borrower_id = $loan->borrower_id;
$re->applied_amount = $principal_balance;
$re->user_id = Sentinel::getUser()->id;
$re->loan_product_id = $loan->loan_product_id;
$re->release_date = Carbon::now()->format('Y-m-d');
$re->first_payment_date = Carbon::createFromFormat('Y-m-d', $loanSchedule->due_date)->addMonth(1)->format('Y-m-d');
$re->disbursed_date = Carbon::now()->format('Y-m-d'); //$loanSchedule->due_date;
$re->loan_disbursed_by_id = null;
$re->disbursed_notes = null;
$this->rescheduleStore($re, $loan->id);
// if (!empty($loan->loan_product->chart_income_interest)) {
// $journal = new JournalEntry();
// $journal->user_id = Sentinel::getUser()->id;
// $journal->account_id = $loan->loan_product->chart_income_interest->id;
// $journal->branch_id = $loan->branch_id;
// $journal->date = $request->collection_date;
// $journal->year = $date[0];
// $journal->month = $date[1];
// $journal->borrower_id = $loan->borrower_id;
// $journal->transaction_type = 'repayment';
// $journal->transaction_sub_type = 'repayment_interest';
// $journal->name = "Interest Repayment";
// $journal->loan_id = $loan->id;
// $journal->loan_transaction_id = $loan_transaction->id;
// $journal->credit = $amt_overpay;
// $journal->reference = $loan_transaction->id;
// $journal->save();
// }
// if (!empty($loan->loan_product->chart_receivable_interest)) {
// $journal = new JournalEntry();
// $journal->user_id = Sentinel::getUser()->id;
// $journal->account_id = $loan->loan_product->chart_receivable_interest->id;
// $journal->branch_id = $loan->branch_id;
// $journal->date = $request->collection_date;
// $journal->year = $date[0];
// $journal->month = $date[1];
// $journal->borrower_id = $loan->borrower_id;
// $journal->transaction_type = 'repayment';
// $journal->name = "Interest Repayment";
// $journal->loan_id = $loan->id;
// $journal->loan_transaction_id = $loan_transaction->id;
// $journal->debit = $amt_overpay;
// $journal->reference = $loan_transaction->id;
// $journal->save();
// }
}
event(new RepaymentCreated($loan_transaction));
GeneralHelper::audit_trail("Added repayment for loan with id:" . $loan->id);
Flash::success("Repayment successfully saved");
return redirect('loan/transaction/' . $loan_transaction->id . '/print_repayment_receipt');
//redirect('loan/' . $loan->id . '/show');
}
public function storePayOff(Request $request, $loan)
{
if (!Sentinel::hasAccess('repayments.create')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
//return GeneralHelper::loan_allocate_payment($loan->id, $request->amount)["penalty"];
if ($request->principal != round($this->getData($loan, 'principal'), 2)) {
Flash::warning("Amount is more than the balance(" . $this->getData($loan, "payOffAmount") . ')');
return redirect()->back()->withInput();
} else if ($request->principal == 0) {
Flash::warning("Amount must be greater than 0");
return redirect()->back()->withInput();
}
// if ($request->collection_date > date("Y-m-d")) {
// Flash::warning(translate('future_date_error'));
// return redirect()->back()->withInput();
// }
// if ($request->collection_date < $loan->disbursed_date) {
// Flash::warning(translate('early_date_error'));
// return redirect()->back()->withInput();
// }
//add interest transaction (remove interest is because it's pay off)
$loan_trans = new LoanTransaction();
$loan_trans->user_id = Sentinel::getUser()->id;
$loan_trans->branch_id = session('branch_id');
$loan_trans->loan_id = $loan->id;
$loan_trans->borrower_id = $loan->borrower_id;
$loan_trans->transaction_type = "interest";
$loan_trans->date = $request->collection_date;
// $date = explode('-', $request->disbursed_date);
$date = explode('-', $request->collection_date);
$loan_trans->year = $date[0];
$loan_trans->month = $date[1];
$interestToUncharge = $this->getData($loan, "interestToUncharge") * (-1);
$loan_trans->debit = $interestToUncharge;
// dd($loan_trans);
$loan_trans->save();
//add pay off interest
$loan_trans = new LoanTransaction();
$loan_trans->user_id = Sentinel::getUser()->id;
$loan_trans->branch_id = session('branch_id');
$loan_trans->loan_id = $loan->id;
$loan_trans->borrower_id = $loan->borrower_id;
$loan_trans->transaction_type = "interest";
$loan_trans->date = $request->collection_date;
// $date = explode('-', $request->disbursed_date);
$date = explode('-', $request->collection_date);
$loan_trans->year = $date[0];
$loan_trans->month = $date[1];
$payOffInterestRate = $request->payOffInterestRate;
$loan_trans->debit = $payOffInterestRate;
// dd($loan_trans);
$loan_trans->save();
//add pay off transaction
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "pay_off";
$loan_transaction->receipt = $request->receipt;
$loan_transaction->date = $request->collection_date;
$loan_transaction->reversible = 1;
$loan_transaction->repayment_method_id = $request->repayment_method_id;
$date = explode('-', $request->collection_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->credit = $request->principal + $request->payOffInterestRate;
// $loan_transaction->debit = ($this->getData($loan, "interestToUncharge")- $this->getData($loan, "payOffInterestRate"))*(-1);
$loan_transaction->notes = $request->notes;
// dd($loan_transaction);
$loan_transaction->save();
//fire payment added event
//debit and credit the necessary accounts
GeneralHelper::modify_loan_schedules($loan_transaction, $interestToUncharge + $payOffInterestRate);
$allocation = GeneralHelper::loan_allocate_payment($loan_transaction);
//return $allocation;
//principal
// if ($allocation['pay_off'] > 0) {
// if (!empty($loan->loan_product->chart_loan_portfolio)) {
// $journal = new JournalEntry();
// $journal->user_id = Sentinel::getUser()->id;
// $journal->account_id = $loan->loan_product->chart_loan_portfolio->id;
// $journal->branch_id = $loan->branch_id;
// $journal->date = $request->collection_date;
// $journal->year = $date[0];
// $journal->month = $date[1];
// $journal->borrower_id = $loan->borrower_id;
// $journal->transaction_type = 'pay_off';
// $journal->transaction_sub_type = 'pay_off';
// $journal->name = "Principal Pay Off";
// $journal->loan_id = $loan->id;
// $journal->loan_transaction_id = $loan_transaction->id;
// $journal->credit = $allocation['principal'];
// $journal->reference = $loan_transaction->id;
// $journal->save();
// }
// if (!empty($loan->loan_product->chart_fund_source)) {
// $journal = new JournalEntry();
// $journal->user_id = Sentinel::getUser()->id;
// $journal->account_id = $loan->loan_product->chart_fund_source->id;
// $journal->branch_id = $loan->branch_id;
// $journal->date = $request->collection_date;
// $journal->year = $date[0];
// $journal->month = $date[1];
// $journal->borrower_id = $loan->borrower_id;
// $journal->transaction_type = 'pay_off';
// $journal->name = "Principal Pay Off";
// $journal->loan_id = $loan->id;
// $journal->loan_transaction_id = $loan_transaction->id;
// $journal->debit = $allocation['pay_off'];
// $journal->reference = $loan_transaction->id;
// $journal->save();
// }
// }
// principal
if ($allocation['principal'] > 0) {
if (!empty($loan->loan_product->chart_loan_portfolio)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_loan_portfolio->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Principal Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->credit = $allocation['principal'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_fund_source)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_fund_source->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Principal Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->debit = $allocation['principal'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
}
//interest
if ($allocation['interest'] > 0) {
if (!empty($loan->loan_product->chart_income_interest)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_income_interest->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'pay_off';
$journal->transaction_sub_type = 'repayment_interest';
$journal->name = "Interest Pay Off";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->credit = $allocation['interest'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_receivable_interest)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_receivable_interest->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'pay_off';
$journal->name = "Interest Pay Off";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->debit = $allocation['interest'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
}
//save custom meta
$custom_fields = CustomField::where('category', 'repayments')->get();
foreach ($custom_fields as $key) {
$custom_field = new CustomFieldMeta();
$id = $key->id;
$custom_field->name = $request->$id;
$custom_field->parent_id = $loan_transaction->id;
$custom_field->custom_field_id = $key->id;
$custom_field->category = "pay_off";
$custom_field->save();
}
//update loan status if need be
if (round(GeneralHelper::loan_total_balance($loan->id)) <= 0) {
$l = Loan::find($loan->id);
$l->status = "closed";
$l->save();
}
event(new RepaymentCreated($loan_transaction));
GeneralHelper::audit_trail("Added Pay Off for loan with id:" . $loan->id);
Flash::success("Pay Off successfully saved");
// return redirect('loan/' . $loan->id . '/show');
return redirect('loan/transaction/' . $loan_transaction->id . '/print_pay_off_receipt');
}
public function reverseRepayment($id)
{
if (!Sentinel::hasAccess('repayments.update')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan_transaction = LoanTransaction::find($id);
$loan_transaction->reversible = 0;
$loan_transaction->reversed = 1;
$loan_transaction->reversal_type = "user";
$loan_transaction->debit = $loan_transaction->credit;
$loan_transaction->save();
//reverse journal transactions
foreach (JournalEntry::where('reference', $id)->where(
'loan_id',
$loan_transaction->loan_id
)->where('transaction_type', 'repayment')->get() as $key) {
$journal = JournalEntry::find($key->id);
if ($key->debit > $key->credit) {
$journal->credit = $journal->debit;
} else {
$journal->debit = $journal->credit;
}
$journal->reversed = 1;
$journal->save();
}
//trigger transactions refresh
event(new RepaymentReversed($loan_transaction));
Flash::success(translate('successfully_saved'));
return redirect('loan/' . $loan_transaction->loan_id . '/show');
}
public function reversePayOff($id)
{
if (!Sentinel::hasAccess('repayments.update')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan_transactions = LoanTransaction::whereIn('id', [$id, ($id - 1), ($id - 2)])->get();
// $id-1 & $Id-2 is transaction created when we pay off
$loan_id = 0;
foreach ($loan_transactions as $loan_transaction) {
$loan_id = $loan_transaction->loan_id;
$loan_transaction->reversible = 0;
$loan_transaction->reversed = 1;
$loan_transaction->reversal_type = "user";
$loan_transaction->debit = $loan_transaction->credit;
$loan_transaction->save();
//reverse journal transactions
foreach (JournalEntry::where('reference', $id)->where(
'loan_id',
$loan_transaction->loan_id
)->where('transaction_type', 'pay_off')->get() as $key) {
$journal = JournalEntry::find($key->id);
if ($key->debit > $key->credit) {
$journal->credit = $journal->debit;
} else {
$journal->debit = $journal->credit;
}
$journal->reversed = 1;
$journal->save();
}
//trigger transactions refresh
event(new PayOffReversed($loan_transaction));
}
LoanSchedule::where('loan_id', $loan_id)->where('description', 'Pay Off')->first()->delete();
Flash::success(translate('successfully_saved'));
return redirect('loan/' . $loan_transaction->loan_id . '/show');
}
public function deleteRepayment($loan, $id)
{
if (!Sentinel::hasAccess('repayments.delete')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
LoanRepayment::destroy($id);
if (GeneralHelper::loan_total_balance($loan->id) > 0 && $loan->status == "closed") {
$l = Loan::find($loan->id);
$l->status = "disbursed";
$l->save();
}
//remove entries from the journal table
JournalEntry::where('loan_transaction_id', $id)->delete();
GeneralHelper::audit_trail("Deleted repayment for loan with id:" . $loan->id);
Flash::success("Repayment successfully deleted");
return redirect('loan/' . $loan->id . '/show');
}
// print repayment
public function pdfRepayment($loan_transaction)
{
PDF::AddPage();
PDF::writeHTML(View::make('loan_repayment.pdf', compact('loan_transaction'))->render());
PDF::SetAuthor('Tererai Mugova');
PDF::Output(
$loan_transaction->borrower->title . ' ' . $loan_transaction->borrower->first_name . ' ' . $loan_transaction->borrower->last_name . " - Repayment Receipt.pdf",
'D'
);
}
public function printRepayment($loan_transaction)
{
return view('loan_repayment.print', compact('loan_transaction'));
}
public function editRepayment($loan_transaction)
{
if (!Sentinel::hasAccess('repayments.update')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$repayment_methods = array();
foreach (LoanRepaymentMethod::all() as $key) {
$repayment_methods[$key->id] = $key->name;
}
$custom_fields = CustomField::where('category', 'repayments')->get();
return view('loan_repayment.edit', compact('loan_transaction', 'repayment_methods', 'custom_fields'));
}
public function updateRepayment(Request $request, $id)
{
if (!Sentinel::hasAccess('repayments.update')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan_transaction = LoanTransaction::find($id);
if ($request->collection_date > date("Y-m-d")) {
Flash::warning(translate('future_date_error'));
return redirect()->back()->withInput();
}
if ($request->collection_date < $loan_transaction->loan->first_payment_date) {
Flash::warning(translate('early_date_error'));
return redirect()->back()->withInput();
}
$loan_transaction->reversible = 0;
$loan_transaction->reversed = 1;
$loan_transaction->reversal_type = "user";
$loan_transaction->debit = $loan_transaction->credit;
$loan_transaction->save();
//reverse journal transactions
foreach (JournalEntry::where('reference', $id)->where(
'loan_id',
$loan_transaction->loan_id
)->where('transaction_type', 'repayment')->get() as $key) {
$journal = JournalEntry::find($key->id);
if ($key->debit > $key->credit) {
$journal->credit = $journal->debit;
} else {
$journal->debit = $journal->credit;
}
$journal->save();
}
//trigger transactions refresh
event(new RepaymentReversed($loan_transaction));
//save new loan transaction
//save custom meta
$custom_fields = CustomField::where('category', 'repayments')->get();
foreach ($custom_fields as $key) {
if (!empty(CustomFieldMeta::where('custom_field_id', $key->id)->where(
'parent_id',
$id
)->where('category', 'repayments')->first())) {
$custom_field = CustomFieldMeta::where('custom_field_id', $key->id)->where(
'parent_id',
$id
)->where('category', 'repayments')->first();
} else {
$custom_field = new CustomFieldMeta();
}
$kid = $key->id;
$custom_field->name = $request->$kid;
$custom_field->parent_id = $id;
$custom_field->custom_field_id = $key->id;
$custom_field->category = "repayments";
$custom_field->save();
}
$loan = $loan_transaction->loan;
//add interest transaction
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "repayment";
$loan_transaction->receipt = $request->receipt;
$loan_transaction->date = $request->collection_date;
$loan_transaction->reversible = 1;
$loan_transaction->repayment_method_id = $request->repayment_method_id;
$date = explode('-', $request->collection_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->credit = $request->amount;
$loan_transaction->notes = $request->notes;
$loan_transaction->save();
//fire payment added event
//debit and credit the necessary accounts
$allocation = GeneralHelper::loan_allocate_payment($loan_transaction);
//return $allocation;
//principal
if ($allocation['principal'] > 0) {
if (!empty($loan->loan_product->chart_loan_portfolio)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_loan_portfolio->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Principal Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->credit = $allocation['principal'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_fund_source)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_fund_source->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Principal Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->debit = $allocation['principal'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
}
//interest
if ($allocation['interest'] > 0) {
if (!empty($loan->loan_product->chart_income_interest)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_income_interest->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Interest Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->credit = $allocation['interest'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_receivable_interest)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_receivable_interest->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Interest Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->debit = $allocation['interest'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
}
//fees
if ($allocation['fees'] > 0) {
if (!empty($loan->loan_product->chart_income_fee)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_income_fee->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Fees Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->credit = $allocation['fees'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_receivable_fee)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_receivable_fee->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Fees Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->debit = $allocation['fees'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
}
if ($allocation['penalty'] > 0) {
if (!empty($loan->loan_product->chart_income_penalty)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_income_penalty->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Penalty Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->credit = $allocation['penalty'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
if (!empty($loan->loan_product->chart_receivable_penalty)) {
$journal = new JournalEntry();
$journal->user_id = Sentinel::getUser()->id;
$journal->account_id = $loan->loan_product->chart_receivable_penalty->id;
$journal->branch_id = $loan->branch_id;
$journal->date = $request->collection_date;
$journal->year = $date[0];
$journal->month = $date[1];
$journal->borrower_id = $loan->borrower_id;
$journal->transaction_type = 'repayment';
$journal->name = "Penalty Repayment";
$journal->loan_id = $loan->id;
$journal->loan_transaction_id = $loan_transaction->id;
$journal->debit = $allocation['penalty'];
$journal->reference = $loan_transaction->id;
$journal->save();
}
}
event(new RepaymentUpdated($loan_transaction));
//update loan status if need be
if (round(GeneralHelper::loan_total_balance($loan_transaction->loan_id)) <= 0) {
$l = Loan::find($loan_transaction->loan_id);
$l->status = "closed";
$l->save();
} else {
$l = Loan::find($loan_transaction->loan_id);
$l->status = "disbursed";
$l->save();
}
GeneralHelper::audit_trail("Updated repayment for loan with id:" . $loan_transaction->loan_id);
Flash::success("Repayment successfully saved");
return redirect('loan/' . $loan_transaction->loan_id . '/show');
}
//transactions
public function showTransaction($loan_transaction)
{
$custom_fields = CustomFieldMeta::where('category', 'repayments')->where(
'parent_id',
$loan_transaction->id
)->get();
return view('loan_transaction.show', compact('loan_transaction', 'custom_fields'));
}
public function pdfTransaction($loan_transaction)
{
$pdf = \App\Services\Pdf::loadView('loan_transaction.pdf', compact('loan_transaction'));
return $pdf->download($loan_transaction->borrower->title . ' ' . $loan_transaction->borrower->first_name . ' ' . $loan_transaction->borrower->last_name . " - Repayment Receipt.pdf");
}
public function printTransaction($loan_transaction)
{
return view('loan_transaction.print', compact('loan_transaction'));
}
public function printRepaymentReceipt($loan_transaction)
{
return view('loan_transaction.print_repayment_receipt', compact('loan_transaction'));
}
public function printPayOffReceipt($loan_transaction)
{
return view('loan_transaction.print_pay_off_receipt', compact('loan_transaction'));
}
//edit loan schedule
public function editSchedule($loan)
{
if (!Sentinel::hasAccess('loans.update')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$rows = 0;
$schedules = LoanSchedule::where('loan_id', $loan->id)->orderBy('due_date', 'asc')->get();
return view('loan.edit_schedule', compact('loan', 'schedules', 'rows'));
}
public function updateSchedule(Request $request, $loan)
{
if (!Sentinel::hasAccess('loans.update')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
if ($request->submit == 'add_row') {
$rows = $request->addrows;
$schedules = LoanSchedule::where('loan_id', $loan->id)->orderBy('due_date', 'asc')->get();
return view('loan.edit_schedule', compact('loan', 'schedules', 'rows'));
}
if ($request->submit == 'submit') {
//lets delete existing schedules
LoanSchedule::where('loan_id', $loan->id)->delete();
for ($count = 0; $count < $request->count; $count++) {
$schedule = new LoanSchedule();
if (empty($request->due_date) && empty($request->principal) && empty($request->interest) && empty($request->fees) && empty($request->penalty)) {
//do nothing
} elseif (empty($request->due_date)) {
//do nothing
} else {
//all rosy, lets save our data here
$schedule->due_date = $request->due_date[$count];
$schedule->principal = $request->principal[$count];
$schedule->description = $request->description[$count];
$schedule->loan_id = $loan->id;
$schedule->borrower_id = $loan->borrower_id;
$schedule->interest = $request->interest[$count];
$schedule->fees = $request->fees[$count];
$schedule->penalty = $request->penalty[$count];
$date = explode('-', $request->due_date[$count]);
$schedule->month = $date[1];
$schedule->year = $date[0];
$schedule->save();
}
}
GeneralHelper::audit_trail("Updated Schedule for loan with id:" . $loan->id);
Flash::success("Schedule successfully updated");
return redirect('loan/' . $loan->id . '/show');
}
}
//charges
public function addCharge(Request $request, $loan)
{
if (!Sentinel::hasAccess('repayments.update')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
if ($request->date < $loan->disbursed_date) {
Flash::warning(translate('early_date_error'));
return redirect()->back()->withInput();
}
$due_date = GeneralHelper::determine_due_date($loan->id, $request->date);
$schedule = LoanSchedule::where('due_date', $due_date)->where('loan_id', $loan->id)->first();
if (!empty($schedule)) {
//add charge transaction
$loan_transaction = new LoanTransaction();
$loan_transaction->user_id = Sentinel::getUser()->id;
$loan_transaction->branch_id = session('branch_id');
$loan_transaction->loan_id = $loan->id;
$loan_transaction->borrower_id = $loan->borrower_id;
$loan_transaction->transaction_type = "specified_due_date_fee";
$loan_transaction->date = $due_date;
$date = explode('-', $due_date);
$loan_transaction->year = $date[0];
$loan_transaction->month = $date[1];
$loan_transaction->debit = $request->amount;
$loan_transaction->notes = $request->notes;
$loan_transaction->reversible = 1;
$loan_transaction->save();
//update schedule
$schedule->fees = $schedule->fees + $request->amount;
$schedule->save();
GeneralHelper::audit_trail("Added charge for loan with id " . $loan->id);
//trigger transactions refresh
event(new LoanTransactionUpdated($loan_transaction));
Flash::success("Charge successfully saved");
return redirect()->back();
} else {
Flash::warning("An error occurred. No schedule found to apply");
return redirect()->back()->withInput();
}
}
public function waiveTransaction(Request $request, $id)
{
if (!Sentinel::hasAccess('repayments.update')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan_transaction = LoanTransaction::find($id);
$loan_transaction->reversible = 0;
$loan_transaction->reversed = 1;
$loan_transaction->credit = $loan_transaction->debit;
$loan_transaction->reversal_type = "user";
$loan_transaction->save();
$schedule = LoanSchedule::where('due_date', $loan_transaction->date)->where(
'loan_id',
$loan_transaction->loan_id
)->first();
if (!empty($schedule)) {
//update schedule
$schedule->fees = $schedule->fees - $loan_transaction->debit;
$schedule->save();
GeneralHelper::audit_trail("Waived charge for loan with id " . $loan_transaction->loan_id);
//trigger transactions refresh
event(new InterestWaived($loan_transaction));
event(new RepaymentReversed($loan_transaction));
Flash::success("Charge successfully saved");
return redirect()->back();
} else {
Flash::warning("An error occurred. No schedule found to apply");
return redirect()->back()->withInput();
}
}
public function pdfSchedule($loan)
{
$schedules = LoanSchedule::where('loan_id', $loan->id)->orderBy('due_date', 'asc')->get();
$pdf = Pdf::loadView('loan.pdf_schedule', compact('loan', 'schedules'));
$pdf->setPaper('A4', 'landscape');
return $pdf->download($loan->borrower->title . ' ' . $loan->borrower->first_name . ' ' . $loan->borrower->last_name . " - Loan Repayment Schedule.pdf");
}
public function printSchedule($loan)
{
$schedules = LoanSchedule::where('loan_id', $loan->id)->orderBy('due_date', 'asc')->get();
return view('loan.print_schedule', compact('loan', 'schedules'));
}
public function printContractMotorRental($loan)
{
// dd($loan->branch);
return view('loan.print_contract_motor_rental', compact('loan'));
}
public function printContractBorrowMoney($loan)
{
// dd($loan->branch);
return view('loan.print_contract_borrow_money', compact('loan'));
}
public function printContractRealEstateMortgage($loan)
{
// dd($loan->branch);
return view('loan.print_real_estate_mortgage', compact('loan'));
}
public function printContractBuySellMotor($loan)
{
// dd($loan->branch);
return view('loan.print_contract_buy_sell_motor', compact('loan'));
}
public function printCollateralReceipt($loan)
{
// dd($loan->branch);
return view('loan.print_collateral_receipt', compact('loan'));
}
public function pdfLoanStatement($loan)
{
$payments = LoanRepayment::where('loan_id', $loan->id)->orderBy('collection_date', 'asc')->get();
$pdf = Pdf::loadView('loan.pdf_loan_statement', compact('loan', 'payments'));
$pdf->setPaper('A4', 'landscape');
return $pdf->download($loan->borrower->title . ' ' . $loan->borrower->first_name . ' ' . $loan->borrower->last_name . " - Loan Statement.pdf");
}
public function printLoanStatement($loan)
{
$payments = LoanRepayment::where('loan_id', $loan->id)->orderBy('collection_date', 'asc')->get();
return view('loan.print_loan_statement', compact('loan', 'payments'));
}
public function pdfBorrowerStatement($borrower)
{
$loans = Loan::where('borrower_id', $borrower->id)->orderBy('release_date', 'asc')->get();
$pdf = \App\Services\Pdf::loadView('loan.pdf_borrower_statement', compact('loans','borrower'));
$pdf->setPaper('A4', 'landscape');
return $pdf->download($borrower->title . ' ' . $borrower->first_name . ' ' . $borrower->last_name . " - Client Statement.pdf");
}
public function printBorrowerStatement($borrower)
{
$loans = Loan::where('borrower_id', $borrower->id)->orderBy('release_date', 'asc')->get();
return view('loan.print_borrower_statement', compact('loans'));
}
public function override(Request $request, $loan)
{
if (!Sentinel::hasAccess('loans.update')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
if ($request->isMethod('post')) {
$l = Loan::find($loan->id);
$l->balance = $request->balance;
if (empty($request->override)) {
$l->override = 0;
} else {
$l->override = $request->override;
}
$l->save();
GeneralHelper::audit_trail("Override balance for loan with id:" . $loan->id);
Flash::success(translate('override_successfully_applied'));
return redirect('loan/' . $loan->id . '/show');
}
return view('loan.override', compact('loan'));
}
public function emailBorrowerStatement($borrower)
{
if (!empty($borrower->email)) {
$body = Setting::where(
'setting_key',
'borrower_statement_email_template'
)->first()->setting_value;
$body = str_replace('{borrowerTitle}', $borrower->title, $body);
$body = str_replace('{borrowerFirstName}', $borrower->first_name, $body);
$body = str_replace('{borrowerLastName}', $borrower->last_name, $body);
$body = str_replace('{borrowerAddress}', $borrower->address, $body);
$body = str_replace('{borrowerUniqueNumber}', $borrower->unique_number, $body);
$body = str_replace('{borrowerMobile}', $borrower->mobile, $body);
$body = str_replace('{borrowerPhone}', $borrower->phone, $body);
$body = str_replace('{borrowerEmail}', $borrower->email, $body);
$body = str_replace('{loansPayments}', GeneralHelper::borrower_loans_total_paid($borrower->id), $body);
$body = str_replace(
'{loansDue}',
round(GeneralHelper::borrower_loans_total_due($borrower->id), 2),
$body
);
$body = str_replace(
'{loansBalance}',
round((GeneralHelper::borrower_loans_total_due($borrower->id) - GeneralHelper::borrower_loans_total_paid($borrower->id)),
2
),
$body
);
$body = str_replace(
'{loanPayments}',
GeneralHelper::borrower_loans_total_paid($borrower->id),
$body
);
$loans = Loan::where('borrower_id', $borrower->id)->orderBy('release_date', 'asc')->get();
$file_name = $borrower->title . ' ' . $borrower->first_name . ' ' . $borrower->last_name . " - Client Statement.pdf";
Mail::raw($body, function ($message) use ($borrower, $file_name, $loans) {
$message->from(
Setting::where('setting_key', 'company_email')->first()->setting_value,
Setting::where('setting_key', 'company_name')->first()->setting_value
);
$message->to($borrower->email);
$headers = $message->getHeaders();
$pdf = Pdf::loadView('loan.pdf_borrower_statement', compact('loans'));
$message->attachData($pdf->output(), $file_name);
$message->setContentType('text/html');
$message->setSubject(Setting::where(
'setting_key',
'borrower_statement_email_subject'
)->first()->setting_value);
});
$mail = new Email();
$mail->user_id = Sentinel::getUser()->id;
$mail->message = $body;
$mail->subject = Setting::where(
'setting_key',
'borrower_statement_email_subject'
)->first()->setting_value;
$mail->recipients = 1;
$mail->send_to = $borrower->first_name . ' ' . $borrower->last_name . '(' . $borrower->unique_number . ')';
$mail->save();
Flash::success("Statement successfully sent");
return redirect('borrower/' . $borrower->id . '/show');
} else {
Flash::warning("Borrower has no email set");
return redirect('borrower/' . $borrower->id . '/show');
}
}
public function emailLoanStatement($loan)
{
$borrower = $loan->borrower;
if (!empty($borrower->email)) {
$body = Setting::where(
'setting_key',
'loan_statement_email_template'
)->first()->setting_value;
$body = str_replace('{borrowerTitle}', $borrower->title, $body);
$body = str_replace('{borrowerFirstName}', $borrower->first_name, $body);
$body = str_replace('{borrowerLastName}', $borrower->last_name, $body);
$body = str_replace('{borrowerAddress}', $borrower->address, $body);
$body = str_replace('{borrowerUniqueNumber}', $borrower->unique_number, $body);
$body = str_replace('{borrowerMobile}', $borrower->mobile, $body);
$body = str_replace('{borrowerPhone}', $borrower->phone, $body);
$body = str_replace('{borrowerEmail}', $borrower->email, $body);
$body = str_replace('{loanNumber}', $loan->id, $body);
$body = str_replace('{loanPayments}', GeneralHelper::loan_total_paid($loan->id), $body);
$body = str_replace(
'{loanDue}',
round(GeneralHelper::loan_total_due_amount($loan->id), 2),
$body
);
$body = str_replace(
'{loanBalance}',
round((GeneralHelper::loan_total_due_amount($loan->id) - GeneralHelper::loan_total_paid($loan->id)),
2
),
$body
);
$payments = LoanRepayment::where('loan_id', $loan->id)->orderBy('collection_date', 'asc')->get();
$file_name = $borrower->title . ' ' . $borrower->first_name . ' ' . $borrower->last_name . " - Loan Statement.pdf";
Mail::raw($body, function ($message) use ($borrower, $loan, $file_name, $payments) {
$message->from(
Setting::where('setting_key', 'company_email')->first()->setting_value,
Setting::where('setting_key', 'company_name')->first()->setting_value
);
$message->to($borrower->email);
$headers = $message->getHeaders();
$pdf = Pdf::loadView('loan.pdf_loan_statement', compact('loan', 'payments'));
$message->attachData($pdf->output(), $file_name);
$message->setContentType('text/html');
$message->setSubject(Setting::where(
'setting_key',
'loan_statement_email_subject'
)->first()->setting_value);
});
$mail = new Email();
$mail->user_id = Sentinel::getUser()->id;
$mail->message = $body;
$mail->subject = Setting::where(
'setting_key',
'loan_statement_email_subject'
)->first()->setting_value;
$mail->recipients = 1;
$mail->send_to = $borrower->first_name . ' ' . $borrower->last_name . '(' . $borrower->unique_number . ')';
$mail->save();
Flash::success("Loan Statement successfully sent");
return redirect('loan/' . $loan->id . '/show');
} else {
Flash::warning("Borrower has no email set");
return redirect('loan/' . $loan->id . '/show');
}
}
public function emailLoanSchedule($loan)
{
$borrower = $loan->borrower;
if (!empty($borrower->email)) {
$body = Setting::where(
'setting_key',
'loan_schedule_email_template'
)->first()->setting_value;
$body = str_replace('{borrowerTitle}', $borrower->title, $body);
$body = str_replace('{borrowerFirstName}', $borrower->first_name, $body);
$body = str_replace('{borrowerLastName}', $borrower->last_name, $body);
$body = str_replace('{borrowerAddress}', $borrower->address, $body);
$body = str_replace('{borrowerUniqueNumber}', $borrower->unique_number, $body);
$body = str_replace('{borrowerMobile}', $borrower->mobile, $body);
$body = str_replace('{borrowerPhone}', $borrower->phone, $body);
$body = str_replace('{borrowerEmail}', $borrower->email, $body);
$body = str_replace('{loanNumber}', $loan->id, $body);
$body = str_replace('{loanPayments}', GeneralHelper::loan_total_paid($loan->id), $body);
$body = str_replace(
'{loanDue}',
round(GeneralHelper::loan_total_due_amount($loan->id), 2),
$body
);
$body = str_replace(
'{loanBalance}',
round((GeneralHelper::loan_total_due_amount($loan->id) - GeneralHelper::loan_total_paid($loan->id)),
2
),
$body
);
$schedules = LoanSchedule::where('loan_id', $loan->id)->orderBy('due_date', 'asc')->get();
$file_name = $borrower->title . ' ' . $borrower->first_name . ' ' . $borrower->last_name . " - Loan Schedule.pdf";
Mail::raw($body, function ($message) use ($borrower, $loan, $file_name, $schedules) {
$message->from(
Setting::where('setting_key', 'company_email')->first()->setting_value,
Setting::where('setting_key', 'company_name')->first()->setting_value
);
$message->to($borrower->email);
$headers = $message->getHeaders();
$pdf = Pdf::loadView('loan.pdf_schedule', compact('loan', 'schedules'));
$message->attachData($pdf->output(), $file_name);
$message->setContentType('text/html');
$message->setSubject(Setting::where(
'setting_key',
'loan_schedule_email_subject'
)->first()->setting_value);
});
$mail = new Email();
$mail->user_id = Sentinel::getUser()->id;
$mail->message = $body;
$mail->subject = Setting::where(
'setting_key',
'loan_statement_email_subject'
)->first()->setting_value;
$mail->recipients = 1;
$mail->send_to = $borrower->first_name . ' ' . $borrower->last_name . '(' . $borrower->unique_number . ')';
$mail->save();
Flash::success("Loan Statement successfully sent");
return redirect('loan/' . $loan->id . '/show');
} else {
Flash::warning("Borrower has no email set");
return redirect('loan/' . $loan->id . '/show');
}
}
//loan applications
public function indexApplication()
{
if (!Sentinel::hasAccess('loans')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$data = LoanApplication::where('branch_id', session('branch_id'))->get();
return view('loan.applications', compact('data'));
}
public function declineApplication($id)
{
if (!Sentinel::hasAccess('loans')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$application = LoanApplication::find($id);
$application->status = "declined";
$application->save();
GeneralHelper::audit_trail("Declined borrower loan application with id:" . $id);
Flash::success(translate('successfully_saved'));
return redirect('loan/loan_application/data');
}
public function deleteApplication($id)
{
if (!Sentinel::hasAccess('loans')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
LoanApplication::destroy($id);
Guarantor::where('loan_application_id', $id)->delete();
GeneralHelper::audit_trail("Deleted borrower loan application with id:" . $id);
Flash::success(translate('successfully_deleted'));
return redirect('loan/loan_application/data');
}
public function approveApplication($id)
{
if (!Sentinel::hasAccess('loans')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$application = LoanApplication::find($id);
//get custom fields
$custom_fields = CustomField::where('category', 'loans')->get();
$loan_product = $application->loan_product;
$charges = array();
foreach (LoanProductCharge::where('loan_product_id', $loan_product->id)->get() as $key) {
if (!empty($key->charge)) {
$charges[$key->id] = $key->charge->name;
}
}
$users = [];
foreach (User::all() as $key) {
$users[$key->id] = $key->first_name . ' ' . $key->last_name;
}
if (!empty($application->loan_product)) {
return view(
'loan.approve_application',
compact('id', 'application', 'loan_product', 'users', 'custom_fields', 'charges')
);
} else {
Flash::warning(translate('loan_application_approve_error'));
return redirect('loan/loan_application/data');
}
}
public function storeApproveApplication(Request $request, $id)
{
if (!Sentinel::hasAccess('loans')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$application = LoanApplication::find($id);
$application->status = "approved";
$application->save();
//lets save the loan here
if (!Sentinel::hasAccess('loans.create')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan = new Loan();
$loan->principal = $request->principal;
$loan->interest_method = $request->interest_method;
$loan->interest_rate = $request->interest_rate;
// $loan->pay_off_interest_rate = $request->pay_off_interest_rate;
$loan->interest_period = $request->interest_period;
$loan->loan_duration = $request->loan_duration;
$loan->loan_duration_type = $request->loan_duration_type;
$loan->repayment_cycle = $request->repayment_cycle;
$loan->decimal_places = $request->decimal_places;
$loan->override_interest = $request->override_interest;
$loan->override_interest_amount = $request->override_interest_amount;
$loan->grace_on_interest_charged = $request->grace_on_interest_charged;
$loan->borrower_id = $request->borrower_id;
$loan->branch_id = $application->branch_id;
$loan->applied_amount = $request->principal;
$loan->user_id = Sentinel::getUser()->id;
$loan->loan_officer_id = $request->loan_officer_id;
$loan->loan_product_id = $request->loan_product_id;
$loan->release_date = $request->release_date;
$date = explode('-', $request->release_date);
$loan->month = $date[1];
$loan->year = $date[0];
if (!empty($request->first_payment_date)) {
$loan->first_payment_date = $request->first_payment_date;
}
$loan->description = $request->description;
$files = array();
if (!empty($request->file('files'))) {
$count = 0;
foreach ($request->file('files') as $key) {
$file = array('files' => $key);
$rules = array('files' => 'required|mimes:jpeg,jpg,bmp,png,pdf,docx,xlsx');
$validator = Validator::make($file, $rules);
if ($validator->fails()) {
Flash::warning(translate('validation_error'));
return redirect()->back()->withInput()->withErrors($validator);
} else {
$files[$count] = $key->getClientOriginalName();
$key->move(
public_path() . '/uploads',
$key->getClientOriginalName()
);
}
$count++;
}
}
$loan->files = serialize($files);
$loan->save();
if (!empty($request->charges)) {
//loop through the array
foreach ($request->charges as $key) {
$amount = "charge_amount_" . $key;
$date = "charge_date_" . $key;
$loan_charge = new LoanCharge();
$loan_charge->loan_id = $loan->id;
$loan_charge->user_id = Sentinel::getUser()->id;
$loan_charge->charge_id = $key;
$loan_charge->amount = $request->$amount;
if (!empty($request->$date)) {
$loan_charge->date = $request->$date;
}
$loan_charge->save();
}
}
//save custom meta
$custom_fields = CustomField::where('category', 'loans')->get();
foreach ($custom_fields as $key) {
$custom_field = new CustomFieldMeta();
$id = $key->id;
$custom_field->name = $request->$id;
$custom_field->parent_id = $loan->id;
$custom_field->custom_field_id = $key->id;
$custom_field->category = "loans";
$custom_field->save();
}
//lets create schedules here
//determine interest rate to use
$interest_rate = GeneralHelper::determine_interest_rate($loan->id);
$period = GeneralHelper::loan_period($loan->id);
$loan = Loan::find($loan->id);
if ($loan->repayment_cycle == 'daily') {
$repayment_cycle = 'day';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' days')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'weekly') {
$repayment_cycle = 'week';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' weeks')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'monthly') {
$repayment_cycle = 'month';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'bi_monthly') {
$repayment_cycle = 'month';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'quarterly') {
$repayment_cycle = 'month';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'semi_annually') {
$repayment_cycle = 'month';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' months')
),
'Y-m-d'
);
}
if ($loan->repayment_cycle == 'yearly') {
$repayment_cycle = 'year';
$loan->maturity_date = date_format(
date_add(
date_create($request->first_payment_date),
date_interval_create_from_date_string($period . ' years')
),
'Y-m-d'
);
}
$loan->save();
//generate schedules until period finished
$next_payment = $request->first_payment_date;
$balance = $request->principal;
GeneralHelper::audit_trail("Approved borrower loan application with id:" . $id);
Flash::success(translate('successfully_saved'));
return redirect('loan/loan_application/data');
}
//loan calculator
public function createLoanCalculator(Request $request)
{
if (!Sentinel::hasAccess('loans.loan_calculator')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$loan_fees = LoanFee::all();
return view(
'loan_calculator/create',
compact('loan_fees')
);
}
public function showLoanCalculator(Request $request)
{
if (!Sentinel::hasAccess('loans.loan_calculator')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
return view(
'loan_calculator/show',
compact('request')
);
}
public function storeLoanCalculator(Request $request)
{
if (!Sentinel::hasAccess('loans.loan_calculator')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
if (!empty($request->pdf)) {
$pdf = Pdf::loadView('loan_calculator.pdf', compact('request'));
$pdf->setPaper('A4', 'landscape');
return $pdf->download("Calculated Schedule.pdf");
}
if (!empty($request->print)) {
return view('loan_calculator.print', compact('request'));
}
}
public function add_guarantor(Request $request, $loan)
{
if (!Sentinel::hasAccess('loans.guarantor.create')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
$guarantor = new LoanGuarantor();
$guarantor->guarantor_id = $request->guarantor_id;
$guarantor->loan_id = $loan->id;;
$guarantor->user_id = Sentinel::getUser()->id;
$guarantor->borrower_id = $loan->borrower_id;
$guarantor->save();
GeneralHelper::audit_trail("Added guarantor for loan with id:" . $loan->id);
Flash::success(translate('successfully_saved'));
return redirect()->back();
}
public function remove_guarantor(Request $request, $id)
{
if (!Sentinel::hasAccess('loans.guarantor.delete')) {
Flash::warning(translate('permission_denied'));
return redirect()->back();;
}
LoanGuarantor::destroy($id);
GeneralHelper::audit_trail("Removed guarantor for loan with id:" . $id);
Flash::success(translate('successfully_saved'));
return redirect()->back();
}
}