Now with the added capability of adding money to a piggy bank from a transfer. Also various fixes (see issue #6). [skip ci]

This commit is contained in:
James Cole
2014-08-16 12:13:50 +02:00
parent 7c57ce8504
commit d645a38aec
13 changed files with 239 additions and 211 deletions

View File

@@ -6,6 +6,7 @@ use Firefly\Storage\Piggybank\PiggybankRepositoryInterface as PRI;
/**
* Class PiggybankController
*
*/
class PiggybankController extends BaseController
{
@@ -63,7 +64,6 @@ class PiggybankController extends BaseController
*/
public function destroy(Piggybank $piggyBank)
{
// TODO move to repository.
$this->_repository->destroy($piggyBank);
Event::fire('piggybanks.change');
Session::flash('success', 'Piggy bank deleted.');
@@ -96,9 +96,9 @@ class PiggybankController extends BaseController
*/
public function index()
{
Event::fire('piggybanks.change');
$countRepeating = $this->_repository->countRepeating();
$countNonRepeating = $this->_repository->countNonrepeating();
Event::fire('piggybanks.change'); // TODO remove
$piggybanks = $this->_repository->get();
return View::make('piggybanks.index')->with('piggybanks', $piggybanks)
@@ -111,7 +111,6 @@ class PiggybankController extends BaseController
*/
public function show(Piggybank $piggyBank)
{
Event::fire('piggybanks.change'); // TODO remove
return View::make('piggybanks.show')->with('piggyBank', $piggyBank);
}
@@ -159,7 +158,7 @@ class PiggybankController extends BaseController
$data['order'] = 0;
$piggyBank = $this->_repository->store($data);
if ($piggyBank->validate()) {
if ($piggyBank->id) {
Session::flash('success', 'New piggy bank "' . $piggyBank->name . '" created!');
Event::fire('piggybanks.change');

View File

@@ -37,10 +37,15 @@ class TransactionController extends BaseController
$budgets = $budgetRepository->getAsSelectList();
$budgets[0] = '(no budget)';
// get the number of piggy banks.
/** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface $piggyRepository */
$piggyRepository = App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface');
$piggies = $piggyRepository->get();
return View::make('transactions.create')->with('accounts', $accounts)->with('budgets', $budgets)->with(
'what', $what
);
)->with('piggies',$piggies);
}
/**

View File

@@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint;
class CreateTransactionsTable extends Migration
{
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('transactions');
}
/**
* Run the migrations.
*
@@ -23,6 +33,7 @@ class CreateTransactionsTable extends Migration
$table->increments('id');
$table->timestamps();
$table->integer('account_id')->unsigned();
$table->integer('piggybank_id')->nullable()->unsigned();
$table->integer('transaction_journal_id')->unsigned();
$table->string('description', 255)->nullable();
$table->decimal('amount', 10, 2);
@@ -32,6 +43,11 @@ class CreateTransactionsTable extends Migration
->references('id')->on('transaction_journals')
->onDelete('cascade');
// connect piggy banks
$table->foreign('piggybank_id')
->references('id')->on('piggybanks')
->onDelete('set null');
// connect account id:
$table->foreign('account_id')
->references('id')->on('accounts')
@@ -41,14 +57,4 @@ class CreateTransactionsTable extends Migration
);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('transactions');
}
}

View File

@@ -1,9 +1,10 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreatePiggyInstance extends Migration {
class CreatePiggyInstance extends Migration
{
/**
* Run the migrations.
@@ -12,22 +13,23 @@ class CreatePiggyInstance extends Migration {
*/
public function up()
{
Schema::create('piggybank_repetitions', function(Blueprint $table)
{
Schema::create(
'piggybank_repetitions', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->integer('piggybank_id')->unsigned();
$table->date('startdate')->nullable();
$table->date('targetdate')->nullable();
$table->decimal('currentamount',10,2);
$table->decimal('currentamount', 10, 2);
$table->unique(['piggybank_id','startdate','targetdate']);
$table->unique(['piggybank_id', 'startdate', 'targetdate']);
// connect instance to piggybank.
$table->foreign('piggybank_id')
->references('id')->on('piggybanks')
->onDelete('cascade');
});
}
);
}
/**

View File

@@ -114,6 +114,8 @@ class Chart implements ChartInterface
$q->where('startdate', $start->format('Y-m-d'));
}]
)->orderBy('name', 'ASC')->get();
$limitInPeriod = '';
$spentInPeriod = '';
foreach ($budgets as $budget) {
$budget->count = 0;

View File

@@ -16,6 +16,9 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface
*/
public function createOrFind($name)
{
if(strlen($name) == 0) {
return null;
}
$category = $this->findByName($name);
if (!$category) {
return $this->store(['name' => $name]);
@@ -55,7 +58,7 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface
*/
public function findByName($name)
{
if ($name == '') {
if ($name == '' || strlen($name) == 0) {
return null;
}

View File

@@ -163,20 +163,15 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
$piggy->startdate
= isset($data['startdate']) && strlen($data['startdate']) > 0 ? new Carbon($data['startdate']) : null;
// everything we can update for NON repeating piggy banks:
if ($piggy->repeats == 0) {
// if non-repeating there is only one PiggyBank instance and we can delete it safely.
// it will be recreated.
$piggy->piggybankrepetitions()->first()->delete();
} else {
// we can delete all of them, because reasons
foreach ($piggy->piggybankrepetitions()->get() as $rep) {
$rep->delete();
}
if ($piggy->repeats == 1) {
$piggy->rep_every = intval($data['rep_every']);
$piggy->rep_length = $data['rep_length'];
}
if ($piggy->validate()) {
// check the things we check for new piggies
$piggy->save();

View File

@@ -287,6 +287,8 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
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:
@@ -310,6 +312,39 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
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');
if (isset($data['piggybank_id'])) {
/** @var \Piggybank $piggyBank */
$piggyBank = $piggyRepository->find(intval($data['piggybank_id']));
if ($piggyBank) {
if ($toAccount->id == $piggyBank->account_id) {
// find the transaction connected to the $toAccount:
/** @var \Transaction $transaction */
$transaction
= $transactionJournal->transactions()->where('account_id', $toAccount->id)->first();
// connect the piggy to it:
$transaction->piggybank()->associate($piggyBank);
$transaction->save();
} else {
\Session::flash(
'warning',
'Piggy bank "' . e($piggyBank->name) . '" is not set to draw money from account "' . e(
$toAccount->name
) . '", so the money isn\'t added to the piggy bank.'
);
}
}
}
}
// attach:
if (!is_null($budget)) {
$transactionJournal->budgets()->save($budget);
@@ -390,10 +425,13 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
break;
case 'Transfer':
// means transaction[0] is account that sent the money (from).
/** @var \Account $fromAccount */
$fromAccount = $accountRepository->find($data['account_from_id']);
/** @var \Account $toAccount */
$toAccount = $accountRepository->find($data['account_to_id']);
$journal->transactions[0]->account()->associate($fromAccount);
$journal->transactions[1]->account()->associate($toAccount);
break;
default:
throw new FireflyException('Cannot edit this!');

View File

@@ -45,6 +45,24 @@ class EloquentPiggybankTrigger
} catch (QueryException $e) {
}
}
// whatever we did here, we now have all repetitions for this
// piggy bank, and we can find transactions that fall within
// that repetition (to fix the "saved amount".
$reps = $piggy->piggybankrepetitions()->get();
/** @var \PiggybankRepetition $rep */
foreach ($reps as $rep) {
$sum = \Transaction::where('piggybank_id', $piggy->id)->leftJoin(
'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
)->where('transaction_journals.date', '>=', $rep->startdate->format('Y-m-d'))->where(
'transaction_journals.date', '<=', $rep->targetdate->format('Y-m-d')
)->sum('transactions.amount');
$rep->currentamount = floatval($sum);
$rep->save();
}
}
unset($piggy, $piggybanks, $rep);
@@ -59,14 +77,8 @@ class EloquentPiggybankTrigger
$rep->targetdate = $repeated->targetdate;
$rep->currentamount = 0;
try {
\Log::debug(
'Creating initial rep ('.$repeated->name.') (from ' . ($rep->startdate ? $rep->startdate->format('d-m-Y')
: 'NULL') . ' to '
. ($rep->targetdate ? $rep->targetdate->format('d-m-Y') : 'NULL') . ')'
);
$rep->save();
} catch (QueryException $e) {
\Log::error('FAILED initital repetition.');
}
unset($rep);
@@ -109,6 +121,19 @@ class EloquentPiggybankTrigger
}
}
}
$reps = $repeated->piggybankrepetitions()->get();
/** @var \PiggybankRepetition $rep */
foreach ($reps as $rep) {
$sum = \Transaction::where('piggybank_id', $repeated->id)->leftJoin(
'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
)->where('transaction_journals.date', '>=', $rep->startdate->format('Y-m-d'))->where(
'transaction_journals.date', '<=', $rep->targetdate->format('Y-m-d')
)->sum('transactions.amount');
$rep->currentamount = floatval($sum);
$rep->save();
}
}
}
}

