mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-26 05:26:17 +00:00
Fixed some problems with creating piggy bank repetitions.
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user