Update and create transactions.

This commit is contained in:
James Cole 2015-02-27 14:27:04 +01:00
parent e685d262cc
commit 75aa3abcae
6 changed files with 299 additions and 34 deletions

View File

@ -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']);
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -13,11 +13,14 @@ use Illuminate\Support\Collection;
interface JournalRepositoryInterface
{
/**
* @param array $data
*
* @return TransactionJournal
* Get the account_id, which is the asset account that paid for the transaction.
*
* @param TransactionJournal $journal
*
* @return int
*/
public function store(array $data);
public function getAssetAccount(TransactionJournal $journal);
/**
* @param string $query
@ -26,4 +29,19 @@ interface JournalRepositoryInterface
* @return Collection
*/
public function searchRelated($query, TransactionJournal $journal);
/**
* @param array $data
*
* @return TransactionJournal
*/
public function store(array $data);
/**
* @param TransactionJournal $journal
* @param array $data
*
* @return mixed
*/
public function update(TransactionJournal $journal, array $data);
}

View File

@ -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

View File

@ -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