From 75aa3abcae9e56c88d96302b3aee6735e57ac384 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 27 Feb 2015 14:27:04 +0100 Subject: [PATCH] Update and create transactions. --- .../Controllers/TransactionController.php | 139 +++++++++++++++++- app/Http/routes.php | 5 - .../Journal/JournalRepository.php | 121 ++++++++++++++- .../Journal/JournalRepositoryInterface.php | 24 ++- resources/views/transactions/delete.blade.php | 6 +- resources/views/transactions/edit.blade.php | 38 ++--- 6 files changed, 299 insertions(+), 34 deletions(-) diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php index 6c1d6893ad..88a8e0f17f 100644 --- a/app/Http/Controllers/TransactionController.php +++ b/app/Http/Controllers/TransactionController.php @@ -15,6 +15,7 @@ use Redirect; use Session; use View; + /** * Class TransactionController * @@ -63,6 +64,105 @@ class TransactionController extends Controller return view('transactions.create', compact('accounts', 'budgets', 'what', 'piggies', 'subTitle')); } + /** + * Shows the form that allows a user to delete a transaction journal. + * + * @param TransactionJournal $journal + * + * @return $this + */ + public function delete(TransactionJournal $journal) + { + $type = strtolower($journal->transactionType->type); + $subTitle = 'Delete ' . e($type) . ' "' . e($journal->description) . '"'; + + return View::make('transactions.delete', compact('journal', 'subTitle')); + + + } + + /** + * @param TransactionJournal $transactionJournal + * + * @return \Illuminate\Http\RedirectResponse + */ + public function destroy(TransactionJournal $transactionJournal) + { + $type = $transactionJournal->transactionType->type; + $return = 'withdrawal'; + + Session::flash('success', 'Transaction "' . e($transactionJournal->description) . '" destroyed.'); + + $transactionJournal->delete(); + + switch ($type) { + case 'Deposit': + $return = 'deposit'; + break; + case 'Transfer': + $return = 'transfers'; + break; + } + + return Redirect::route('transactions.index', $return); + } + + /** + * Shows the view to edit a transaction. + * + * @param TransactionJournal $journal + * + * @return $this + */ + public function edit(TransactionJournal $journal, JournalRepositoryInterface $repository) + { + $what = strtolower($journal->transactiontype->type); + $accounts = ExpandedForm::makeSelectList( + Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->where('active', 1)->orderBy('name', 'DESC')->get(['accounts.*']) + ); + $budgets = ExpandedForm::makeSelectList(Auth::user()->budgets()->get()); + $budgets[0] = '(no budget)'; + $transactions = $journal->transactions()->orderBy('amount', 'DESC')->get(); + $piggies = ExpandedForm::makeSelectList(Auth::user()->piggyBanks()->get()); + $piggies[0] = '(no piggy bank)'; + $preFilled = [ + 'date' => $journal->date->format('Y-m-d'), + 'category' => '', + 'budget_id' => 0, + 'piggy_bank_id' => 0 + ]; + + $category = $journal->categories()->first(); + if (!is_null($category)) { + $preFilled['category'] = $category->name; + } + + $budget = $journal->budgets()->first(); + if (!is_null($budget)) { + $preFilled['budget_id'] = $budget->id; + } + + if ($journal->piggyBankEvents()->count() > 0) { + $preFilled['piggy_bank_id'] = $journal->piggyBankEvents()->first()->piggy_bank_id; + } + + $preFilled['amount'] = 0; + /** @var Transaction $t */ + foreach ($transactions as $t) { + if (floatval($t->amount) > 0) { + $preFilled['amount'] = floatval($t->amount); + } + } + $preFilled['account_id'] = $repository->getAssetAccount($journal); + $preFilled['expense_account'] = $transactions[0]->account->name; + $preFilled['revenue_account'] = $transactions[1]->account->name; + $preFilled['account_from_id'] = $transactions[1]->account->id; + $preFilled['account_to_id'] = $transactions[0]->account->id; + + + return View::make('transactions.edit', compact('journal', 'accounts', 'what', 'budgets', 'piggies', 'subTitle'))->with('data', $preFilled); + } + /** * @param $what * @@ -108,7 +208,6 @@ class TransactionController extends Controller } - /** * @param TransactionJournal $journal * @@ -139,11 +238,11 @@ class TransactionController extends Controller } } - return view('transactions.show', compact('journal', 'members'))->with('subTitle', e($journal->transactiontype->type) . ' "' . e($journal->description) . '"' + return view('transactions.show', compact('journal', 'members'))->with( + 'subTitle', e($journal->transactiontype->type) . ' "' . e($journal->description) . '"' ); } - public function store(JournalFormRequest $request, JournalRepositoryInterface $repository) { @@ -171,4 +270,38 @@ class TransactionController extends Controller } + /** + * @param TransactionJournal $journal + * + * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. + * + * @return $this + * @throws FireflyException + */ + public function update(TransactionJournal $journal, JournalFormRequest $request, JournalRepositoryInterface $repository) + { + + $journalData = [ + 'what' => $request->get('what'), + 'description' => $request->get('description'), + 'account_id' => intval($request->get('account_id')), + 'account_from_id' => intval($request->get('account_from_id')), + 'account_to_id' => intval($request->get('account_to_id')), + 'expense_account' => $request->get('expense_account'), + 'revenue_account' => $request->get('revenue_account'), + 'amount' => floatval($request->get('amount')), + 'user' => Auth::user()->id, + 'amount_currency_id' => intval($request->get('amount_currency_id')), + 'date' => new Carbon($request->get('date')), + 'budget_id' => intval($request->get('budget_id')), + 'category' => $request->get('category'), + ]; + + $repository->update($journal, $journalData); + Session::flash('success', 'Transaction "' . e($journalData['description']) . '" updated.'); + + return Redirect::route('transactions.index', $journalData['what']); + + } + } diff --git a/app/Http/routes.php b/app/Http/routes.php index 39577154d1..b5e0d830cd 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -317,11 +317,6 @@ Route::group( ); Route::post('/transaction/update/{tj}', ['uses' => 'TransactionController@update', 'as' => 'transactions.update']); Route::post('/transaction/destroy/{tj}', ['uses' => 'TransactionController@destroy', 'as' => 'transactions.destroy']); - //Route::get('/transaction/relate/{tj}', ['uses' => 'TransactionController@relate', 'as' => 'transactions.relate']); - //Route::post('/transactions/relatedSearch/{tj}', ['uses' => 'TransactionController@relatedSearch', 'as' => 'transactions.relatedSearch']); - //Route::post('/transactions/alreadyRelated/{tj}', ['uses' => 'TransactionController@alreadyRelated', 'as' => 'transactions.alreadyRelated']); - //Route::post('/transactions/doRelate', ['uses' => 'TransactionController@doRelate', 'as' => 'transactions.doRelate']); - //Route::any('/transactions/unrelate/{tj}', ['uses' => 'TransactionController@unrelate', 'as' => 'transactions.unrelate']); /** * Auth\Auth Controller diff --git a/app/Repositories/Journal/JournalRepository.php b/app/Repositories/Journal/JournalRepository.php index 0adb8f3ffb..1f9930519c 100644 --- a/app/Repositories/Journal/JournalRepository.php +++ b/app/Repositories/Journal/JournalRepository.php @@ -2,6 +2,7 @@ namespace FireflyIII\Repositories\Journal; +use Auth; use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; use FireflyIII\Models\Budget; @@ -10,7 +11,6 @@ use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; use Illuminate\Support\Collection; -use Auth; /** * Class JournalRepository @@ -20,6 +20,36 @@ use Auth; class JournalRepository implements JournalRepositoryInterface { + /** + * + * Get the account_id, which is the asset account that paid for the transaction. + * + * @param TransactionJournal $journal + * + * @return mixed + */ + public function getAssetAccount(TransactionJournal $journal) + { + $positive = true; // the asset account is in the transaction with the positive amount. + switch ($journal->transactionType->type) { + case 'Withdrawal': + $positive = false; + break; + } + /** @var Transaction $transaction */ + foreach ($journal->transactions()->get() as $transaction) { + if (floatval($transaction->amount) > 0 && $positive === true) { + return $transaction->account_id; + } + if (floatval($transaction->amount) < 0 && $positive === false) { + return $transaction->account_id; + } + + } + + return $journal->transactions()->first()->account_id; + } + /** * @param string $query * @param TransactionJournal $journal @@ -160,9 +190,98 @@ class JournalRepository implements JournalRepositoryInterface 'amount' => $data['amount'] ] ); + $journal->completed = 1; + $journal->save(); return $journal; } + + + /** + * @param TransactionJournal $journal + * @param array $data + * + * @return mixed + */ + public function update(TransactionJournal $journal, array $data) + { + // update actual journal. + $journal->transaction_currency_id = $data['amount_currency_id']; + $journal->description = $data['description']; + $journal->date = $data['date']; + + + // unlink all categories, recreate them: + $journal->categories()->detach(); + if (strlen($data['category']) > 0) { + $category = Category::firstOrCreate(['name' => $data['category'], 'user_id' => $data['user']]); + $journal->categories()->save($category); + } + + // unlink all budgets and recreate them: + $journal->budgets()->detach(); + if (intval($data['budget_id']) > 0) { + $budget = Budget::find($data['budget_id']); + $journal->budgets()->save($budget); + } + + // store accounts (depends on type) + switch ($journal->transactionType->type) { + case 'Withdrawal': + + $from = Account::find($data['account_id']); + + if (strlen($data['expense_account']) > 0) { + $toType = AccountType::where('type', 'Expense account')->first(); + $to = Account::firstOrCreate( + ['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => $data['expense_account'], 'active' => 1] + ); + } else { + $toType = AccountType::where('type', 'Cash account')->first(); + $to = Account::firstOrCreate(['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]); + } + break; + + case 'Deposit': + $to = Account::find($data['account_id']); + + if (strlen($data['revenue_account']) > 0) { + $fromType = AccountType::where('type', 'Revenue account')->first(); + $from = Account::firstOrCreate( + ['user_id' => $data['user'], 'account_type_id' => $fromType->id, 'name' => $data['revenue_account'], 'active' => 1] + ); + } else { + $toType = AccountType::where('type', 'Cash account')->first(); + $from = Account::firstOrCreate(['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]); + } + + break; + case 'Transfer': + $from = Account::find($data['account_from_id']); + $to = Account::find($data['account_to_id']); + break; + } + + // update the from and to transaction. + /** @var Transaction $transaction */ + foreach ($journal->transactions()->get() as $transaction) { + if ($transaction->account_id === $from->id) { + // this is the from transaction, negative amount: + $transaction->amount = $data['amount'] * -1; + $transaction->save(); + } + if ($transaction->account_id === $to->id) { + $transaction->amount = $data['amount']; + $transaction->save(); + } + } + + + $journal->save(); + + return $journal; + } + } \ No newline at end of file diff --git a/app/Repositories/Journal/JournalRepositoryInterface.php b/app/Repositories/Journal/JournalRepositoryInterface.php index 50984df4b8..f083fb9a3e 100644 --- a/app/Repositories/Journal/JournalRepositoryInterface.php +++ b/app/Repositories/Journal/JournalRepositoryInterface.php @@ -12,6 +12,24 @@ use Illuminate\Support\Collection; */ interface JournalRepositoryInterface { + /** + * + * Get the account_id, which is the asset account that paid for the transaction. + * + * @param TransactionJournal $journal + * + * @return int + */ + public function getAssetAccount(TransactionJournal $journal); + + /** + * @param string $query + * @param TransactionJournal $journal + * + * @return Collection + */ + public function searchRelated($query, TransactionJournal $journal); + /** * @param array $data * @@ -20,10 +38,10 @@ interface JournalRepositoryInterface public function store(array $data); /** - * @param string $query * @param TransactionJournal $journal + * @param array $data * - * @return Collection + * @return mixed */ - public function searchRelated($query, TransactionJournal $journal); + public function update(TransactionJournal $journal, array $data); } \ No newline at end of file diff --git a/resources/views/transactions/delete.blade.php b/resources/views/transactions/delete.blade.php index aef2335fc8..bf62d775d4 100644 --- a/resources/views/transactions/delete.blade.php +++ b/resources/views/transactions/delete.blade.php @@ -1,7 +1,7 @@ @extends('layouts.default') @section('content') -{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $journal) }} -{{Form::open(['class' => 'form-horizontal','id' => 'destroy','url' => route('transactions.destroy',$journal->id)])}} +{!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $journal) !!} +{!! Form::open(['class' => 'form-horizontal','id' => 'destroy','url' => route('transactions.destroy',$journal->id)]) !!}
@@ -38,6 +38,6 @@
-{{Form::close()}} +{!! Form::close() !!} @stop diff --git a/resources/views/transactions/edit.blade.php b/resources/views/transactions/edit.blade.php index 0996995257..884582ff36 100644 --- a/resources/views/transactions/edit.blade.php +++ b/resources/views/transactions/edit.blade.php @@ -1,8 +1,10 @@ @extends('layouts.default') @section('content') -{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $journal) }} -{{Form::open(['class' => 'form-horizontal','id' => 'update','url' => route('transactions.update',$journal->id)])}} +{!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $journal) !!} +{!! Form::open(['class' => 'form-horizontal','id' => 'update','url' => route('transactions.update',$journal->id)]) !!} + +
@@ -13,33 +15,33 @@
- {{Form::ffText('description',$journal->description)}} + {!! ExpandedForm::text('description',$journal->description) !!} @if($what == 'deposit' || $what == 'withdrawal') - {{Form::ffSelect('account_id',$accounts,$data['account_id'])}} + {!! ExpandedForm::select('account_id',$accounts,$data['account_id']) !!} @endif @if($what == 'withdrawal') - {{Form::ffText('expense_account',$data['expense_account'])}} + {!! ExpandedForm::text('expense_account',$data['expense_account']) !!} @endif @if($what == 'deposit') - {{Form::ffText('revenue_account',$data['revenue_account'])}} + {!! ExpandedForm::text('revenue_account',$data['revenue_account']) !!} @endif @if($what == 'transfer') - {{Form::ffSelect('account_from_id',$accounts,$data['account_from_id'])}} - {{Form::ffSelect('account_to_id',$accounts,$data['account_to_id'])}} + {!! ExpandedForm::select('account_from_id',$accounts,$data['account_from_id']) !!} + {!! ExpandedForm::select('account_to_id',$accounts,$data['account_to_id']) !!} @endif - {{Form::ffAmount('amount',$data['amount'],['currency' => $journal->transactionCurrency])}} + {!! ExpandedForm::amount('amount',$data['amount'],['currency' => $journal->transactionCurrency]) !!} - {{Form::ffDate('date',$data['date'])}} + {!! ExpandedForm::date('date',$data['date']) !!}
@@ -59,16 +61,16 @@
@if($what == 'withdrawal') - {{Form::ffSelect('budget_id',$budgets,$data['budget_id'])}} + {!! ExpandedForm::select('budget_id',$budgets,$data['budget_id']) !!} @endif - {{Form::ffText('category',$data['category'])}} + {!! ExpandedForm::text('category',$data['category']) !!} @if($what == 'transfer' && count($piggies) > 0) - {{Form::ffSelect('piggy_bank_id',$piggies,$data['piggy_bank_id'])}} + {!! ExpandedForm::select('piggy_bank_id',$piggies,$data['piggy_bank_id']) !!} @endif
@@ -79,18 +81,16 @@ Options
- {{Form::ffOptionsList('update','transaction')}} + {!! ExpandedForm::optionsList('update','transaction') !!}
- - -{{Form::close()}} +{!! Form::close() !!} @stop @section('scripts') -{{HTML::script('assets/javascript/typeahead/bootstrap3-typeahead.min.js')}} -{{HTML::script('assets/javascript/firefly/transactions.js')}} + + @stop