bank reconciliation
This commit is contained in:
21
app/Filters/Banking/Reconciliations.php
Normal file
21
app/Filters/Banking/Reconciliations.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filters\Banking;
|
||||
|
||||
use EloquentFilter\ModelFilter;
|
||||
|
||||
class Reconciliations extends ModelFilter
|
||||
{
|
||||
/**
|
||||
* Related Models that have ModelFilters as well as the method on the ModelFilter
|
||||
* As [relatedModel => [input_key1, input_key2]].
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $relations = [];
|
||||
|
||||
public function account($account)
|
||||
{
|
||||
return $this->where('account_id', $account);
|
||||
}
|
||||
}
|
316
app/Http/Controllers/Banking/Reconciliations.php
Normal file
316
app/Http/Controllers/Banking/Reconciliations.php
Normal file
@ -0,0 +1,316 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Banking;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Banking\Reconciliation as Request;
|
||||
use App\Models\Banking\Account;
|
||||
use App\Models\Banking\Reconciliation;
|
||||
use App\Models\Setting\Currency;
|
||||
use Date;
|
||||
|
||||
class Reconciliations extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$reconciliations = Reconciliation::collect();
|
||||
|
||||
$accounts = collect(Account::enabled()->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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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',
|
||||
|
@ -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);
|
||||
|
33
app/Http/Requests/Banking/Reconciliation.php
Normal file
33
app/Http/Requests/Banking/Reconciliation.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Banking;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class Reconciliation extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'account_id' => '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',
|
||||
];
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
45
app/Models/Banking/Reconciliation.php
Normal file
45
app/Models/Banking/Reconciliation.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Banking;
|
||||
|
||||
use App\Models\Model;
|
||||
use Sofa\Eloquence\Eloquence;
|
||||
|
||||
class Reconciliation extends Model
|
||||
{
|
||||
use Eloquence;
|
||||
|
||||
protected $table = 'reconciliations';
|
||||
|
||||
protected $dates = ['deleted_at', 'started_at', 'ended_at'];
|
||||
|
||||
/**
|
||||
* Attributes that should be mass-assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['company_id', 'account_id', 'started_at', 'ended_at', 'closing_balance', 'reconciled'];
|
||||
|
||||
/**
|
||||
* Sortable columns.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $sortable = ['created_at', 'account_id', 'started_at', 'ended_at', 'closing_balance', 'reconciled'];
|
||||
|
||||
public function account()
|
||||
{
|
||||
return $this->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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user