diff --git a/app/Filters/Banking/Reconciliations.php b/app/Filters/Banking/Reconciliations.php new file mode 100644 index 000000000..f7a839c26 --- /dev/null +++ b/app/Filters/Banking/Reconciliations.php @@ -0,0 +1,21 @@ + [input_key1, input_key2]]. + * + * @var array + */ + public $relations = []; + + public function account($account) + { + return $this->where('account_id', $account); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Banking/Reconciliations.php b/app/Http/Controllers/Banking/Reconciliations.php new file mode 100644 index 000000000..035d97f07 --- /dev/null +++ b/app/Http/Controllers/Banking/Reconciliations.php @@ -0,0 +1,316 @@ +orderBy('name')->pluck('name', 'id')) + ->prepend(trans('general.all_type', ['type' => trans_choice('general.accounts', 2)]), ''); + + return view('banking.reconciliations.index', compact('reconciliations', 'accounts')); + } + + /** + * 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() + { + $accounts = Account::enabled()->pluck('name', 'id'); + + $account_id = request('account_id', setting('general.default_account')); + $started_at = request('started_at', '0000-00-00'); + $ended_at = request('ended_at', '0000-00-00'); + + $account = Account::find($account_id); + + $currency = $account->currency; + + $transactions = $this->getTransactions($account, $started_at, $ended_at); + + $opening_balance = $this->getOpeningBalance($account, $started_at, $ended_at); + + return view('banking.reconciliations.create', compact('accounts', 'account', 'currency', 'opening_balance', 'transactions')); + } + + /** + * Store a newly created resource in storage. + * + * @param Request $request + * + * @return Response + */ + public function store(Request $request) + { + $reconcile = $request->get('reconcile'); + $transactions = $request->get('transactions'); + + Reconciliation::create([ + 'company_id' => session('company_id'), + 'account_id' => $request->get('account_id'), + 'started_at' => $request->get('started_at'), + 'ended_at' => $request->get('ended_at'), + 'closing_balance' => $request->get('closing_balance'), + 'reconciled' => $reconcile ? 1 : 0, + ]); + + if ($transactions) { + foreach ($transactions as $key => $value) { + $t = explode('_', $key); + $m = '\\' . $t['1']; + + $transaction = $m::find($t[0]); + $transaction->reconciled = 1; + $transaction->save(); + } + } + + $message = trans('messages.success.added', ['type' => trans_choice('general.reconciliations', 1)]); + + flash($message)->success(); + + return redirect()->route('reconciliations.index'); + } + + /** + * 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) + { + $reconcile = $request->get('reconcile'); + $transactions = $request->get('transactions'); + + $reconciliation->reconciled = $reconcile ? 1 : 0; + $reconciliation->save(); + + if ($transactions) { + foreach ($transactions as $key => $value) { + $t = explode('_', $key); + $m = '\\' . $t['1']; + + $transaction = $m::find($t[0]); + $transaction->reconciled = 1; + $transaction->save(); + } + } + + $message = trans('messages.success.updated', ['type' => trans_choice('general.reconciliations', 1)]); + + flash($message)->success(); + + return redirect()->route('reconciliations.index'); + } + + /** + * Remove the specified resource from storage. + * + * @param Reconciliation $reconciliation + * + * @return Response + */ + public function destroy(Reconciliation $reconciliation) + { + $reconciliation->delete(); + + $models = [ + 'App\Models\Expense\Payment', + 'App\Models\Expense\BillPayment', + 'App\Models\Income\Revenue', + 'App\Models\Income\InvoicePayment', + ]; + + foreach ($models as $model) { + $m = '\\' . $model; + + $m::where('account_id', $reconciliation->account_id) + ->reconciled() + ->whereBetween('paid_at', [$reconciliation->started_at, $reconciliation->ended_at])->each(function ($item) { + $item->reconciled = 0; + $item->save(); + }); + } + + $message = trans('messages.success.deleted', ['type' => trans_choice('general.reconciliations', 1)]); + + flash($message)->success(); + + return redirect()->route('reconciliations.index'); + } + + /** + * Add transactions array. + * + * @param $account_id + * @param $started_at + * @param $ended_at + * + * @return array + */ + protected function getTransactions($account, $started_at, $ended_at) + { + $started = explode(' ', $started_at); + $ended = explode(' ', $ended_at); + + $models = [ + 'App\Models\Expense\Payment', + 'App\Models\Expense\BillPayment', + 'App\Models\Income\Revenue', + 'App\Models\Income\InvoicePayment', + ]; + + $transactions = []; + + foreach ($models as $model) { + $m = '\\' . $model; + + $m::where('account_id', $account->id)->whereBetween('paid_at', [$started[0], $ended[0]])->each(function($item) use(&$transactions, $model) { + $item->model = $model; + + if ((basename($model) == 'Invoice') || (basename($model) == 'Revenue')) { + if ($item->invoice) { + $item->contact = $item->invoice->customer; + } else { + $item->contact = $item->customer; + } + } else { + if ($item->bill) { + $item->contact = $item->bill->vendor; + } else { + $item->contact = $item->vendor; + } + } + + $transactions[] = $item; + }); + } + + 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 invoices + $invoice_payments = $account->invoice_payments()->whereDate('paid_at', '<', $started_at)->get(); + foreach ($invoice_payments as $item) { + $total += $item->amount; + } + + // Sum revenues + $revenues = $account->revenues()->whereDate('paid_at', '<', $started_at)->get(); + foreach ($revenues as $item) { + $total += $item->amount; + } + + // Subtract bills + $bill_payments = $account->bill_payments()->whereDate('paid_at', '<', $started_at)->get(); + foreach ($bill_payments as $item) { + $total -= $item->amount; + } + + // Subtract payments + $payments = $account->payments()->whereDate('paid_at', '<', $started_at)->get(); + foreach ($payments as $item) { + $total -= $item->amount; + } + + return $total; + } + + public function calculate() + { + $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) { + $model = explode('_', $key); + + if ((basename($model[1]) == 'Invoice') || (basename($model[1]) == 'Revenue')) { + $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); + } +} diff --git a/app/Http/Controllers/Expenses/Bills.php b/app/Http/Controllers/Expenses/Bills.php index fba2db439..13bda6147 100644 --- a/app/Http/Controllers/Expenses/Bills.php +++ b/app/Http/Controllers/Expenses/Bills.php @@ -64,43 +64,6 @@ class Bills extends Controller */ public function show(Bill $bill) { - $paid = 0; - - // Get Bill Payments - if ($bill->payments->count()) { - $_currencies = Currency::enabled()->pluck('rate', 'code')->toArray(); - - foreach ($bill->payments as $item) { - $default_amount = (double) $item->amount; - - if ($bill->currency_code == $item->currency_code) { - $amount = $default_amount; - } else { - $default_amount_model = new BillPayment(); - - $default_amount_model->default_currency_code = $bill->currency_code; - $default_amount_model->amount = $default_amount; - $default_amount_model->currency_code = $item->currency_code; - $default_amount_model->currency_rate = $_currencies[$item->currency_code]; - - $default_amount = (double) $default_amount_model->getDivideConvertedAmount(); - - $convert_amount = new BillPayment(); - - $convert_amount->default_currency_code = $item->currency_code; - $convert_amount->amount = $default_amount; - $convert_amount->currency_code = $bill->currency_code; - $convert_amount->currency_rate = $_currencies[$bill->currency_code]; - - $amount = (double) $convert_amount->getDynamicConvertedAmount(); - } - - $paid += $amount; - } - } - - $bill->paid = $paid; - $accounts = Account::enabled()->orderBy('name')->pluck('name', 'id'); $currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray(); diff --git a/app/Http/Controllers/Incomes/Invoices.php b/app/Http/Controllers/Incomes/Invoices.php index 2b5b27b2c..027928e16 100644 --- a/app/Http/Controllers/Incomes/Invoices.php +++ b/app/Http/Controllers/Incomes/Invoices.php @@ -70,43 +70,6 @@ class Invoices extends Controller */ public function show(Invoice $invoice) { - $paid = 0; - - // Get Invoice Payments - if ($invoice->payments->count()) { - $_currencies = Currency::enabled()->pluck('rate', 'code')->toArray(); - - foreach ($invoice->payments as $item) { - $default_amount = $item->amount; - - if ($invoice->currency_code == $item->currency_code) { - $amount = (double)$default_amount; - } else { - $default_amount_model = new InvoicePayment(); - - $default_amount_model->default_currency_code = $invoice->currency_code; - $default_amount_model->amount = $default_amount; - $default_amount_model->currency_code = $item->currency_code; - $default_amount_model->currency_rate = $_currencies[$item->currency_code]; - - $default_amount = (double) $default_amount_model->getDivideConvertedAmount(); - - $convert_amount = new InvoicePayment(); - - $convert_amount->default_currency_code = $item->currency_code; - $convert_amount->amount = $default_amount; - $convert_amount->currency_code = $invoice->currency_code; - $convert_amount->currency_rate = $_currencies[$invoice->currency_code]; - - $amount = (double) $convert_amount->getDynamicConvertedAmount(); - } - - $paid += $amount; - } - } - - $invoice->paid = $paid; - $accounts = Account::enabled()->orderBy('name')->pluck('name', 'id'); $currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray(); diff --git a/app/Http/Middleware/AdminMenu.php b/app/Http/Middleware/AdminMenu.php index 817204b3c..8f73efa01 100644 --- a/app/Http/Middleware/AdminMenu.php +++ b/app/Http/Middleware/AdminMenu.php @@ -91,7 +91,7 @@ class AdminMenu } // Banking - if ($user->can(['read-banking-accounts', 'read-banking-transfers', 'read-banking-transactions'])) { + if ($user->can(['read-banking-accounts', 'read-banking-transfers', 'read-banking-transactions', 'read-banking-reconciliations'])) { $menu->dropdown(trans('general.banking'), function ($sub) use($user, $attr) { if ($user->can('read-banking-accounts')) { $sub->url('banking/accounts', trans_choice('general.accounts', 2), 1, $attr); @@ -104,6 +104,10 @@ class AdminMenu if ($user->can('read-banking-transactions')) { $sub->url('banking/transactions', trans_choice('general.transactions', 2), 3, $attr); } + + if ($user->can('read-banking-reconciliations')) { + $sub->url('banking/reconciliations', trans_choice('general.reconciliations', 2), 4, $attr); + } }, 5, [ 'title' => trans('general.banking'), 'icon' => 'fa fa-university', diff --git a/app/Http/Middleware/DateFormat.php b/app/Http/Middleware/DateFormat.php index b308637f5..df0676bd6 100644 --- a/app/Http/Middleware/DateFormat.php +++ b/app/Http/Middleware/DateFormat.php @@ -17,7 +17,7 @@ class DateFormat public function handle($request, Closure $next) { if (($request->method() == 'POST') || ($request->method() == 'PATCH')) { - $fields = ['paid_at', 'due_at', 'billed_at', 'invoiced_at']; + $fields = ['paid_at', 'due_at', 'billed_at', 'invoiced_at', 'started_at', 'ended_at']; foreach ($fields as $field) { $date = $request->get($field); diff --git a/app/Http/Requests/Banking/Reconciliation.php b/app/Http/Requests/Banking/Reconciliation.php new file mode 100644 index 000000000..861aea9c3 --- /dev/null +++ b/app/Http/Requests/Banking/Reconciliation.php @@ -0,0 +1,33 @@ + 'required|integer', + 'started_at' => 'required|date_format:Y-m-d H:i:s', + 'ended_at' => 'required|date_format:Y-m-d H:i:s', + 'closing_balance' => 'required|amount', + ]; + } +} diff --git a/app/Listeners/Updates/Version130.php b/app/Listeners/Updates/Version130.php index b6aa5bd1d..a50dc1dfe 100644 --- a/app/Listeners/Updates/Version130.php +++ b/app/Listeners/Updates/Version130.php @@ -29,5 +29,51 @@ class Version130 extends Listener setting(['general.schedule_item_stocks' => '3,5,7']); setting()->save(); + + $this->updatePermissions(); + + // Update database + Artisan::call('migrate', ['--force' => true]); + } + + protected function updatePermissions() + { + $permissions = []; + + $permissions[] = Permission::firstOrCreate([ + 'name' => 'read-banking-reconciliations', + 'display_name' => 'Read Banking Reconciliations', + 'description' => 'Read Banking Reconciliations', + ]); + $permissions[] = Permission::firstOrCreate([ + 'name' => 'create-banking-reconciliations', + 'display_name' => 'Create Banking Reconciliations', + 'description' => 'Create Banking Reconciliations', + ]); + $permissions[] = Permission::firstOrCreate([ + 'name' => 'update-banking-reconciliations', + 'display_name' => 'Update Banking Reconciliations', + 'description' => 'Update Banking Reconciliations', + ]); + $permissions[] = Permission::firstOrCreate([ + 'name' => 'delete-banking-reconciliations', + 'display_name' => 'Delete Banking Reconciliations', + 'description' => 'Delete Banking Reconciliations', + ]); + + // Attach permission to roles + $roles = Role::all(); + + foreach ($roles as $role) { + $allowed = ['admin', 'manager']; + + if (!in_array($role->name, $allowed)) { + continue; + } + + foreach ($permissions as $permission) { + $role->attachPermission($permission); + } + } } } diff --git a/app/Models/Banking/Reconciliation.php b/app/Models/Banking/Reconciliation.php new file mode 100644 index 000000000..a3c0d728e --- /dev/null +++ b/app/Models/Banking/Reconciliation.php @@ -0,0 +1,45 @@ +belongsTo('App\Models\Banking\Account'); + } + + /** + * Convert closing balance to double. + * + * @param string $value + * @return void + */ + public function setClosingBalanceAttribute($value) + { + $this->attributes['closing_balance'] = (double) $value; + } +} diff --git a/app/Models/Expense/Bill.php b/app/Models/Expense/Bill.php index 3258163e1..cba81dfc3 100644 --- a/app/Models/Expense/Bill.php +++ b/app/Models/Expense/Bill.php @@ -3,6 +3,7 @@ namespace App\Models\Expense; use App\Models\Model; +use App\Models\Setting\Currency; use App\Traits\Currencies; use App\Traits\DateTime; use App\Traits\Media; @@ -22,7 +23,7 @@ class Bill extends Model * * @var array */ - protected $appends = ['attachment', 'discount']; + protected $appends = ['attachment', 'discount', 'paid']; protected $dates = ['deleted_at', 'billed_at', 'due_at']; @@ -199,4 +200,55 @@ class Bill extends Model return $percent; } + + /** + * Get the paid amount. + * + * @return string + */ + public function getPaidAttribute() + { + $paid = 0; + $reconciled = $reconciled_amount = 0; + + if ($this->payments->count()) { + $currencies = Currency::enabled()->pluck('rate', 'code')->toArray(); + + foreach ($this->payments as $item) { + if ($this->currency_code == $item->currency_code) { + $amount = (double) $item->amount; + } else { + $default_model = new BillPayment(); + $default_model->default_currency_code = $this->currency_code; + $default_model->amount = $item->amount; + $default_model->currency_code = $item->currency_code; + $default_model->currency_rate = $currencies[$item->currency_code]; + + $default_amount = (double) $default_model->getDivideConvertedAmount(); + + $convert_model = new BillPayment(); + $convert_model->default_currency_code = $item->currency_code; + $convert_model->amount = $default_amount; + $convert_model->currency_code = $this->currency_code; + $convert_model->currency_rate = $currencies[$this->currency_code]; + + $amount = (double) $convert_model->getDynamicConvertedAmount(); + } + + $paid += $amount; + + if ($item->reconciled) { + $reconciled_amount = +$amount; + } + } + } + + if ($this->amount == $reconciled_amount) { + $reconciled = 1; + } + + $this->setAttribute('reconciled', $reconciled); + + return $paid; + } } diff --git a/app/Models/Income/Invoice.php b/app/Models/Income/Invoice.php index 1e765293e..ca992084a 100644 --- a/app/Models/Income/Invoice.php +++ b/app/Models/Income/Invoice.php @@ -3,6 +3,7 @@ namespace App\Models\Income; use App\Models\Model; +use App\Models\Setting\Currency; use App\Traits\Currencies; use App\Traits\DateTime; use App\Traits\Incomes; @@ -23,7 +24,7 @@ class Invoice extends Model * * @var array */ - protected $appends = ['attachment', 'discount']; + protected $appends = ['attachment', 'discount', 'paid']; protected $dates = ['deleted_at', 'invoiced_at', 'due_at']; @@ -56,6 +57,8 @@ class Invoice extends Model 'notes' => 2, ]; + protected $reconciled_amount = []; + /** * Clonable relationships. * @@ -201,4 +204,55 @@ class Invoice extends Model return $percent; } + + /** + * Get the paid amount. + * + * @return string + */ + public function getPaidAttribute() + { + $paid = 0; + $reconciled = $reconciled_amount = 0; + + if ($this->payments->count()) { + $currencies = Currency::enabled()->pluck('rate', 'code')->toArray(); + + foreach ($this->payments as $item) { + if ($this->currency_code == $item->currency_code) { + $amount = (double) $item->amount; + } else { + $default_model = new InvoicePayment(); + $default_model->default_currency_code = $this->currency_code; + $default_model->amount = $item->amount; + $default_model->currency_code = $item->currency_code; + $default_model->currency_rate = $currencies[$item->currency_code]; + + $default_amount = (double) $default_model->getDivideConvertedAmount(); + + $convert_model = new InvoicePayment(); + $convert_model->default_currency_code = $item->currency_code; + $convert_model->amount = $default_amount; + $convert_model->currency_code = $this->currency_code; + $convert_model->currency_rate = $currencies[$this->currency_code]; + + $amount = (double) $convert_model->getDynamicConvertedAmount(); + } + + $paid += $amount; + + if ($item->reconciled) { + $reconciled_amount = +$amount; + } + } + } + + if ($this->amount == $reconciled_amount) { + $reconciled = 1; + } + + $this->setAttribute('reconciled', $reconciled); + + return $paid; + } } diff --git a/app/Models/Model.php b/app/Models/Model.php index df758de33..a52cad77a 100644 --- a/app/Models/Model.php +++ b/app/Models/Model.php @@ -115,4 +115,16 @@ class Model extends Eloquent { return $query->where('enabled', 0); } + + /** + * Scope to only include reconciled models. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param $value + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeReconciled($query, $value = 1) + { + return $query->where('reconciled', $value); + } } diff --git a/database/migrations/2018_10_27_000000_add_reconciled_column.php b/database/migrations/2018_10_27_000000_add_reconciled_column.php new file mode 100644 index 000000000..9aa23f498 --- /dev/null +++ b/database/migrations/2018_10_27_000000_add_reconciled_column.php @@ -0,0 +1,54 @@ +boolean('reconciled')->default(0); + }); + + Schema::table('invoice_payments', function ($table) { + $table->boolean('reconciled')->default(0); + }); + + Schema::table('payments', function ($table) { + $table->boolean('reconciled')->default(0); + }); + + Schema::table('revenues', function ($table) { + $table->boolean('reconciled')->default(0); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('bill_payments', function ($table) { + $table->dropColumn('reconciled'); + }); + + Schema::table('invoice_payments', function ($table) { + $table->dropColumn('reconciled'); + }); + + Schema::table('payments', function ($table) { + $table->dropColumn('reconciled'); + }); + + Schema::table('revenues', function ($table) { + $table->dropColumn('reconciled'); + }); + } +} diff --git a/database/migrations/2018_10_27_000000_create_reconciliations_table.php b/database/migrations/2018_10_27_000000_create_reconciliations_table.php new file mode 100644 index 000000000..1f0fb4f13 --- /dev/null +++ b/database/migrations/2018_10_27_000000_create_reconciliations_table.php @@ -0,0 +1,39 @@ +increments('id'); + $table->integer('company_id'); + $table->integer('account_id'); + $table->dateTime('started_at'); + $table->dateTime('ended_at'); + $table->double('closing_balance', 15, 4)->default('0.0000'); + $table->boolean('reconciled'); + $table->timestamps(); + $table->softDeletes(); + + $table->index('company_id'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('reconciliations'); + } +} diff --git a/public/css/app.css b/public/css/app.css index 0058aecdf..74af5a3b9 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -515,6 +515,9 @@ ul.add-new.nav.navbar-nav.pull-left { .amount-space { padding-right: 30px !important; } + .amount-space-left { + padding-left: 30px !important; + } } .text-disabled { diff --git a/resources/lang/en-GB/general.php b/resources/lang/en-GB/general.php index daee66c9d..215c64937 100644 --- a/resources/lang/en-GB/general.php +++ b/resources/lang/en-GB/general.php @@ -38,6 +38,10 @@ return [ 'numbers' => 'Number|Numbers', 'statuses' => 'Status|Statuses', 'others' => 'Other|Others', + 'contacts' => 'Contact|Contacts', + 'reconciliations' => 'Reconciliation|Reconciliations', + 'deposits' => 'Deposit|Deposits', + 'withdrawals' => 'Withdrawal|Withdrawals', 'dashboard' => 'Dashboard', 'banking' => 'Banking', @@ -106,6 +110,13 @@ return [ 'disable' => 'Disable', 'select_all' => 'Select All', 'unselect_all' => 'Unselect All', + 'create_date' => 'Create Date', + 'period' => 'Period', + 'start' => 'Start', + 'end' => 'End', + 'clear' => 'Clear', + 'difference' => 'Difference', + 'title' => [ 'new' => 'New :type', 'edit' => 'Edit :type', diff --git a/resources/lang/en-GB/reconciliations.php b/resources/lang/en-GB/reconciliations.php new file mode 100644 index 000000000..0ab0e4022 --- /dev/null +++ b/resources/lang/en-GB/reconciliations.php @@ -0,0 +1,14 @@ + 'Reconcile', + 'reconciled' => 'Reconciled', + 'closing_balance' => 'Closing Balance', + 'unreconciled' => 'Unreconciled', + 'list_transactions' => 'List Transactions', + 'start_date' => 'Start Date', + 'end_date' => 'End Date', + 'cleared_amount' => 'Cleared Amount', + +]; diff --git a/resources/views/banking/accounts/index.blade.php b/resources/views/banking/accounts/index.blade.php index 153392384..ba3ae143a 100644 --- a/resources/views/banking/accounts/index.blade.php +++ b/resources/views/banking/accounts/index.blade.php @@ -41,7 +41,7 @@ @foreach($accounts as $item) - {{ $item->name }} + {{ $item->name }} {{ $item->number }} @money($item->balance, $item->currency_code, true) @@ -57,7 +57,7 @@ @@ -292,6 +296,11 @@ @money($payment->amount, $payment->currency_code, true) {{ $payment->account->name }} + @if ($payment->reconciled) + + @else {!! Form::open([ @@ -307,6 +316,7 @@ 'onclick' => 'confirmDelete("' . '#invoice-payment-' . $payment->id . '", "' . trans_choice('general.payments', 2) . '", "' . trans('general.delete_confirm', ['name' => '' . Date::parse($payment->paid_at)->format($date_format) . ' - ' . money($payment->amount, $payment->currency_code, true) . ' - ' . $payment->account->name . '', 'type' => strtolower(trans_choice('general.revenues', 1))]) . '", "' . trans('general.cancel') . '", "' . trans('general.delete') . '")' )) !!} {!! Form::close() !!} + @endif @endforeach diff --git a/resources/views/incomes/revenues/index.blade.php b/resources/views/incomes/revenues/index.blade.php index 01db5b3c6..c2eb2fdb4 100644 --- a/resources/views/incomes/revenues/index.blade.php +++ b/resources/views/incomes/revenues/index.blade.php @@ -47,7 +47,11 @@ @foreach($revenues as $item) + @if ($item->reconciled) + {{ Date::parse($item->paid_at)->format($date_format) }} + @else {{ Date::parse($item->paid_at)->format($date_format) }} + @endif @money($item->amount, $item->currency_code, true) {{ !empty($item->customer->name) ? $item->customer->name : trans('general.na') }} {{ $item->category->name }} @@ -59,14 +63,18 @@ diff --git a/resources/views/partials/admin/header.blade.php b/resources/views/partials/admin/header.blade.php index 93af21b6e..21cfdd9fd 100644 --- a/resources/views/partials/admin/header.blade.php +++ b/resources/views/partials/admin/header.blade.php @@ -77,6 +77,9 @@ @permission('create-banking-transfers')
  • {{ trans_choice('general.transfers', 1) }}
  • @endpermission + @permission('create-banking-reconciliations') +
  • {{ trans_choice('general.reconciliations', 1) }}
  • + @endpermission diff --git a/routes/web.php b/routes/web.php index 127316e8c..bfd43df77 100644 --- a/routes/web.php +++ b/routes/web.php @@ -106,6 +106,9 @@ Route::group(['middleware' => 'language'], function () { Route::resource('accounts', 'Banking\Accounts', ['middleware' => ['dateformat', 'money']]); Route::resource('transactions', 'Banking\Transactions'); Route::resource('transfers', 'Banking\Transfers', ['middleware' => ['dateformat', 'money']]); + Route::post('reconciliations/calculate', 'Banking\Reconciliations@calculate')->middleware(['money']); + Route::patch('reconciliations/calculate', 'Banking\Reconciliations@calculate')->middleware(['money']); + Route::resource('reconciliations', 'Banking\Reconciliations', ['middleware' => ['dateformat', 'money']]); }); Route::group(['prefix' => 'reports'], function () {