Fixed some problems with creating piggy bank repetitions.

This commit is contained in:
James Cole
2014-08-21 15:14:46 +02:00
parent 22bd995b42
commit b5a706152d
6 changed files with 106 additions and 89 deletions

View File

@@ -10,7 +10,8 @@ class BaseController extends Controller
* *
*/ */
public function __construct() { public function __construct() {
Event::fire('limits.check'); \Event::fire('limits.check');
\Event::fire('piggybanks.check');
} }
/** /**
* Setup the layout used by the controller. * Setup the layout used by the controller.

View File

@@ -137,6 +137,10 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
$piggyBank = new \Piggybank($data); $piggyBank = new \Piggybank($data);
if($piggyBank->repeats && !isset($data['targetdate'])) {
$piggyBank->errors()->add('targetdate','Target date is mandatory!');
return $piggyBank;
}
if (!is_null($account)) { if (!is_null($account)) {
$piggyBank->account()->associate($account); $piggyBank->account()->associate($account);
} }

View File

@@ -30,8 +30,6 @@ class EloquentLimitTrigger
/** @var \Limit $limit */ /** @var \Limit $limit */
foreach ($limits as $limit) { foreach ($limits as $limit) {
/** @var \Budget $budget */
$budget = $limit->budget()->first();
// the limit repeats, and there should be at least one repetition already. // the limit repeats, and there should be at least one repetition already.
/** @var \LimitRepetition $primer */ /** @var \LimitRepetition $primer */
$primer = $limit->limitrepetitions()->orderBy('startdate', 'DESC')->first(); $primer = $limit->limitrepetitions()->orderBy('startdate', 'DESC')->first();

View File

@@ -21,7 +21,8 @@ class EloquentPiggybankTrigger
*/ */
public function createRelatedTransfer( public function createRelatedTransfer(
\Piggybank $piggyBank, \TransactionJournal $journal, \Transaction $transaction \Piggybank $piggyBank, \TransactionJournal $journal, \Transaction $transaction
) { )
{
$repetition = $piggyBank->repetitionForDate($journal->date); $repetition = $piggyBank->repetitionForDate($journal->date);
if (!is_null($repetition)) { if (!is_null($repetition)) {
// get the amount transferred TO this // get the amount transferred TO this
@@ -88,6 +89,8 @@ class EloquentPiggybankTrigger
*/ */
public function storePiggy(\Piggybank $piggyBank) public function storePiggy(\Piggybank $piggyBank)
{ {
$piggyBank->createRepetition($piggyBank->startdate, $piggyBank->targetdate);
return true;
$rep = new \PiggybankRepetition; $rep = new \PiggybankRepetition;
$rep->piggybank()->associate($piggyBank); $rep->piggybank()->associate($piggyBank);
$rep->targetdate = $piggyBank->targetdate; $rep->targetdate = $piggyBank->targetdate;
@@ -100,59 +103,85 @@ class EloquentPiggybankTrigger
} }
/** /**
* Validates and creates all repetitions for repeating piggy banks.
* This routine is also called whenever Firefly runs, so new repetitions
* are created automatically.
*
* @param \Piggybank $piggyBank * @param \Piggybank $piggyBank
* *
* @return bool * @return bool
*/ */
public function storeRepeated(\Piggybank $piggyBank) public function storeRepeated(\Piggybank $piggyBank)
{ {
// loop from start to today or something $piggyBank->createRepetition($piggyBank->startdate, $piggyBank->targetdate);
$rep = new \PiggybankRepetition;
$rep->piggybank()->associate($piggyBank);
$rep->startdate = $piggyBank->startdate;
$rep->targetdate = $piggyBank->targetdate;
$rep->currentamount = 0;
$rep->save();
unset($rep);
$today = new Carbon;
if ($piggyBank->targetdate <= $today) {
// add 1 month to startdate, or maybe X period, like 3 weeks.
$startTarget = clone $piggyBank->targetdate;
while ($startTarget <= $today) {
$startCurrent = clone $startTarget;
// add some kind of period to start current making $endCurrent.
$endCurrent = clone $startCurrent;
switch ($piggyBank->rep_length) {
default:
return true; return true;
break; }
/**
*
*/
public function checkRepeatingPiggies()
{
if (\Auth::check()) {
$piggies = \Auth::user()->piggybanks()->whereNotNull('repeats')->get();
} else {
$piggies = [];
}
\Log::debug('Now in checkRepeatingPiggies with ' . count($piggies) . ' piggies');
/** @var \Piggybank $piggyBank */
foreach ($piggies as $piggyBank) {
\Log::debug('Now working on ' . $piggyBank->name);
// get the latest repetition, see if we need to "append" more:
/** @var \PiggybankRepetition $primer */
$primer = $piggyBank->piggybankrepetitions()->orderBy('targetdate', 'DESC')->first();
\Log::debug('Last target date is: ' . $primer->targetdate);
// for repeating piggy banks, the target date is mandatory:
$today = new Carbon;
$end = clone $primer->targetdate;
// the next repetition must be created starting at the day after the target date:
$start = clone $primer->targetdate;
$start->addDay();
while ($start <= $today) {
\Log::debug('Looping! Start is: ' . $start);
// to get to the end of the current repetition, we switch on the piggy bank's
// repetition period:
$end = clone $start;
switch ($piggyBank->rep_length) {
case 'day': case 'day':
$endCurrent->addDays($piggyBank->rep_every); $end->addDays($piggyBank->rep_every);
break; break;
case 'week': case 'week':
$endCurrent->addWeeks($piggyBank->rep_every); $end->addWeeks($piggyBank->rep_every);
break; break;
case 'month': case 'month':
$endCurrent->addMonths($piggyBank->rep_every); $end->addMonths($piggyBank->rep_every);
break; break;
case 'year': case 'year':
$endCurrent->addYears($piggyBank->rep_every); $end->addYears($piggyBank->rep_every);
break; break;
} }
$end->subDay();
// create repetition:
$piggyBank->createRepetition($start, $end);
$start = clone $end;
$start->addDay();
$rep = new \PiggybankRepetition;
$rep->piggybank()->associate($piggyBank);
$rep->startdate = $startCurrent;
$rep->targetdate = $endCurrent;
$rep->currentamount = 0;
$startTarget = $endCurrent;
$rep->save();
}
} }
return true; }
} }
/** /**
@@ -181,6 +210,7 @@ class EloquentPiggybankTrigger
'piggybanks.updateRelatedTransfer', 'piggybanks.updateRelatedTransfer',
'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@updateRelatedTransfer' 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@updateRelatedTransfer'
); );
$events->listen('piggybanks.check', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@checkRepeatingPiggies');
} }
public function update(\Piggybank $piggyBank) public function update(\Piggybank $piggyBank)

View File

@@ -49,7 +49,7 @@ class Piggybank extends Ardent
'targetamount' => 'required|min:0', // amount you want to save 'targetamount' => 'required|min:0', // amount you want to save
'startdate' => 'date', // when you started 'startdate' => 'date', // when you started
'targetdate' => 'date', // when its due 'targetdate' => 'date', // when its due
'repeats' => 'required|between:0,1', // does it repeat? 'repeats' => 'required|boolean', // does it repeat?
'rep_length' => 'in:day,week,month,year', // how long is the period? 'rep_length' => 'in:day,week,month,year', // how long is the period?
'rep_every' => 'required|min:1|max:100', // how often does it repeat? every 3 years. 'rep_every' => 'required|min:1|max:100', // how often does it repeat? every 3 years.
'rep_times' => 'min:1|max:100', // how many times do you want to save this amount? eg. 3 times 'rep_times' => 'min:1|max:100', // how many times do you want to save this amount? eg. 3 times
@@ -73,32 +73,6 @@ class Piggybank extends Ardent
'order' 'order'
]; ];
/**
* @return array
*/
public static function factory()
{
$start = new Carbon;
$start->startOfMonth();
$end = new Carbon;
$end->endOfMonth();
return [
'account_id' => 'factory|Account',
'name' => 'string',
'targetamount' => 'integer',
'startdate' => $start->format('Y-m-d'),
'targetdate' => $end->format('Y-m-d'),
'repeats' => 0,
'rep_length' => null,
'rep_times' => 0,
'rep_every' => 0,
'reminder' => null,
'reminder_skip' => 0,
'order' => 1,
];
}
/** /**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/ */
@@ -107,6 +81,16 @@ class Piggybank extends Ardent
return $this->belongsTo('Account'); return $this->belongsTo('Account');
} }
public function createRepetition(Carbon $start = null, Carbon $target = null) {
$rep = new \PiggybankRepetition;
$rep->piggybank()->associate($this);
$rep->startdate = $start;
$rep->targetdate = $target;
$rep->currentamount = 0;
$rep->save();
return $rep;
}
/** /**
* @return array * @return array
*/ */

View File

@@ -97,40 +97,40 @@
@if($repeated->repeats == 1) @if($repeated->repeats == 1)
<!-- display repeated expense --> <!-- display repeated expense -->
<tr><td> <tr><td>
<h4><a href="{{route('piggybanks.show',$repeated->id)}}">{{{$repeated->name}}}</a><small> <span class="label label-default">{{$piggyBank->currentRelevantRep()->pct()}}%</span></small></h4> <h4><a href="{{route('piggybanks.show',$repeated->id)}}">{{{$repeated->name}}}</a><small> <span class="label label-default">{{$repeated->currentRelevantRep()->pct()}}%</span></small></h4>
<p> <p>
<!-- target amount --> <!-- target amount -->
Saving up to {{mf($repeated->targetamount)}}. Saving up to {{mf($repeated->targetamount)}}.
<!-- currently saved --> <!-- currently saved -->
Currently saved Currently saved
{{mf($piggyBank->currentRelevantRep()->currentamount)}}. {{mf($repeated->currentRelevantRep()->currentamount)}}.
<!-- start date (if any) --> <!-- start date (if any) -->
@if(!is_null($piggyBank->startdate)) @if(!is_null($repeated->startdate))
Start date: {{$piggyBank->currentRelevantRep()->startdate->format('d M Y')}}. Start date: {{$repeated->currentRelevantRep()->startdate->format('d M Y')}}.
@endif @endif
<!-- target date (if any) --> <!-- target date (if any) -->
@if(!is_null($piggyBank->targetdate)) @if(!is_null($repeated->targetdate))
Target date: {{$piggyBank->currentRelevantRep()->targetdate->format('d M Y')}}. Target date: {{$repeated->currentRelevantRep()->targetdate->format('d M Y')}}.
@endif @endif
@if(!is_null($piggyBank->reminder)) @if(!is_null($repeated->reminder))
Next reminder: {{$piggyBank->nextReminderDate()->format('d M Y')}} Next reminder: {{$repeated->nextReminderDate()->format('d M Y')}}
@endif @endif
</p> </p>
<div class="btn-group btn-group-sm"> <div class="btn-group btn-group-sm">
<a href="{{route('piggybanks.edit',$piggyBank->id)}}" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span></a> <a href="{{route('piggybanks.edit',$repeated->id)}}" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span></a>
@if($piggyBank->leftInAccount > 0) @if($repeated->leftInAccount > 0)
<a data-toggle="modal" href="{{route('piggybanks.amount.add',$piggyBank->id)}}" data-target="#modal" class="btn btn-default"><span class="glyphicon glyphicon-plus-sign"></span> Add money</a> <a data-toggle="modal" href="{{route('piggybanks.amount.add',$repeated->id)}}" data-target="#modal" class="btn btn-default"><span class="glyphicon glyphicon-plus-sign"></span> Add money</a>
@endif @endif
@if($piggyBank->currentRelevantRep()->currentamount > 0) @if($repeated->currentRelevantRep()->currentamount > 0)
<a data-toggle="modal" href="{{route('piggybanks.amount.remove',$piggyBank->id)}}" data-target="#modal" class="btn btn-default"><span class="glyphicon glyphicon-minus-sign"></span> Remove money</a> <a data-toggle="modal" href="{{route('piggybanks.amount.remove',$repeated->id)}}" data-target="#modal" class="btn btn-default"><span class="glyphicon glyphicon-minus-sign"></span> Remove money</a>
@endif @endif
<a href="{{route('piggybanks.delete',$piggyBank->id)}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span></a> <a href="{{route('piggybanks.delete',$repeated->id)}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span></a>
</div> </div>
</td></tr> </td></tr>