View File

@@ -52,22 +52,6 @@ class Transaction extends Ardent
return $this->belongsTo('Account');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function transactionJournal()
{
return $this->belongsTo('TransactionJournal');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function components()
{
return $this->belongsToMany('Component');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
@@ -83,4 +67,28 @@ class Transaction extends Ardent
{
return $this->belongsToMany('Category', 'component_transaction', 'transaction_id', 'component_id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function components()
{
return $this->belongsToMany('Component');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function piggybank()
{
return $this->belongsTo('Piggybank');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function transactionJournal()
{
return $this->belongsTo('TransactionJournal');
}
}

View File

@@ -3,91 +3,6 @@
use LaravelBook\Ardent\Ardent;
/**
* TransactionJournal
*
* @property integer $id
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
* @property integer $transaction_type_id
* @property integer $transaction_currency_id
* @property string $description
* @property boolean $completed
* @property \Carbon\Carbon $date
* @property-read \TransactionType $transactionType
* @property-read \TransactionCurrency $transactionCurrency
* @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions
* @property-read \Illuminate\Database\Eloquent\Collection|\Component[] $components
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereId($value)
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereCreatedAt($value)
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereUpdatedAt($value)
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereTransactionTypeId($value)
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereTransactionCurrencyId($value)
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereDescription($value)
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereCompleted($value)
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereDate($value)
* @method static \TransactionJournal after($date)
* @method static \TransactionJournal before($date)
* @property integer $user_id
* @property-read \User $user
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereUserId($value)
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Budget[] $budgets
* @property-read \Illuminate\Database\Eloquent\Collection|\
* 'Category[] $categories
*/
class TransactionJournal extends Ardent
{
@@ -117,49 +32,6 @@ class TransactionJournal extends Ardent
];
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function transactionType()
{
return $this->belongsTo('TransactionType');
}
/**
* User
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('User');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function transactionCurrency()
{
return $this->belongsTo('TransactionCurrency');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function transactions()
{
return $this->hasMany('Transaction');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function components()
{
return $this->belongsToMany('Component');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
@@ -180,6 +52,14 @@ class TransactionJournal extends Ardent
);
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function components()
{
return $this->belongsToMany('Component');
}
/**
* @return array
*/
@@ -210,4 +90,38 @@ class TransactionJournal extends Ardent
return $query->where('date', '<=', $date->format('Y-m-d'));
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function transactionCurrency()
{
return $this->belongsTo('TransactionCurrency');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function transactionType()
{
return $this->belongsTo('TransactionType');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function transactions()
{
return $this->hasMany('Transaction');
}
/**
* User
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('User');
}
}

View File

@@ -175,6 +175,37 @@
</div>
</div>
<!-- RELATE THIS TRANSFER TO A PIGGY BANK -->
@if($what == 'transfer' && count($piggies) > 0)
<div class="form-group">
<label for="piggybank_id" class="col-sm-4 control-label">
Piggy bank
</label>
<div class="col-sm-8">
<select name="piggybank_id" class="form-control">
<option value="0" label="(no piggy bank)">(no piggy bank)</option>
@foreach($piggies as $piggy)
@if($piggy->id == Input::old('piggybank_id'))
<option value="{{$piggy->id}}" label="{{{$piggy->name}}}" selected="selected ">{{{$piggy->name}}}</option>
@else
<option value="{{$piggy->id}}" label="{{{$piggy->name}}}">{{{$piggy->name}}}</option>
@endif
@endforeach
</select>
@if($errors->has('piggybank_id'))
<p class="text-danger">{{$errors->first('piggybank_id')}}</p>
@else
<span class="help-block">
You can directly add the amount you're transferring
to one of your piggy banks, provided they are related to the account your
transferring <em>to</em>.
</span>
@endif
</div>
</div>
@endif
</div>
</div>