More stuff for repeated expenses.

This commit is contained in:
James Cole 2014-11-24 18:06:21 +01:00
parent b051278d2e
commit 743deb4227
10 changed files with 278 additions and 257 deletions

View File

@ -57,5 +57,12 @@ class ReminderController extends BaseController
Session::flash('success','Reminder dismissed');
return Redirect::route('index');
}
public function notnow(Reminder $reminder) {
$reminder->active = 0;
$reminder->notnow = 1;
$reminder->save();
Session::flash('success','Reminder dismissed');
return Redirect::route('index');
}
}

View File

@ -26,6 +26,7 @@ class EventTableAdditions1 extends Migration
// remove some fields:
Schema::table(
'reminders', function (Blueprint $table) {
$table->boolean('notnow');
$table->integer('remindersable_id')->unsigned()->nullable();
$table->string('remindersable_type')->nullable();
}

View File

@ -7,17 +7,24 @@ use Carbon\Carbon;
class PiggybankPart
{
/** @var int */
public $amount;
/** @var float */
public $amountPerBar;
/** @var int */
/** @var float */
public $currentamount;
/** @var float */
public $cumulativeAmount;
/** @var \Reminder */
public $reminder;
/** @var \PiggybankRepetition */
public $repetition;
/** @var Carbon */
public $startdate;
/** @var Carbon */
public $targetdate;
@ -92,10 +99,10 @@ class PiggybankPart
public function percentage()
{
if ($this->getCurrentamount() < $this->getAmount()) {
if ($this->getCurrentamount() < $this->getCumulativeAmount()) {
$pct = 0;
// calculate halway point?
if ($this->getAmount() - $this->getCurrentamount() < $this->getAmountPerBar()) {
if ($this->getCumulativeAmount() - $this->getCurrentamount() < $this->getAmountPerBar()) {
$left = $this->getCurrentamount() % $this->getAmountPerBar();
$pct = round($left / $this->getAmountPerBar() * 100);
}
@ -107,7 +114,7 @@ class PiggybankPart
}
/**
* @return int
* @return float
*/
public function getCurrentamount()
{
@ -115,7 +122,7 @@ class PiggybankPart
}
/**
* @param int $currentamount
* @param float $currentamount
*/
public function setCurrentamount($currentamount)
{
@ -123,23 +130,7 @@ class PiggybankPart
}
/**
* @return int
*/
public function getAmount()
{
return $this->amount;
}
/**
* @param int $amount
*/
public function setAmount($amount)
{
$this->amount = $amount;
}
/**
* @return mixed
* @return float
*/
public function getAmountPerBar()
{
@ -147,10 +138,30 @@ class PiggybankPart
}
/**
* @param mixed $amountPerBar
* @param float $amountPerBar
*/
public function setAmountPerBar($amountPerBar)
{
$this->amountPerBar = $amountPerBar;
}
/**
* @return float
*/
public function getCumulativeAmount()
{
return $this->cumulativeAmount;
}
/**
* @param float $cumulativeAmount
*/
public function setCumulativeAmount($cumulativeAmount)
{
$this->cumulativeAmount = $cumulativeAmount;
}
}

View File

@ -8,7 +8,6 @@ use FireflyIII\Collection\PiggybankPart;
use FireflyIII\Database\Ifaces\CommonDatabaseCalls;
use FireflyIII\Database\Ifaces\CUD;
use FireflyIII\Database\Ifaces\PiggybankInterface;
use FireflyIII\Exception\FireflyException;
use FireflyIII\Exception\NotImplementedException;
use Illuminate\Support\Collection;
use Illuminate\Support\MessageBag;
@ -39,228 +38,234 @@ class RepeatedExpense implements CUD, CommonDatabaseCalls, PiggybankInterface
\Log::debug('Repetition id is ' . $repetition->id);
/** @var \Piggybank $piggyBank */
$piggyBank = $repetition->piggybank()->first();
$bars = new Collection;
\Log::debug('connected piggy bank is: ' . $piggyBank->name . ' (#' . $piggyBank->id . ')');
/*
* If no reminders are set, the repetition is split in exactly one part:
*/
if (is_null($piggyBank->reminder)) {
$parts = 1;
} else {
/*
* Number of parts is the number of [reminder period]s between
* the start date and the target date
*/
/** @var Carbon $start */
$start = clone $repetition->startdate;
/** @var Carbon $target */
$target = clone $repetition->targetdate;
switch ($piggyBank->reminder) {
default:
throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses (calculateParts)');
break;
case 'week':
$parts = $start->diffInWeeks($target);
break;
case 'month':
$parts = $start->diffInMonths($target);
break;
case 'quarter':
$parts = ceil($start->diffInMonths($target) / 3);
break;
case 'year':
$parts = $start->diffInYears($target);
break;
}
$parts = $parts < 1 ? 1 : $parts;
unset($start, $target);
// /*
// * Otherwise, FF3 splits by the difference in time and the amount
// * of reminders the user wants.
// */
// switch ($piggyBank->reminder) {
// default:
// throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses (calculateParts)');
// break;
// case 'week':
// $start = clone $repetition->startdate;
// $start->startOfWeek();
// $end = clone $repetition->targetdate;
// $end->endOfWeek();
// $parts = $start->diffInWeeks($end);
// unset($start, $end);
// break;
// case 'month':
// $start = clone $repetition->startdate;
// $start->startOfMonth();
// $end = clone $repetition->targetdate;
// $end->endOfMonth();
// $parts = $start->diffInMonths($end);
// unset($start, $end);
// break;
// }
}
$amountPerBar = floatval($piggyBank->targetamount) / $parts;
$currentAmount = floatval($amountPerBar);
$currentStart = clone $repetition->startdate;
$currentTarget = clone $repetition->targetdate;
$bars = new Collection;
// if($parts > 12) {
// $parts = 12;
// $currentStart = \DateKit::startOfPeriod(Carbon::now(), $piggyBank->reminder);
// $currentEnd = \DateKit::endOfPeriod($currentEnd, $piggyBank->reminder);
// }
for ($i = 0; $i < $parts; $i++) {
/*
* If it's not the first repetition, jump the start date a [period]
* and jump the target date a [period]
*/
if($i > 0) {
$currentStart = clone $currentTarget;
$currentStart->addDay();
$currentTarget = \DateKit::addPeriod($currentStart, $piggyBank->reminder,0);
}
/*
* If it's the first one, and has reminders, jump to the end of the [period]
*/
if($i == 0 && !is_null($piggyBank->reminder)) {
$currentTarget = \DateKit::endOfX($currentStart, $piggyBank->reminder);
}
if($currentStart > $repetition->targetdate) {
break;
}
/*
* Jump one month ahead after the first instance:
*/
// if ($i > 0) {
// $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0);
// /*
// * Jump to the start of the period too:
// */
// $currentStart = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder);
//
// }
/*
* Move the current start to the actual start of
* the [period] once the first iteration has passed.
*/
// if ($i != 0) {
// $currentStart = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder);
// }
// if($i == 0 && !is_null($piggyBank->reminder)) {
// $currentEnd = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder);
// $currentEnd = \DateKit::endOfPeriod($currentEnd, $piggyBank->reminder);
// }
$part = new PiggybankPart;
$part->setRepetition($repetition);
$part->setAmount($currentAmount);
$part->setAmountPerBar($amountPerBar);
$part->setAmountPerBar(floatval($piggyBank->targetamount));
$part->setCurrentamount($repetition->currentamount);
$part->setCumulativeAmount($piggyBank->targetamount);
$part->setStartdate(clone $repetition->startdate);
$part->setTargetdate(clone $repetition->targetdate);
$bars->push($part);
$repetition->bars = $bars;
return $repetition;
}
$currentStart = clone $repetition->startdate;
/*
* Loop between start and target instead of counting manually.
*/
$index = 0;
//echo 'Looping!<br>';
//echo $repetition->startdate . ' until ' . $repetition->targetdate . '<br>';
while ($currentStart < $repetition->targetdate) {
$currentTarget = \DateKit::endOfX($currentStart, $piggyBank->reminder);
if ($currentTarget > $repetition->targetdate) {
$currentTarget = clone $repetition->targetdate;
}
// create a part:
$part = new PiggybankPart;
$part->setRepetition($repetition);
$part->setCurrentamount($repetition->currentamount);
$part->setStartdate($currentStart);
$part->setTargetdate($currentTarget);
if (!is_null($piggyBank->reminder)) {
// might be a reminder for this range?
$reminder = $piggyBank->reminders()
->where('startdate',$currentStart->format('Y-m-d'))
->where('enddate',$currentTarget->format('Y-m-d'))
->first();
if($reminder) {
$part->setReminder($reminder);
}
$bars->push($part);
//echo 'Loop #' . $index . ', from ' . $currentStart . ' until ' . $currentTarget . '<br />';
/*
* Jump to the next period by adding a day.
*/
$currentStart = clone $currentTarget;
$currentStart->addDay();//\DateKit::addPeriod($currentTarget, $piggyBank->reminder, 0);
$index++;
}
/*
* Loop parts again to add some
*/
$parts = $bars->count();
$amountPerBar = floatval($piggyBank->targetamount) / $parts;
$cumulative = $amountPerBar;
/** @var PiggybankPart $bar */
foreach ($bars as $bar) {
$bar->setAmountPerBar($amountPerBar);
$bar->setCumulativeAmount($cumulative);
$reminder = $piggyBank->reminders()
->where('startdate', $bar->getStartdate()->format('Y-m-d'))
->where('enddate', $bar->getTargetdate()->format('Y-m-d'))
->first();
if ($reminder) {
$bar->setReminder($reminder);
}
// if (!is_null($piggyBank->reminder)) {
// $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0);
// $currentEnd = \DateKit::endOfPeriod($currentStart, $piggyBank->reminder);
// }
$bars->push($part);
$currentAmount += $amountPerBar;
$cumulative += $amountPerBar;
}
$repetition->bars = $bars;
return $repetition;
exit;
$repetition->hello = 'World!';
return $repetition;
$return = new Collection;
$repetitions = $piggyBank->piggybankrepetitions()->get();
/** @var \PiggybankRepetition $repetition */
foreach ($repetitions as $repetition) {
if (is_null($piggyBank->reminder)) {
// simple, one part "repetition".
$part = new PiggybankPart;
$part->setRepetition($repetition);
} else {
$part = new PiggybankPart;
}
// end!
$return->push($part);
}
exit;
return $return;
$piggyBank->currentRelevantRep(); // get the current relevant repetition.
if (!is_null($piggyBank->reminder)) {
switch ($piggyBank->reminder) {
default:
throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses');
break;
case 'month':
$start = clone $piggyBank->currentRep->startdate;
$start->startOfMonth();
$end = clone $piggyBank->currentRep->targetdate;
$end->endOfMonth();
$piggyBank->parts = $start->diffInMonths($end);
unset($start, $end);
break;
}
} else {
$piggyBank->parts = 1;
}
// number of bars:
$piggyBank->barCount = floor(12 / $piggyBank->parts) == 0 ? 1 : floor(12 / $piggyBank->parts);
$amountPerBar = floatval($piggyBank->targetamount) / $piggyBank->parts;
$currentAmount = floatval($amountPerBar);
$bars = [];
$currentStart = clone $piggyBank->currentRep->startdate;
for ($i = 0; $i < $piggyBank->parts; $i++) {
// niet elke keer een andere dinges pakken? om target te redden?
if (!is_null($piggyBank->reminder)) {
$currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0);
}
$bars[] = [
'amount' => $currentAmount,
'date' => $currentStart
];
$currentAmount += $amountPerBar;
}
$piggyBank->bars = $bars;
//
// // if($parts > 12) {
// // $parts = 12;
// // $currentStart = \DateKit::startOfPeriod(Carbon::now(), $piggyBank->reminder);
// // $currentEnd = \DateKit::endOfPeriod($currentEnd, $piggyBank->reminder);
// // }
//
// for ($i = 0; $i < $parts; $i++) {
// /*
// * If it's not the first repetition, jump the start date a [period]
// * and jump the target date a [period]
// */
// if ($i > 0) {
// $currentStart = clone $currentTarget;
// $currentStart->addDay();
// $currentTarget = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0);
// }
// /*
// * If it's the first one, and has reminders, jump to the end of the [period]
// */
// if ($i == 0 && !is_null($piggyBank->reminder)) {
// $currentTarget = \DateKit::endOfX($currentStart, $piggyBank->reminder);
// }
// if ($currentStart > $repetition->targetdate) {
// break;
// }
//
//
// /*
// * Jump one month ahead after the first instance:
// */
// // if ($i > 0) {
// // $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0);
// // /*
// // * Jump to the start of the period too:
// // */
// // $currentStart = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder);
// //
// // }
//
//
// /*
// * Move the current start to the actual start of
// * the [period] once the first iteration has passed.
// */
// // if ($i != 0) {
// // $currentStart = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder);
// // }
// // if($i == 0 && !is_null($piggyBank->reminder)) {
// // $currentEnd = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder);
// // $currentEnd = \DateKit::endOfPeriod($currentEnd, $piggyBank->reminder);
// // }
//
// $part = new PiggybankPart;
// $part->setRepetition($repetition);
// $part->setAmount($currentAmount);
// $part->setAmountPerBar($amountPerBar);
// $part->setCurrentamount($repetition->currentamount);
// $part->setStartdate($currentStart);
// $part->setTargetdate($currentTarget);
// if (!is_null($piggyBank->reminder)) {
// // might be a reminder for this range?
// $reminder = $piggyBank->reminders()
// ->where('startdate', $currentStart->format('Y-m-d'))
// ->where('enddate', $currentTarget->format('Y-m-d'))
// ->first();
// if ($reminder) {
// $part->setReminder($reminder);
// }
//
// }
//
// // if (!is_null($piggyBank->reminder)) {
// // $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0);
// // $currentEnd = \DateKit::endOfPeriod($currentStart, $piggyBank->reminder);
// // }
//
//
// $bars->push($part);
// $currentAmount += $amountPerBar;
// }
// $repetition->bars = $bars;
//
// return $repetition;
// exit;
//
//
// $repetition->hello = 'World!';
//
// return $repetition;
//
// $return = new Collection;
// $repetitions = $piggyBank->piggybankrepetitions()->get();
// /** @var \PiggybankRepetition $repetition */
// foreach ($repetitions as $repetition) {
//
//
// if (is_null($piggyBank->reminder)) {
// // simple, one part "repetition".
// $part = new PiggybankPart;
// $part->setRepetition($repetition);
// } else {
// $part = new PiggybankPart;
// }
//
//
// // end!
// $return->push($part);
// }
//
// exit;
//
// return $return;
// $piggyBank->currentRelevantRep(); // get the current relevant repetition.
// if (!is_null($piggyBank->reminder)) {
// switch ($piggyBank->reminder) {
// default:
// throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses');
// break;
// case 'month':
// $start = clone $piggyBank->currentRep->startdate;
// $start->startOfMonth();
// $end = clone $piggyBank->currentRep->targetdate;
// $end->endOfMonth();
// $piggyBank->parts = $start->diffInMonths($end);
// unset($start, $end);
// break;
// }
//
// } else {
// $piggyBank->parts = 1;
// }
//
// // number of bars:
// $piggyBank->barCount = floor(12 / $piggyBank->parts) == 0 ? 1 : floor(12 / $piggyBank->parts);
// $amountPerBar = floatval($piggyBank->targetamount) / $piggyBank->parts;
// $currentAmount = floatval($amountPerBar);
// $bars = [];
// $currentStart = clone $piggyBank->currentRep->startdate;
// for ($i = 0; $i < $piggyBank->parts; $i++) {
// // niet elke keer een andere dinges pakken? om target te redden?
// if (!is_null($piggyBank->reminder)) {
// $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0);
// }
// $bars[] = [
// 'amount' => $currentAmount,
// 'date' => $currentStart
// ];
//
//
// $currentAmount += $amountPerBar;
// }
// $piggyBank->bars = $bars;
}
/**

View File

@ -86,7 +86,7 @@ class Reminders
}
);
$today = Carbon::now();
//$today = new Carbon('15-12-2014');
//$today = new Carbon('14-12-2014');
/** @var \Piggybank $piggybank */
foreach ($set as $piggybank) {

View File

@ -13,6 +13,7 @@ use LaravelBook\Ardent\Ardent;
* @property \Carbon\Carbon $startdate
* @property \Carbon\Carbon $enddate
* @property boolean $active
* @property boolean $notnow
* @property integer $remembersable_id
* @property string $remembersable_type
* @property-read \Piggybank $remindersable

View File

@ -223,6 +223,7 @@ Route::group(
// reminder controller
Route::get('/reminders/{reminder}',['uses' => 'ReminderController@show','as' => 'reminders.show']);
Route::get('/reminders/{reminder}/dismiss',['uses' => 'ReminderController@dismiss','as' => 'reminders.dismiss']);
Route::get('/reminders/{reminder}/notnow',['uses' => 'ReminderController@notnow','as' => 'reminders.notnow']);
Route::get('/reminders/{reminder}/act',['uses' => 'ReminderController@act','as' => 'reminders.act']);
// search controller:

View File

@ -21,7 +21,7 @@
<p>
<a href="{{route('reminders.act',$reminder->id)}}" class="btn btn-primary"><i class="fa fa-fw fa-thumbs-o-up"></i> I want to do this</a>
<a href="{{route('reminders.dismiss',$reminder->id)}}" class="btn btn-success"><i class="fa fa-smile-o fa-fw"></i> I already did this</a>
<a href="{{route('reminders.dismiss',$reminder->id)}}" class="btn btn-danger"><i class="fa fa-fw fa-clock-o"></i> Not this time</a>
<a href="{{route('reminders.notnow',$reminder->id)}}" class="btn btn-danger"><i class="fa fa-fw fa-clock-o"></i> Not this time</a>
</p>
</div>

View File

@ -36,7 +36,7 @@ $barSize = floor(12 / $entry->currentRep->bars->count()) == 0 ? 1 : floor(12 / $
@foreach($entry->currentRep->bars as $bar)
<div class="col-lg-{{$barSize}} col-md-{{$barSize}} col-sm-{{$barSize}}">
<div class="progress">
<!-- currentAmount:{{$bar->getCurrentAmount()}} getAmount:{{$bar->getAmount()}} -->
<!-- currentAmount:{{$bar->getCurrentAmount()}} getAmount:{{$bar->getCumulativeAmount()}} -->
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{$bar->percentage()}}" aria-valuemin="0" aria-valuemax="100" style="width: {{$bar->percentage()}}%;"></div>
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="{{100-$bar->percentage()}}" aria-valuemin="0" aria-valuemax="100" style="width: {{100-$bar->percentage()}}%;"></div>
</div>

View File

@ -26,38 +26,33 @@
@foreach($rep->bars as $bar)
<div class="col-lg-{{$barSize}} col-md-{{$barSize}} col-sm-{{$barSize}}">
<div class="progress">
<!-- currentAmount:{{$bar->getCurrentAmount()}} getAmount:{{$bar->getAmount()}} -->
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{$bar->percentage()}}" aria-valuemin="0" aria-valuemax="100" style="width: {{$bar->percentage()}}%;"></div>
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="{{100-$bar->percentage()}}" aria-valuemin="0" aria-valuemax="100" style="width: {{100-$bar->percentage()}}%;"></div>
<!-- currentAmount:{{$bar->getCurrentAmount()}} getAmount:{{$bar->getCumulativeAmount()}} -->
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{$bar->percentage()}}" aria-valuemin="0" aria-valuemax="100" style="width: {{$bar->percentage()}}%;">
@if($bar->percentage() > 50 && $bar->percentage() == 100)
@if($bar->hasReminder() && $bar->getReminder()->active == 1)
<a href="{{route('reminders.show',$bar->getReminder()->id)}}" style="color:#fff;"><i class="fa fa-fw fa-clock-o"></i></a>
@endif
@if($bar->hasReminder() && $bar->getReminder()->active == 0 && $bar->getReminder()->notnow == 0)
<i class="fa fa-fw fa-thumbs-up"></i>
@endif
@if($bar->hasReminder() && $bar->getReminder()->active == 0 && $bar->getReminder()->notnow == 1)
<i class="fa fa-fw fa-thumbs-down"></i>
@endif
@endif
@if($bar->percentage() > 50 && $bar->percentage() < 100)
{{mf($rep->currentamount,false)}}
@endif
</div>
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="{{100-$bar->percentage()}}" aria-valuemin="0" aria-valuemax="100" style="width: {{100-$bar->percentage()}}%;">
</div>
</div>
<p class="small">
<!-- {{mf($bar->getAmount())}} -->
{{--
@if($bar->hasReminder())
<a href="{{route('reminders.show',$bar->getReminder()->id)}}">
{{DateKit::periodShow($bar->getStartDate(),$piggyBank->reminder)}}
</a>
@else
@if(!is_null($piggyBank->reminder))
{{DateKit::periodShow($bar->getStartDate(),$piggyBank->reminder)}}
@endif
@endif
--}}
{{$bar->getStartDate()->format('d/m/y')}} &rarr; {{$bar->getTargetDate()->format('d/m/y')}}
@if($bar->hasReminder())
!
@endif
</p>
</div>
@endforeach
</div>
</div>
</div>
@endforeach
@foreach($piggyBank->reminders()->get() as $reminder)
Reminder: #{{$reminder->id}} [from: {{$reminder->startdate->format('d/m/y')}}, to: {{$reminder->enddate->format('d/m/y')}}]<br />
@endforeach
</div>
</div>
@stop