akaunting/app/Http/Controllers/Banking/Reconciliations.php

257 lines
7.8 KiB
PHP

<?php
namespace App\Http\Controllers\Banking;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Banking\Reconciliation as Request;
use App\Http\Requests\Banking\ReconciliationCalculate as CalculateRequest;
use App\Jobs\Banking\CreateReconciliation;
use App\Jobs\Banking\DeleteReconciliation;
use App\Jobs\Banking\UpdateReconciliation;
use App\Models\Banking\Account;
use App\Models\Banking\Reconciliation;
use App\Models\Banking\Transaction;
use App\Utilities\Date;
class Reconciliations extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$reconciliations = Reconciliation::with('account')->collect();
$reconciled_amount = money($reconciliations->where('reconciled', 1)->sum('closing_balance'), default_currency(), true);
$in_progress_amount = money($reconciliations->where('reconciled', 0)->sum('closing_balance'), default_currency(), true);
$summary_amounts = [
'amount_exact' => $reconciled_amount->format(),
'amount_for_humans' => $reconciled_amount->formatForHumans(),
'in_progress_exact' => $in_progress_amount->format(),
'in_progress_for_humans' => $in_progress_amount->formatForHumans(),
];
return $this->response('banking.reconciliations.index', compact('reconciliations', 'summary_amounts'));
}
/**
* Show the form for viewing the specified resource.
*
* @return Response
*/
public function show()
{
return redirect()->route('reconciliations.index');
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
$account_id = request('account_id', setting('default.account'));
$started_at = request('started_at', Date::now()->firstOfMonth()->toDateString());
$ended_at = request('ended_at', Date::now()->endOfMonth()->toDateString());
$account = Account::find($account_id);
$currency = $account->currency;
$transactions = $this->getTransactions($account, $started_at, $ended_at);
$opening_balance = $this->getOpeningBalance($account, $started_at);
return view('banking.reconciliations.create', compact('account', 'currency', 'opening_balance', 'transactions'));
}
/**
* Store a newly created resource in storage.
*
* @param Request $request
*
* @return Response
*/
public function store(Request $request)
{
$response = $this->ajaxDispatch(new CreateReconciliation($request));
if ($response['success']) {
$response['redirect'] = route('reconciliations.index');
$message = trans('messages.success.added', ['type' => trans_choice('general.reconciliations', 1)]);
flash($message)->success();
} else {
$response['redirect'] = route('reconciliations.create');
$message = $response['message'];
flash($message)->error()->important();
}
return response()->json($response);
}
/**
* Show the form for editing the specified resource.
*
* @param Reconciliation $reconciliation
*
* @return Response
*/
public function edit(Reconciliation $reconciliation)
{
$account = $reconciliation->account;
$currency = $account->currency;
$transactions = $this->getTransactions($account, $reconciliation->started_at, $reconciliation->ended_at);
$opening_balance = $this->getOpeningBalance($account, $reconciliation->started_at, $reconciliation->ended_at);
return view('banking.reconciliations.edit', compact('reconciliation', 'account', 'currency', 'opening_balance', 'transactions'));
}
/**
* Update the specified resource in storage.
*
* @param Reconciliation $reconciliation
* @param Request $request
*
* @return Response
*/
public function update(Reconciliation $reconciliation, Request $request)
{
$response = $this->ajaxDispatch(new UpdateReconciliation($reconciliation, $request));
if ($response['success']) {
$response['redirect'] = route('reconciliations.index');
$message = trans('messages.success.updated', ['type' => trans_choice('general.reconciliations', 1)]);
flash($message)->success();
} else {
$response['redirect'] = route('reconciliations.edit', $reconciliation->id);
$message = $response['message'];
flash($message)->error()->important();
}
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Reconciliation $reconciliation
*
* @return Response
*/
public function destroy(Reconciliation $reconciliation)
{
$response = $this->ajaxDispatch(new DeleteReconciliation($reconciliation));
$response['redirect'] = route('reconciliations.index');
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => trans_choice('general.reconciliations', 1)]);
flash($message)->success();
} else {
$message = $response['message'];
flash($message)->error()->important();
}
return response()->json($response);
}
/**
* Add transactions array.
*
* @param $account
* @param $started_at
* @param $ended_at
*
* @return mixed
*/
protected function getTransactions($account, $started_at, $ended_at)
{
$started = explode(' ', $started_at)[0] . ' 00:00:00';
$ended = explode(' ', $ended_at)[0] . ' 23:59:59';
$transactions = Transaction::with('account', 'contact')->where('account_id', $account->id)->whereBetween('paid_at', [$started, $ended])->get();
return collect($transactions)->sortByDesc('paid_at');
}
/**
* Get the opening balance
*
* @param $account
* @param $started_at
*
* @return string
*/
public function getOpeningBalance($account, $started_at)
{
// Opening Balance
$total = $account->opening_balance;
// Sum income transactions
$transactions = $account->income_transactions()->whereDate('paid_at', '<', $started_at)->get();
foreach ($transactions as $item) {
$total += $item->amount;
}
// Subtract expense transactions
$transactions = $account->expense_transactions()->whereDate('paid_at', '<', $started_at)->get();
foreach ($transactions as $item) {
$total -= $item->amount;
}
return $total;
}
public function calculate(CalculateRequest $request)
{
$currency_code = $request['currency_code'];
$closing_balance = $request['closing_balance'];
$json = new \stdClass();
$cleared_amount = $difference = $income_total = $expense_total = 0;
if ($transactions = $request['transactions']) {
$opening_balance = $request['opening_balance'];
foreach ($transactions as $key => $value) {
$k = explode('_', $key);
if ($k[1] == 'income') {
$income_total += $value;
} else {
$expense_total += $value;
}
}
$cleared_amount = $opening_balance + ($income_total - $expense_total);
}
$difference = $closing_balance - $cleared_amount;
$json->closing_balance = money($closing_balance, $currency_code, true)->format();
$json->cleared_amount = money($cleared_amount, $currency_code, true)->format();
$json->difference = money($difference, $currency_code, true)->format();
$json->difference_raw = (int) $difference;
return response()->json($json);
}
}