v2 first commit

This commit is contained in:
denisdulici
2019-11-16 10:21:14 +03:00
parent 5b23e9c2c4
commit 6d50fa8442
3075 changed files with 3451681 additions and 65594 deletions

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Jobs\Banking;
use App\Abstracts\Job;
use App\Models\Banking\Account;
class CreateAccount extends Job
{
protected $request;
/**
* Create a new job instance.
*
* @param $request
*/
public function __construct($request)
{
$this->request = $this->getRequestInstance($request);
}
/**
* Execute the job.
*
* @return Account
*/
public function handle()
{
$account = Account::create($this->request->all());
// Set default account
if ($this->request['default_account']) {
setting()->set('default.account', $account->id);
setting()->save();
}
return $account;
}
}

View File

@@ -0,0 +1,213 @@
<?php
namespace App\Jobs\Banking;
use App\Abstracts\Job;
use App\Jobs\Banking\CreateTransaction;
use App\Jobs\Expense\CreateBillHistory;
use App\Jobs\Income\CreateInvoiceHistory;
use App\Models\Banking\Transaction;
use App\Models\Income\Invoice;
use App\Models\Setting\Currency;
use Date;
class CreateDocumentTransaction extends Job
{
protected $model;
protected $request;
/**
* Create a new job instance.
*
* @param $model
* @param $request
*/
public function __construct($model, $request)
{
$this->model = $model;
$this->request = $this->getRequestInstance($request);
}
/**
* Execute the job.
*
* @return Transaction
*/
public function handle()
{
$this->prepareRequest();
$this->checkAmount();
$transaction = $this->dispatch(new CreateTransaction($this->request));
// Upload attachment
if ($this->request->file('attachment')) {
$media = $this->getMedia($this->request->file('attachment'), 'transactions');
$transaction->attachMedia($media, 'attachment');
}
$this->model->save();
$this->createHistory($transaction);
return $transaction;
}
protected function prepareRequest()
{
if ($this->request->missing('currency_code')) {
$this->request['currency_code'] = $this->model->currency_code;
}
$this->currency = Currency::where('code', $this->request['currency_code'])->first();
$this->request['type'] = ($this->model instanceof Invoice) ? 'income' : 'expense';
$this->request['currency_rate'] = $this->currency->rate;
$this->request['amount'] = isset($this->request['amount']) ? $this->request['amount'] : ($this->model->amount - $this->getPaidAmount());
$this->request['paid_at'] = isset($this->request['paid_at']) ? $this->request['paid_at'] : Date::now()->format('Y-m-d');
$this->request['company_id'] = isset($this->request['company_id']) ? $this->request['company_id'] : session('company_id');
$this->request['account_id'] = isset($this->request['account_id']) ? $this->request['account_id'] : setting('default.account');
$this->request['payment_method'] = isset($this->request['payment_method']) ? $this->request['payment_method'] : setting('default.payment_method');
$this->request['currency_code'] = isset($this->request['currency_code']) ? $this->request['currency_code'] : $this->model->currency_code;
$this->request['document_id'] = isset($this->request['document_id']) ? $this->request['document_id'] : $this->model->id;
$this->request['contact_id'] = isset($this->request['contact_id']) ? $this->request['contact_id'] : $this->model->contact_id;
$this->request['category_id'] = isset($this->request['category_id']) ? $this->request['category_id'] : $this->model->category_id;
$this->request['notify'] = isset($this->request['notify']) ? $this->request['notify'] : 0;
}
protected function checkAmount()
{
$currencies = Currency::enabled()->pluck('rate', 'code')->toArray();
$total_amount = $this->model->amount;
$default_amount = (double) $this->request['amount'];
if ($this->model->currency_code == $this->request['currency_code']) {
$amount = $default_amount;
} else {
$default_amount_model = new Transaction();
$default_amount_model->default_currency_code = $this->model->currency_code;
$default_amount_model->amount = $default_amount;
$default_amount_model->currency_code = $this->request['currency_code'];
$default_amount_model->currency_rate = $currencies[$this->request['currency_code']];
$default_amount = (double) $default_amount_model->getDivideConvertedAmount();
$convert_amount_model = new Transaction();
$convert_amount_model->default_currency_code = $this->request['currency_code'];
$convert_amount_model->amount = $default_amount;
$convert_amount_model->currency_code = $this->model->currency_code;
$convert_amount_model->currency_rate = $currencies[$this->model->currency_code];
$amount = (double) $convert_amount_model->getAmountConvertedFromCustomDefault();
}
$total_amount -= $this->getPaidAmount();
// For amount cover integer
$multiplier = 1;
for ($i = 0; $i < $this->currency->precision; $i++) {
$multiplier *= 10;
}
$amount_check = (int) ($amount * $multiplier);
$total_amount_check = (int) (round($total_amount, $this->currency->precision) * $multiplier);
if ($amount_check > $total_amount_check) {
$error_amount = $total_amount;
if ($this->model->currency_code != $this->request['currency_code']) {
$error_amount_model = new Transaction();
$error_amount_model->default_currency_code = $this->request['currency_code'];
$error_amount_model->amount = $error_amount;
$error_amount_model->currency_code = $this->model->currency_code;
$error_amount_model->currency_rate = $currencies[$this->model->currency_code];
$error_amount = (double) $error_amount_model->getDivideConvertedAmount();
$convert_amount_model = new Transaction();
$convert_amount_model->default_currency_code = $this->model->currency_code;
$convert_amount_model->amount = $error_amount;
$convert_amount_model->currency_code = $this->request['currency_code'];
$convert_amount_model->currency_rate = $currencies[$this->request['currency_code']];
$error_amount = (double) $convert_amount_model->getAmountConvertedFromCustomDefault();
}
$message = trans('messages.error.over_payment', ['amount' => money($error_amount, $this->request['currency_code'], true)]);
throw new \Exception($message);
} else {
$this->setStatusCode($amount_check, $total_amount_check);
}
return true;
}
protected function getPaidAmount()
{
$paid = 0;
if (!$this->model->transactions->count()) {
return $paid;
}
$currencies = Currency::enabled()->pluck('rate', 'code')->toArray();
foreach ($this->model->transactions as $item) {
$default_amount = $item->amount;
if ($this->model->currency_code == $item->currency_code) {
$amount = (double) $default_amount;
} else {
$default_amount_model = new Transaction();
$default_amount_model->default_currency_code = $this->model->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_model = new Transaction();
$convert_amount_model->default_currency_code = $item->currency_code;
$convert_amount_model->amount = $default_amount;
$convert_amount_model->currency_code = $this->model->currency_code;
$convert_amount_model->currency_rate = $currencies[$this->model->currency_code];
$amount = (double) $convert_amount_model->getAmountConvertedFromCustomDefault();
}
$paid += $amount;
}
return $paid;
}
protected function setStatusCode($amount_check, $total_amount_check)
{
$column = ($this->model instanceof Invoice) ? 'invoice_status_code' : 'bill_status_code';
if ($amount_check == $total_amount_check) {
$this->model->$column = 'paid';
} else {
$this->model->$column = 'partial';
}
}
protected function createHistory($transaction)
{
$history_desc = money((double) $transaction->amount, (string) $transaction->currency_code, true)->format() . ' ' . trans_choice('general.payments', 1);
if ($this->model instanceof Invoice) {
$this->dispatch(new CreateInvoiceHistory($this->model, 0, $history_desc));
} else {
$this->dispatch(new CreateBillHistory($this->model, 0, $history_desc));
}
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace App\Jobs\Banking;
use App\Abstracts\Job;
use App\Models\Banking\Reconciliation;
class CreateReconciliation extends Job
{
protected $request;
/**
* Create a new job instance.
*
* @param $request
*/
public function __construct($request)
{
$this->request = $this->getRequestInstance($request);
}
/**
* Execute the job.
*
* @return Reconciliation
*/
public function handle()
{
$reconcile = $this->request->get('reconcile');
$transactions = $this->request->get('transactions');
$reconciliation = Reconciliation::create([
'company_id' => session('company_id'),
'account_id' => $this->request->get('account_id'),
'started_at' => $this->request->get('started_at'),
'ended_at' => $this->request->get('ended_at'),
'closing_balance' => $this->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();
}
}
return $reconciliation;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Jobs\Banking;
use App\Abstracts\Job;
use App\Models\Banking\Transaction;
class CreateTransaction extends Job
{
protected $request;
/**
* Create a new job instance.
*
* @param $request
*/
public function __construct($request)
{
$this->request = $this->getRequestInstance($request);
}
/**
* Execute the job.
*
* @return Transaction
*/
public function handle()
{
$transaction = Transaction::create($this->request->all());
// Upload attachment
if ($this->request->file('attachment')) {
$media = $this->getMedia($this->request->file('attachment'), 'transactions');
$transaction->attachMedia($media, 'attachment');
}
// Recurring
$transaction->createRecurring();
return $transaction;
}
}

View File

@@ -0,0 +1,105 @@
<?php
namespace App\Jobs\Banking;
use App\Abstracts\Job;
use App\Models\Banking\Account;
use App\Models\Banking\Transaction;
use App\Models\Banking\Transfer;
use App\Models\Setting\Category;
use App\Models\Setting\Currency;
class CreateTransfer extends Job
{
protected $request;
/**
* Create a new job instance.
*
* @param $request
*/
public function __construct($request)
{
$this->request = $this->getRequestInstance($request);
}
/**
* Execute the job.
*
* @return Transfer
*/
public function handle()
{
$currencies = Currency::enabled()->pluck('rate', 'code')->toArray();
$expense_currency_code = Account::where('id', $this->request->get('from_account_id'))->pluck('currency_code')->first();
$income_currency_code = Account::where('id', $this->request->get('to_account_id'))->pluck('currency_code')->first();
$expense_transaction = Transaction::create([
'company_id' => $this->request['company_id'],
'type' => 'expense',
'account_id' => $this->request->get('from_account_id'),
'paid_at' => $this->request->get('transferred_at'),
'currency_code' => $expense_currency_code,
'currency_rate' => $currencies[$expense_currency_code],
'amount' => $this->request->get('amount'),
'contact_id' => 0,
'description' => $this->request->get('description'),
'category_id' => Category::transfer(), // Transfer Category ID
'payment_method' => $this->request->get('payment_method'),
'reference' => $this->request->get('reference'),
]);
// Convert amount if not same currency
if ($expense_currency_code != $income_currency_code) {
$default_currency = setting('default.currency', 'USD');
$default_amount = $this->request->get('amount');
if ($default_currency != $expense_currency_code) {
$default_amount_model = new Transfer();
$default_amount_model->default_currency_code = $default_currency;
$default_amount_model->amount = $this->request->get('amount');
$default_amount_model->currency_code = $expense_currency_code;
$default_amount_model->currency_rate = $currencies[$expense_currency_code];
$default_amount = $default_amount_model->getAmountDivided();
}
$transfer_amount = new Transfer();
$transfer_amount->default_currency_code = $expense_currency_code;
$transfer_amount->amount = $default_amount;
$transfer_amount->currency_code = $income_currency_code;
$transfer_amount->currency_rate = $currencies[$income_currency_code];
$amount = $transfer_amount->getAmountConvertedFromCustomDefault();
} else {
$amount = $this->request->get('amount');
}
$income_transaction = Transaction::create([
'company_id' => $this->request['company_id'],
'type' => 'income',
'account_id' => $this->request->get('to_account_id'),
'paid_at' => $this->request->get('transferred_at'),
'currency_code' => $income_currency_code,
'currency_rate' => $currencies[$income_currency_code],
'amount' => $amount,
'contact_id' => 0,
'description' => $this->request->get('description'),
'category_id' => Category::transfer(), // Transfer Category ID
'payment_method' => $this->request->get('payment_method'),
'reference' => $this->request->get('reference'),
]);
$transfer = Transfer::create([
'company_id' => $this->request['company_id'],
'expense_transaction_id' => $expense_transaction->id,
'income_transaction_id' => $income_transaction->id,
]);
return $transfer;
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Jobs\Banking;
use App\Abstracts\Job;
class DeleteAccount extends Job
{
protected $account;
/**
* Create a new job instance.
*
* @param $account
*/
public function __construct($account)
{
$this->account = $account;
}
/**
* Execute the job.
*
* @return boolean|Exception
*/
public function handle()
{
$this->authorize();
$this->account->delete();
return true;
}
/**
* Determine if this action is applicable.
*
* @return void
*/
public function authorize()
{
if ($relationships = $this->getRelationships()) {
$message = trans('messages.warning.deleted', ['name' => $this->account->name, 'text' => implode(', ', $relationships)]);
throw new \Exception($message);
}
}
public function getRelationships()
{
$rels = [
'transactions' => 'transactions',
];
$relationships = $this->countRelationships($this->account, $rels);
if ($this->account->id == setting('default.account')) {
$relationships[] = strtolower(trans_choice('general.companies', 1));
}
return $relationships;
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace App\Jobs\Banking;
use App\Abstracts\Job;
use App\Models\Banking\Transaction;
class DeleteReconciliation extends Job
{
protected $reconciliation;
/**
* Create a new job instance.
*
* @param $reconciliation
*/
public function __construct($reconciliation)
{
$this->reconciliation = $reconciliation;
}
/**
* Execute the job.
*
* @return boolean|Exception
*/
public function handle()
{
$this->reconciliation->delete();
Transaction::where('account_id', $this->reconciliation->account_id)
->reconciled()
->whereBetween('paid_at', [$this->reconciliation->started_at, $this->reconciliation->ended_at])->each(function ($transaction) {
$transaction->reconciled = 0;
$transaction->save();
});
return true;
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Jobs\Banking;
use App\Abstracts\Job;
use App\Models\Setting\Category;
class DeleteTransaction extends Job
{
protected $transaction;
/**
* Create a new job instance.
*
* @param $transaction
*/
public function __construct($transaction)
{
$this->transaction = $transaction;
}
/**
* Execute the job.
*
* @return boolean|Exception
*/
public function handle()
{
$this->authorize();
$this->transaction->recurring()->delete();
$this->transaction->delete();
return true;
}
/**
* Determine if this action is applicable.
*
* @return void
*/
public function authorize()
{
if ($this->transaction->category->id == Category::transfer()) {
throw new \Exception('Unauthorized');
}
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace App\Jobs\Banking;
use App\Abstracts\Job;
class DeleteTransfer extends Job
{
protected $transfer;
/**
* Create a new job instance.
*
* @param $transfer
*/
public function __construct($transfer)
{
$this->transfer = $transfer;
}
/**
* Execute the job.
*
* @return mixed
*/
public function handle()
{
$this->deleteRelationships($this->transfer, ['expense_transaction', 'income_transaction']);
$this->transfer->delete();
return true;
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace App\Jobs\Banking;
use App\Abstracts\Job;
use App\Models\Banking\Account;
class UpdateAccount extends Job
{
protected $account;
protected $request;
/**
* Create a new job instance.
*
* @param $account
* @param $request
*/
public function __construct($account, $request)
{
$this->account = $account;
$this->request = $this->getRequestInstance($request);
}
/**
* Execute the job.
*
* @return Account
*/
public function handle()
{
$this->authorize();
$this->account->update($this->request->all());
// Set default account
if ($this->request['default_account']) {
setting()->set('default.account', $this->account->id);
setting()->save();
}
return $this->account;
}
/**
* Determine if this action is applicable.
*
* @return void
*/
public function authorize()
{
if (!$relationships = $this->getRelationships()) {
return;
}
if ($this->account->currency_code != $this->request->get('currency_code')) {
$message = trans('messages.warning.disable_code', ['name' => $this->account->name, 'text' => implode(', ', $relationships)]);
throw new \Exception($message);
}
if (!$this->request->get('enabled') && ($this->account->id == setting('default.account'))) {
$relationships[] = strtolower(trans_choice('general.companies', 1));
$message = trans('messages.warning.disabled', ['name' => $this->account->name, 'text' => implode(', ', $relationships)]);
throw new \Exception($message);
}
}
public function getRelationships()
{
$rels = [
'transactions' => 'transactions',
];
return $this->countRelationships($this->account, $rels);
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Jobs\Banking;
use App\Abstracts\Job;
use App\Models\Banking\Reconciliation;
class UpdateReconciliation extends Job
{
protected $reconciliation;
protected $request;
/**
* Create a new job instance.
*
* @param $reconciliation
* @param $request
*/
public function __construct($reconciliation, $request)
{
$this->reconciliation = $reconciliation;
$this->request = $this->getRequestInstance($request);
}
/**
* Execute the job.
*
* @return Reconciliation
*/
public function handle()
{
$reconcile = $this->request->get('reconcile');
$transactions = $this->request->get('transactions');
$this->reconciliation->reconciled = $reconcile ? 1 : 0;
$this->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();
}
}
return $this->reconciliation;
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace App\Jobs\Banking;
use App\Abstracts\Job;
use App\Models\Banking\Transaction;
class UpdateTransaction extends Job
{
protected $transaction;
protected $request;
/**
* Create a new job instance.
*
* @param $transaction
* @param $request
*/
public function __construct($transaction, $request)
{
$this->transaction = $transaction;
$this->request = $this->getRequestInstance($request);
}
/**
* Execute the job.
*
* @return Transaction
*/
public function handle()
{
$this->transaction->update($this->request->all());
// Upload attachment
if ($this->request->file('attachment')) {
$media = $this->getMedia($this->request->file('attachment'), 'transactions');
$this->transaction->attachMedia($media, 'attachment');
}
// Recurring
$this->transaction->updateRecurring();
return $this->transaction;
}
}

View File

@@ -0,0 +1,112 @@
<?php
namespace App\Jobs\Banking;
use App\Abstracts\Job;
use App\Models\Banking\Account;
use App\Models\Banking\Transaction;
use App\Models\Banking\Transfer;
use App\Models\Setting\Category;
use App\Models\Setting\Currency;
class UpdateTransfer extends Job
{
protected $transfer;
protected $request;
/**
* Create a new job instance.
*
* @param $transfer
* @param $request
*/
public function __construct($transfer, $request)
{
$this->transfer = $transfer;
$this->request = $this->getRequestInstance($request);
}
/**
* Execute the job.
*
* @return Transfer
*/
public function handle()
{
$currencies = Currency::enabled()->pluck('rate', 'code')->toArray();
$expense_currency_code = Account::where('id', $this->request->get('from_account_id'))->pluck('currency_code')->first();
$income_currency_code = Account::where('id', $this->request->get('to_account_id'))->pluck('currency_code')->first();
$expense_transaction = Transaction::findOrFail($this->transfer->expense_transaction_id);
$income_transaction = Transaction::findOrFail($this->transfer->income_transaction_id);
$expense_transaction->update([
'company_id' => $this->request['company_id'],
'type' => 'expense',
'account_id' => $this->request->get('from_account_id'),
'paid_at' => $this->request->get('transferred_at'),
'currency_code' => $expense_currency_code,
'currency_rate' => $currencies[$expense_currency_code],
'amount' => $this->request->get('amount'),
'contact_id' => 0,
'description' => $this->request->get('description'),
'category_id' => Category::transfer(), // Transfer Category ID
'payment_method' => $this->request->get('payment_method'),
'reference' => $this->request->get('reference'),
]);
// Convert amount if not same currency
if ($expense_currency_code != $income_currency_code) {
$default_currency = setting('default.currency', 'USD');
$default_amount = $this->request->get('amount');
if ($default_currency != $expense_currency_code) {
$default_amount_model = new Transfer();
$default_amount_model->default_currency_code = $default_currency;
$default_amount_model->amount = $this->request->get('amount');
$default_amount_model->currency_code = $expense_currency_code;
$default_amount_model->currency_rate = $currencies[$expense_currency_code];
$default_amount = $default_amount_model->getDivideConvertedAmount();
}
$transfer_amount = new Transfer();
$transfer_amount->default_currency_code = $expense_currency_code;
$transfer_amount->amount = $default_amount;
$transfer_amount->currency_code = $income_currency_code;
$transfer_amount->currency_rate = $currencies[$income_currency_code];
$amount = $transfer_amount->getAmountConvertedFromCustomDefault();
} else {
$amount = $this->request->get('amount');
}
$income_transaction->update([
'company_id' => $this->request['company_id'],
'type' => 'income',
'account_id' => $this->request->get('to_account_id'),
'paid_at' => $this->request->get('transferred_at'),
'currency_code' => $income_currency_code,
'currency_rate' => $currencies[$income_currency_code],
'amount' => $amount,
'contact_id' => 0,
'description' => $this->request->get('description'),
'category_id' => Category::transfer(), // Transfer Category ID
'payment_method' => $this->request->get('payment_method'),
'reference' => $this->request->get('reference'),
]);
$this->transfer->update([
'company_id' => $this->request['company_id'],
'expense_transaction_id' => $expense_transaction->id,
'income_transaction_id' => $income_transaction->id,
]);
return $this->transfer;
}
}