Sindbad~EG File Manager
<?php
namespace App\Http\Controllers;
use App\Models\CustomField;
use App\Models\Guarantor;
use App\Models\Loan;
use App\Models\LoanCollateral;
use App\Models\LoanPayment;
use App\Models\LoanProduct;
use App\Models\LoanRepayment;
use App\Models\SavingsAccount;
use App\Models\Transaction;
use App\Notifications\ApprovedLoanRequest;
use App\Notifications\RejectLoanRequest;
use App\Utilities\LoanCalculator as Calculator;
use DataTables;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
class LoanController extends Controller {
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct() {
date_default_timezone_set(get_option('timezone', 'Asia/Dhaka'));
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request, $status = '') {
if ($status == 'pending') {
$status = 0;
} else if ($status == 'active') {
$status = 1;
}
return view('backend.loan.list', compact('status'));
}
public function get_table_data(Request $request) {
$loans = Loan::select('loans.*')
->with('borrower')
->with('currency')
->with('loan_product')
->orderBy("loans.id", "desc");
return Datatables::eloquent($loans)
->filter(function ($query) use ($request) {
if ($request->has('status')) {
$query->where('status', $request->status);
}
}, true)
->editColumn('borrower.first_name', function ($loan) {
return $loan->borrower->first_name . ' ' . $loan->borrower->last_name;
})
->editColumn('applied_amount', function ($loan) {
return decimalPlace($loan->applied_amount, currency($loan->currency->name));
})
->editColumn('status', function ($loan) {
if ($loan->status == 0) {
return show_status(_lang('Pending'), 'warning');
} else if ($loan->status == 1) {
return show_status(_lang('Approved'), 'success');
} elseif ($loan->status == 2) {
return show_status(_lang('Completed'), 'info');
} elseif ($loan->status == 3) {
return show_status(_lang('Cancelled'), 'danger');
}
})
->filterColumn('borrower.first_name', function ($query, $keyword) {
$query->whereHas('borrower', function ($query) use ($keyword) {
return $query->where("first_name", "like", "{$keyword}%")
->orWhere("last_name", "like", "{$keyword}%");
});
}, true)
->addColumn('action', function ($loan) {
return '<form action="' . route('loans.destroy', $loan['id']) . '" class="text-center" method="post">'
. '<a href="' . route('loans.show', $loan['id']) . '" class="btn btn-primary btn-xs"><i class="ti-eye"></i> ' . _lang('View') . '</a> '
. '<a href="' . route('loans.edit', $loan['id']) . '" class="btn btn-warning btn-xs"><i class="ti-pencil-alt"></i> ' . _lang('Edit') . '</a> '
. csrf_field()
. '<input name="_method" type="hidden" value="DELETE">'
. '<button class="btn btn-danger btn-xs btn-remove" type="submit"><i class="ti-trash"></i> ' . _lang('Delete') . '</button>'
. '</form>';
})
->setRowId(function ($loan) {
return "row_" . $loan->id;
})
->rawColumns(['status', 'action'])
->make(true);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create(Request $request) {
$alert_col = "col-lg-8 offset-lg-2";
$customFields = CustomField::where('table', 'loans')
->where('status', 1)
->orderBy("id", "asc")
->get();
if (!$request->ajax()) {
return view('backend.loan.create', compact('alert_col', 'customFields'));
} else {
return view('backend.loan.modal.create', compact('alert_col', 'customFields'));
}
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request) {
@ini_set('max_execution_time', 0);
@set_time_limit(0);
$loanProduct = LoanProduct::find($request->loan_product_id);
$min_amount = $loanProduct->minimum_amount;
$max_amount = $loanProduct->maximum_amount;
$validationRules = [
'loan_id' => 'required|unique:loans',
'loan_product_id' => 'required',
'borrower_id' => 'required',
'currency_id' => 'required',
'first_payment_date' => 'required',
'release_date' => 'required',
'applied_amount' => "required|numeric|min:$min_amount|max:$max_amount",
'late_payment_penalties' => 'required|numeric',
'debit_account_id' => 'required',
'attachment' => 'nullable|mimes:jpeg,JPEG,png,PNG,jpg,doc,pdf,docx,zip|max:8192', //8MB = 8192KB
];
$validationMessages = [];
// Custom field validation
$customFields = CustomField::where('table', 'loans')
->orderBy("id", "desc")
->get();
$customValidation = generate_custom_field_validation($customFields);
$validationRules = array_merge($validationRules, $customValidation['rules']);
$validationMessages = array_merge($validationMessages, $customValidation['messages']);
$validator = Validator::make($request->all(), $validationRules, $validationMessages);
if ($validator->fails()) {
if ($request->ajax()) {
return response()->json(['result' => 'error', 'message' => $validator->errors()->all()]);
} else {
return redirect()->route('loans.create')
->withErrors($validator)
->withInput();
}
}
//Check Debit account is valid account
$account = SavingsAccount::where('id', $request->debit_account_id)
->where('member_id', $request->borrower_id)
->first();
if (!$account) {
return back()->with('error', _lang('Invalid account'));
}
$attachment = "";
if ($request->hasfile('attachment')) {
$file = $request->file('attachment');
$attachment = time() . $file->getClientOriginalName();
$file->move(public_path() . "/uploads/media/", $attachment);
}
DB::beginTransaction();
// Store custom field data
$customFieldsData = store_custom_field_data($customFields);
$loan = new Loan();
$loan->loan_id = $loanProduct->loan_id_prefix . $loanProduct->starting_loan_id;
$loan->loan_product_id = $request->input('loan_product_id');
$loan->borrower_id = $request->input('borrower_id');
$loan->currency_id = $request->input('currency_id');
$loan->first_payment_date = $request->input('first_payment_date');
$loan->release_date = $request->input('release_date');
$loan->applied_amount = $request->input('applied_amount');
$loan->late_payment_penalties = $request->input('late_payment_penalties');
$loan->attachment = $attachment;
$loan->description = $request->input('description');
$loan->remarks = $request->input('remarks');
$loan->created_user_id = Auth::id();
$loan->branch_id = auth()->user()->branch_id;
$loan->custom_fields = json_encode($customFieldsData);
$loan->debit_account_id = $request->debit_account_id;
$loan->save();
// Create Loan Repayments
$calculator = new Calculator(
$loan->applied_amount,
$loan->first_payment_date,
$loan->loan_product->interest_rate,
$loan->loan_product->term,
$loan->loan_product->term_period,
$loan->late_payment_penalties
);
if ($loan->loan_product->interest_type == 'flat_rate') {
$repayments = $calculator->get_flat_rate();
} else if ($loan->loan_product->interest_type == 'fixed_rate') {
$repayments = $calculator->get_fixed_rate();
} else if ($loan->loan_product->interest_type == 'mortgage') {
$repayments = $calculator->get_mortgage();
} else if ($loan->loan_product->interest_type == 'one_time') {
$repayments = $calculator->get_one_time();
} else if ($loan->loan_product->interest_type == 'reducing_amount') {
$repayments = $calculator->get_reducing_amount();
}
$loan->total_payable = $calculator->payable_amount;
$loan->save();
//Check Account has enough balance for deducting fee
$convertedAmount = convert_currency($loan->currency->name, $account->savings_type->currency->name, $loan->applied_amount);
$charge = 0;
$charge += $loanProduct->loan_application_fee_type == 1 ? ($loanProduct->loan_application_fee / 100) * $convertedAmount : $loanProduct->loan_application_fee;
$charge += $loanProduct->loan_insurance_fee_type == 1 ? ($loanProduct->loan_insurance_fee / 100) * $convertedAmount : $loanProduct->loan_insurance_fee;
if (get_account_balance($account->id, $loan->borrower_id) < $charge) {
return back()->with('error', _lang('Insufficient balance for deducting loan application and insurance fee !'));
}
//Deduct Loan Processing Fee
process_loan_fee('loan_application_fee', $loan->borrower_id, $request->debit_account_id, $convertedAmount, $loanProduct->loan_application_fee, $loanProduct->loan_application_fee_type, $loan->id);
//Increment Loan ID
if ($loanProduct->starting_loan_id != null) {
$loanProduct->increment('starting_loan_id');
}
DB::commit();
if (!$request->ajax()) {
return redirect()->route('loans.show', $loan->id)->with('success', _lang('New Loan added successfully'));
} else {
return response()->json(['result' => 'success', 'action' => 'store', 'message' => _lang('New Loan added successfully'), 'data' => $loan, 'table' => '#loans_table']);
}
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show(Request $request, $id) {
$loan = Loan::find($id);
$loancollaterals = LoanCollateral::where('loan_id', $loan->id)
->orderBy("id", "desc")
->get();
$customFields = CustomField::where('table', 'loans')
->where('status', 1)
->orderBy("id", "asc")
->get();
$repayments = LoanRepayment::where('loan_id', $loan->id)->orderBy('id', 'asc')->get();
$guarantors = Guarantor::where('loan_id', $loan->id)->get();
$payments = LoanPayment::where('loan_id', $loan->id)->orderBy('id', 'desc')->get();
return view('backend.loan.view', compact('loan', 'loancollaterals', 'repayments', 'payments', 'guarantors', 'customFields'));
}
/**
* Approve Loan
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function approve(Request $request, $id) {
DB::beginTransaction();
$loan = Loan::find($id);
if ($loan->status == 1) {
abort(403);
}
if ($loan->loan_id == NULL || $loan->release_date == NULL) {
return back()->with('error', _lang('Loan ID and Release date must required !'));
}
//Deduct Loan Processing Fee
$account = SavingsAccount::where('id', $loan->debit_account_id)
->where('member_id', $loan->borrower_id)
->first();
if (!$account) {
$account = SavingsAccount::where('member_id', $loan->borrower_id)->first();
if (!$account) {
return back()->with('error', _lang('No account found for deducting loan processing fee'));
}
}
$loanProduct = $loan->loan_product;
//Check Account has enough balance for deducting fee
$convertedAmount = convert_currency($loan->currency->name, $account->savings_type->currency->name, $loan->applied_amount);
$charge = 0;
$charge += $loanProduct->loan_application_fee_type == 1 ? ($loanProduct->loan_application_fee / 100) * $convertedAmount : $loanProduct->loan_application_fee;
$charge += $loanProduct->loan_insurance_fee_type == 1 ? ($loanProduct->loan_insurance_fee / 100) * $convertedAmount : $loanProduct->loan_insurance_fee;
if (get_account_balance($account->id, $loan->borrower_id) < $charge) {
return back()->with('error', _lang('Insufficient balance for deducting loan application and insurance fee !'));
}
//Deduct Loan Processing Fee
process_loan_fee('loan_processing_fee', $loan->borrower_id, $account->id, $convertedAmount, $loanProduct->loan_processing_fee, $loanProduct->loan_processing_fee_type, $loan->id);
$loan->status = 1;
$loan->approved_date = date('Y-m-d');
$loan->approved_user_id = Auth::id();
$loan->save();
// Create Loan Repayments
$calculator = new Calculator(
$loan->applied_amount,
$loan->getRawOriginal('first_payment_date'),
$loan->loan_product->interest_rate,
$loan->loan_product->term,
$loan->loan_product->term_period,
$loan->late_payment_penalties
);
if ($loan->loan_product->interest_type == 'flat_rate') {
$repayments = $calculator->get_flat_rate();
} else if ($loan->loan_product->interest_type == 'fixed_rate') {
$repayments = $calculator->get_fixed_rate();
} else if ($loan->loan_product->interest_type == 'mortgage') {
$repayments = $calculator->get_mortgage();
} else if ($loan->loan_product->interest_type == 'one_time') {
$repayments = $calculator->get_one_time();
} else if ($loan->loan_product->interest_type == 'reducing_amount') {
$repayments = $calculator->get_reducing_amount();
}
$loan->total_payable = $calculator->payable_amount;
$loan->save();
foreach ($repayments as $repayment) {
$loan_repayment = new LoanRepayment();
$loan_repayment->loan_id = $loan->id;
$loan_repayment->repayment_date = $repayment['date'];
$loan_repayment->amount_to_pay = $repayment['amount_to_pay'];
$loan_repayment->penalty = $repayment['penalty'];
$loan_repayment->principal_amount = $repayment['principle_amount'];
$loan_repayment->interest = $repayment['interest'];
$loan_repayment->balance = $repayment['balance'];
$loan_repayment->save();
}
DB::commit();
try {
$loan->borrower->notify(new ApprovedLoanRequest($loan));
} catch (\Exception $e) {}
return back()->with('success', _lang('Loan Request Approved'));
}
/**
* Reject Loan
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function reject(Request $request, $id) {
$loan = Loan::find($id);
/** If not pending */
if ($loan->status != 0) {
abort(403);
}
$loan->status = 3; //Cancelled
$loan->save();
try {
$loan->borrower->notify(new RejectLoanRequest($loan));
} catch (\Exception $e) {}
return back()->with('success', _lang('Loan Request Rejected'));
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit(Request $request, $id) {
$loan = Loan::find($id);
if ($loan->status == 2) {
return back()->with('error', _lang('Sorry, This Loan is already completed'));
}
$customFields = CustomField::where('table', 'loans')
->where('status', 1)
->orderBy("id", "asc")
->get();
if (!$request->ajax()) {
return view('backend.loan.edit', compact('loan', 'id', 'customFields'));
} else {
return view('backend.loan.modal.edit', compact('loan', 'id', 'customFields'));
}
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id) {
@ini_set('max_execution_time', 0);
@set_time_limit(0);
$loan = Loan::find($id);
if ($loan->status == 2) {
return back()->with('error', _lang('Sorry, This Loan is already completed'));
}
if ($loan->status != 0) {
$loan->description = $request->input('description');
$loan->remarks = $request->input('remarks');
$loan->save();
return redirect()->route('loans.index')->with('success', _lang('Updated successfully'));
} else {
$validationRules = [
'loan_id' => [
'required',
Rule::unique('loans')->ignore($id),
],
'loan_product_id' => 'required',
'borrower_id' => 'required',
'currency_id' => 'required',
'first_payment_date' => 'required',
'release_date' => 'required',
'applied_amount' => 'required|numeric',
'late_payment_penalties' => 'required|numeric',
'debit_account_id' => 'required',
'attachment' => 'nullable|mimes:jpeg,JPEG,png,PNG,jpg,doc,pdf,docx,zip|max:8192', //8MB = 8192KB
];
$validationMessages = [];
// Custom field validation
$customFields = CustomField::where('table', 'loans')
->orderBy("id", "desc")
->get();
$customValidation = generate_custom_field_validation($customFields, true);
$validationRules = array_merge($validationRules, $customValidation['rules']);
$validationMessages = array_merge($validationMessages, $customValidation['messages']);
$validator = Validator::make($request->all(), $validationRules, $validationMessages);
}
if ($validator->fails()) {
if ($request->ajax()) {
return response()->json(['result' => 'error', 'message' => $validator->errors()->all()]);
} else {
return redirect()->route('loans.edit', $id)
->withErrors($validator)
->withInput();
}
}
if ($request->hasfile('attachment')) {
$file = $request->file('attachment');
$attachment = time() . $file->getClientOriginalName();
$file->move(public_path() . "/uploads/media/", $attachment);
}
DB::beginTransaction();
// Store custom field data
$customFieldsData = store_custom_field_data($customFields, json_decode($loan->custom_fields, true));
$loan = Loan::find($id);
$loan->loan_id = $request->input('loan_id');
$loan->loan_product_id = $request->input('loan_product_id');
$loan->borrower_id = $request->input('borrower_id');
$loan->currency_id = $request->input('currency_id');
$loan->first_payment_date = $request->input('first_payment_date');
$loan->release_date = $request->input('release_date');
$loan->applied_amount = $request->input('applied_amount');
$loan->late_payment_penalties = $request->input('late_payment_penalties');
if ($request->hasfile('attachment')) {
$loan->attachment = $attachment;
}
$loan->description = $request->input('description');
$loan->remarks = $request->input('remarks');
$loan->debit_account_id = $request->debit_account_id;
$loan->custom_fields = json_encode($customFieldsData);
// Create Loan Repayments
$calculator = new Calculator(
$loan->applied_amount,
$loan->first_payment_date,
$loan->loan_product->interest_rate,
$loan->loan_product->term,
$loan->loan_product->term_period,
$loan->late_payment_penalties
);
if ($loan->loan_product->interest_type == 'flat_rate') {
$repayments = $calculator->get_flat_rate();
} else if ($loan->loan_product->interest_type == 'fixed_rate') {
$repayments = $calculator->get_fixed_rate();
} else if ($loan->loan_product->interest_type == 'mortgage') {
$repayments = $calculator->get_mortgage();
} else if ($loan->loan_product->interest_type == 'one_time') {
$repayments = $calculator->get_one_time();
} else if ($loan->loan_product->interest_type == 'reducing_amount') {
$repayments = $calculator->get_reducing_amount();
}
$loan->total_payable = $calculator->payable_amount;
$loan->save();
DB::commit();
if (!$request->ajax()) {
return redirect()->route('loans.index')->with('success', _lang('Updated successfully'));
} else {
return response()->json(['result' => 'success', 'action' => 'update', 'message' => _lang('Updated successfully'), 'data' => $loan, 'table' => '#loans_table']);
}
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id) {
DB::beginTransaction();
$loan = Loan::find($id);
$loancollaterals = LoanCollateral::where('loan_id', $loan->id);
$loancollaterals->delete();
$repayments = LoanRepayment::where('loan_id', $loan->id);
$repayments->delete();
$loanpayment = LoanPayment::where('loan_id', $loan->id);
$loanpayment->delete();
$transaction = Transaction::where('loan_id', $loan->id);
$transaction->delete();
$loan->delete();
DB::commit();
return redirect()->route('loans.index')->with('success', _lang('Deleted successfully'));
}
public function calculator() {
$data = array();
$data['first_payment_date'] = '';
$data['apply_amount'] = '';
$data['interest_rate'] = '';
$data['interest_type'] = '';
$data['term'] = '';
$data['term_period'] = '';
$data['late_payment_penalties'] = 0;
return view('backend.loan.calculator', $data);
}
public function calculate(Request $request) {
$validator = Validator::make($request->all(), [
'apply_amount' => 'required|numeric',
'interest_rate' => 'required',
'interest_type' => 'required',
'term' => 'required|integer|max:100',
'term_period' => $request->interest_type == 'one_time' ? '' : 'required',
'late_payment_penalties' => 'required',
'first_payment_date' => 'required',
]);
if ($validator->fails()) {
if ($request->ajax()) {
return response()->json(['result' => 'error', 'message' => $validator->errors()->all()]);
} else {
return redirect()->route('loans.admin_calculator')->withErrors($validator)->withInput();
}
}
$first_payment_date = $request->first_payment_date;
$apply_amount = $request->apply_amount;
$interest_rate = $request->interest_rate;
$interest_type = $request->interest_type;
$term = $request->term;
$term_period = $request->term_period;
$late_payment_penalties = $request->late_payment_penalties;
$data = array();
$table_data = array();
if ($interest_type == 'flat_rate') {
$calculator = new Calculator($apply_amount, $first_payment_date, $interest_rate, $term, $term_period, $late_payment_penalties);
$table_data = $calculator->get_flat_rate();
$data['payable_amount'] = $calculator->payable_amount;
} else if ($interest_type == 'fixed_rate') {
$calculator = new Calculator($apply_amount, $first_payment_date, $interest_rate, $term, $term_period, $late_payment_penalties);
$table_data = $calculator->get_fixed_rate();
$data['payable_amount'] = $calculator->payable_amount;
} else if ($interest_type == 'mortgage') {
$calculator = new Calculator($apply_amount, $first_payment_date, $interest_rate, $term, $term_period, $late_payment_penalties);
$table_data = $calculator->get_mortgage();
$data['payable_amount'] = $calculator->payable_amount;
} else if ($interest_type == 'one_time') {
$calculator = new Calculator($apply_amount, $first_payment_date, $interest_rate, 1, $term_period, $late_payment_penalties);
$table_data = $calculator->get_one_time();
$data['payable_amount'] = $calculator->payable_amount;
} else if ($interest_type == 'reducing_amount') {
$calculator = new Calculator($apply_amount, $first_payment_date, $interest_rate, $term, $term_period, $late_payment_penalties);
$table_data = $calculator->get_reducing_amount();
$data['payable_amount'] = $calculator->payable_amount;
}
$data['table_data'] = $table_data;
$data['first_payment_date'] = $request->first_payment_date;
$data['apply_amount'] = $request->apply_amount;
$data['interest_rate'] = $request->interest_rate;
$data['interest_type'] = $request->interest_type;
$data['term'] = $request->term;
$data['term_period'] = $request->term_period;
$data['late_payment_penalties'] = $request->late_payment_penalties;
return view('backend.loan.calculator', $data);
}
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists