Build some transaction handling.

This commit is contained in:
James Cole
2014-11-13 17:01:09 +01:00
parent 9e2f7af59b
commit 953d68c3a2
4 changed files with 156 additions and 50 deletions

View File

@@ -2,7 +2,6 @@
use FireflyIII\Exception\FireflyException; use FireflyIII\Exception\FireflyException;
use FireflyIII\Exception\NotImplementedException;
use Illuminate\Support\MessageBag; use Illuminate\Support\MessageBag;
/** /**
@@ -319,47 +318,51 @@ class TransactionController extends BaseController
*/ */
public function update(TransactionJournal $journal) public function update(TransactionJournal $journal)
{ {
throw new NotImplementedException; /** @var \FireflyIII\Database\TransactionJournal $repos */
// switch (Input::get('post_submit_action')) { $repos = App::make('FireflyIII\Database\TransactionJournal');
// case 'update':
// case 'return_to_edit': $data = Input::except('_token');
// $what = strtolower($journal->transactionType->type); $data['currency'] = 'EUR';
// $messageBag = $this->_helper->update($journal, Input::all()); $data['what'] = strtolower($journal->transactionType->type);
// if ($messageBag->count() == 0) {
// // has been saved, return to index:
// Session::flash('success', 'Transaction updated!'); switch (Input::get('post_submit_action')) {
// Event::fire('journals.update', [$journal]); case 'update':
// case 'return_to_edit':
// if (Input::get('post_submit_action') == 'return_to_edit') { $messageBag = $repos->update($journal, $data);
// return Redirect::route('transactions.edit', $journal->id)->withInput(); if ($messageBag->count() == 0) {
// } else { // has been saved, return to index:
// return Redirect::route('transactions.index.' . $what); Session::flash('success', 'Transaction updated!');
// } // Event::fire('journals.update', [$journal]);
// } else {
// Session::flash('error', 'Could not update transaction: ' . $journal->errors()->first()); if (Input::get('post_submit_action') == 'return_to_edit') {
// return Redirect::route('transactions.edit', $journal->id)->withInput();
// return Redirect::route('transactions.edit', $journal->id)->withInput()->withErrors( } else {
// $journal->errors() return Redirect::route('transactions.index', $data['what']);
// ); }
// } } else {
// Session::flash('error', 'Could not update transaction: ' . $journal->errors()->first());
// break;
// case 'validate_only': return Redirect::route('transactions.edit', $journal->id)->withInput()->withErrors(
// $data = Input::all(); $journal->errors()
// $data['what'] = strtolower($journal->transactionType->type); );
// $messageBags = $this->_helper->validate($data); }
//
// Session::flash('warnings', $messageBags['warnings']); break;
// Session::flash('successes', $messageBags['successes']); case 'validate_only':
// Session::flash('errors', $messageBags['errors']); $messageBags = $repos->validate($data);
//
// return Redirect::route('transactions.edit', $journal->id)->withInput(); Session::flash('warnings', $messageBags['warnings']);
// break; Session::flash('successes', $messageBags['successes']);
// default: Session::flash('errors', $messageBags['errors']);
// throw new FireflyException('Method ' . Input::get('post_submit_action') . ' not implemented yet.');
// break; return Redirect::route('transactions.edit', $journal->id)->withInput();
// } break;
// default:
throw new FireflyException('Method ' . Input::get('post_submit_action') . ' not implemented yet.');
break;
}
} }

View File

@@ -192,8 +192,8 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface
public function openingBalanceTransaction(\Account $account) public function openingBalanceTransaction(\Account $account)
{ {
return \TransactionJournal::withRelevantData()->accountIs($account)->leftJoin( return \TransactionJournal::withRelevantData()->accountIs($account)->leftJoin(
'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id' 'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id'
)->where('transaction_types.type', 'Opening balance')->first(['transaction_journals.*']); )->where('transaction_types.type', 'Opening balance')->first(['transaction_journals.*']);
} }
/** /**
@@ -469,4 +469,19 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface
return \Account::firstOrCreate($data); return \Account::firstOrCreate($data);
} }
public function firstRevenueAccountOrCreate($name)
{
/** @var \FireflyIII\Database\AccountType $accountTypeRepos */
$accountTypeRepos = \App::make('FireflyIII\Database\AccountType');
$accountType = $accountTypeRepos->findByWhat('revenue');
$data = ['user_id' => $this->getUser()->id, 'account_type_id' => $accountType->id, 'name' => $name, 'active' => 1];
return \Account::firstOrCreate($data);
}
} }

View File

@@ -92,6 +92,14 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData
break; break;
case 'opening': case 'opening':
break; break;
case 'deposit':
$data['to'] = $accountRepository->find($data['account_id']);
$data['from'] = $accountRepository->firstRevenueAccountOrCreate($data['revenue_account']);
break;
case 'transfer':
$data['from'] = $accountRepository->find($data['account_from_id']);
$data['to'] = $accountRepository->find($data['account_to_id']);
break;
default: default:
throw new FireflyException('Cannot save transaction journal with accounts based on $what "' . $data['what'] . '".'); throw new FireflyException('Cannot save transaction journal with accounts based on $what "' . $data['what'] . '".');
@@ -118,6 +126,10 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData
throw new FireflyException($validate['errors']->first()); throw new FireflyException($validate['errors']->first());
} }
/*
* TODO store budget and category.
*/
$journal->completed = 1; $journal->completed = 1;
$journal->save(); $journal->save();
@@ -132,8 +144,81 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData
*/ */
public function update(Ardent $model, array $data) public function update(Ardent $model, array $data)
{ {
// TODO: Implement update() method. var_dump($data);
throw new NotImplementedException; /** @var \FireflyIII\Database\TransactionType $typeRepository */
$typeRepository = \App::make('FireflyIII\Database\TransactionType');
/** @var \FireflyIII\Database\Account $accountRepository */
$accountRepository = \App::make('FireflyIII\Database\Account');
/** @var \FireflyIII\Database\TransactionCurrency $currencyRepository */
$currencyRepository = \App::make('FireflyIII\Database\TransactionCurrency');
/** @var \FireflyIII\Database\Transaction $transactionRepository */
$transactionRepository = \App::make('FireflyIII\Database\Transaction');
$journalType = $typeRepository->findByWhat($data['what']);
$currency = $currencyRepository->findByCode($data['currency']);
$model->transactionType()->associate($journalType);
$model->transactionCurrency()->associate($currency);
$model->user()->associate($this->getUser());
$model->description = $data['description'];
$model->date = $data['date'];
/*
* This must be enough to store the journal:
*/
if (!$model->validate()) {
\Log::error($model->errors()->all());
throw new FireflyException('store() transaction journal failed, but it should not!');
}
$model->save();
/*
* Still need to find the accounts related to the transactions.
* This depends on the type of transaction.
*/
switch ($data['what']) {
case 'withdrawal':
$data['from'] = $accountRepository->find($data['account_id']);
$data['to'] = $accountRepository->firstExpenseAccountOrCreate($data['expense_account']);
break;
case 'opening':
break;
case 'deposit':
$data['to'] = $accountRepository->find($data['account_id']);
$data['from'] = $accountRepository->firstRevenueAccountOrCreate($data['revenue_account']);
break;
case 'transfer':
$data['from'] = $accountRepository->find($data['account_from_id']);
$data['to'] = $accountRepository->find($data['account_to_id']);
break;
default:
throw new FireflyException('Cannot save transaction journal with accounts based on $what "' . $data['what'] . '".');
break;
}
/*
* Now we can update the transactions related to this journal.
*/
$amount = floatval($data['amount']);
/** @var \Transaction $transaction */
foreach ($model->transactions()->get() as $transaction) {
if (floatval($transaction->amount) > 0) {
// the TO transaction.
$transaction->account()->associate($data['to']);
$transaction->amount = $amount;
} else {
$transaction->account()->associate($data['from']);
$transaction->amount = $amount * -1;
}
if (!$transaction->validate()) {
throw new FireflyException('Could not validate transaction while saving.');
}
$transaction->save();
}
return new MessageBag;
} }
/** /**
@@ -391,8 +476,8 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData
$sum = \DB::table('transactions')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->leftJoin( $sum = \DB::table('transactions')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->leftJoin(
'transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id' 'transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id'
)->where('amount', '>', 0)->where('transaction_types.type', '=', 'Withdrawal')->where('transaction_journals.date', '>=', $date->format('Y-m-d'))->where( )->where('amount', '>', 0)->where('transaction_types.type', '=', 'Withdrawal')->where('transaction_journals.date', '>=', $date->format('Y-m-d'))->where(
'transaction_journals.date', '<=', $end->format('Y-m-d') 'transaction_journals.date', '<=', $end->format('Y-m-d')
)->sum('transactions.amount'); )->sum('transactions.amount');
$sum = floatval($sum); $sum = floatval($sum);
return $sum; return $sum;
@@ -412,8 +497,8 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData
$sum = \DB::table('transactions')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->leftJoin( $sum = \DB::table('transactions')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->leftJoin(
'transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id' 'transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id'
)->where('amount', '>', 0)->where('transaction_types.type', '=', 'Deposit')->where('transaction_journals.date', '>=', $date->format('Y-m-d'))->where( )->where('amount', '>', 0)->where('transaction_types.type', '=', 'Deposit')->where('transaction_journals.date', '>=', $date->format('Y-m-d'))->where(
'transaction_journals.date', '<=', $end->format('Y-m-d') 'transaction_journals.date', '<=', $end->format('Y-m-d')
)->sum('transactions.amount'); )->sum('transactions.amount');
$sum = floatval($sum); $sum = floatval($sum);
return $sum; return $sum;

View File

@@ -113,6 +113,9 @@ class TransactionType implements TransactionTypeInterface, CUD, CommonDatabaseCa
case 'withdrawal': case 'withdrawal':
return \TransactionType::whereType('Withdrawal')->first(); return \TransactionType::whereType('Withdrawal')->first();
break; break;
case 'deposit':
return \TransactionType::whereType('Deposit')->first();
break;
default: default:
throw new FireflyException('Cannot find transaction type described as "' . e($what) . '".'); throw new FireflyException('Cannot find transaction type described as "' . e($what) . '".');
break; break;