mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-30 02:26:58 +00:00
Clean up edit routines
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Firefly\Exception\FireflyException;
|
use Firefly\Exception\FireflyException;
|
||||||
use Firefly\Helper\Controllers\TransactionInterface as TI;
|
use Firefly\Helper\Controllers\TransactionInterface as TI;
|
||||||
use Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface as TJRI;
|
use Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface as TJRI;
|
||||||
@@ -19,12 +18,6 @@ class TransactionController extends BaseController
|
|||||||
|
|
||||||
protected $_helper;
|
protected $_helper;
|
||||||
|
|
||||||
/** @var Carbon|null $_start */
|
|
||||||
protected $_start;
|
|
||||||
|
|
||||||
/** @var Carbon|null $_end */
|
|
||||||
protected $_end;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new transaction controller with two of the most often used helpers.
|
* Construct a new transaction controller with two of the most often used helpers.
|
||||||
*
|
*
|
||||||
@@ -37,13 +30,6 @@ class TransactionController extends BaseController
|
|||||||
$this->_helper = $helper;
|
$this->_helper = $helper;
|
||||||
View::share('title', 'Transactions');
|
View::share('title', 'Transactions');
|
||||||
View::share('mainTitleIcon', 'fa-repeat');
|
View::share('mainTitleIcon', 'fa-repeat');
|
||||||
|
|
||||||
/*
|
|
||||||
* With this construction, every method has access to a possibly set start
|
|
||||||
* and end date, to be used at their leisure:
|
|
||||||
*/
|
|
||||||
$this->_start = is_null(Input::get('startdate')) ? null : new Carbon(Input::get('startdate'));
|
|
||||||
$this->_end = is_null(Input::get('enddate')) ? null : new Carbon(Input::get('enddate'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -166,16 +152,20 @@ class TransactionController extends BaseController
|
|||||||
* Get all piggy banks plus (if any) the relevant piggy bank. Since just one
|
* Get all piggy banks plus (if any) the relevant piggy bank. Since just one
|
||||||
* of the transactions in the journal has this field, it should all fill in nicely.
|
* of the transactions in the journal has this field, it should all fill in nicely.
|
||||||
*/
|
*/
|
||||||
$piggies = $piggyRepository->get();
|
// get the piggy banks.
|
||||||
$piggyBankId = null;
|
$piggies = $toolkit->makeSelectList($piggyRepository->get());
|
||||||
|
$piggies[0] = '(no piggy bank)';
|
||||||
|
$piggyBankId = 0;
|
||||||
foreach ($journal->transactions as $t) {
|
foreach ($journal->transactions as $t) {
|
||||||
$piggyBankId = $t->piggybank_id;
|
if (!is_null($t->piggybank_id)) {
|
||||||
|
$piggyBankId = $t->piggybank_id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Data to properly display the edit form.
|
* Data to properly display the edit form.
|
||||||
*/
|
*/
|
||||||
$data = [
|
$prefilled = [
|
||||||
'date' => $journal->date->format('Y-m-d'),
|
'date' => $journal->date->format('Y-m-d'),
|
||||||
'category' => '',
|
'category' => '',
|
||||||
'budget_id' => 0,
|
'budget_id' => 0,
|
||||||
@@ -187,7 +177,7 @@ class TransactionController extends BaseController
|
|||||||
*/
|
*/
|
||||||
$category = $journal->categories()->first();
|
$category = $journal->categories()->first();
|
||||||
if (!is_null($category)) {
|
if (!is_null($category)) {
|
||||||
$data['category'] = $category->name;
|
$prefilled['category'] = $category->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -195,24 +185,24 @@ class TransactionController extends BaseController
|
|||||||
* relevant fields:
|
* relevant fields:
|
||||||
*/
|
*/
|
||||||
switch ($what) {
|
switch ($what) {
|
||||||
case 'Withdrawal':
|
case 'withdrawal':
|
||||||
$data['account_id'] = $journal->transactions[0]->account->id;
|
$prefilled['account_id'] = $journal->transactions[0]->account->id;
|
||||||
$data['beneficiary'] = $journal->transactions[1]->account->name;
|
$prefilled['expense_account'] = $journal->transactions[1]->account->name;
|
||||||
$data['amount'] = floatval($journal->transactions[1]->amount);
|
$prefilled['amount'] = floatval($journal->transactions[1]->amount);
|
||||||
$budget = $journal->budgets()->first();
|
$budget = $journal->budgets()->first();
|
||||||
if (!is_null($budget)) {
|
if (!is_null($budget)) {
|
||||||
$data['budget_id'] = $budget->id;
|
$prefilled['budget_id'] = $budget->id;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Deposit':
|
case 'deposit':
|
||||||
$data['account_id'] = $journal->transactions[1]->account->id;
|
$prefilled['account_id'] = $journal->transactions[1]->account->id;
|
||||||
$data['beneficiary'] = $journal->transactions[0]->account->name;
|
$prefilled['revenue_account'] = $journal->transactions[0]->account->name;
|
||||||
$data['amount'] = floatval($journal->transactions[1]->amount);
|
$prefilled['amount'] = floatval($journal->transactions[1]->amount);
|
||||||
break;
|
break;
|
||||||
case 'Transfer':
|
case 'transfer':
|
||||||
$data['account_from_id'] = $journal->transactions[1]->account->id;
|
$prefilled['account_from_id'] = $journal->transactions[1]->account->id;
|
||||||
$data['account_to_id'] = $journal->transactions[0]->account->id;
|
$prefilled['account_to_id'] = $journal->transactions[0]->account->id;
|
||||||
$data['amount'] = floatval($journal->transactions[1]->amount);
|
$prefilled['amount'] = floatval($journal->transactions[1]->amount);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,7 +211,7 @@ class TransactionController extends BaseController
|
|||||||
*/
|
*/
|
||||||
return View::make('transactions.edit')->with('journal', $journal)->with('accounts', $accounts)->with(
|
return View::make('transactions.edit')->with('journal', $journal)->with('accounts', $accounts)->with(
|
||||||
'what', $what
|
'what', $what
|
||||||
)->with('budgets', $budgets)->with('data', $data)->with('piggies', $piggies)->with(
|
)->with('budgets', $budgets)->with('data', $prefilled)->with('piggies', $piggies)->with(
|
||||||
'subTitle', 'Edit ' . $what . ' "' . $journal->description . '"'
|
'subTitle', 'Edit ' . $what . ' "' . $journal->description . '"'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -233,7 +223,7 @@ class TransactionController extends BaseController
|
|||||||
{
|
{
|
||||||
return View::make('transactions.list')->with('subTitle', 'Expenses')->with(
|
return View::make('transactions.list')->with('subTitle', 'Expenses')->with(
|
||||||
'subTitleIcon', 'fa-long-arrow-left'
|
'subTitleIcon', 'fa-long-arrow-left'
|
||||||
)->with('what','expenses');
|
)->with('what', 'expenses');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -243,40 +233,17 @@ class TransactionController extends BaseController
|
|||||||
{
|
{
|
||||||
return View::make('transactions.list')->with('subTitle', 'Revenue')->with(
|
return View::make('transactions.list')->with('subTitle', 'Revenue')->with(
|
||||||
'subTitleIcon', 'fa-long-arrow-right'
|
'subTitleIcon', 'fa-long-arrow-right'
|
||||||
)->with('what','revenue');
|
)->with('what', 'revenue');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function transfers()
|
public function transfers()
|
||||||
{
|
{
|
||||||
return View::make('transactions.list')->with('subTitle', 'Transfers')->with(
|
return View::make('transactions.list')->with('subTitle', 'Transfers')->with(
|
||||||
'subTitleIcon', 'fa-arrows-h'
|
'subTitleIcon', 'fa-arrows-h'
|
||||||
)->with('what','transfers');
|
)->with('what', 'transfers');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return $this|\Illuminate\View\View
|
|
||||||
*/
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
$start = is_null(Input::get('startdate')) ? null : new Carbon(Input::get('startdate'));
|
|
||||||
$end = is_null(Input::get('enddate')) ? null : new Carbon(Input::get('enddate'));
|
|
||||||
if ($start <= $end && !is_null($start) && !is_null($end)) {
|
|
||||||
$journals = $this->_repository->paginate(25, $start, $end);
|
|
||||||
$filtered = true;
|
|
||||||
$filters = ['start' => $start, 'end' => $end];
|
|
||||||
} else {
|
|
||||||
$journals = $this->_repository->paginate(25);
|
|
||||||
$filtered = false;
|
|
||||||
$filters = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return View::make('transactions.index')->with('journals', $journals)->with('filtered', $filtered)->with(
|
|
||||||
'filters', $filters
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TransactionJournal $journal
|
* @param TransactionJournal $journal
|
||||||
*
|
*
|
||||||
@@ -284,9 +251,9 @@ class TransactionController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function show(TransactionJournal $journal)
|
public function show(TransactionJournal $journal)
|
||||||
{
|
{
|
||||||
View::share('subTitle', $journal->transactionType->type . ' "' . $journal->description . '"');
|
return View::make('transactions.show')->with('journal', $journal)->with(
|
||||||
|
'subTitle', $journal->transactionType->type . ' "' . $journal->description . '"'
|
||||||
return View::make('transactions.show')->with('journal', $journal);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -305,6 +272,7 @@ class TransactionController extends BaseController
|
|||||||
|
|
||||||
switch (Input::get('post_submit_action')) {
|
switch (Input::get('post_submit_action')) {
|
||||||
case 'store':
|
case 'store':
|
||||||
|
case 'create_another':
|
||||||
/*
|
/*
|
||||||
* Try to store:
|
* Try to store:
|
||||||
*/
|
*/
|
||||||
@@ -323,16 +291,13 @@ class TransactionController extends BaseController
|
|||||||
*/
|
*/
|
||||||
Session::flash('success', 'Transaction "' . e(Input::get('description')) . '" saved!');
|
Session::flash('success', 'Transaction "' . e(Input::get('description')) . '" saved!');
|
||||||
|
|
||||||
switch ($what) {
|
/*
|
||||||
case 'withdrawal':
|
* Redirect to original location or back to the form.
|
||||||
return Redirect::route('transactions.expenses');
|
*/
|
||||||
break;
|
if (Input::get('post_submit_action') == 'create_another') {
|
||||||
case 'deposit':
|
return Redirect::route('transactions.create', $what)->withInput();
|
||||||
return Redirect::route('transactions.revenue');
|
} else {
|
||||||
break;
|
return Redirect::route('transactions.index.' . $what);
|
||||||
case 'transfer':
|
|
||||||
return Redirect::route('transactions.transfers');
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -349,17 +314,33 @@ class TransactionController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function update(TransactionJournal $journal)
|
public function update(TransactionJournal $journal)
|
||||||
{
|
{
|
||||||
$journal = $this->_repository->update($journal, Input::all());
|
switch (Input::get('post_submit_action')) {
|
||||||
if ($journal->validate()) {
|
case 'store':
|
||||||
// has been saved, return to index:
|
case 'return_to_edit':
|
||||||
Session::flash('success', 'Transaction updated!');
|
$what = strtolower($journal->transactionType->type);
|
||||||
Event::fire('journals.update', [$journal]);
|
$messageBag = $this->_helper->update($journal, Input::all());
|
||||||
|
if ($messageBag->count() == 0) {
|
||||||
|
// has been saved, return to index:
|
||||||
|
Session::flash('success', 'Transaction updated!');
|
||||||
|
Event::fire('journals.update', [$journal]);
|
||||||
|
|
||||||
return Redirect::route('transactions.index');
|
if (Input::get('post_submit_action') == 'create_another') {
|
||||||
} else {
|
return Redirect::route('transactions.create', $what)->withInput();
|
||||||
Session::flash('error', 'Could not update transaction: ' . $journal->errors()->first());
|
} else {
|
||||||
|
return Redirect::route('transactions.index.' . $what);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Session::flash('error', 'Could not update transaction: ' . $journal->errors()->first());
|
||||||
|
|
||||||
return Redirect::route('transactions.edit', $journal->id)->withInput()->withErrors($journal->errors());
|
return Redirect::route('transactions.edit', $journal->id)->withInput()->withErrors(
|
||||||
|
$journal->errors()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new FireflyException('Method ' . Input::get('post_submit_action') . ' not implemented yet.');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -32,6 +32,138 @@ class Transaction implements TransactionInterface
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \TransactionJournal $journal
|
||||||
|
* @param array $data
|
||||||
|
*
|
||||||
|
* @return MessageBag|\TransactionJournal
|
||||||
|
*/
|
||||||
|
public function update(\TransactionJournal $journal, array $data) {
|
||||||
|
/*
|
||||||
|
* All the repositories we need:
|
||||||
|
*/
|
||||||
|
/** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $journals */
|
||||||
|
$journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface');
|
||||||
|
$journals->overruleUser($this->_user);
|
||||||
|
|
||||||
|
/** @var \Firefly\Storage\Category\CategoryRepositoryInterface $categories */
|
||||||
|
$categories = \App::make('Firefly\Storage\Category\CategoryRepositoryInterface');
|
||||||
|
$categories->overruleUser($this->_user);
|
||||||
|
|
||||||
|
/** @var \Firefly\Storage\Budget\BudgetRepositoryInterface $budgets */
|
||||||
|
$budgets = \App::make('Firefly\Storage\Budget\BudgetRepositoryInterface');
|
||||||
|
$budgets->overruleUser($this->_user);
|
||||||
|
|
||||||
|
/** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface $piggybanks */
|
||||||
|
$piggybanks = \App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface');
|
||||||
|
$piggybanks->overruleUser($this->_user);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update the journal using the repository.
|
||||||
|
*/
|
||||||
|
$journal = $journals->update($journal, $data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If invalid, return the message bag:
|
||||||
|
*/
|
||||||
|
if (!$journal->validate()) {
|
||||||
|
return $journal->errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find budget using repository
|
||||||
|
*/
|
||||||
|
if (isset($data['budget_id'])) {
|
||||||
|
$budget = $budgets->find($data['budget_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find category using repository
|
||||||
|
*/
|
||||||
|
$category = $categories->firstOrCreate($data['category']);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find piggy bank using repository:
|
||||||
|
*/
|
||||||
|
$piggybank = null;
|
||||||
|
if(isset($data['piggybank_id'])) {
|
||||||
|
$piggybank = $piggybanks->find($data['piggybank_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* save accounts using repositories
|
||||||
|
* this depends on the kind of transaction and i've yet to fix this.
|
||||||
|
*/
|
||||||
|
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */
|
||||||
|
$accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||||
|
|
||||||
|
if (isset($data['account_id'])) {
|
||||||
|
$from = $accounts->findAssetAccountById($data['account_id']);
|
||||||
|
}
|
||||||
|
if (isset($data['expense_account'])) {
|
||||||
|
$to = $accounts->findExpenseAccountByName($data['expense_account']);
|
||||||
|
}
|
||||||
|
if (isset($data['revenue_account'])) {
|
||||||
|
$from = $accounts->findRevenueAccountByName($data['revenue_account']);
|
||||||
|
$to = $accounts->findAssetAccountById($data['account_id']);
|
||||||
|
}
|
||||||
|
if (isset($data['account_from_id'])) {
|
||||||
|
$from = $accounts->findAssetAccountById($data['account_from_id']);
|
||||||
|
}
|
||||||
|
if (isset($data['account_to_id'])) {
|
||||||
|
$to = $accounts->findAssetAccountById($data['account_to_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a custom error when they are the same.
|
||||||
|
*/
|
||||||
|
if($to->id == $from->id) {
|
||||||
|
$bag = new MessageBag;
|
||||||
|
$bag->add('account_from_id','The account from cannot be the same as the account to.');
|
||||||
|
return $bag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if the transactions need new data:
|
||||||
|
*/
|
||||||
|
$transactions = $journal->transactions()->orderBy('amount','ASC')->get();
|
||||||
|
/** @var \Transaction $transaction */
|
||||||
|
foreach($transactions as $index => $transaction) {
|
||||||
|
switch(true) {
|
||||||
|
case ($index == 0): // FROM account
|
||||||
|
$transaction->account()->associate($from);
|
||||||
|
$transaction->amount = floatval($data['amount']) * -1;
|
||||||
|
break;
|
||||||
|
case ($index == 1): // TO account.
|
||||||
|
$transaction->account()->associate($to);
|
||||||
|
$transaction->amount = floatval($data['amount']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$transaction->save();
|
||||||
|
// either way, try to attach the piggy bank:
|
||||||
|
if(!is_null($piggybank)) {
|
||||||
|
if($piggybank->account_id == $transaction->account_id) {
|
||||||
|
$transaction->piggybank()->associate($piggybank);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Connect budget and category:
|
||||||
|
*/
|
||||||
|
$budgetids = is_null($budget) ? [] : [$budget->id];
|
||||||
|
$catids = is_null($category) ? [] : [$category->id];
|
||||||
|
$journal->budgets()->sync($budgetids);
|
||||||
|
$journal->categories()->sync($catids);
|
||||||
|
$journal->save();
|
||||||
|
if(isset($data['return_journal']) && $data['return_journal'] == true) {
|
||||||
|
return $journal;
|
||||||
|
}
|
||||||
|
return $journal->errors();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a full transaction journal and associated stuff
|
* Store a full transaction journal and associated stuff
|
||||||
*
|
*
|
||||||
@@ -76,14 +208,14 @@ class Transaction implements TransactionInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* save budget using repository
|
* find budget using repository
|
||||||
*/
|
*/
|
||||||
if (isset($data['budget_id'])) {
|
if (isset($data['budget_id'])) {
|
||||||
$budget = $budgets->find($data['budget_id']);
|
$budget = $budgets->find($data['budget_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* save category using repository
|
* find category using repository
|
||||||
*/
|
*/
|
||||||
$category = $categories->firstOrCreate($data['category']);
|
$category = $categories->firstOrCreate($data['category']);
|
||||||
|
|
||||||
@@ -159,11 +291,6 @@ class Transaction implements TransactionInterface
|
|||||||
if (!is_null($category)) {
|
if (!is_null($category)) {
|
||||||
$journal->categories()->save($category);
|
$journal->categories()->save($category);
|
||||||
}
|
}
|
||||||
if(isset($piggybank) && !is_null($piggybank)) {
|
|
||||||
// some trigger?
|
|
||||||
|
|
||||||
//$journal->piggybanks()->save($piggybank);
|
|
||||||
}
|
|
||||||
$journal->completed = true;
|
$journal->completed = true;
|
||||||
$journal->save();
|
$journal->save();
|
||||||
if(isset($data['return_journal']) && $data['return_journal'] == true) {
|
if(isset($data['return_journal']) && $data['return_journal'] == true) {
|
||||||
|
@@ -15,10 +15,18 @@ interface TransactionInterface {
|
|||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
*
|
||||||
* @return MessageBag
|
* @return MessageBag|\TransactionJournal
|
||||||
*/
|
*/
|
||||||
public function store(array $data);
|
public function store(array $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \TransactionJournal $journal
|
||||||
|
* @param array $data
|
||||||
|
*
|
||||||
|
* @return MessageBag|\TransactionJournal
|
||||||
|
*/
|
||||||
|
public function update(\TransactionJournal $journal, array $data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrule the user used when the class is created.
|
* Overrule the user used when the class is created.
|
||||||
*
|
*
|
||||||
|
@@ -188,6 +188,17 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
|||||||
$type = $this->findAccountType('Revenue account');
|
$type = $this->findAccountType('Revenue account');
|
||||||
$account = $this->_user->accounts()->where('name', $name)->where('account_type_id', $type->id)->first();
|
$account = $this->_user->accounts()->where('name', $name)->where('account_type_id', $type->id)->first();
|
||||||
|
|
||||||
|
// create if not found:
|
||||||
|
if (strlen($name) > 0) {
|
||||||
|
$set = [
|
||||||
|
'name' => $name,
|
||||||
|
'user_id' => $this->_user->id,
|
||||||
|
'active' => 1,
|
||||||
|
'account_type_id' => $type->id
|
||||||
|
];
|
||||||
|
$account = $this->firstOrCreate($set);
|
||||||
|
}
|
||||||
|
|
||||||
// find cash account as fall back:
|
// find cash account as fall back:
|
||||||
if (is_null($account)) {
|
if (is_null($account)) {
|
||||||
$cashType = $this->findAccountType('Cash account');
|
$cashType = $this->findAccountType('Cash account');
|
||||||
|
@@ -4,8 +4,8 @@
|
|||||||
namespace Firefly\Storage\TransactionJournal;
|
namespace Firefly\Storage\TransactionJournal;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Firefly\Exception\FireflyException;
|
|
||||||
use Illuminate\Queue\Jobs\Job;
|
use Illuminate\Queue\Jobs\Job;
|
||||||
|
use Illuminate\Support\MessageBag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class EloquentTransactionJournalRepository
|
* Class EloquentTransactionJournalRepository
|
||||||
@@ -51,11 +51,6 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */
|
|
||||||
$accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
|
||||||
$accounts->overruleUser($user);
|
|
||||||
|
|
||||||
/** @var \Firefly\Helper\Controllers\TransactionInterface $transactions */
|
/** @var \Firefly\Helper\Controllers\TransactionInterface $transactions */
|
||||||
$transactions = \App::make('Firefly\Helper\Controllers\TransactionInterface');
|
$transactions = \App::make('Firefly\Helper\Controllers\TransactionInterface');
|
||||||
$transactions->overruleUser($this->_user);
|
$transactions->overruleUser($this->_user);
|
||||||
@@ -92,19 +87,48 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
|||||||
* Find the 'from' account:
|
* Find the 'from' account:
|
||||||
*/
|
*/
|
||||||
$oldFromAccountEntry = $repository->findImportEntry($importMap, 'Account', $fromAccountId);
|
$oldFromAccountEntry = $repository->findImportEntry($importMap, 'Account', $fromAccountId);
|
||||||
$accountFrom = $accounts->find($oldFromAccountEntry->new);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the 'to' account:
|
* Find the 'to' account:
|
||||||
*/
|
*/
|
||||||
$oldToAccountEntry = $repository->findImportEntry($importMap, 'Account', $toAccountId);
|
$oldToAccountEntry = $repository->findImportEntry($importMap, 'Account', $toAccountId);
|
||||||
$accountTo = $accounts->find($oldToAccountEntry->new);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If either is NULL, wait a bit and then reschedule.
|
* Import transfer:
|
||||||
*/
|
*/
|
||||||
if (is_null($accountTo) || is_null($accountFrom)) {
|
$set = [
|
||||||
\Log::notice('No account to, or account from. Release transfer ' . $description);
|
'account_from_id' => $oldFromAccountEntry->new,
|
||||||
|
'account_to_id' => $oldToAccountEntry->new,
|
||||||
|
'amount' => $amount,
|
||||||
|
'description' => $description,
|
||||||
|
'date' => $date->format('Y-m-d'),
|
||||||
|
'category' => '',
|
||||||
|
'what' => 'transfer',
|
||||||
|
'return_journal' => true
|
||||||
|
];
|
||||||
|
$journal = $transactions->store($set);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate the store action:
|
||||||
|
*/
|
||||||
|
if ($journal instanceof MessageBag) {
|
||||||
|
/*
|
||||||
|
* It's a message bag; clearly something went wrong.
|
||||||
|
*/
|
||||||
|
\Log::notice('Could not import TJ "' . $description . '": ' . $journal->first());
|
||||||
|
if (\Config::get('queue.default') == 'sync') {
|
||||||
|
$importMap->jobsdone++;
|
||||||
|
$importMap->save();
|
||||||
|
$job->delete(); // count fixed
|
||||||
|
} else {
|
||||||
|
$job->release(300); // proper release.
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if ($journal instanceof \TransactionJournal && $journal->errors()->count() > 0) {
|
||||||
|
/*
|
||||||
|
* It's a journal but it still failed somehow.
|
||||||
|
*/
|
||||||
|
\Log::notice('Could not import TJ "' . $description . '": ' . $journal->errors()->first());
|
||||||
if (\Config::get('queue.default') == 'sync') {
|
if (\Config::get('queue.default') == 'sync') {
|
||||||
$importMap->jobsdone++;
|
$importMap->jobsdone++;
|
||||||
$importMap->save();
|
$importMap->save();
|
||||||
@@ -114,22 +138,6 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Import transfer:
|
|
||||||
*/
|
|
||||||
$set = [
|
|
||||||
'account_from_id' => $accountFrom->id,
|
|
||||||
'account_to_id' => $accountTo->id,
|
|
||||||
'amount' => $amount,
|
|
||||||
'description' => $description,
|
|
||||||
'date' => $date->format('Y-m-d'),
|
|
||||||
'category' => '',
|
|
||||||
'what' => 'transfer',
|
|
||||||
'return_journal' => true
|
|
||||||
];
|
|
||||||
$journal = $transactions->store($set);
|
|
||||||
|
|
||||||
$repository->store($importMap, 'Transfer', $transferId, $journal->id);
|
$repository->store($importMap, 'Transfer', $transferId, $journal->id);
|
||||||
\Log::debug('Imported transfer "' . $description . '" (' . $amount . ') (' . $date->format('Y-m-d') . ')');
|
\Log::debug('Imported transfer "' . $description . '" (' . $amount . ') (' . $date->format('Y-m-d') . ')');
|
||||||
|
|
||||||
@@ -152,6 +160,11 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
*
|
||||||
|
* @return \TransactionJournal
|
||||||
|
*/
|
||||||
public function store(array $data)
|
public function store(array $data)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -285,14 +298,65 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
|||||||
* Find the asset account this transaction is paid from / paid to:
|
* Find the asset account this transaction is paid from / paid to:
|
||||||
*/
|
*/
|
||||||
$accountEntry = $repository->findImportEntry($importMap, 'Account', $accountId);
|
$accountEntry = $repository->findImportEntry($importMap, 'Account', $accountId);
|
||||||
$assetAccount = $accounts->find($accountEntry->new);
|
|
||||||
unset($accountEntry);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If $assetAccount is null, we release this job and try later.
|
* Prep some data for the import routine:
|
||||||
*/
|
*/
|
||||||
if (is_null($assetAccount)) {
|
$set = [
|
||||||
\Log::notice('No asset account for "' . $description . '", try again later.');
|
'category' => '',
|
||||||
|
'description' => $description,
|
||||||
|
'date' => $date->format('Y-m-d'),
|
||||||
|
'return_journal' => true,
|
||||||
|
'account_id' => $accountEntry->new
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the amount is less than zero, we move money to the $importAccount. Otherwise,
|
||||||
|
* we move it from the $importAccount.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ($amount < 0) {
|
||||||
|
// if amount is less than zero, move to $importAccount
|
||||||
|
$set['what'] = 'withdrawal';
|
||||||
|
$set['expense_account'] = $importAccount->name;
|
||||||
|
} else {
|
||||||
|
$set['what'] = 'deposit';
|
||||||
|
$set['revenue_account'] = $importAccount->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Modify the amount so it will work with or new transaction journal structure.
|
||||||
|
*/
|
||||||
|
$set['amount'] = $amount < 0 ? $amount * -1 : $amount;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Import it:
|
||||||
|
*/
|
||||||
|
$journal = $transactions->store($set);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate the store action:
|
||||||
|
*/
|
||||||
|
if ($journal instanceof MessageBag) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It's a message bag; clearly something went wrong.
|
||||||
|
*/
|
||||||
|
\Log::notice('Could not import transfer "' . $description . '": ' . $journal->first());
|
||||||
|
if (\Config::get('queue.default') == 'sync') {
|
||||||
|
$importMap->jobsdone++;
|
||||||
|
$importMap->save();
|
||||||
|
$job->delete(); // count fixed
|
||||||
|
} else {
|
||||||
|
$job->release(300); // proper release.
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if ($journal instanceof \TransactionJournal && $journal->errors()->count() > 0) {
|
||||||
|
/*
|
||||||
|
* It's a journal but it still failed somehow.
|
||||||
|
*/
|
||||||
|
\Log::notice('Could not import transfer "' . $description . '": ' . $journal->errors()->first());
|
||||||
if (\Config::get('queue.default') == 'sync') {
|
if (\Config::get('queue.default') == 'sync') {
|
||||||
$importMap->jobsdone++;
|
$importMap->jobsdone++;
|
||||||
$importMap->save();
|
$importMap->save();
|
||||||
@@ -302,44 +366,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* Prep some data for the import routine:
|
|
||||||
*/
|
|
||||||
$set = [
|
|
||||||
'category' => '',
|
|
||||||
'description' => $description,
|
|
||||||
'date' => $date->format('Y-m-d'),
|
|
||||||
'return_journal' => true
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the amount is less than zero, we move money to the $importAccount. Otherwise,
|
|
||||||
* we move it from the $importAccount.
|
|
||||||
*/
|
|
||||||
if ($amount < 0) {
|
|
||||||
// if amount is less than zero, move to $importAccount
|
|
||||||
$accountFrom = $assetAccount;
|
|
||||||
$accountTo = $importAccount;
|
|
||||||
$set['what'] = 'withdrawal';
|
|
||||||
$set['account_id'] = $accountFrom->id;
|
|
||||||
$set['expense_account'] = $importAccount->name;
|
|
||||||
} else {
|
|
||||||
$accountFrom = $importAccount;
|
|
||||||
$accountTo = $assetAccount;
|
|
||||||
$set['what'] = 'deposit';
|
|
||||||
$set['account_id'] = $accountTo->id;
|
|
||||||
$set['revenue_account'] = $accountFrom->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Modify the amount so it will work with or new transaction journal structure.
|
|
||||||
*/
|
|
||||||
$set['amount'] = $amount < 0 ? $amount * -1 : $amount;
|
|
||||||
/*
|
|
||||||
* Import it:
|
|
||||||
*/
|
|
||||||
$journal = $transactions->store($set);
|
|
||||||
$repository->store($importMap, 'Transaction', $transactionId, $journal->id);
|
$repository->store($importMap, 'Transaction', $transactionId, $journal->id);
|
||||||
\Log::debug('Imported transaction "' . $description . '" (' . $amount . ') (' . $date->format('Y-m-d') . ')');
|
\Log::debug('Imported transaction "' . $description . '" (' . $amount . ') (' . $date->format('Y-m-d') . ')');
|
||||||
|
|
||||||
@@ -479,140 +506,162 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
|||||||
*/
|
*/
|
||||||
public function update(\TransactionJournal $journal, $data)
|
public function update(\TransactionJournal $journal, $data)
|
||||||
{
|
{
|
||||||
/** @var \Firefly\Storage\Category\CategoryRepositoryInterface $catRepository */
|
/*
|
||||||
$catRepository = \App::make('Firefly\Storage\Category\CategoryRepositoryInterface');
|
* Update the basic fields:
|
||||||
$catRepository->overruleUser($this->_user);
|
*/
|
||||||
|
$journal->description = trim($data['description']);
|
||||||
|
$journal->date = new Carbon($data['date']);
|
||||||
|
|
||||||
/** @var \Firefly\Storage\Budget\BudgetRepositoryInterface $budgetRepository */
|
/*
|
||||||
$budRepository = \App::make('Firefly\Storage\Budget\BudgetRepositoryInterface');
|
* Validate & save journal
|
||||||
$budRepository->overruleUser($this->_user);
|
*/
|
||||||
|
$journal->validate();
|
||||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accountRepository */
|
$journal->save();
|
||||||
$accountRepository = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
|
||||||
$accountRepository->overruleUser($this->_user);
|
|
||||||
|
|
||||||
|
|
||||||
// update basics first:
|
|
||||||
$journal->description = $data['description'];
|
|
||||||
$journal->date = $data['date'];
|
|
||||||
$amount = floatval($data['amount']);
|
|
||||||
|
|
||||||
// remove previous category, if any:
|
|
||||||
if (!is_null($journal->categories()->first())) {
|
|
||||||
$journal->categories()->detach($journal->categories()->first()->id);
|
|
||||||
}
|
|
||||||
// remove previous budget, if any:
|
|
||||||
if (!is_null($journal->budgets()->first())) {
|
|
||||||
$journal->budgets()->detach($journal->budgets()->first()->id);
|
|
||||||
}
|
|
||||||
// remove previous piggy bank, if any:
|
|
||||||
|
|
||||||
|
|
||||||
$category = isset($data['category']) ? $catRepository->findByName($data['category']) : null;
|
|
||||||
if (!is_null($category)) {
|
|
||||||
$journal->categories()->attach($category);
|
|
||||||
}
|
|
||||||
// update the amounts:
|
|
||||||
$transactions = $journal->transactions()->orderBy('amount', 'ASC')->get();
|
|
||||||
|
|
||||||
// remove previous piggy bank, if any:
|
|
||||||
/** @var \Transaction $transaction */
|
|
||||||
foreach ($transactions as $transaction) {
|
|
||||||
if (!is_null($transaction->piggybank()->first())) {
|
|
||||||
$transaction->piggybank_id = null;
|
|
||||||
$transaction->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($transaction);
|
|
||||||
|
|
||||||
$transactions[0]->amount = $amount * -1;
|
|
||||||
$transactions[1]->amount = $amount;
|
|
||||||
|
|
||||||
// switch on type to properly change things:
|
|
||||||
$fireEvent = false;
|
|
||||||
switch ($journal->transactiontype->type) {
|
|
||||||
case 'Withdrawal':
|
|
||||||
// means transaction[0] is the users account.
|
|
||||||
$account = $accountRepository->find($data['account_id']);
|
|
||||||
$beneficiary = $accountRepository->createOrFindBeneficiary($data['beneficiary']);
|
|
||||||
$transactions[0]->account()->associate($account);
|
|
||||||
$transactions[1]->account()->associate($beneficiary);
|
|
||||||
|
|
||||||
// do budget:
|
|
||||||
$budget = $budRepository->find($data['budget_id']);
|
|
||||||
if (!is_null($budget)) {
|
|
||||||
$journal->budgets()->attach($budget);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'Deposit':
|
|
||||||
// means transaction[0] is the beneficiary.
|
|
||||||
$account = $accountRepository->find($data['account_id']);
|
|
||||||
$beneficiary = $accountRepository->createOrFindBeneficiary($data['beneficiary']);
|
|
||||||
$journal->transactions[0]->account()->associate($beneficiary);
|
|
||||||
$journal->transactions[1]->account()->associate($account);
|
|
||||||
break;
|
|
||||||
case 'Transfer':
|
|
||||||
// means transaction[0] is account that sent the money (from).
|
|
||||||
/** @var \Account $fromAccount */
|
|
||||||
$fromAccount = $accountRepository->find($data['account_from_id']);
|
|
||||||
/** @var \Account $toAccount */
|
|
||||||
$toAccount = $accountRepository->find($data['account_to_id']);
|
|
||||||
$journal->transactions[0]->account()->associate($fromAccount);
|
|
||||||
$journal->transactions[1]->account()->associate($toAccount);
|
|
||||||
|
|
||||||
// attach the new piggy bank, if valid:
|
|
||||||
/** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface $piggyRepository */
|
|
||||||
$piggyRepository = \App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface');
|
|
||||||
$piggyRepository->overruleUser($this->_user);
|
|
||||||
|
|
||||||
if (isset($data['piggybank_id'])) {
|
|
||||||
/** @var \Piggybank $piggyBank */
|
|
||||||
$piggyBank = $piggyRepository->find(intval($data['piggybank_id']));
|
|
||||||
|
|
||||||
// loop transactions and re-attach the piggy bank:
|
|
||||||
|
|
||||||
if ($piggyBank) {
|
|
||||||
|
|
||||||
$connected = false;
|
|
||||||
foreach ($journal->transactions()->get() as $transaction) {
|
|
||||||
if ($transaction->account_id == $piggyBank->account_id) {
|
|
||||||
$connected = true;
|
|
||||||
$transaction->piggybank()->associate($piggyBank);
|
|
||||||
$transaction->save();
|
|
||||||
$fireEvent = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($connected === false) {
|
|
||||||
\Session::flash(
|
|
||||||
'warning', 'Piggy bank "' . e($piggyBank->name)
|
|
||||||
. '" is not set to draw money from any of the accounts in this transfer'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new FireflyException('Cannot edit this!');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$transactions[0]->save();
|
|
||||||
$transactions[1]->save();
|
|
||||||
if ($journal->validate()) {
|
|
||||||
$journal->save();
|
|
||||||
}
|
|
||||||
if ($fireEvent) {
|
|
||||||
\Event::fire('piggybanks.updateRelatedTransfer', [$piggyBank]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return regardless.
|
||||||
|
*/
|
||||||
return $journal;
|
return $journal;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// /*
|
||||||
|
// * Grab some of the repositories we need:
|
||||||
|
// */
|
||||||
|
// /** @var \Firefly\Storage\Category\CategoryRepositoryInterface $catRepository */
|
||||||
|
// $catRepository = \App::make('Firefly\Storage\Category\CategoryRepositoryInterface');
|
||||||
|
// $catRepository->overruleUser($this->_user);
|
||||||
|
//
|
||||||
|
// /** @var \Firefly\Storage\Budget\BudgetRepositoryInterface $budgetRepository */
|
||||||
|
// $budRepository = \App::make('Firefly\Storage\Budget\BudgetRepositoryInterface');
|
||||||
|
// $budRepository->overruleUser($this->_user);
|
||||||
|
//
|
||||||
|
// /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accountRepository */
|
||||||
|
// $accountRepository = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||||
|
// $accountRepository->overruleUser($this->_user);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// update basics first:
|
||||||
|
// $journal->description = $data['description'];
|
||||||
|
// $journal->date = $data['date'];
|
||||||
|
// $amount = floatval($data['amount']);
|
||||||
|
//
|
||||||
|
// // remove previous category, if any:
|
||||||
|
// if (!is_null($journal->categories()->first())) {
|
||||||
|
// $journal->categories()->detach($journal->categories()->first()->id);
|
||||||
|
// }
|
||||||
|
// // remove previous budget, if any:
|
||||||
|
// if (!is_null($journal->budgets()->first())) {
|
||||||
|
// $journal->budgets()->detach($journal->budgets()->first()->id);
|
||||||
|
// }
|
||||||
|
// // remove previous piggy bank, if any:
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// $category = isset($data['category']) ? $catRepository->findByName($data['category']) : null;
|
||||||
|
// if (!is_null($category)) {
|
||||||
|
// $journal->categories()->attach($category);
|
||||||
|
// }
|
||||||
|
// // update the amounts:
|
||||||
|
// $transactions = $journal->transactions()->orderBy('amount', 'ASC')->get();
|
||||||
|
//
|
||||||
|
// // remove previous piggy bank, if any:
|
||||||
|
// /** @var \Transaction $transaction */
|
||||||
|
// foreach ($transactions as $transaction) {
|
||||||
|
// if (!is_null($transaction->piggybank()->first())) {
|
||||||
|
// $transaction->piggybank_id = null;
|
||||||
|
// $transaction->save();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// unset($transaction);
|
||||||
|
//
|
||||||
|
// $transactions[0]->amount = $amount * -1;
|
||||||
|
// $transactions[1]->amount = $amount;
|
||||||
|
//
|
||||||
|
// // switch on type to properly change things:
|
||||||
|
// $fireEvent = false;
|
||||||
|
// switch ($journal->transactiontype->type) {
|
||||||
|
// case 'Withdrawal':
|
||||||
|
// // means transaction[0] is the users account.
|
||||||
|
// $account = $accountRepository->find($data['account_id']);
|
||||||
|
// $beneficiary = $accountRepository->createOrFindBeneficiary($data['beneficiary']);
|
||||||
|
// $transactions[0]->account()->associate($account);
|
||||||
|
// $transactions[1]->account()->associate($beneficiary);
|
||||||
|
//
|
||||||
|
// // do budget:
|
||||||
|
// $budget = $budRepository->find($data['budget_id']);
|
||||||
|
// if (!is_null($budget)) {
|
||||||
|
// $journal->budgets()->attach($budget);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// break;
|
||||||
|
// case 'Deposit':
|
||||||
|
// // means transaction[0] is the beneficiary.
|
||||||
|
// $account = $accountRepository->find($data['account_id']);
|
||||||
|
// $beneficiary = $accountRepository->createOrFindBeneficiary($data['beneficiary']);
|
||||||
|
// $journal->transactions[0]->account()->associate($beneficiary);
|
||||||
|
// $journal->transactions[1]->account()->associate($account);
|
||||||
|
// break;
|
||||||
|
// case 'Transfer':
|
||||||
|
// // means transaction[0] is account that sent the money (from).
|
||||||
|
// /** @var \Account $fromAccount */
|
||||||
|
// $fromAccount = $accountRepository->find($data['account_from_id']);
|
||||||
|
// /** @var \Account $toAccount */
|
||||||
|
// $toAccount = $accountRepository->find($data['account_to_id']);
|
||||||
|
// $journal->transactions[0]->account()->associate($fromAccount);
|
||||||
|
// $journal->transactions[1]->account()->associate($toAccount);
|
||||||
|
//
|
||||||
|
// // attach the new piggy bank, if valid:
|
||||||
|
// /** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface $piggyRepository */
|
||||||
|
// $piggyRepository = \App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface');
|
||||||
|
// $piggyRepository->overruleUser($this->_user);
|
||||||
|
//
|
||||||
|
// if (isset($data['piggybank_id'])) {
|
||||||
|
// /** @var \Piggybank $piggyBank */
|
||||||
|
// $piggyBank = $piggyRepository->find(intval($data['piggybank_id']));
|
||||||
|
//
|
||||||
|
// // loop transactions and re-attach the piggy bank:
|
||||||
|
//
|
||||||
|
// if ($piggyBank) {
|
||||||
|
//
|
||||||
|
// $connected = false;
|
||||||
|
// foreach ($journal->transactions()->get() as $transaction) {
|
||||||
|
// if ($transaction->account_id == $piggyBank->account_id) {
|
||||||
|
// $connected = true;
|
||||||
|
// $transaction->piggybank()->associate($piggyBank);
|
||||||
|
// $transaction->save();
|
||||||
|
// $fireEvent = true;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if ($connected === false) {
|
||||||
|
// \Session::flash(
|
||||||
|
// 'warning', 'Piggy bank "' . e($piggyBank->name)
|
||||||
|
// . '" is not set to draw money from any of the accounts in this transfer'
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// throw new FireflyException('Cannot edit this!');
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// $transactions[0]->save();
|
||||||
|
// $transactions[1]->save();
|
||||||
|
// if ($journal->validate()) {
|
||||||
|
// $journal->save();
|
||||||
|
// }
|
||||||
|
// if ($fireEvent) {
|
||||||
|
// \Event::fire('piggybanks.updateRelatedTransfer', [$piggyBank]);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return $journal;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@@ -140,7 +140,8 @@
|
|||||||
@if(
|
@if(
|
||||||
!(strpos($r,'transactions.expenses') === false) ||
|
!(strpos($r,'transactions.expenses') === false) ||
|
||||||
!(strpos($r,'transactions.revenue') === false) ||
|
!(strpos($r,'transactions.revenue') === false) ||
|
||||||
!(strpos($r,'transactions.transfers') === false)
|
!(strpos($r,'transactions.transfers') === false) ||
|
||||||
|
!(strpos($r,'transactions.index') === false)
|
||||||
)
|
)
|
||||||
class="active"
|
class="active"
|
||||||
@endif
|
@endif
|
||||||
@@ -148,13 +149,13 @@
|
|||||||
<a href="{{route('transactions.index')}}"><i class="fa fa-repeat fa-fw"></i> Transactions<span class="fa arrow"></span></a>
|
<a href="{{route('transactions.index')}}"><i class="fa fa-repeat fa-fw"></i> Transactions<span class="fa arrow"></span></a>
|
||||||
<ul class="nav nav-second-level">
|
<ul class="nav nav-second-level">
|
||||||
<li>
|
<li>
|
||||||
<a @if($r == 'transactions.expenses') class="active" @endif href="{{route('transactions.expenses')}}"><i class="fa fa-long-arrow-left fa-fw"></i> Expenses</a>
|
<a @if($r == 'transactions.expenses' || $r == 'transactions.index.withdrawal') class="active" @endif href="{{route('transactions.expenses')}}"><i class="fa fa-long-arrow-left fa-fw"></i> Expenses</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a @if($r == 'transactions.revenue') class="active" @endif href="{{route('transactions.revenue')}}"><i class="fa fa-long-arrow-right fa-fw"></i> Revenue / income</a>
|
<a @if($r == 'transactions.revenue' || $r == 'transactions.index.deposit') class="active" @endif href="{{route('transactions.revenue')}}"><i class="fa fa-long-arrow-right fa-fw"></i> Revenue / income</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a @if($r == 'transactions.transfers') class="active" @endif href="{{route('transactions.transfers')}}"><i class="fa fa-arrows-h fa-fw"></i> Transfers</a>
|
<a @if($r == 'transactions.transfers' || $r == 'transactions.index.transfer') class="active" @endif href="{{route('transactions.transfers')}}"><i class="fa fa-arrows-h fa-fw"></i> Transfers</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@@ -158,7 +158,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||||
<!-- panel for mandatory fields -->
|
<!-- panel for optional fields -->
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<i class="fa fa-smile-o"></i> Optional fields
|
<i class="fa fa-smile-o"></i> Optional fields
|
||||||
@@ -203,7 +203,7 @@
|
|||||||
Piggy bank
|
Piggy bank
|
||||||
</label>
|
</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
{{Form::select('piggybank_id',$budgets,Input::old('piggybank_id') ?: 0,['class' => 'form-control'])}}
|
{{Form::select('piggybank_id',$piggies,Input::old('piggybank_id') ?: 0,['class' => 'form-control'])}}
|
||||||
@if($errors->has('piggybank_id'))
|
@if($errors->has('piggybank_id'))
|
||||||
<p class="text-danger">{{$errors->first('piggybank_id')}}</p>
|
<p class="text-danger">{{$errors->first('piggybank_id')}}</p>
|
||||||
@else
|
@else
|
||||||
@@ -218,7 +218,7 @@
|
|||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- panel for options -->
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<i class="fa fa-bolt"></i> Options
|
<i class="fa fa-bolt"></i> Options
|
||||||
|
@@ -1,153 +1,160 @@
|
|||||||
@extends('layouts.default')
|
@extends('layouts.default')
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
|
||||||
<p class="text-info">
|
|
||||||
Technically speaking, withdrawals, deposits and transfers are all transactions, moving money from
|
|
||||||
account <em>A</em> to account <em>B</em>.
|
|
||||||
</p>
|
|
||||||
<p class="text-info">
|
|
||||||
Updating a transaction will also update balances, budgets and other records.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{Form::open(['class' => 'form-horizontal','url' => route('transactions.update',$journal->id)])}}
|
{{Form::open(['class' => 'form-horizontal','url' => route('transactions.update',$journal->id)])}}
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||||
<h4>Mandatory fields</h4>
|
<!-- panel for mandatory fields -->
|
||||||
|
<div class="panel panel-primary">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<i class="fa fa-exclamation-circle"></i> Mandatory fields
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<!-- ALWAYS AVAILABLE -->
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="description" class="col-sm-4 control-label">Description</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text"
|
||||||
|
name="description" value="{{{Input::old('description') ?: $journal->description}}}"
|
||||||
|
autocomplete="off" class="form-control" placeholder="Description" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- ALWAYS AVAILABLE -->
|
<!-- SHOW ACCOUNT (FROM) ONLY FOR WITHDRAWALS AND DEPOSITS -->
|
||||||
<div class="form-group">
|
@if($what == 'deposit' || $what == 'withdrawal')
|
||||||
<label for="description" class="col-sm-4 control-label">Description</label>
|
<div class="form-group">
|
||||||
<div class="col-sm-8">
|
<label for="account_id" class="col-sm-4 control-label">
|
||||||
<input type="text" name="description" value="{{{Input::old('description') ?: $journal->description}}}" autocomplete="off" class="form-control" placeholder="Description" />
|
@if($what == 'deposit')
|
||||||
</div>
|
Received into account
|
||||||
</div>
|
@endif
|
||||||
|
@if($what == 'withdrawal')
|
||||||
|
Paid from account
|
||||||
|
@endif
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
{{Form::select('account_id',$accounts,Input::old('account_id') ?: $data['account_id'],['class' => 'form-control'])}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<!-- SHOW ACCOUNT (FROM) ONLY FOR WITHDRAWALS AND DEPOSITS -->
|
<!-- SHOW EXPENSE ACCOUNT ONLY FOR WITHDRAWALS -->
|
||||||
@if($what == 'deposit' || $what == 'withdrawal')
|
@if($what == 'withdrawal')
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="account_id" class="col-sm-4 control-label">
|
<label for="expense_account" class="col-sm-4 control-label">
|
||||||
@if($what == 'deposit')
|
Expense account
|
||||||
Receiving account
|
</label>
|
||||||
@endif
|
<div class="col-sm-8">
|
||||||
@if($what == 'withdrawal')
|
<input type="text"
|
||||||
Paid from account
|
name="expense_account"
|
||||||
@endif
|
value="{{{Input::old('expense_account') ?: $data['expense_account']}}}"
|
||||||
</label>
|
autocomplete="off" class="form-control" />
|
||||||
<div class="col-sm-8">
|
</div>
|
||||||
{{Form::select('account_id',$accounts,Input::old('account_id') ?: $data['account_id'],['class' => 'form-control'])}}
|
</div>
|
||||||
</div>
|
@endif
|
||||||
</div>
|
<!-- SHOW REVENUE ACCOUNT ONLY FOR DEPOSITS -->
|
||||||
@endif
|
@if($what == 'deposit')
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="revenue_account" class="col-sm-4 control-label">
|
||||||
|
Revenue account
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text"
|
||||||
|
name="revenue_account"
|
||||||
|
value="{{{Input::old('revenue_account') ?: $data['revenue_account']}}}"
|
||||||
|
autocomplete="off" class="form-control" placeholder="Beneficiary" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<!-- SHOW BENEFICIARY (ACCOUNT TO) ONLY FOR WITHDRAWALS AND DEPOSITS -->
|
<!-- ONLY SHOW FROM/TO ACCOUNT WHEN CREATING TRANSFER -->
|
||||||
@if($what == 'deposit' || $what == 'withdrawal')
|
@if($what == 'transfer')
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="beneficiary" class="col-sm-4 control-label">
|
<label for="account_from_id" class="col-sm-4 control-label">Account from</label>
|
||||||
@if($what == 'deposit')
|
<div class="col-sm-8">
|
||||||
Paying beneficiary
|
{{Form::select('account_to_id',$accounts,Input::old('account_from_id') ?: $data['account_from_id'],['class' => 'form-control'])}}
|
||||||
@endif
|
</div>
|
||||||
@if($what == 'withdrawal')
|
</div>
|
||||||
Beneficiary
|
|
||||||
@endif
|
|
||||||
</label>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<input type="text" name="beneficiary" value="{{{Input::old('beneficiary') ?: $data['beneficiary']}}}" autocomplete="off" class="form-control" placeholder="Beneficiary" />
|
|
||||||
<span class="help-block">This field will auto-complete your existing beneficiaries (if any), but you can type freely to create new ones.</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<!-- ONLY SHOW FROM/TO ACCOUNT WHEN CREATING TRANSFER -->
|
<div class="form-group">
|
||||||
@if($what == 'transfer')
|
<label for="account_to_id" class="col-sm-4 control-label">Account to</label>
|
||||||
<div class="form-group">
|
<div class="col-sm-8">
|
||||||
<label for="account_from_id" class="col-sm-4 control-label">Account from</label>
|
{{Form::select('account_from_id',$accounts,Input::old('account_to_id') ?: $data['account_to_id'],['class' => 'form-control'])}}
|
||||||
<div class="col-sm-8">
|
</div>
|
||||||
{{Form::select('account_to_id',$accounts,Input::old('account_from_id') ?: $data['account_from_id'],['class' => 'form-control'])}}
|
</div>
|
||||||
</div>
|
@endif
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
<!-- ALWAYS SHOW AMOUNT -->
|
||||||
<label for="account_to_id" class="col-sm-4 control-label">Account to</label>
|
<div class="form-group">
|
||||||
<div class="col-sm-8">
|
<label for="amount" class="col-sm-4 control-label">
|
||||||
{{Form::select('account_from_id',$accounts,Input::old('account_to_id') ?: $data['account_to_id'],['class' => 'form-control'])}}
|
@if($what == 'withdrawal')
|
||||||
</div>
|
Amount spent
|
||||||
</div>
|
@endif
|
||||||
@endif
|
@if($what == 'deposit')
|
||||||
|
Amount received
|
||||||
|
@endif
|
||||||
|
@if($what == 'transfer')
|
||||||
|
Amount transferred
|
||||||
|
@endif
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" name="amount" min="0.01" value="{{Input::old('amount') ?: $data['amount']}}" step="any" class="form-control" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- ALWAYS SHOW AMOUNT -->
|
<!-- ALWAYS SHOW DATE -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="amount" class="col-sm-4 control-label">
|
<label for="date" class="col-sm-4 control-label">Date</label>
|
||||||
@if($what == 'withdrawal')
|
<div class="col-sm-8">
|
||||||
Amount spent
|
<input type="date" name="date" value="{{Input::old('date') ?: $data['date']}}" class="form-control" />
|
||||||
@endif
|
</div>
|
||||||
@if($what == 'deposit')
|
</div>
|
||||||
Amount received
|
|
||||||
@endif
|
|
||||||
@if($what == 'transfer')
|
|
||||||
Amount transferred
|
|
||||||
@endif
|
|
||||||
</label>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<input type="number" name="amount" min="0.01" value="{{Input::old('amount') ?: $data['amount']}}" step="any" class="form-control" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> <!-- close panel -->
|
||||||
|
|
||||||
<!-- ALWAYS SHOW DATE -->
|
<p>
|
||||||
<div class="form-group">
|
<button type="submit" class="btn btn-lg btn-success">
|
||||||
<label for="date" class="col-sm-4 control-label">Date</label>
|
<i class="fa fa-plus-circle"></i> Update {{{$what}}}
|
||||||
<div class="col-sm-8">
|
</button>
|
||||||
<input type="date" name="date" value="{{Input::old('date') ?: $data['date']}}" class="form-control" />
|
</p>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||||
<h4>Optional fields</h4>
|
<!-- panel for optional fields -->
|
||||||
|
<div class="panel panel-default">
|
||||||
<!-- BUDGET ONLY WHEN CREATING A WITHDRAWAL -->
|
<div class="panel-heading">
|
||||||
@if($what == 'withdrawal')
|
<i class="fa fa-smile-o"></i> Optional fields
|
||||||
<div class="form-group">
|
|
||||||
<label for="budget_id" class="col-sm-4 control-label">Budget</label>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
{{Form::select('budget_id',$budgets,Input::old('budget_id') ?: $data['budget_id'],['class' => 'form-control'])}}
|
|
||||||
<span class="help-block">Select one of your budgets to make this transaction a part of it.</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="panel-body">
|
||||||
@endif
|
<!-- BUDGET ONLY WHEN CREATING A WITHDRAWAL -->
|
||||||
<!-- CATEGORY ALWAYS -->
|
@if($what == 'withdrawal')
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="category" class="col-sm-4 control-label">Category</label>
|
<label for="budget_id" class="col-sm-4 control-label">Budget</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input type="text" name="category" value="{{Input::old('category') ?: $data['category']}}" autocomplete="off" class="form-control" placeholder="Category" />
|
{{Form::select('budget_id',$budgets,Input::old('budget_id') ?: $data['budget_id'],['class' => 'form-control'])}}
|
||||||
<span class="help-block">Add more fine-grained information to this transaction by entering a category.
|
<span class="help-block">Select one of your budgets to make this transaction a part of it.</span>
|
||||||
Like the beneficiary-field, this field will auto-complete existing categories but can also be used
|
</div>
|
||||||
to create new ones.
|
</div>
|
||||||
</span>
|
@endif
|
||||||
</div>
|
<!-- CATEGORY ALWAYS -->
|
||||||
</div>
|
<div class="form-group">
|
||||||
|
<label for="category" class="col-sm-4 control-label">Category</label>
|
||||||
<!-- RELATE THIS TRANSFER TO A PIGGY BANK -->
|
<div class="col-sm-8">
|
||||||
|
<input type="text" name="category" value="{{Input::old('category') ?: $data['category']}}" autocomplete="off" class="form-control" placeholder="Category" />
|
||||||
|
<span class="help-block">Add more fine-grained information to this transaction by entering a category.
|
||||||
|
Like the beneficiary-field, this field will auto-complete existing categories but can also be used
|
||||||
|
to create new ones.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- RELATE THIS TRANSFER TO A PIGGY BANK -->
|
||||||
@if($what == 'transfer' && count($piggies) > 0)
|
@if($what == 'transfer' && count($piggies) > 0)
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="piggybank_id" class="col-sm-4 control-label">
|
<label for="piggybank_id" class="col-sm-4 control-label">
|
||||||
Piggy bank
|
Piggy bank
|
||||||
</label>
|
</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<select name="piggybank_id" class="form-control">
|
{{Form::select('piggybank_id',$piggies,Input::old('piggybank_id') ?: $data['piggybank_id'],['class' => 'form-control'])}}
|
||||||
<option value="0" label="(no piggy bank)">(no piggy bank)</option>
|
|
||||||
@foreach($piggies as $piggy)
|
|
||||||
@if($piggy->id == Input::old('piggybank_id') || $piggy->id == $data['piggybank_id'])
|
|
||||||
<option value="{{$piggy->id}}" label="{{{$piggy->name}}}" selected="selected ">{{{$piggy->name}}}</option>
|
|
||||||
@else
|
|
||||||
<option value="{{$piggy->id}}" label="{{{$piggy->name}}}">{{{$piggy->name}}}</option>
|
|
||||||
@endif
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
@if($errors->has('piggybank_id'))
|
@if($errors->has('piggybank_id'))
|
||||||
<p class="text-danger">{{$errors->first('piggybank_id')}}</p>
|
<p class="text-danger">{{$errors->first('piggybank_id')}}</p>
|
||||||
@else
|
@else
|
||||||
@@ -160,17 +167,54 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
</div>
|
||||||
|
</div><!-- end of panel for options-->
|
||||||
|
|
||||||
</div>
|
<!-- panel for options -->
|
||||||
</div>
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
<div class="row">
|
<i class="fa fa-bolt"></i> Options
|
||||||
<div class="col-lg-6">
|
</div>
|
||||||
<!-- ALWAYS SHOW SUBMit -->
|
<div class="panel-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="submit" class="col-sm-4 control-label"> </label>
|
<label for="default" class="col-sm-4 control-label">
|
||||||
<div class="col-sm-8">
|
Update
|
||||||
<input type="submit" name="submit" value="Update {{$what}}" class="btn btn-info" />
|
</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="radio">
|
||||||
|
<label>
|
||||||
|
{{Form::radio('post_submit_action','store',true)}}
|
||||||
|
Update the {{{$what}}}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="validate_only" class="col-sm-4 control-label">
|
||||||
|
Validate only
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="radio">
|
||||||
|
<label>
|
||||||
|
{{Form::radio('post_submit_action','validate_only')}}
|
||||||
|
Only validate, do not save changes
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="return_to_form" class="col-sm-4 control-label">
|
||||||
|
Return here
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="radio">
|
||||||
|
<label>
|
||||||
|
{{Form::radio('post_submit_action','return_to_edit')}}
|
||||||
|
After update, return here again.
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user