Expanded reminders.

This commit is contained in:
James Cole 2015-03-07 09:21:06 +01:00
parent a60671d4c1
commit 93996ada96
13 changed files with 304 additions and 214 deletions

View File

@ -0,0 +1,140 @@
<?php
namespace FireflyIII\Helpers\Reminders;
use Amount;
use Auth;
use Carbon\Carbon;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\Reminder;
use Navigation;
/**
* Class ReminderHelper
*
* @package FireflyIII\Helpers\Reminders
*/
class ReminderHelper implements ReminderHelperInterface
{
/**
* @param PiggyBank $piggyBank
* @param Carbon $start
* @param Carbon $end
*
* @return Reminder
*/
public function createReminder(PiggyBank $piggyBank, Carbon $start, Carbon $end)
{
$reminder = Auth::user()->reminders()
->where('remindersable_id', $piggyBank->id)
->onDates($start, $end)
->first();
if (is_null($reminder)) {
if (!is_null($piggyBank->targetdate)) {
// get ranges again, but now for the start date
$ranges = $this->getReminderRanges($piggyBank, $start);
$currentRep = $piggyBank->currentRelevantRep();
$left = $piggyBank->targetamount - $currentRep->currentamount;
$perReminder = $left / count($ranges);
} else {
$perReminder = null;
}
$metaData = [
'perReminder' => $perReminder
];
// create one:
$reminder = new Reminder;
$reminder->user()->associate(Auth::user());
$reminder->startdate = $start;
$reminder->enddate = $end;
$reminder->active = true;
$reminder->metadata = $metaData;
$reminder->notnow = false;
$reminder->remindersable()->associate($piggyBank);
$reminder->save();
return $reminder;
} else {
return $reminder;
}
}
/**
* This routine will return an array consisting of two dates which indicate the start
* and end date for each reminder that this piggy bank will have, if the piggy bank has
* any reminders. For example:
*
* [12 mar - 15 mar]
* [15 mar - 18 mar]
*
* etcetera.
*
* Array is filled with tiny arrays with Carbon objects in them.
*
* @param PiggyBank $piggyBank
* @param Carbon $date ;
*
* @return array
*/
public function getReminderRanges(PiggyBank $piggyBank, Carbon $date = null)
{
$ranges = [];
if (is_null($date)) {
$date = new Carbon;
}
if ($piggyBank->remind_me === false) {
return $ranges;
}
if (!is_null($piggyBank->targetdate)) {
// count back until now.
// echo 'Count back!<br>';
$start = $piggyBank->targetdate;
$end = $piggyBank->startdate;
while ($start >= $end) {
$currentEnd = clone $start;
$start = Navigation::subtractPeriod($start, $piggyBank->reminder, 1);
$currentStart = clone $start;
$ranges[] = ['start' => clone $currentStart, 'end' => clone $currentEnd];
}
} else {
$start = clone $piggyBank->startdate;
while ($start < $date) {
$currentStart = clone $start;
$start = Navigation::addPeriod($start, $piggyBank->reminder, 0);
$currentEnd = clone $start;
$ranges[] = ['start' => clone $currentStart, 'end' => clone $currentEnd];
}
}
return $ranges;
}
/**
* Takes a reminder, finds the piggy bank and tells you what to do now.
* Aka how much money to put in.
*
*
* @param Reminder $reminder
*
* @return string
*/
public function getReminderText(Reminder $reminder)
{
/** @var PiggyBank $piggyBank */
$piggyBank = $reminder->remindersable;
if (is_null($piggyBank->targetdate)) {
return 'Add money to this piggy bank to reach your target of ' . Amount::format($piggyBank->targetamount);
}
return 'Add ' . Amount::format($reminder->metadata->perReminder) . ' to fill this piggy bank on ' . $piggyBank->targetdate->format('jS F Y');
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace FireflyIII\Helpers\Reminders;
use FireflyIII\Models\Reminder;
use FireflyIII\Models\PiggyBank;
use Carbon\Carbon;
/**
* Interface ReminderHelperInterface
*
* @package FireflyIII\Helpers\Reminders
*/
interface ReminderHelperInterface {
/**
* Takes a reminder, finds the piggy bank and tells you what to do now.
* Aka how much money to put in.
*
* @param Reminder $reminder
*
* @return string
*/
public function getReminderText(Reminder $reminder);
/**
* This routine will return an array consisting of two dates which indicate the start
* and end date for each reminder that this piggy bank will have, if the piggy bank has
* any reminders. For example:
*
* [12 mar - 15 mar]
* [15 mar - 18 mar]
*
* etcetera.
*
* Array is filled with tiny arrays with Carbon objects in them.
*
* @param PiggyBank $piggyBank
*
* @return array
*/
public function getReminderRanges(PiggyBank $piggyBank);
/**
* @param PiggyBank $piggyBank
* @param Carbon $start
* @param Carbon $end
*
* @return Reminder
*/
public function createReminder(PiggyBank $piggyBank, Carbon $start, Carbon $end);
}

View File

@ -2,10 +2,18 @@
use Auth;
use Carbon\Carbon;
use FireflyIII\Helpers\Reminders\ReminderHelperInterface;
use FireflyIII\Http\Requests;
use FireflyIII\Models\Reminder;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use Redirect;
use URL;
/**
* Class ReminderController
*
* @package FireflyIII\Http\Controllers
*/
class ReminderController extends Controller
{
@ -13,17 +21,20 @@ class ReminderController extends Controller
/**
*
*/
public function index(PiggyBankRepositoryInterface $repository)
public function index(ReminderHelperInterface $helper)
{
$reminders = Auth::user()->reminders()->get();
$reminders->each(function(Reminder $reminder) use ($helper) {
$reminder->description = $helper->getReminderText($reminder);
});
$today = new Carbon;
// active reminders:
$active = $reminders->filter(
function (Reminder $reminder) use ($today, $repository) {
function (Reminder $reminder) use ($today) {
if ($reminder->notnow === false && $reminder->active === true && $reminder->startdate <= $today && $reminder->enddate >= $today) {
$reminder->description = $repository->getReminderText($reminder);
return $reminder;
}
}
@ -71,5 +82,16 @@ class ReminderController extends Controller
}
/**
* @param Reminder $reminder
*/
public function dismiss(Reminder $reminder)
{
$reminder->notnow = true;
$reminder->save();
return Redirect::to(URL::previous());
}
}

View File

@ -49,20 +49,20 @@ class Reminders
// do reminders stuff.
$piggyBanks = $this->auth->user()->piggyBanks()->where('remind_me', 1)->get();
$today = new Carbon;
/** @var \FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface $repository */
$repository = App::make('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface');
/** @var \FireflyIII\Helpers\Reminders\ReminderHelperInterface $helper */
$helper = App::make('FireflyIII\Helpers\Reminders\ReminderHelperInterface');
/** @var PiggyBank $piggyBank */
foreach ($piggyBanks as $piggyBank) {
$ranges = $repository->getReminderRanges($piggyBank);
$ranges = $helper->getReminderRanges($piggyBank);
foreach ($ranges as $range) {
if ($today < $range['end'] && $today > $range['start']) {
// create a reminder here!
$repository->createReminder($piggyBank, $range['start'], $range['end']);
$helper->createReminder($piggyBank, $range['start'], $range['end']);
// stop looping, we're done.
break;
}
// stop looping, we're done.
}
}
@ -71,8 +71,8 @@ class Reminders
// get and list active reminders:
$reminders = $this->auth->user()->reminders()->today()->get();
$reminders->each(
function (Reminder $reminder) use ($repository) {
$reminder->description = $repository->getReminderText($reminder);
function (Reminder $reminder) use ($helper) {
$reminder->description = $helper->getReminderText($reminder);
}
);
View::share('reminders', $reminders);

View File

@ -305,8 +305,10 @@ Route::group(
* Reminder Controller
*/
Route::get('/reminders', ['uses' => 'ReminderController@index', 'as' => 'reminders.index']);
Route::get('/reminder/dismiss/{reminder}', ['uses' => 'ReminderController@dismiss', 'as' => 'reminders.dismiss']);
Route::get('/reminder/{reminder}', ['uses' => 'ReminderController@show', 'as' => 'reminders.show']);
/**
* Repeated Expenses Controller
*/

View File

@ -13,7 +13,7 @@ class Reminder extends Model
{
protected $fillable = ['user_id', 'startdate', 'enddate', 'active', 'notnow', 'remindersable_id', 'remindersable_type',];
protected $fillable = ['user_id', 'startdate', 'metadata', 'enddate', 'active', 'notnow', 'remindersable_id', 'remindersable_type',];
/**
* @param $value
@ -33,6 +33,16 @@ class Reminder extends Model
return ['created_at', 'updated_at', 'startdate', 'enddate'];
}
/**
* @param $value
*
* @return mixed
*/
public function getMetadataAttribute($value)
{
return json_decode($value);
}
/**
* @param $value
*
@ -67,7 +77,16 @@ class Reminder extends Model
{
$today = new Carbon;
return $query->where('startdate', '<=', $today->format('Y-m-d 00:00:00'))->where('enddate', '>=', $today->format('Y-m-d 00:00:00'))->where('active', 1);
return $query->where('startdate', '<=', $today->format('Y-m-d 00:00:00'))->where('enddate', '>=', $today->format('Y-m-d 00:00:00'))->where('active', 1)
->where('notnow', 0);
}
/**
* @param $value
*/
public function setMetadataAttribute($value)
{
$this->attributes['metadata'] = json_encode($value);
}
/**

View File

@ -64,6 +64,8 @@ class FireflyServiceProvider extends ServiceProvider
$this->app->bind('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface', 'FireflyIII\Repositories\PiggyBank\PiggyBankRepository');
$this->app->bind('FireflyIII\Support\Search\SearchInterface', 'FireflyIII\Support\Search\Search');
$this->app->bind('FireflyIII\Helpers\Reminders\ReminderHelperInterface', 'FireflyIII\Helpers\Reminders\ReminderHelper');
$this->app->bind('FireflyIII\Helpers\Report\ReportHelperInterface', 'FireflyIII\Helpers\Report\ReportHelper');
$this->app->bind('FireflyIII\Helpers\Report\ReportQueryInterface', 'FireflyIII\Helpers\Report\ReportQuery');

View File

@ -88,117 +88,6 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
return $part;
}
/**
* @param PiggyBank $piggyBank
* @param Carbon $currentStart
* @param Carbon $currentEnd
*
* @return Reminder
*/
public function createReminder(PiggyBank $piggyBank, Carbon $currentStart, Carbon $currentEnd)
{
$reminder = Auth::user()->reminders()
->where('remindersable_id', $piggyBank->id)
->onDates($currentStart, $currentEnd)
->first();
if (is_null($reminder)) {
// create one:
$reminder = new Reminder;
$reminder->user()->associate(Auth::user());
$reminder->startdate = $currentStart;
$reminder->enddate = $currentEnd;
$reminder->active = true;
$reminder->notnow = false;
$reminder->remindersable()->associate($piggyBank);
$reminder->save();
return $reminder;
} else {
return $reminder;
}
}
/**
* This routine will return an array consisting of two dates which indicate the start
* and end date for each reminder that this piggy bank will have, if the piggy bank has
* any reminders. For example:
*
* [12 mar - 15 mar]
* [15 mar - 18 mar]
*
* etcetera.
*
* Array is filled with tiny arrays with Carbon objects in them.
*
* @param PiggyBank $piggyBank
*
* @return array
*/
public function getReminderRanges(PiggyBank $piggyBank)
{
$ranges = [];
$today = new Carbon;
if ($piggyBank->remind_me === false) {
return $ranges;
}
if (!is_null($piggyBank->targetdate)) {
// count back until now.
// echo 'Count back!<br>';
$start = $piggyBank->targetdate;
$end = $piggyBank->startdate;
while ($start >= $end) {
$currentEnd = clone $start;
$start = Navigation::subtractPeriod($start, $piggyBank->reminder, 1);
$currentStart = clone $start;
$ranges[] = ['start' => clone $currentStart, 'end' => clone $currentEnd];
}
} else {
$start = clone $piggyBank->startdate;
while ($start < $today) {
$currentStart = clone $start;
$start = Navigation::addPeriod($start, $piggyBank->reminder, 0);
$currentEnd = clone $start;
$ranges[] = ['start' => clone $currentStart, 'end' => clone $currentEnd];
}
}
return $ranges;
}
/**
* Takes a reminder, finds the piggy bank and tells you what to do now.
* Aka how much money to put in.
*
*
* @param Reminder $reminder
*
* @return string
*/
public function getReminderText(Reminder $reminder)
{
/** @var PiggyBank $piggyBank */
$piggyBank = $reminder->remindersable;
if (is_null($piggyBank->targetdate)) {
return 'Add money to this piggy bank to reach your target of ' . Amount::format($piggyBank->targetamount);
}
$currentRep = $piggyBank->currentRelevantRep();
$ranges = $this->getReminderRanges($piggyBank);
// calculate number of reminders:
$left = $piggyBank->targetamount - $currentRep->currentamount;
$perReminder = $left / count($ranges);
return 'Add '.Amount::format($perReminder).' to fill this piggy bank on '.$piggyBank->targetdate->format('jS F Y');
}
/**
* @param array $data
*
@ -243,4 +132,5 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
return $piggyBank;
}
}

View File

@ -37,14 +37,7 @@ interface PiggyBankRepositoryInterface
*/
public function createPiggyBankPart(array $data);
/**
* @param PiggyBank $piggyBank
* @param Carbon $currentStart
* @param Carbon $currentEnd
*
* @return Reminder
*/
public function createReminder(PiggyBank $piggyBank, Carbon $currentStart, Carbon $currentEnd);
/**
* @param array $data
@ -60,37 +53,4 @@ interface PiggyBankRepositoryInterface
* @return PiggyBank
*/
public function update(PiggyBank $piggyBank, array $data);
/**
* Takes a reminder, finds the piggy bank and tells you what to do now.
* Aka how much money to put in.
*
* TODO the routine to calculate the number of reminders is probably the same
* routine as is used in the Reminders-middle ware and can be used again.
*
*
*
* @param Reminder $reminder
*
* @return string
*/
public function getReminderText(Reminder $reminder);
/**
* This routine will return an array consisting of two dates which indicate the start
* and end date for each reminder that this piggy bank will have, if the piggy bank has
* any reminders. For example:
*
* [12 mar - 15 mar]
* [15 mar - 18 mar]
*
* etcetera.
*
* Array is filled with tiny arrays with Carbon objects in them.
*
* @param PiggyBank $piggyBank
*
* @return array
*/
public function getReminderRanges(PiggyBank $piggyBank);
}

View File

@ -8,7 +8,7 @@ use Illuminate\Support\MessageBag;
use Input;
use Session;
use View;
use Amount;
use Amount as Amt;
/**
* Class ExpandedForm
@ -33,7 +33,7 @@ class ExpandedForm
$value = $this->fillFieldValue($name, $value);
$options['step'] = 'any';
$options['min'] = '0.01';
$defaultCurrency = isset($options['currency']) ? $options['currency'] : \Amount::getDefaultCurrency();
$defaultCurrency = isset($options['currency']) ? $options['currency'] : Amt::getDefaultCurrency();
$currencies = TransactionCurrency::orderBy('code', 'ASC')->get();
$html = View::make('form.amount', compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
@ -128,7 +128,7 @@ class ExpandedForm
public function fillFieldValue($name, $value)
{
if (Session::has('preFilled')) {
$preFilled = \Session::get('preFilled');
$preFilled = Session::get('preFilled');
$value = isset($preFilled[$name]) && is_null($value) ? $preFilled[$name] : $value;
}
if (!is_null(Input::old($name))) {
@ -152,7 +152,7 @@ class ExpandedForm
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
$options['step'] = 'any';
$defaultCurrency = isset($options['currency']) ? $options['currency'] : Amount::getDefaultCurrency();
$defaultCurrency = isset($options['currency']) ? $options['currency'] : Amt::getDefaultCurrency();
$currencies = TransactionCurrency::orderBy('code', 'ASC')->get();
$html = View::make('form.balance', compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
@ -214,7 +214,7 @@ class ExpandedForm
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
$options['step'] = '1';
$html = \View::make('form.integer', compact('classes', 'name', 'label', 'value', 'options'))->render();
$html = View::make('form.integer', compact('classes', 'name', 'label', 'value', 'options'))->render();
return $html;
@ -237,7 +237,7 @@ class ExpandedForm
$selectList[0] = '(none)';
}
$fields = ['title', 'name', 'description'];
/** @var \Eloquent $entry */
/** @var Eloquent $entry */
foreach ($set as $entry) {
$id = intval($entry->id);
$title = null;
@ -261,9 +261,9 @@ class ExpandedForm
*/
public function optionsList($type, $name)
{
$previousValue = \Input::old('post_submit_action');
$previousValue = Input::old('post_submit_action');
$previousValue = is_null($previousValue) ? 'store' : $previousValue;
$html = \View::make('form.options', compact('type', 'name', 'previousValue'))->render();
$html = View::make('form.options', compact('type', 'name', 'previousValue'))->render();
return $html;
}
@ -282,7 +282,7 @@ class ExpandedForm
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
$selected = $this->fillFieldValue($name, $selected);
$html = \View::make('form.select', compact('classes', 'name', 'label', 'selected', 'options', 'list'))->render();
$html = View::make('form.select', compact('classes', 'name', 'label', 'selected', 'options', 'list'))->render();
return $html;
}
@ -301,7 +301,7 @@ class ExpandedForm
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
$options['data-role'] = 'tagsinput';
$html = \View::make('form.tags', compact('classes', 'name', 'label', 'value', 'options'))->render();
$html = View::make('form.tags', compact('classes', 'name', 'label', 'value', 'options'))->render();
return $html;
}

View File

@ -23,6 +23,13 @@ class ChangesForV332 extends Migration {
}
);
Schema::table(
'reminders', function (Blueprint $table) {
$table->text('metadata');
}
);
}

View File

@ -328,21 +328,7 @@ class TestDataSeeder extends Seeder
{
$user = User::whereEmail('thegrumpydictator@gmail.com')->first();
// for weekly piggy bank (clothes)
$nextWeek = clone $this->_startOfMonth;
$piggyBank = PiggyBank::whereName('New clothes')->orderBy('id', 'DESC')->first();
$nextWeek->addWeek();
$week = $nextWeek->format('Y-m-d');
Reminder::create(
['user_id' => $user->id, 'startdate' => $this->som, 'enddate' => $week, 'active' => 1, 'notnow' => 0,
'remindersable_id' => $piggyBank->id, 'remindersable_type' => 'PiggyBank']
);
// a fake reminder::
Reminder::create(
['user_id' => $user->id, 'startdate' => $this->som, 'enddate' => $week, 'active' => 0, 'notnow' => 0, 'remindersable_id' => 40,
'remindersable_type' => 'Transaction']
);
}
/**
@ -371,14 +357,6 @@ class TestDataSeeder extends Seeder
'order' => 0,
]
);
// PiggyBankRepetition::create(['piggy_bank_id' => $recurring->id, 'startdate' => $this->som, 'targetdate' => $this->eom, 'currentamount' => 0]);
// PiggyBankRepetition::create(
// ['piggy_bank_id' => $recurring->id, 'startdate' => $this->nsom, 'targetdate' => $this->neom, 'currentamount' => 0]
// );
Reminder::create(
['user_id' => $user->id, 'startdate' => $this->som, 'enddate' => $this->neom, 'active' => 1, 'notnow' => 0,
'remindersable_id' => $recurring->id, 'remindersable_type' => 'PiggyBank']
);
}
/**

View File

@ -1,23 +1,42 @@
<div class="row">
@foreach($reminders as $reminder)
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div class="panel panel-default">
<div class="panel-heading">
Reminder for piggy bank "{{$reminder->remindersable->name}}"
</div>
<div class="panel-body">
@if(isset($reminder->description))
{!! $reminder->description !!}
@endif
</div>
<div class="panel-footer">
<div class="btn-group">
<a class="btn btn-warning" href="#">Dismiss</a>
<a class="btn btn-success" href="#">Act</a>
@if($reminders->count() > 0)
@foreach($reminders as $reminder)
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div class="panel panel-default">
<div class="panel-heading">
@if($reminder->notnow === true)
Dismissed reminder
@else
Reminder
@endif
for piggy bank "{{$reminder->remindersable->name}}"
</div>
<div class="panel-body">
<p>
Active between {{$reminder->startdate->format('jS F Y')}}
and {{$reminder->enddate->format('jS F Y')}}.
</p>
@if(isset($reminder->description))
<p>{!! $reminder->description !!}</p>
@endif
</div>
<div class="panel-footer">
<div class="btn-group">
@if($reminder->active === true)
<a class="btn btn-warning" href="{{route('reminders.dismiss',$reminder->id)}}">Dismiss</a>
<a class="btn btn-success" href="#">Act</a>
@endif
</div>
</div>
</div>
</div>
@endforeach
@else
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<p class="small">
(No reminders)
</p>
</div>
</div>
@endforeach
@endif
</div>