257 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			257 lines
		
	
	
		
			7.9 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'), setting('default.currency'), true);
 | |
|         $in_progress_amount = money($reconciliations->where('reconciled', 0)->sum('closing_balance'), setting('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);
 | |
|     }
 | |
| }
 |