From 6a264085522123a0a0220bae783cb3f15b722491 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 20 Sep 2014 08:39:24 +0200 Subject: [PATCH] Expanded the 'save transaction' routine and cleaned it up. Still some work to do though. --- app/controllers/TransactionController.php | 65 +-- .../Helper/Controllers/Transaction.php | 119 +++++ .../Controllers/TransactionInterface.php | 22 + .../Firefly/Helper/HelperServiceProvider.php | 6 + .../Account/AccountRepositoryInterface.php | 7 + .../Account/EloquentAccountRepository.php | 34 ++ .../Category/CategoryRepositoryInterface.php | 2 +- .../Category/EloquentCategoryRepository.php | 73 ++- .../EloquentTransactionJournalRepository.php | 316 ++---------- .../TransactionJournalRepositoryInterface.php | 42 +- app/models/Component.php | 4 +- app/views/transactions/create.blade.php | 458 ++++++++++-------- 12 files changed, 592 insertions(+), 556 deletions(-) create mode 100644 app/lib/Firefly/Helper/Controllers/Transaction.php create mode 100644 app/lib/Firefly/Helper/Controllers/TransactionInterface.php diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 8bd880a8e2..0c668c23df 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -2,6 +2,8 @@ use Carbon\Carbon; +use Firefly\Exception\FireflyException; +use Firefly\Helper\Controllers\TransactionInterface as TI; use Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface as TJRI; /** @@ -14,13 +16,16 @@ class TransactionController extends BaseController { protected $_repository; + protected $_helper; /** * @param TJRI $repository + * @param TI $helper */ - public function __construct(TJRI $repository) + public function __construct(TJRI $repository, TI $helper) { $this->_repository = $repository; + $this->_helper = $helper; View::share('title', 'Transactions'); View::share('mainTitleIcon', 'fa-repeat'); } @@ -55,7 +60,7 @@ class TransactionController extends BaseController return View::make('transactions.create')->with('accounts', $assetAccounts)->with('budgets', $budgets)->with( 'what', $what - )->with('piggies', $piggies)->with('subTitle', 'Add a new ' . $what)->with('title', 'Transactions'); + )->with('piggies', $piggies)->with('subTitle', 'Add a new ' . $what); } /** @@ -272,34 +277,37 @@ class TransactionController extends BaseController /** * @param $what * - * @return \Illuminate\Http\RedirectResponse + * @return $this|\Illuminate\Http\RedirectResponse + * @throws FireflyException */ public function store($what) { + /* + * Collect data to process: + */ + $data = Input::except(['_token']); + $data['what'] = $what; - $journal = $this->_repository->store($what, Input::all()); - if ($journal->errors()->count() > 0) { - Session::flash('error', 'Could not save transaction: ' . $journal->errors()->first() . '!'); - return Redirect::route('transactions.create', [$what])->withInput()->withErrors($journal->errors()); - } + switch (Input::get('post_submit_action')) { + case 'store': + /* + * Try to store: + */ + $messageBag = $this->_helper->store($data); - if ($journal->validate() && !is_null($journal->id)) { - Session::flash('success', 'Transaction "' . $journal->description . '" saved!'); + /* + * Failure! + */ + if($messageBag->count() > 0) { + Session::flash('error', 'Could not save transaction: ' . $messageBag->first()); + return Redirect::route('transactions.create', [$what])->withInput()->withErrors($messageBag); + } - // if reminder present, deactivate it: - if (Input::get('reminder')) { - /** @var \Firefly\Storage\Reminder\ReminderRepositoryInterface $reminders */ - $reminders = App::make('Firefly\Storage\Reminder\ReminderRepositoryInterface'); - $reminder = $reminders->find(Input::get('reminder')); - $reminders->deactivate($reminder); - } + /* + * Success! + */ + Session::flash('success', 'Transaction "' . e(Input::get('description')) . '" saved!'); - // trigger the creation for recurring transactions. - Event::fire('journals.store', [$journal]); - - if (Input::get('create') == '1') { - return Redirect::route('transactions.create', [$what])->withInput(); - } else { switch ($what) { case 'withdrawal': return Redirect::route('transactions.expenses'); @@ -312,14 +320,11 @@ class TransactionController extends BaseController break; } - } - } else { - Session::flash('error', 'Could not save transaction: ' . $journal->errors()->first() . '!'); - - return Redirect::route('transactions.create', [$what])->withInput()->withErrors($journal->errors()); + break; + default: + throw new FireflyException('Method ' . Input::get('post_submit_action') . ' not implemented yet.'); + break; } - - } /** diff --git a/app/lib/Firefly/Helper/Controllers/Transaction.php b/app/lib/Firefly/Helper/Controllers/Transaction.php new file mode 100644 index 0000000000..e1b451e8a5 --- /dev/null +++ b/app/lib/Firefly/Helper/Controllers/Transaction.php @@ -0,0 +1,119 @@ +store($data); + + /* + * If invalid, return the message bag: + */ + if (!$journal->validate()) { + return $journal->errors(); + } + + /* + * save budget using repository + */ + if (isset($data['budget_id'])) { + /** @var \Firefly\Storage\Budget\BudgetRepositoryInterface $budgets */ + $budgets = \App::make('Firefly\Storage\Budget\BudgetRepositoryInterface'); + $budget = $budgets->find($data['budget_id']); + } + + /* + * save category using repository + */ + /** @var \Firefly\Storage\Category\CategoryRepositoryInterface $categories */ + $categories = \App::make('Firefly\Storage\Category\CategoryRepositoryInterface'); + $category = $categories->firstOrCreate($data['category']); + + /* + * 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; + } + + /* + * save transactions using repository. + */ + $one = $journals->saveTransaction($journal, $from, floatval($data['amount']) * -1); + $two = $journals->saveTransaction($journal, $to, floatval($data['amount'])); + /* + * Count for $journal is zero? Then there were errors! + */ + if ($journal->transactions()->count() < 2) { + /* + * Join message bags and return them: + */ + $bag = $one->errors(); + $bag->merge($two->errors()); + return $bag; + } + + /* + * Connect budget and category: + */ + if (isset($budget) && !is_null($budget)) { + $journal->budgets()->save($budget); + } + if (!is_null($category)) { + $journal->categories()->save($category); + } + $journal->completed = true; + $journal->save(); + return $journal->errors(); + } + +} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Controllers/TransactionInterface.php b/app/lib/Firefly/Helper/Controllers/TransactionInterface.php new file mode 100644 index 0000000000..50529788cb --- /dev/null +++ b/app/lib/Firefly/Helper/Controllers/TransactionInterface.php @@ -0,0 +1,22 @@ +app->bind( + 'Firefly\Helper\Controllers\TransactionInterface', + 'Firefly\Helper\Controllers\Transaction' + ); + $this->app->bind( 'Firefly\Helper\Controllers\CategoryInterface', 'Firefly\Helper\Controllers\Category' diff --git a/app/lib/Firefly/Storage/Account/AccountRepositoryInterface.php b/app/lib/Firefly/Storage/Account/AccountRepositoryInterface.php index 295d9902fe..355e04313e 100644 --- a/app/lib/Firefly/Storage/Account/AccountRepositoryInterface.php +++ b/app/lib/Firefly/Storage/Account/AccountRepositoryInterface.php @@ -96,6 +96,13 @@ interface AccountRepositoryInterface */ public function findExpenseAccountByName($name); + /** + * @param $name + * + * @return |Account|null + */ + public function findRevenueAccountByName($name); + /** * @param \Account $from * @param \Account $to diff --git a/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php b/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php index 0c925e12ec..dd2c64e3ea 100644 --- a/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php +++ b/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php @@ -118,6 +118,40 @@ class EloquentAccountRepository implements AccountRepositoryInterface return $account; } + /** + * @param $name + * + * @return |Account|null + */ + public function findRevenueAccountByName($name) + { + // find account: + $type = $this->findAccountType('Revenue account'); + $account = $this->_user->accounts()->where('name', $name)->where('account_type_id', $type->id)->first(); + + // find cash account as fall back: + if (is_null($account)) { + $cashType = $this->findAccountType('Cash account'); + $account = $this->_user->accounts()->where('account_type_id', $cashType->id)->first(); + } + + // create cash account as ultimate fall back: + if (is_null($account)) { + $set = [ + 'name' => 'Cash account', + 'user_id' => $this->_user->id, + 'active' => 1, + 'account_type_id' => $cashType->id + ]; + $account = $this->firstOrCreate($set); + } + + if ($account->active == 0) { + return null; + } + + return $account; + } /** * @param $type diff --git a/app/lib/Firefly/Storage/Category/CategoryRepositoryInterface.php b/app/lib/Firefly/Storage/Category/CategoryRepositoryInterface.php index 5440e58e4a..15c6785548 100644 --- a/app/lib/Firefly/Storage/Category/CategoryRepositoryInterface.php +++ b/app/lib/Firefly/Storage/Category/CategoryRepositoryInterface.php @@ -55,7 +55,7 @@ interface CategoryRepositoryInterface * * @return mixed */ - public function createOrFind($name); + public function firstOrCreate($name); /** * @param \User $user diff --git a/app/lib/Firefly/Storage/Category/EloquentCategoryRepository.php b/app/lib/Firefly/Storage/Category/EloquentCategoryRepository.php index 9439fdd688..097a94b38e 100644 --- a/app/lib/Firefly/Storage/Category/EloquentCategoryRepository.php +++ b/app/lib/Firefly/Storage/Category/EloquentCategoryRepository.php @@ -29,7 +29,8 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface * * @return mixed */ - public function importUpdateTransfer(Job $job, array $payload) { + public function importUpdateTransfer(Job $job, array $payload) + { /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); @@ -57,13 +58,13 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface /* * Prep some vars from the payload */ - $transferId = intval($payload['data']['transfer_id']); - $componentId = intval($payload['data']['component_id']); + $transferId = intval($payload['data']['transfer_id']); + $componentId = intval($payload['data']['component_id']); /* * Find the import map for both: */ - $categoryMap = $repository->findImportEntry($importMap, 'Category', $componentId); + $categoryMap = $repository->findImportEntry($importMap, 'Category', $componentId); $transferMap = $repository->findImportEntry($importMap, 'Transfer', $transferId); /* @@ -71,7 +72,7 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface */ if (is_null($categoryMap) || is_null($transferMap)) { \Log::notice('No map found in category/transfer mapper. Release.'); - if(\Config::get('queue.default') == 'sync') { + if (\Config::get('queue.default') == 'sync') { $importMap->jobsdone++; $importMap->save(); $job->delete(); // count fixed @@ -93,7 +94,7 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface */ if (is_null($category) || is_null($journal)) { \Log::notice('Map is incorrect in category/transfer mapper. Release.'); - if(\Config::get('queue.default') == 'sync') { + if (\Config::get('queue.default') == 'sync') { $importMap->jobsdone++; $importMap->save(); $job->delete(); // count fixed @@ -119,6 +120,27 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface return; } + /** + * @param \User $user + * + * @return mixed|void + */ + public function overruleUser(\User $user) + { + $this->_user = $user; + return true; + } + + /** + * @param $categoryId + * + * @return mixed + */ + public function find($categoryId) + { + return $this->_user->categories()->find($categoryId); + } + /** * Takes a transaction/category component and updates the transaction journal to match. * @@ -170,7 +192,7 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface */ if (is_null($categoryMap) || is_null($transactionMap)) { \Log::notice('No map found in category/transaction mapper. Release.'); - if(\Config::get('queue.default') == 'sync') { + if (\Config::get('queue.default') == 'sync') { $importMap->jobsdone++; $importMap->save(); $job->delete(); // count fixed @@ -192,7 +214,7 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface */ if (is_null($category) || is_null($journal)) { \Log::notice('Map is incorrect in category/transaction mapper. Release.'); - if(\Config::get('queue.default') == 'sync') { + if (\Config::get('queue.default') == 'sync') { $importMap->jobsdone++; $importMap->save(); $job->delete(); // count fixed @@ -218,27 +240,6 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface return; } - /** - * @param \User $user - * - * @return mixed|void - */ - public function overruleUser(\User $user) - { - $this->_user = $user; - return true; - } - - /** - * @param $categoryId - * - * @return mixed - */ - public function find($categoryId) - { - return $this->_user->categories()->find($categoryId); - } - /** * @param Job $job * @param array $payload @@ -334,18 +335,16 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface * * @return \Category|mixed */ - public function createOrFind($name) + public function firstOrCreate($name) { if (strlen($name) == 0) { return null; } - $category = $this->findByName($name); - if (!$category) { - return $this->store(['name' => $name]); - } - - return $category; - + $data = [ + 'name' => $name, + 'user_id' => $this->_user->id, + ]; + return \Category::firstOrCreate($data); } diff --git a/app/lib/Firefly/Storage/TransactionJournal/EloquentTransactionJournalRepository.php b/app/lib/Firefly/Storage/TransactionJournal/EloquentTransactionJournalRepository.php index 242c820179..d076b8936d 100644 --- a/app/lib/Firefly/Storage/TransactionJournal/EloquentTransactionJournalRepository.php +++ b/app/lib/Firefly/Storage/TransactionJournal/EloquentTransactionJournalRepository.php @@ -52,7 +52,6 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito } - /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); $accounts->overruleUser($user); @@ -102,7 +101,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito */ if (is_null($accountTo) || is_null($accountFrom)) { \Log::notice('No account to, or account from. Release transfer ' . $description); - if(\Config::get('queue.default') == 'sync') { + if (\Config::get('queue.default') == 'sync') { $importMap->jobsdone++; $importMap->save(); $job->delete(); // count fixed @@ -140,143 +139,58 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito return true; } - /** - * - * We're building this thinking the money goes from A to B. - * If the amount is negative however, the money still goes - * from A to B but the balances are reversed. - * - * Aka: - * - * Amount = 200 - * A loses 200 (-200). * -1 - * B gains 200 (200). * 1 - * - * Final balance: -200 for A, 200 for B. - * - * When the amount is negative: - * - * Amount = -200 - * A gains 200 (200). * -1 - * B loses 200 (-200). * 1 - * - * @param \Account $from - * @param \Account $toAccount - * @param $description - * @param $amount - * @param \Carbon\Carbon $date - * - * @return \TransactionJournal - * @throws \Firefly\Exception\FireflyException - */ - public function createSimpleJournal(\Account $fromAccount, \Account $toAccount, $description, $amount, Carbon $date) + public function store(array $data) { + /* + * Create the journal and fill relevant fields. + */ $journal = new \TransactionJournal; + $journal->description = trim($data['description']); + $journal->date = new Carbon($data['date']); + $journal->user_id = $this->_user->id; $journal->completed = false; - $journal->description = $description; - $journal->date = $date; - $amountFrom = $amount * -1; - $amountTo = $amount; + /* + * Find the more complex fields and fill those: + */ + $currency = \TransactionCurrency::where('code', 'EUR')->first(); + $journal->transaction_currency_id = $currency->id; + $transactionType = \TransactionType::where('type', $data['what'])->first(); + $journal->transaction_type_id = $transactionType->id; - if (round(floatval($amount), 2) == 0.00) { - $journal->errors()->add('amount', 'Amount must not be zero.'); - - return $journal; - } - - // account types for both: - $toAT = $toAccount->accountType->type; - $fromAT = $fromAccount->accountType->type; - - $journalType = null; - - switch (true) { - case ($fromAccount->transactions()->count() == 0 && $toAccount->transactions()->count() == 0): - $journalType = \TransactionType::where('type', 'Opening balance')->first(); - break; - - case (in_array($fromAT, ['Default account', 'Asset account']) - && in_array( - $toAT, ['Default account', 'Asset account'] - )): // both are yours: - // determin transaction type. If both accounts are new, it's an initial balance transfer. - $journalType = \TransactionType::where('type', 'Transfer')->first(); - break; - case ($amount < 0): - $journalType = \TransactionType::where('type', 'Deposit')->first(); - break; - // is deposit into one of your own accounts: - case ($toAT == 'Default account' || $toAT == 'Asset account'): - $journalType = \TransactionType::where('type', 'Deposit')->first(); - break; - // is withdrawal from one of your own accounts: - case ($fromAT == 'Default account' || $fromAT == 'Asset account'): - $journalType = \TransactionType::where('type', 'Withdrawal')->first(); - break; - } - - if (is_null($journalType)) { - throw new FireflyException('Could not figure out transaction type.'); - } - - - // always the same currency: - $currency = \TransactionCurrency::where('code', 'EUR')->first(); - if (is_null($currency)) { - throw new FireflyException('No currency for journal!'); - } - - // new journal: - - $journal->transactionType()->associate($journalType); - $journal->transactionCurrency()->associate($currency); - $journal->user()->associate($this->_user); - - // same account: - if ($fromAccount->id == $toAccount->id) { - - $journal->errors()->add('account_to_id', 'Must be different from the "account from".'); - $journal->errors()->add('account_from_id', 'Must be different from the "account to".'); - return $journal; - } - - - if (!$journal->validate()) { - return $journal; - } - $journal->save(); - - // create transactions: - $fromTransaction = new \Transaction; - $fromTransaction->account()->associate($fromAccount); - $fromTransaction->transactionJournal()->associate($journal); - $fromTransaction->description = null; - $fromTransaction->amount = $amountFrom; - if (!$fromTransaction->validate()) { - throw new FireflyException('Cannot create valid transaction (from): ' . $fromTransaction->errors() - ->first()); - } - $fromTransaction->save(); - - $toTransaction = new \Transaction; - $toTransaction->account()->associate($toAccount); - $toTransaction->transactionJournal()->associate($journal); - $toTransaction->description = null; - $toTransaction->amount = $amountTo; - if (!$toTransaction->validate()) { - - throw new FireflyException('Cannot create valid transaction (to): ' . $toTransaction->errors()->first() - . ': ' . print_r($toAccount->toArray(), true)); - } - $toTransaction->save(); - - $journal->completed = true; + /* + * Validatre & save journal + */ + $journal->validate(); $journal->save(); + /* + * Return regardless. + */ return $journal; } + /** + * @param \TransactionJournal $journal + * @param \Account $account + * @param $amount + * + * @return mixed + */ + public function saveTransaction(\TransactionJournal $journal, \Account $account, $amount) + { + $transaction = new \Transaction; + $transaction->account_id = $account->id; + $transaction->transaction_journal_id = $journal->id; + $transaction->amount = $amount; + if ($transaction->validate()) { + $transaction->save(); + } + return $transaction; + + } + + /** * @param Job $job * @param array $payload @@ -304,7 +218,6 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito } - /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); $accounts->overruleUser($user); @@ -364,7 +277,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito */ if (is_null($assetAccount)) { \Log::notice('No asset account for "' . $description . '", try again later.'); - if(\Config::get('queue.default') == 'sync') { + if (\Config::get('queue.default') == 'sync') { $importMap->jobsdone++; $importMap->save(); $job->delete(); // count fixed @@ -417,20 +330,20 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito { return $this->_user->transactionjournals()->with( ['transactions' => function ($q) { - return $q->orderBy('amount', 'ASC'); - }, 'transactioncurrency', 'transactiontype', 'components', 'transactions.account', + return $q->orderBy('amount', 'ASC'); + }, 'transactioncurrency', 'transactiontype', 'components', 'transactions.account', 'transactions.account.accounttype'] ) ->where('id', $journalId)->first(); } - /** - * - */ - public function get() - { - - } +// /** +// * +// */ +// public function get() +// { +// +// } /** * @param $type @@ -534,129 +447,6 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito return $result; } - /** - * @param $what - * @param $data - * - * @return mixed|\TransactionJournal - */ - public function store($what, $data) - { - // $fromAccount and $toAccount are found - // depending on the $what - - $fromAccount = null; - $toAccount = null; - - /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accountRepository */ - $accountRepository = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); - $accountRepository->overruleUser($this->_user); - - /** @var \Firefly\Storage\Category\CategoryRepositoryInterface $catRepository */ - $catRepository = \App::make('Firefly\Storage\Category\CategoryRepositoryInterface'); - $catRepository->overruleUser($this->_user); - - /** @var \Firefly\Storage\Budget\BudgetRepositoryInterface $budRepository */ - $budRepository = \App::make('Firefly\Storage\Budget\BudgetRepositoryInterface'); - $budRepository->overruleUser($this->_user); - - - switch ($what) { - case 'withdrawal': - $fromAccount = $accountRepository->find(intval($data['account_id'])); - $expenseAccountType = $accountRepository->findAccountType('Expense account'); - $set = [ - 'name' => $data['expense_account'], - 'account_type_id' => $expenseAccountType->id, - 'user_id' => $this->_user->id, - 'active' => 1]; - $toAccount = $accountRepository->firstOrCreate($set); - break; - - case 'deposit': - $revenueAccountType = $accountRepository->findAccountType('Revenue account'); - $set = [ - 'name' => $data['revenue_account'], - 'account_type_id' => $revenueAccountType->id, - 'user_id' => $this->_user->id, - 'active' => 1]; - - $fromAccount = $accountRepository->firstOrCreate($set); - $toAccount = $accountRepository->find(intval($data['account_id'])); - break; - case 'transfer': - $fromAccount = $accountRepository->find(intval($data['account_from_id'])); - $toAccount = $accountRepository->find(intval($data['account_to_id'])); - - break; - } - // fall back to cash if necessary: - $fromAccount = is_null($fromAccount) ? $fromAccount = $accountRepository->getCashAccount() : $fromAccount; - $toAccount = is_null($toAccount) ? $toAccount = $accountRepository->getCashAccount() : $toAccount; - - // create or find category: - $category = isset($data['category']) ? $catRepository->createOrFind($data['category']) : null; - - // find budget: - $budget = isset($data['budget_id']) ? $budRepository->find(intval($data['budget_id'])) : null; - // find amount & description: - $description = trim($data['description']); - $amount = floatval($data['amount']); - $date = new Carbon($data['date']); - - // try to create a journal: - $transactionJournal = $this->createSimpleJournal($fromAccount, $toAccount, $description, $amount, $date); - if (!$transactionJournal->id || $transactionJournal->completed == 0) { - return $transactionJournal; - } - - // here we're done and we have transactions in the journal: - // do something with the piggy bank: - if ($what == 'transfer') { - /** @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'])); - - if ($piggyBank) { - // one of the two transactions may be connected to this piggy bank. - $connected = false; - foreach ($transactionJournal->transactions()->get() as $transaction) { - if ($transaction->account_id == $piggyBank->account_id) { - $connected = true; - $transaction->piggybank()->associate($piggyBank); - $transaction->save(); - \Event::fire( - 'piggybanks.createRelatedTransfer', [$piggyBank, $transactionJournal, $transaction] - ); - 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' - ); - } - } - } - } - - - // attach: - if (!is_null($budget)) { - $transactionJournal->budgets()->save($budget); - } - if (!is_null($category)) { - $transactionJournal->categories()->save($category); - } - - return $transactionJournal; - } - /** * @param \TransactionJournal $journal * @param $data diff --git a/app/lib/Firefly/Storage/TransactionJournal/TransactionJournalRepositoryInterface.php b/app/lib/Firefly/Storage/TransactionJournal/TransactionJournalRepositoryInterface.php index a0114d234b..94e14a8091 100644 --- a/app/lib/Firefly/Storage/TransactionJournal/TransactionJournalRepositoryInterface.php +++ b/app/lib/Firefly/Storage/TransactionJournal/TransactionJournalRepositoryInterface.php @@ -28,21 +28,21 @@ interface TransactionJournalRepositoryInterface */ public function importTransfer(Job $job, array $payload); - /** - * @param \Account $from - * @param \Account $toAccount - * @param $description - * @param $amount - * @param Carbon $date - * - * @return mixed - */ - public function createSimpleJournal(\Account $from, \Account $toAccount, $description, $amount, Carbon $date); +// /** +// * @param \Account $from +// * @param \Account $toAccount +// * @param $description +// * @param $amount +// * @param Carbon $date +// * +// * @return mixed +// */ +// public function createSimpleJournal(\Account $from, \Account $toAccount, $description, $amount, Carbon $date); - /** - * @return mixed - */ - public function get(); +// /** +// * @return mixed +// */ +// public function get(); /** @@ -53,12 +53,22 @@ interface TransactionJournalRepositoryInterface public function overruleUser(\User $user); /** - * @param $what + * Store a new transaction journal. + * * @param $data * + * @return \TransactionJournal|null + */ + public function store(array $data); + + /** + * @param \TransactionJournal $journal + * @param \Account $account + * @param $amount + * * @return mixed */ - public function store($what, $data); + public function saveTransaction(\TransactionJournal $journal, \Account $account, $amount); /** * @param \TransactionJournal $journal diff --git a/app/models/Component.php b/app/models/Component.php index 61147a48d5..e1310481e5 100644 --- a/app/models/Component.php +++ b/app/models/Component.php @@ -27,11 +27,13 @@ class Component extends SingleTableInheritanceEntity public static $rules = [ 'user_id' => 'exists:users,id|required', - 'name' => ['required', 'between:1,100', 'alphabasic'], + 'name' => ['required', 'between:1,100','min:1', 'alphabasic'], 'class' => 'required', ]; protected $table = 'components'; protected $subclassField = 'class'; + protected $fillable = ['name','user_id']; + /** * @return \Illuminate\Database\Eloquent\Relations\HasMany diff --git a/app/views/transactions/create.blade.php b/app/views/transactions/create.blade.php index fe09e3abf8..4bf784fe71 100644 --- a/app/views/transactions/create.blade.php +++ b/app/views/transactions/create.blade.php @@ -1,235 +1,277 @@ @extends('layouts.default') @section('content') -
-
-

- @if($what == 'withdrawal') - Some text about moving from asset accounts to expense accounts - @endif - @if($what == 'deposit') - A deposit is when you earn money, moving an amount from a beneficiary into your own account. - @endif - @if($what == 'transfer') - TRANSFER - @endif -

-
-
- {{Form::open(['class' => 'form-horizontal','url' => route('transactions.store',$what)])}} {{Form::hidden('reminder',Input::get('reminder_id'))}}
-

Mandatory fields

- - -
- -
- - @if($errors->has('description')) -

{{$errors->first('description')}}

- @endif + +
+
+ Mandatory fields
+
+ +
has('description')) + class="form-group has-error has-feedback" + @else + class="form-group" + @endif + > + +
+ + @if($errors->has('description')) +

{{$errors->first('description')}}

+ @endif +
+
+ + @if($what == 'deposit' || $what == 'withdrawal') +
+ +
+ {{Form::select('account_id',$accounts,Input::old('account_id') ?: Input::get('account_id'),['class' => 'form-control'])}} + @if($errors->has('account_id')) +

{{$errors->first('account_id')}}

+ @endif +
+
+ @endif + + + @if($what == 'withdrawal') +
+ +
+ + @if($errors->has('expense_account')) +

{{$errors->first('expense_account')}}

+ @else + + This field will auto-complete your existing expense accounts (where you spent the + money), but you can type freely to create new ones. If you took the money from + an ATM, you should leave this field empty. + @endif +
+
+ @endif + + + @if($what == 'deposit') +
+ +
+ + @if($errors->has('beneficiary')) +

{{$errors->first('revenue_account')}}

+ @else + + This field will auto-complete your existing revenue accounts (if any), but you can type freely to create new ones. + @endif +
+
+ @endif + + + @if($what == 'transfer') +
+ +
+ {{Form::select('account_from_id',$accounts,Input::old('account_from_id') ?: Input::get('account_from_id'),['class' => 'form-control'])}} + @if($errors->has('account_from_id')) +

{{$errors->first('account_from_id')}}

+ @endif +
+
+ +
+ +
+ {{Form::select('account_to_id',$accounts,Input::old('account_to_id') ?: Input::get('account_to_id'),['class' => 'form-control'])}} + @if($errors->has('account_to_id')) +

{{$errors->first('account_to_id')}}

+ @endif +
+
+ @endif + + +
+ +
+ + @if($errors->has('amount')) +

{{$errors->first('amount')}}

+ @endif +
+
+ + +
+ +
+ + @if($errors->has('date')) +

{{$errors->first('date')}}

+ @endif +
+
+
- - @if($what == 'deposit' || $what == 'withdrawal') -
- -
- {{Form::select('account_id',$accounts,Input::old('account_id') ?: Input::get('account_id'),['class' => 'form-control'])}} - @if($errors->has('account_id')) -

{{$errors->first('account_id')}}

- @endif -
-
- @endif - - - @if($what == 'withdrawal') -
- -
- - @if($errors->has('expense_account')) -

{{$errors->first('expense_account')}}

- @else - This field will auto-complete your existing expense accounts (if any), but you can type freely to create new ones. - @endif -
-
- @endif - - - @if($what == 'deposit') -
- -
- - @if($errors->has('beneficiary')) -

{{$errors->first('revenue_account')}}

- @else - This field will auto-complete your existing revenue accounts (if any), but you can type freely to create new ones. - @endif -
-
- @endif - - - @if($what == 'transfer') -
- -
- {{Form::select('account_from_id',$accounts,Input::old('account_from_id') ?: Input::get('account_from_id'),['class' => 'form-control'])}} - @if($errors->has('account_from_id')) -

{{$errors->first('account_from_id')}}

- @endif -
-
- -
- -
- {{Form::select('account_to_id',$accounts,Input::old('account_to_id') ?: Input::get('account_to_id'),['class' => 'form-control'])}} - @if($errors->has('account_to_id')) -

{{$errors->first('account_to_id')}}

- @endif -
-
- @endif - - -
- -
- - @if($errors->has('amount')) -

{{$errors->first('amount')}}

- @endif -
-
- - -
- -
- - @if($errors->has('date')) -

{{$errors->first('date')}}

- @endif -
-
+

+ +

-

Optional fields

- - - @if($what == 'withdrawal') -
- -
- {{Form::select('budget_id',$budgets,Input::old('budget_id') ?: 0,['class' => 'form-control'])}} - @if($errors->has('budget_id')) -

{{$errors->first('budget_id')}}

- @else - Select one of your budgets to make this transaction a part of it. - @endif -
-
- @endif - -
- -
- - @if($errors->has('category')) -

{{$errors->first('category')}}

- @else - 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. - - @endif -
-
- - - @if($what == 'transfer' && count($piggies) > 0) -
- -
- - @if($errors->has('piggybank_id')) -

{{$errors->first('piggybank_id')}}

- @else - - You can directly add the amount you're transferring - to one of your piggy banks, provided they are related to the account your - transferring to. - - @endif -
-
- @endif + +
+ +
+ + @if($errors->has('category')) +

{{$errors->first('category')}}

+ @else + Add more fine-grained information to this transaction by entering a category. + This field will auto-complete existing categories but can also be used to create new ones. + + @endif +
+
+ -
-
+ + @if($what == 'transfer' && count($piggies) > 0) +
+ +
+ + @if($errors->has('piggybank_id')) +

{{$errors->first('piggybank_id')}}

+ @else + + You can directly add the amount you're transferring + to one of your piggy banks, provided they are related to the account your + transferring to. + + @endif +
+
+ @endif +
+
-
-
- -
- -
-
- +
+
+ Options +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
- -
- -
- -
-
-
+ + {{Form::close()}} @stop @section('scripts') + + @stop \ No newline at end of file