Reconciliation feature fixes.

This commit is contained in:
Cüneyt Şentürk 2020-02-18 17:14:06 +03:00
parent 93140b6513
commit af1b0c7345
5 changed files with 208 additions and 67 deletions

View File

@ -4,6 +4,7 @@ namespace App\Jobs\Banking;
use App\Abstracts\Job;
use App\Models\Banking\Reconciliation;
use App\Models\Banking\Transaction;
class CreateReconciliation extends Job
{
@ -40,10 +41,13 @@ class CreateReconciliation extends Job
if ($transactions) {
foreach ($transactions as $key => $value) {
$t = explode('_', $key);
$m = '\\' . $t['1'];
if (empty($value)) {
continue;
}
$transaction = $m::find($t[0]);
$t = explode('_', $key);
$transaction = Transaction::find($t[1]);
$transaction->reconciled = 1;
$transaction->save();
}

View File

@ -4,6 +4,7 @@ namespace App\Jobs\Banking;
use App\Abstracts\Job;
use App\Models\Banking\Reconciliation;
use App\Models\Banking\Transaction;
class UpdateReconciliation extends Job
{
@ -38,10 +39,13 @@ class UpdateReconciliation extends Job
if ($transactions) {
foreach ($transactions as $key => $value) {
if (empty($value)) {
continue;
}
$t = explode('_', $key);
$m = '\\' . $t['1'];
$transaction = $m::find($t[0]);
$transaction = Transaction::find($t[1]);
$transaction->reconciled = 1;
$transaction->save();
}

View File

@ -28,7 +28,79 @@ const app = new Vue({
data: function () {
return {
form: new Form('reconciliation'),
bulk_action: new BulkAction('reconciliations')
bulk_action: new BulkAction('reconciliations'),
reconcile: true,
difference: null,
totals: {
closing_balance: 0,
cleared_amount: 0,
difference: 0,
},
currency: null,
}
}
},
mounted() {
this.totals.closing_balance = parseFloat(document.getElementById('closing_balance').value);
},
methods:{
onReconcilition() {
let form = document.getElementById('form-create-reconciliation');
let path = form.action +'?started_at=' + this.form.started_at + '&ended_at=' + this.form.ended_at + '&closing_balance=' + this.form.closing_balance + '&account_id=' + this.form.account_id;
window.location.href = path;
},
onCalculate() {
this.reconcile = true;
this.difference = null;
let transactions = this.form.transactions;
let cleared_amount = 0;
let difference = 0;
let income_total = 0;
let expense_total = 0;
if (transactions) {
// get all transactions.
Object.keys(transactions).forEach(function(transaction) {
if (!transactions[transaction]) {
return;
}
let type = transaction.split('_');
if (type[0] == 'income') {
income_total += parseFloat(document.getElementById('transaction-' + type[1] + '-' + type[0]).value);
} else {
expense_total += parseFloat(document.getElementById('transaction-' + type[1] + '-' + type[0]).value);
}
});
cleared_amount = parseFloat(this.form.opening_balance) + parseFloat(income_total - expense_total);
}
difference = parseFloat(this.form.closing_balance) - cleared_amount;
if (difference != 0) {
this.difference = 'table-danger';
this.reconcile = true;
} else {
this.difference = 'table-success';
this.reconcile = false;
}
this.totals.cleared_amount = cleared_amount;
this.totals.difference = difference;
},
onReconcileSubmit() {
this.form.reconcile = 1;
this.form.submit();
}
},
});

View File

@ -5,10 +5,9 @@
@section('content')
<div class="card">
{!! Form::open([
'method' => 'GET',
'route' => 'reconciliations.create',
'id' => 'reconciliation',
'@submit.prevent' => 'onSubmit',
'@keydown' => 'form.errors.clear($event.target.name)',
'id' => 'form-create-reconciliation',
'files' => true,
'role' => 'form',
'class' => 'form-loading-button mb-0',
@ -17,16 +16,16 @@
<div class="card-body">
<div class="row align-items-center">
{{ Form::dateGroup('started_at', trans('reconciliations.start_date'), 'calendar',['id' => 'started_at', 'class' => 'form-control datepicker', 'required' => 'required', 'date-format' => 'Y-m-d', 'autocomplete' => 'off'], request('started_at'), 'col-xl-3') }}
{{ Form::dateGroup('started_at', trans('reconciliations.start_date'), 'calendar', ['id' => 'started_at', 'class' => 'form-control datepicker', 'required' => 'required', 'date-format' => 'Y-m-d', 'autocomplete' => 'off'], request('started_at'), 'col-xl-3') }}
{{ Form::dateGroup('ended_at', trans('reconciliations.end_date'), 'calendar',['id' => 'ended_at', 'class' => 'form-control datepicker', 'required' => 'required', 'date-format' => 'Y-m-d', 'autocomplete' => 'off'], request('started_at'), 'col-xl-3') }}
{{ Form::dateGroup('ended_at', trans('reconciliations.end_date'), 'calendar', ['id' => 'ended_at', 'class' => 'form-control datepicker', 'required' => 'required', 'date-format' => 'Y-m-d', 'autocomplete' => 'off'], request('ended_at'), 'col-xl-3') }}
{{ Form::moneyGroup('closing_balance', trans('reconciliations.closing_balance'), 'balance-scale', ['required' => 'required', 'autofocus' => 'autofocus', 'currency' => $currency], '0', 'col-xl-2') }}
{{ Form::moneyGroup('closing_balance', trans('reconciliations.closing_balance'), 'balance-scale', ['required' => 'required', 'autofocus' => 'autofocus', 'currency' => $currency], request('closing_balance'), 'col-xl-2') }}
{{ Form::selectGroup('account_id', trans_choice('general.accounts', 1), 'university', $accounts, request('account_id', setting('default.account')), ['required' => 'required'], 'col-xl-2') }}
{{ Form::selectGroup('account_id', trans_choice('general.accounts', 1), 'university', $accounts, request('account_id', setting('default.account')), ['required' => 'required', 'change' => 'onChangeAccount'], 'col-xl-2') }}
<div class="col-xl-2">
{!! Form::button('<span class="fa fa-list"></span> &nbsp;' . trans('reconciliations.transactions'), ['type' => 'submit', 'class' => 'btn btn-success header-button-top']) !!}
{!! Form::button('<span class="fa fa-list"></span> &nbsp;' . trans('reconciliations.transactions'), ['type' => 'button', '@click' => 'onReconcilition', 'class' => 'btn btn-success header-button-top']) !!}
</div>
</div>
</div>
@ -40,11 +39,12 @@
</div>
{!! Form::open([
'route' => 'reconciliations.create',
'id' => 'reconciliation',
'route' => 'reconciliations.store',
'@submit.prevent' => 'onSubmit',
'@keydown' => 'form.errors.clear($event.target.name)',
'role' => 'form',
'class' => 'form-loading-button',
'id' => 'form-reconciliations',
'class' => 'mb-0'
'class' => 'form-loading-button mb-0',
]) !!}
{{ Form::hidden('account_id', $account->id) }}
@ -73,13 +73,26 @@
<tr class="row align-items-center border-top-1">
<td class="col-xs-4 col-sm-3 col-md-2 long-texts">@date($item->paid_at)</td>
<td class="col-md-2 text-center d-none d-md-block">{{ $item->description }}</td>
<td class="col-sm-3 col-md-3 d-none d-sm-block">{{ $item->contact->name }}</td>
<td class="col-md-2 col-sm-3 col-md-3 d-none d-sm-block">{{ $item->contact->name }}</td>
@if ($item->type == 'income')
<td class="col-xs-4 col-sm-3 col-md-2 text-right">@money($item->amount, $item->currency_code, true)</td>
<td class="col-xs-4 col-sm-3 col-md-2 text-right">N/A</td>
@else
<td class="col-xs-4 col-sm-3 col-md-2 text-right">N/A</td>
<td class="col-xs-4 col-sm-3 col-md-2 text-right">@money($item->amount, $item->currency_code, true)</td>
@endif
<td class="col-md-1 text-right d-none d-md-block">{{ Form::checkbox('transactions['. $item->id . '_'. $item->type . ']', $item->amount, $item->reconciled) }}</td>
<td class="col-md-1 text-right d-none d-md-block">
<div class="custom-control custom-checkbox">
{{ Form::checkbox($item->type . '_' . $item->id, $item->amount, $item->reconciled, [
'data-field' => 'transactions',
'v-model' => 'form.transactions.' . $item->type . '_' . $item->id,
'id' => 'transaction-' . $item->id . '-'. $item->type,
'class' => 'custom-control-input',
'@change' => 'onCalculate'
]) }}
<label class="custom-control-label" for="transaction-{{ $item->id . '-'. $item->type }}"></label>
</div>
</td>
</tr>
@endforeach
</tbody>
@ -89,15 +102,27 @@
<tbody>
<tr class="row">
<th class="col-md-9 col-lg-11 text-right d-none d-md-block">{{ trans('reconciliations.closing_balance') }}:</th>
<td id="closing-balance" class="col-md-3 col-lg-1 text-right d-none d-md-block">@money(request('closing_balance', '0'), $account->currency_code, true)</td>
<td id="closing-balance" class="col-md-3 col-lg-1 text-right d-none d-md-block">
{{ Form::moneyGroup('closing_balance_total', '', '', ['disabled' => 'disabled', 'required' => 'required', 'v-model' => 'totals.closing_balance', 'currency' => $currency, 'dynamic-currency' => 'currency', 'masked' => 'true'], 0.00, 'text-right d-none') }}
<span id="closing-balance-total" v-if="totals.closing_balance" v-html="totals.closing_balance"></span>
<span v-else>@money(0, $account->currency_code, true)</span>
</td>
</tr>
<tr class="row">
<th class="col-md-9 col-lg-11 text-right d-none d-md-block">{{ trans('reconciliations.cleared_amount') }}:</th>
<td id="cleared-amount" class="col-md-3 col-lg-1 text-right d-none d-md-block">@money('0', $account->currency_code, true)</td>
<td id="cleared-amount" class="col-md-3 col-lg-1 text-right d-none d-md-block">
{{ Form::moneyGroup('cleared_amount_total', '', '', ['disabled' => 'disabled', 'required' => 'required', 'v-model' => 'totals.cleared_amount', 'currency' => $currency, 'dynamic-currency' => 'currency', 'masked' => 'true'], 0.00, 'text-right d-none') }}
<span id="cleared-amount-total" v-if="totals.cleared_amount" v-html="totals.cleared_amount"></span>
<span v-else>@money(0, $account->currency_code, true)</span>
</td>
</tr>
<tr class="row">
<tr :class="difference" class="row">
<th class="col-md-9 col-lg-11 text-right d-none d-md-block">{{ trans('general.difference') }}:</th>
<td id="difference" class="col-md-3 col-lg-1 text-right d-none d-md-block">@money('0', $account->currency_code, true)</td>
<td id="difference" class="col-md-3 col-lg-1 text-right d-none d-md-block">
{{ Form::moneyGroup('difference_total', '', '', ['disabled' => 'disabled', 'required' => 'required', 'v-model' => 'totals.difference', 'currency' => $currency, 'dynamic-currency' => 'currency', 'masked' => 'true'], 0.00, 'text-right d-none') }}
<span id="difference-total" v-if="totals.difference" v-html="totals.difference"></span>
<span v-else>@money(0, $account->currency_code, true)</span>
</td>
</tr>
</tbody>
</table>
@ -112,8 +137,8 @@
<a href="{{ route('reconciliations.index') }}" class="btn btn-outline-secondary header-button-top"><span class="fa fa-times"></span> &nbsp;{{ trans('general.cancel') }}</a>
{!! Form::button(
'<div v-if="form.loading" class="aka-loader-frame"><div class="aka-loader"></div></div> <span v-if="!form.loading" class="btn-inner--icon"><i class="fas fa-check"></i></span>' . '<span v-if="!form.loading" class="btn-inner--text"> ' . trans('reconciliations.reconcile') . '</span>',
[':disabled' => 'form.loading', 'type' => 'submit', 'class' => 'btn btn-icon btn-info header-button-top', 'data-loading-text' => trans('general.loading')]) !!}
'<div v-if="form.loading" class="aka-loader-frame"><div class="aka-loader"></div></div> <span :class="[{\'opacity-10\': reconcile}]" v-if="!form.loading" class="btn-inner--icon"><i class="fas fa-check"></i></span>' . '<span :class="[{\'opacity-10\': reconcile}]" class="btn-inner--text"> ' . trans('reconciliations.reconcile') . '</span>',
[':disabled' => 'reconcile || form.loading', '@click' => 'onReconcileSubmit', 'type' => 'button', 'class' => 'btn btn-icon btn-info header-button-top', 'data-loading-text' => trans('general.loading')]) !!}
{!! Form::button(
'<div v-if="form.loading" class="aka-loader-frame"><div class="aka-loader"></div></div> <span v-if="!form.loading" class="btn-inner--icon"><i class="fas fa-save"></i></span>' . '<span v-if="!form.loading" class="btn-inner--text"> ' . trans('general.save') . '</span>',

View File

@ -5,11 +5,14 @@
@section('content')
<div class="card">
{!! Form::model($reconciliation, [
'id' => 'reconciliation',
'method' => 'PATCH',
'route' => ['reconciliations.update', $reconciliation->id],
'@submit.prevent' => 'onSubmit',
'@keydown' => 'form.errors.clear($event.target.name)',
'role' => 'form',
'id' => 'form-reconciliations',
'class' => 'form-loading-button mb-0'
'class' => 'form-loading-button mb-0',
'novalidate' => true
]) !!}
<div class="card-header border-0">
@ -25,10 +28,10 @@
{{ Form::hidden('reconcile', $reconciliation->reconcile, ['id' => 'hidden-reconcile']) }}
<div class="table-responsive">
<table class="table align-items-center table-flush">
<table class="table table-flush table-hover">
<thead class="thead-light">
<tr class="row">
<th class="col-xs-4 col-sm-3 col-md-2 long-texts">{{ trans('general.date') }}</th>
<tr class="row table-head-line">
<th class="col-xs-4 col-sm-3 col-md-2 long-texts">{{ trans('general.date') }}</th>
<th class="col-md-2 text-center d-none d-md-block">{{ trans('general.description') }}</th>
<th class="col-md-2 col-sm-3 col-md-3 d-none d-sm-block">{{ trans_choice('general.contacts', 1) }}</th>
<th class="col-xs-4 col-sm-3 col-md-2 text-right">{{ trans('reconciliations.deposit') }}</th>
@ -39,58 +42,91 @@
<tbody>
@foreach($transactions as $item)
<tr class="row">
<tr class="row align-items-center border-top-1">
<td class="col-xs-4 col-sm-3 col-md-2 long-texts">@date($item->paid_at)</td>
<td class="col-md-2 text-center d-none d-md-block">{{ $item->description }}</td>
<td class="col-sm-3 col-md-3 d-none d-sm-block">{{ $item->contact->name }}</td>
<td class="col-md-2 col-sm-3 col-md-3 d-none d-sm-block">{{ $item->contact->name }}</td>
@if ($item->type == 'income')
<td class="col-xs-4 col-sm-3 col-md-2 text-right">@money($item->amount, $item->currency_code, true)</td>
<td class="col-xs-4 col-sm-3 col-md-2 text-right"> </td>
<td class="col-xs-4 col-sm-3 col-md-2 text-right">N/A</td>
@else
<td class="col-xs-4 col-sm-3 col-md-2 text-right">&nbsp;</td>
<td class="col-xs-4 col-sm-3 col-md-2 text-right">N/A</td>
<td class="col-xs-4 col-sm-3 col-md-2 text-right">@money($item->amount, $item->currency_code, true)</td>
@endif
<td class="col-md-1 text-right d-none d-md-block">{{ Form::checkbox('transactions['. $item->id . '_'. $item->type . ']', $item->amount, $item->reconciled) }}</td>
<td class="col-md-1 text-right d-none d-md-block">
<div class="custom-control custom-checkbox">
{{ Form::checkbox($item->type . '_' . $item->id, $item->amount, $item->reconciled, [
'data-field' => 'transactions',
'v-model' => 'form.transactions.' . $item->type . '_' . $item->id,
'id' => 'transaction-' . $item->id . '-'. $item->type,
'class' => 'custom-control-input',
'@change' => 'onCalculate'
]) }}
<label class="custom-control-label" for="transaction-{{ $item->id . '-'. $item->type }}"></label>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
@if ($transactions->count())
<table class="table">
<tbody>
<tr class="row">
<th class="col-md-9 col-lg-11 text-right d-none d-md-block">{{ trans('reconciliations.closing_balance') }}:</th>
<td id="closing-balance" class="col-md-1 text-right">@money($reconciliation->closing_balance, $account->currency_code, true)</td>
</tr>
<tr class="row">
<th class="col-md-9 col-lg-11 text-right d-none d-md-block">{{ trans('reconciliations.cleared_amount') }}:</th>
<td id="cleared-amount" class="col-md-3 col-lg-1 text-right d-none d-md-block">@money('0', $account->currency_code, true)</td>
</tr>
<tr class="row">
<th class="col-md-9 col-lg-11 text-right d-none d-md-block">{{ trans('general.difference') }}:</th>
<td id="difference" class="col-md-3 col-lg-1 text-right d-none d-md-block">@money('0', $account->currency_code, true)</td>
</tr>
</tbody>
</table>
<table class="table">
<tbody>
<tr class="row">
<th class="col-md-9 col-lg-11 text-right d-none d-md-block">{{ trans('reconciliations.closing_balance') }}:</th>
<td id="closing-balance" class="col-md-3 col-lg-1 text-right d-none d-md-block">
{{ Form::moneyGroup('closing_balance_total', '', '', ['disabled' => 'disabled', 'required' => 'required', 'v-model' => 'totals.closing_balance', 'currency' => $currency, 'dynamic-currency' => 'currency', 'masked' => 'true'], $reconciliation->closing_balance, 'text-right d-none') }}
<span id="closing-balance-total" v-if="totals.closing_balance" v-html="totals.closing_balance"></span>
<span v-else>@money($reconciliation->closing_balance, $account->currency_code, true)</span>
</td>
</tr>
<tr class="row">
<th class="col-md-9 col-lg-11 text-right d-none d-md-block">{{ trans('reconciliations.cleared_amount') }}:</th>
<td id="cleared-amount" class="col-md-3 col-lg-1 text-right d-none d-md-block">
{{ Form::moneyGroup('cleared_amount_total', '', '', ['disabled' => 'disabled', 'required' => 'required', 'v-model' => 'totals.cleared_amount', 'currency' => $currency, 'dynamic-currency' => 'currency', 'masked' => 'true'], 0.00, 'text-right d-none') }}
<span id="cleared-amount-total" v-if="totals.cleared_amount" v-html="totals.cleared_amount"></span>
<span v-else>@money(0, $account->currency_code, true)</span>
</td>
</tr>
<tr :class="difference" class="row">
<th class="col-md-9 col-lg-11 text-right d-none d-md-block">{{ trans('general.difference') }}:</th>
<td id="difference" class="col-md-3 col-lg-1 text-right d-none d-md-block">
{{ Form::moneyGroup('difference_total', '', '', ['disabled' => 'disabled', 'required' => 'required', 'v-model' => 'totals.difference', 'currency' => $currency, 'dynamic-currency' => 'currency', 'masked' => 'true'], 0.00, 'text-right d-none') }}
<span id="difference-total" v-if="totals.difference" v-html="totals.difference"></span>
<span v-else>@money(0, $account->currency_code, true)</span>
</td>
</tr>
</tbody>
</table>
@endif
</div>
<div class="card-footer">
<div class="row float-right">
@if ($transactions->count())
<a href="{{ route('reconciliations.index') }}" class="btn btn-outline-secondary header-button-top"><span class="fa fa-times"></span> &nbsp;{{ trans('general.cancel') }}</a>
{!! Form::button(
'<div v-if="form.loading" class="aka-loader-frame"><div class="aka-loader"></div></div> <span v-if="!form.loading" class="btn-inner--icon"><i class="fas fa-check"></i></span>' . '<span v-if="!form.loading" class="btn-inner--text"> ' . trans('reconciliations.reconcile') . '</span>',
[':disabled' => 'form.loading', 'type' => 'submit', 'class' => 'btn btn-icon btn-info button-submit header-button-top', 'data-loading-text' => trans('general.loading')]) !!}
@permission('update-banking-reconciliations')
<div class="card-footer">
<div class="row">
<div class="col-md-12">
@if ($transactions->count())
<div class="float-right">
<a href="{{ route('reconciliations.index') }}" class="btn btn-outline-secondary header-button-top"><span class="fa fa-times"></span> &nbsp;{{ trans('general.cancel') }}</a>
{!! Form::button(
'<div v-if="form.loading" class="aka-loader-frame"><div class="aka-loader"></div></div> <span v-if="!form.loading" class="btn-inner--icon"><i class="fas fa-save"></i></span>' . '<span v-if="!form.loading" class="btn-inner--text"> ' . trans('general.save') . '</span>',
[':disabled' => 'form.loading', 'type' => 'submit', 'class' => 'btn btn-icon btn-success button-submit header-button-top', 'data-loading-text' => trans('general.loading')]) !!}
@else
<small>{{ trans('general.no_records') }}</small>
@endif
{!! Form::button(
'<div v-if="form.loading" class="aka-loader-frame"><div class="aka-loader"></div></div> <span :class="[{\'opacity-10\': reconcile}]" v-if="!form.loading" class="btn-inner--icon"><i class="fas fa-check"></i></span>' . '<span :class="[{\'opacity-10\': reconcile}]" class="btn-inner--text"> ' . trans('reconciliations.reconcile') . '</span>',
[':disabled' => 'reconcile || form.loading', '@click' => 'onReconcileSubmit', 'type' => 'button', 'class' => 'btn btn-icon btn-info header-button-top', 'data-loading-text' => trans('general.loading')]) !!}
{!! Form::button(
'<div v-if="form.loading" class="aka-loader-frame"><div class="aka-loader"></div></div> <span v-if="!form.loading" class="btn-inner--icon"><i class="fas fa-save"></i></span>' . '<span v-if="!form.loading" class="btn-inner--text"> ' . trans('general.save') . '</span>',
[':disabled' => 'form.loading', 'type' => 'submit', 'class' => 'btn btn-icon btn-success header-button-top', 'data-loading-text' => trans('general.loading')]) !!}
</div>
@else
<div class="text-sm text-muted" id="datatable-basic_info" role="status" aria-live="polite">
<small>{{ trans('general.no_records') }}</small>
</div>
@endif
</div>
</div>
</div>
</div>
@endpermission
{!! Form::close() !!}
</div>
@endsection