'required|exists:accounts,id', // link to Account 'name' => 'required|between:1,255', // name '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? '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 'reminder' => 'in:day,week,month,year', // want a reminder to put money in this? 'reminder_skip' => 'required|min:0|max:100', // every week? every 2 months? 'order' => 'required:min:1', // not yet used. ]; public $fillable = [ 'account_id', 'name', 'targetamount', 'startdate', 'targetdate', 'repeats', 'rep_length', 'rep_every', 'rep_times', 'reminder', 'reminder_skip', 'order' ]; /** * @return array */ public static function factory() { $start = new Carbon; $start->endOfMonth(); $today = new Carbon; return [ 'account_id' => 'factory|Account', 'name' => 'string', 'targetamount' => 'required|min:0', 'startdate' => $today, 'targetdate' => $start, 'repeats' => 0, 'rep_length' => null, 'rep_times' => 0, 'rep_every' => 0, 'reminder' => null, 'reminder_skip' => 0, 'order' => 1, ]; } /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function account() { return $this->belongsTo('Account'); } /** * @return array */ public function getDates() { return ['created_at', 'updated_at', 'targetdate','startdate']; } /** * Firefly shouldn't create piggybank repetions that completely * lie in the future, so we should be able to safely grab the "latest" * one and use that to calculate when the user will be reminded. */ public function nextReminderDate() { if(is_null($this->reminder)) { return null; } /** @var \PiggybankRepetition $rep */ $rep = $this->currentRelevantRep(); if($rep) { $today = new Carbon; if(is_null($rep->startdate)) { switch($this->reminder) { case 'day': return $today; break; case 'week': return $today->endOfWeek(); break; case 'month': return $today->endOfMonth(); break; case 'year': return $today->endOfYear(); break; } } else { // start with the start date // when its bigger than today, return it: $start = clone $rep->startdate; while($start <= $today) { switch($this->reminder) { case 'day': $start->addDay(); break; case 'week': $start->addWeek(); break; case 'month': $start->addMonth(); break; case 'year': $start->addYear(); break; } } return $start; } // if start date is null, simple switch on // the reminder period (if any) and go to the end of the period. // otherwise, keep jumping until we are past today. } return new Carbon; } /** * Grabs the PiggyBankRepetition that's currently relevant / active * * @returns \PiggybankRepetition */ public function currentRelevantRep() { return $this->piggybankrepetitions() ->where(function ($q) { $today = new Carbon; $q->whereNull('startdate'); $q->orWhere('startdate','<=',$today->format('Y-m-d')); }) ->where(function ($q) { $today = new Carbon; $q->whereNull('targetdate'); $q->orWhere('targetdate','>=',$today->format('Y-m-d')); }) ->first(); } /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function piggybankrepetitions() { return $this->hasMany('PiggybankRepetition'); } }