diff --git a/app/controllers/BaseController.php b/app/controllers/BaseController.php index 2fbda0cb97..418082a7d6 100644 --- a/app/controllers/BaseController.php +++ b/app/controllers/BaseController.php @@ -10,7 +10,8 @@ class BaseController extends Controller * */ public function __construct() { - Event::fire('limits.check'); + \Event::fire('limits.check'); + \Event::fire('piggybanks.check'); } /** * Setup the layout used by the controller. diff --git a/app/lib/Firefly/Storage/Piggybank/EloquentPiggybankRepository.php b/app/lib/Firefly/Storage/Piggybank/EloquentPiggybankRepository.php index 7daf85d7f8..7adc705f7a 100644 --- a/app/lib/Firefly/Storage/Piggybank/EloquentPiggybankRepository.php +++ b/app/lib/Firefly/Storage/Piggybank/EloquentPiggybankRepository.php @@ -137,6 +137,10 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface $piggyBank = new \Piggybank($data); + if($piggyBank->repeats && !isset($data['targetdate'])) { + $piggyBank->errors()->add('targetdate','Target date is mandatory!'); + return $piggyBank; + } if (!is_null($account)) { $piggyBank->account()->associate($account); } diff --git a/app/lib/Firefly/Trigger/Limits/EloquentLimitTrigger.php b/app/lib/Firefly/Trigger/Limits/EloquentLimitTrigger.php index feeac60173..c63bfab92c 100644 --- a/app/lib/Firefly/Trigger/Limits/EloquentLimitTrigger.php +++ b/app/lib/Firefly/Trigger/Limits/EloquentLimitTrigger.php @@ -30,8 +30,6 @@ class EloquentLimitTrigger /** @var \Limit $limit */ foreach ($limits as $limit) { - /** @var \Budget $budget */ - $budget = $limit->budget()->first(); // the limit repeats, and there should be at least one repetition already. /** @var \LimitRepetition $primer */ $primer = $limit->limitrepetitions()->orderBy('startdate', 'DESC')->first(); diff --git a/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php b/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php index 4b4475e324..95db4cb542 100644 --- a/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php +++ b/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php @@ -13,15 +13,16 @@ use Illuminate\Events\Dispatcher; class EloquentPiggybankTrigger { /** - * @param \Piggybank $piggyBank + * @param \Piggybank $piggyBank * @param \TransactionJournal $journal - * @param \Transaction $transaction + * @param \Transaction $transaction * * @return bool */ public function createRelatedTransfer( \Piggybank $piggyBank, \TransactionJournal $journal, \Transaction $transaction - ) { + ) + { $repetition = $piggyBank->repetitionForDate($journal->date); if (!is_null($repetition)) { // get the amount transferred TO this @@ -88,6 +89,8 @@ class EloquentPiggybankTrigger */ public function storePiggy(\Piggybank $piggyBank) { + $piggyBank->createRepetition($piggyBank->startdate, $piggyBank->targetdate); + return true; $rep = new \PiggybankRepetition; $rep->piggybank()->associate($piggyBank); $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 * * @return bool */ public function storeRepeated(\Piggybank $piggyBank) { - // loop from start to today or something - $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; + $piggyBank->createRepetition($piggyBank->startdate, $piggyBank->targetdate); + return true; + } - 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; - break; - case 'day': - $endCurrent->addDays($piggyBank->rep_every); - break; - case 'week': - $endCurrent->addWeeks($piggyBank->rep_every); - break; - case 'month': - $endCurrent->addMonths($piggyBank->rep_every); - break; - case 'year': - $endCurrent->addYears($piggyBank->rep_every); - break; - } + /** + * + */ + public function checkRepeatingPiggies() + { - $rep = new \PiggybankRepetition; - $rep->piggybank()->associate($piggyBank); - $rep->startdate = $startCurrent; - $rep->targetdate = $endCurrent; - $rep->currentamount = 0; - $startTarget = $endCurrent; - $rep->save(); - } + if (\Auth::check()) { + $piggies = \Auth::user()->piggybanks()->whereNotNull('repeats')->get(); + } else { + $piggies = []; } - return true; + \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': + $end->addDays($piggyBank->rep_every); + break; + case 'week': + $end->addWeeks($piggyBank->rep_every); + break; + case 'month': + $end->addMonths($piggyBank->rep_every); + break; + case 'year': + $end->addYears($piggyBank->rep_every); + break; + } + $end->subDay(); + + // create repetition: + $piggyBank->createRepetition($start, $end); + + $start = clone $end; + $start->addDay(); + + + } + + } } /** @@ -181,6 +210,7 @@ class EloquentPiggybankTrigger 'piggybanks.updateRelatedTransfer', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@updateRelatedTransfer' ); + $events->listen('piggybanks.check', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@checkRepeatingPiggies'); } public function update(\Piggybank $piggyBank) diff --git a/app/models/Piggybank.php b/app/models/Piggybank.php index fbfe7a936e..191a6870a1 100644 --- a/app/models/Piggybank.php +++ b/app/models/Piggybank.php @@ -49,7 +49,7 @@ class Piggybank extends Ardent 'targetamount' => 'required|min:0', // amount you want to save 'startdate' => 'date', // when you started '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_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 @@ -73,32 +73,6 @@ class Piggybank extends Ardent '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 */ @@ -107,6 +81,16 @@ class Piggybank extends Ardent 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 */ diff --git a/app/views/piggybanks/index.blade.php b/app/views/piggybanks/index.blade.php index a29a60f0e7..ff594f1ca3 100644 --- a/app/views/piggybanks/index.blade.php +++ b/app/views/piggybanks/index.blade.php @@ -97,40 +97,40 @@ @if($repeated->repeats == 1)
Saving up to {{mf($repeated->targetamount)}}. Currently saved - {{mf($piggyBank->currentRelevantRep()->currentamount)}}. + {{mf($repeated->currentRelevantRep()->currentamount)}}. - @if(!is_null($piggyBank->startdate)) - Start date: {{$piggyBank->currentRelevantRep()->startdate->format('d M Y')}}. + @if(!is_null($repeated->startdate)) + Start date: {{$repeated->currentRelevantRep()->startdate->format('d M Y')}}. @endif - @if(!is_null($piggyBank->targetdate)) - Target date: {{$piggyBank->currentRelevantRep()->targetdate->format('d M Y')}}. + @if(!is_null($repeated->targetdate)) + Target date: {{$repeated->currentRelevantRep()->targetdate->format('d M Y')}}. @endif - @if(!is_null($piggyBank->reminder)) - Next reminder: {{$piggyBank->nextReminderDate()->format('d M Y')}} + @if(!is_null($repeated->reminder)) + Next reminder: {{$repeated->nextReminderDate()->format('d M Y')}} @endif