mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-29 06:34:37 +00:00 
			
		
		
		
	Update and create transactions.
This commit is contained in:
		| @@ -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']); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -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); | ||||
| } | ||||
| @@ -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)]) !!} | ||||
|  | ||||
| <div class="row"> | ||||
|     <div class="col-lg-6 col-md-6 col-sm-12"> | ||||
| @@ -38,6 +38,6 @@ | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
| {{Form::close()}} | ||||
| {!! Form::close() !!} | ||||
|  | ||||
| @stop | ||||
|   | ||||
| @@ -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)]) !!} | ||||
|  | ||||
| <input type="hidden" name="id" value="{{$journal->id}}" /> | ||||
| <input type="hidden" name="what" value="{{$what}}" /> | ||||
|  | ||||
| <div class="row"> | ||||
|     <div class="col-lg-6 col-md-12 col-sm-12"> | ||||
| @@ -13,33 +15,33 @@ | ||||
|                 </div> | ||||
|                 <div class="panel-body"> | ||||
|                     <!-- ALWAYS AVAILABLE --> | ||||
|                     {{Form::ffText('description',$journal->description)}} | ||||
|                     {!! ExpandedForm::text('description',$journal->description) !!} | ||||
|  | ||||
|                     <!-- SHOW ACCOUNT (FROM) ONLY FOR WITHDRAWALS AND DEPOSITS --> | ||||
|                     @if($what == 'deposit' || $what == 'withdrawal') | ||||
|                         {{Form::ffSelect('account_id',$accounts,$data['account_id'])}} | ||||
|                         {!! ExpandedForm::select('account_id',$accounts,$data['account_id']) !!} | ||||
|                     @endif | ||||
|  | ||||
|                     <!-- SHOW EXPENSE ACCOUNT ONLY FOR WITHDRAWALS --> | ||||
|                     @if($what == 'withdrawal') | ||||
|                         {{Form::ffText('expense_account',$data['expense_account'])}} | ||||
|                         {!! ExpandedForm::text('expense_account',$data['expense_account']) !!} | ||||
|                     @endif | ||||
|                     <!-- SHOW REVENUE ACCOUNT ONLY FOR DEPOSITS --> | ||||
|                     @if($what == 'deposit') | ||||
|                         {{Form::ffText('revenue_account',$data['revenue_account'])}} | ||||
|                         {!! ExpandedForm::text('revenue_account',$data['revenue_account']) !!} | ||||
|                     @endif | ||||
|  | ||||
|                     <!-- ONLY SHOW FROM/TO ACCOUNT WHEN CREATING TRANSFER --> | ||||
|                     @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 | ||||
|  | ||||
|                     <!-- ALWAYS SHOW AMOUNT --> | ||||
|                     {{Form::ffAmount('amount',$data['amount'],['currency' => $journal->transactionCurrency])}} | ||||
|                     {!! ExpandedForm::amount('amount',$data['amount'],['currency' => $journal->transactionCurrency]) !!} | ||||
|  | ||||
|                     <!-- ALWAYS SHOW DATE --> | ||||
|                     {{Form::ffDate('date',$data['date'])}} | ||||
|                     {!! ExpandedForm::date('date',$data['date']) !!} | ||||
|             </div> | ||||
|         </div> <!-- close panel --> | ||||
|  | ||||
| @@ -59,16 +61,16 @@ | ||||
|             <div class="panel-body"> | ||||
|                 <!-- BUDGET ONLY WHEN CREATING A WITHDRAWAL --> | ||||
|                 @if($what == 'withdrawal') | ||||
|                     {{Form::ffSelect('budget_id',$budgets,$data['budget_id'])}} | ||||
|                     {!! ExpandedForm::select('budget_id',$budgets,$data['budget_id']) !!} | ||||
|                 @endif | ||||
|                 <!-- CATEGORY ALWAYS --> | ||||
|                 {{Form::ffText('category',$data['category'])}} | ||||
|                 {!! ExpandedForm::text('category',$data['category']) !!} | ||||
|  | ||||
|                 <!-- TAGS --> | ||||
|  | ||||
|                 <!-- RELATE THIS TRANSFER TO A PIGGY BANK --> | ||||
|                 @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 | ||||
|                     </div> | ||||
|             </div><!-- end of panel for options--> | ||||
| @@ -79,18 +81,16 @@ | ||||
|                     <i class="fa fa-bolt"></i> Options | ||||
|                 </div> | ||||
|                 <div class="panel-body"> | ||||
|                     {{Form::ffOptionsList('update','transaction')}} | ||||
|                     {!! ExpandedForm::optionsList('update','transaction') !!} | ||||
|                 </div> | ||||
|             </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| {{Form::close()}} | ||||
| {!! Form::close() !!} | ||||
|  | ||||
|  | ||||
| @stop | ||||
| @section('scripts') | ||||
| {{HTML::script('assets/javascript/typeahead/bootstrap3-typeahead.min.js')}} | ||||
| {{HTML::script('assets/javascript/firefly/transactions.js')}} | ||||
| <script type="text/javascript" src="js/bootstrap3-typeahead.min.js"></script> | ||||
| <script type="text/javascript" src="js/transactions.js"></script> | ||||
| @stop | ||||
|   | ||||
		Reference in New Issue
	
	Block a user