diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php
index 15651be465..464e24e20e 100644
--- a/app/controllers/GoogleChartController.php
+++ b/app/controllers/GoogleChartController.php
@@ -336,6 +336,34 @@ class GoogleChartController extends BaseController
}
+ public function budgetLimitSpending(\Budget $budget, \LimitRepetition $repetition)
+ {
+ $start = clone $repetition->startdate;
+ $end = $repetition->enddate;
+
+ /** @var \Grumpydictator\Gchart\GChart $chart */
+ $chart = App::make('gchart');
+ $chart->addColumn('Day', 'date');
+ $chart->addColumn('Left', 'number');
+
+
+ $amount = $repetition->amount;
+
+ while ($start <= $end) {
+ /*
+ * Sum of expenses on this day:
+ */
+ $sum = floatval($budget->transactionjournals()->lessThan(0)->transactionTypes(['Withdrawal'])->onDate($start)->sum('amount'));
+ $amount += $sum;
+ $chart->addRow(clone $start, $amount);
+ $start->addDay();
+ }
+ $chart->generate();
+
+ return Response::json($chart->getData());
+
+ }
+
/**
* @return \Illuminate\Http\JsonResponse
*/
@@ -445,28 +473,44 @@ class GoogleChartController extends BaseController
}
- public function budgetLimitSpending(\Budget $budget, \LimitRepetition $repetition) {
- $start = clone $repetition->startdate;
- $end = $repetition->enddate;
+ /**
+ * @param RecurringTransaction $recurring
+ */
+ public function recurringOverview(RecurringTransaction $recurring)
+ {
+
+ /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */
+ $dateKit = App::make('FireflyIII\Shared\Toolkit\Date');
/** @var \Grumpydictator\Gchart\GChart $chart */
$chart = App::make('gchart');
- $chart->addColumn('Day', 'date');
- $chart->addColumn('Left', 'number');
+ $chart->addColumn('Date', 'date');
+ $chart->addColumn('Max amount', 'number');
+ $chart->addColumn('Min amount', 'number');
+ $chart->addColumn('Current entry', 'number');
-
- $amount = $repetition->amount;
-
- while($start <= $end) {
- /*
- * Sum of expenses on this day:
- */
- $sum = floatval($budget->transactionjournals()->lessThan(0)->transactionTypes(['Withdrawal'])->onDate($start)->sum('amount'));
- $amount += $sum;
- $chart->addRow(clone $start, $amount);
- $start->addDay();
+ // get first transaction or today for start:
+ $first = $recurring->transactionjournals()->orderBy('date', 'ASC')->first();
+ if ($first) {
+ $start = $first->date;
+ } else {
+ $start = new Carbon;
}
+ $end = new Carbon;
+ while ($start <= $end) {
+ $result = $recurring->transactionjournals()->before($end)->after($start)->first();
+ if($result) {
+ $amount = $result->getAmount();
+ } else {
+ $amount = 0;
+ }
+ unset($result);
+ $chart->addRow(clone $start, $recurring->amount_max, $recurring->amount_min, $amount);
+ $start = $dateKit->addPeriod($start, $recurring->repeat_freq, 0);
+ }
+
$chart->generate();
+
return Response::json($chart->getData());
}
@@ -551,6 +595,7 @@ class GoogleChartController extends BaseController
$chart->addRow('Paid: ' . join(', ', $paid['items']), $paid['amount']);
$chart->generate();
+
return Response::json($chart->getData());
}
diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php
index 2f2310c75a..e1bca56ab6 100644
--- a/app/controllers/PiggybankController.php
+++ b/app/controllers/PiggybankController.php
@@ -20,6 +20,7 @@ class PiggybankController extends BaseController
/**
* Add money to piggy bank
+ *
* @param Piggybank $piggybank
*
* @return $this
@@ -109,7 +110,7 @@ class PiggybankController extends BaseController
* Flash some data to fill the form.
*/
$prefilled = ['name' => $piggybank->name, 'account_id' => $piggybank->account_id, 'targetamount' => $piggybank->targetamount,
- 'targetdate' => $piggybank->targetdate, 'remind_me' => intval($piggybank->remind_me) == 1 ? true : false];
+ 'targetdate' => !is_null($piggybank->targetdate) ? $piggybank->targetdate->format('Y-m-d') : null,'reminder' => $piggybank->reminder, 'remind_me' => intval($piggybank->remind_me) == 1 ? true : false];
Session::flash('prefilled', $prefilled);
return View::make('piggybanks.edit', compact('piggybank', 'accounts', 'periods', 'prefilled'))->with('title', 'Piggybanks')->with(
@@ -152,6 +153,7 @@ class PiggybankController extends BaseController
/**
* POST add money to piggy bank
+ *
* @param Piggybank $piggybank
*
* @return \Illuminate\Http\RedirectResponse
@@ -176,7 +178,7 @@ class PiggybankController extends BaseController
/*
* Create event!
*/
- Event::fire('piggybank.addMoney',[$piggybank, $amount]);
+ Event::fire('piggybank.addMoney', [$piggybank, $amount]);
Session::flash('success', 'Added ' . mf($amount, false) . ' to "' . e($piggybank->name) . '".');
} else {
@@ -205,7 +207,7 @@ class PiggybankController extends BaseController
/*
* Create event!
*/
- Event::fire('piggybank.removeMoney',[$piggybank, $amount]);
+ Event::fire('piggybank.removeMoney', [$piggybank, $amount]);
Session::flash('success', 'Removed ' . mf($amount, false) . ' from "' . e($piggybank->name) . '".');
} else {
@@ -228,7 +230,21 @@ class PiggybankController extends BaseController
public function show(Piggybank $piggybank)
{
- return View::make('piggybanks.show', compact('piggybank'))->with('title', 'Piggy banks')->with('mainTitleIcon', 'fa-sort-amount-asc')->with(
+ $events = $piggybank->piggybankevents()->orderBy('date', 'DESC')->get();
+
+ /*
+ * Number of reminders:
+ */
+ $remindersCount = $piggybank->countFutureReminders();
+ if ($remindersCount > 0) {
+ $amountPerReminder = ($piggybank->targetamount - $piggybank->currentRelevantRep()->currentamount) / $remindersCount;
+ } else {
+ $amountPerReminder = ($piggybank->targetamount - $piggybank->currentRelevantRep()->currentamount);
+ }
+
+ return View::make('piggybanks.show', compact('amountPerReminder', 'remindersCount', 'piggybank', 'events'))->with('title', 'Piggy banks')->with(
+ 'mainTitleIcon', 'fa-sort-amount-asc'
+ )->with(
'subTitle', $piggybank->name
);
@@ -296,7 +312,7 @@ class PiggybankController extends BaseController
default:
throw new FireflyException('Cannot handle post_submit_action "' . e(Input::get('post_submit_action')) . '"');
break;
- case 'create_another':
+ case 'return_to_edit':
case 'update':
$messages = $repos->validate($data);
/** @var MessageBag $messages ['errors'] */
@@ -311,7 +327,7 @@ class PiggybankController extends BaseController
$repos->update($piggyBank, $data);
Session::flash('success', 'Piggy bank updated!');
- if ($data['post_submit_action'] == 'create_another') {
+ if ($data['post_submit_action'] == 'return_to_edit') {
return Redirect::route('piggybanks.edit', $piggyBank->id);
} else {
return Redirect::route('piggybanks.index');
diff --git a/app/lib/FireflyIII/Database/Piggybank.php b/app/lib/FireflyIII/Database/Piggybank.php
index 439d26f9de..b54c2c9710 100644
--- a/app/lib/FireflyIII/Database/Piggybank.php
+++ b/app/lib/FireflyIII/Database/Piggybank.php
@@ -79,10 +79,12 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface
$model->reminder_skip = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0;
$model->order = isset($data['order']) ? $data['order'] : 0;
$model->remind_me = isset($data['remind_me']) ? intval($data['remind_me']) : 0;
+ $model->reminder = isset($data['reminder']) ? $data['reminder'] : 'month';
if (!$model->validate()) {
var_dump($model->errors());
exit();
}
+
$model->save();
return true;
diff --git a/app/lib/FireflyIII/Form/Form.php b/app/lib/FireflyIII/Form/Form.php
index 171c0a7d96..a5a30fe4f8 100644
--- a/app/lib/FireflyIII/Form/Form.php
+++ b/app/lib/FireflyIII/Form/Form.php
@@ -111,6 +111,9 @@ class Form
$options['id'] = 'ffInput_' . $name;
$options['autocomplete'] = 'off';
$label = self::label($name, $options);
+
+
+
/*
* Make label and placeholder look nice.
*/
diff --git a/app/lib/FireflyIII/Shared/Toolkit/Date.php b/app/lib/FireflyIII/Shared/Toolkit/Date.php
index 194305a829..a41f40b5f9 100644
--- a/app/lib/FireflyIII/Shared/Toolkit/Date.php
+++ b/app/lib/FireflyIII/Shared/Toolkit/Date.php
@@ -30,9 +30,11 @@ class Date
case 'daily':
$date->addDays($add);
break;
+ case 'week':
case 'weekly':
$date->addWeeks($add);
break;
+ case 'month':
case 'monthly':
$date->addMonths($add);
break;
diff --git a/app/models/Piggybank.php b/app/models/Piggybank.php
index 890e1ea270..172c91c689 100644
--- a/app/models/Piggybank.php
+++ b/app/models/Piggybank.php
@@ -70,6 +70,20 @@ class Piggybank extends Ardent
return $this->belongsTo('Account');
}
+ public function countFutureReminders() {
+ /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */
+ $dateKit = App::make('FireflyIII\Shared\Toolkit\Date');
+
+ $start = new Carbon;
+ $end = !is_null($this->targetdate) ? clone $this->targetdate : new Carbon;
+ $reminders = 0;
+ while($start <= $end) {
+ $reminders++;
+ $start = $dateKit->addPeriod($start, $this->reminder, $this->reminder_skip);
+ }
+ return $reminders;
+ }
+
public function createRepetition(Carbon $start = null, Carbon $target = null)
{
$rep = new \PiggybankRepetition;
@@ -90,15 +104,16 @@ class Piggybank extends Ardent
*/
public function currentRelevantRep()
{
- if($this->currentRep) {
+ if ($this->currentRep) {
return $this->currentRep;
}
if ($this->repeats == 0) {
- $rep = $this->piggybankrepetitions()->first();
+ $rep = $this->piggybankrepetitions()->first();
$this->currentRep = $rep;
+
return $rep;
} else {
- $query = $this->piggybankrepetitions()->where(
+ $query = $this->piggybankrepetitions()->where(
function ($q) {
$q->where(
@@ -122,7 +137,7 @@ class Piggybank extends Ardent
$q->where('targetdate', '>=', $today->format('Y-m-d'));
}
)->orderBy('startdate', 'ASC');
- $result = $query->first();
+ $result = $query->first();
$this->currentRep = $result;
return $result;
diff --git a/app/views/list/piggybank-events.blade.php b/app/views/list/piggybank-events.blade.php
new file mode 100644
index 0000000000..0493b986c7
--- /dev/null
+++ b/app/views/list/piggybank-events.blade.php
@@ -0,0 +1,18 @@
+
+
+ | Date |
+ Amount |
+
+ @foreach($events as $event)
+
+ | {{$event->date->format('j F Y')}} |
+
+ @if($event->amount < 0)
+ Removed {{mf($event->amount*-1,false)}}
+ @else
+ Added {{mf($event->amount,false)}}
+ @endif
+ |
+
+ @endforeach
+
\ No newline at end of file
diff --git a/app/views/piggybanks/edit.blade.php b/app/views/piggybanks/edit.blade.php
index e8ae4435ac..0f6b179842 100644
--- a/app/views/piggybanks/edit.blade.php
+++ b/app/views/piggybanks/edit.blade.php
@@ -1,6 +1,6 @@
@extends('layouts.default')
@section('content')
-{{Form::open(['class' => 'form-horizontal','url' => route('piggybanks.update',$piggybank->id)])}}
+{{Form::model($piggybank, ['class' => 'form-horizontal','url' => route('piggybanks.update',$piggybank->id)])}}
@@ -30,7 +30,7 @@
{{Form::ffDate('targetdate')}}
{{Form::ffCheckbox('remind_me','1',$prefilled['remind_me'],['label' => 'Remind me'])}}
- {{Form::ffSelect('reminder',$periods,'month',['label' => 'Remind every'])}}
+ {{Form::ffSelect('reminder',$periods,$prefilled['reminder'],['label' => 'Remind every'])}}
diff --git a/app/views/piggybanks/show.blade.php b/app/views/piggybanks/show.blade.php
index 813f8ed5db..27a307933d 100644
--- a/app/views/piggybanks/show.blade.php
+++ b/app/views/piggybanks/show.blade.php
@@ -8,15 +8,29 @@
Events
-
@@ -72,15 +86,23 @@
| Reminders left |
- 12 |
+ {{$remindersCount}} |
| Expected amount per reminder |
- {{mf(0)}} |
+ {{mf($amountPerReminder)}} |
+
+
+ Table
+
+
+ @include('list.piggybank-events')
+
+
diff --git a/app/views/recurring/show.blade.php b/app/views/recurring/show.blade.php
index a1f229b27d..ff82f65402 100644
--- a/app/views/recurring/show.blade.php
+++ b/app/views/recurring/show.blade.php
@@ -81,6 +81,7 @@
Chart
diff --git a/bootstrap/start.php b/bootstrap/start.php
index d476cc0f57..3a43913112 100644
--- a/bootstrap/start.php
+++ b/bootstrap/start.php
@@ -100,8 +100,6 @@ Event::subscribe('FireflyIII\Event\Piggybank');
// TODO event for when a transfer gets created and set an associated piggy bank; save as Piggy bank event.
// TODO when this transfer gets edited, retro-actively edit the event and THUS also the piggy bank.
// TODO event for when a transfer gets deleted; also delete related piggy bank event.
-// TODO event for when money is added to a piggy bank.
-// TODO event for when money is removed from a piggy bank.
// TODO event to create the first repetition (for non-repeating piggy banks) when the piggy bank is created.
// TODO event for when the non-repeating piggy bank is updated because the single repetition must also be changed.
// (also make piggy bank events "invalid" when they start falling outside of the date-scope of the piggy bank,
diff --git a/public/assets/javascript/firefly/recurring.js b/public/assets/javascript/firefly/recurring.js
index 5d052dc207..177dada460 100644
--- a/public/assets/javascript/firefly/recurring.js
+++ b/public/assets/javascript/firefly/recurring.js
@@ -2,9 +2,13 @@ $(document).ready(function () {
if (typeof(googleTable) == 'function') {
googleTable('table/recurring', 'recurring-table');
+
+ if (typeof(recurringID) != 'undefined') {
+ googleTable('table/recurring/' + recurringID + '/transactions', 'transaction-table');
+ }
}
- if (typeof(googleTable) == 'function') {
- googleTable('table/recurring/' + recurringID + '/transactions', 'transaction-table');
+ if (typeof(googleLineChart) == 'function' && typeof(recurringID) != 'undefined') {
+ googleLineChart('chart/recurring/' + recurringID, 'recurring-overview');
}
}
);
\ No newline at end of file