mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
All code for reminders based on piggy banks. I hope.
This commit is contained in:
parent
d56c00915c
commit
6e17c805c2
@ -11,4 +11,5 @@
|
||||
// The available directives right now are require, require_directory, and require_tree
|
||||
//
|
||||
//= require jquery
|
||||
//= require bootstrap/bootstrap.min
|
||||
//= require bootstrap/bootstrap.min
|
||||
//= require firefly/reminders
|
69
app/assets/javascripts/firefly/reminders.js
Normal file
69
app/assets/javascripts/firefly/reminders.js
Normal file
@ -0,0 +1,69 @@
|
||||
$(function () {
|
||||
|
||||
$('#reminderModal').on('loaded.bs.modal', function () {
|
||||
|
||||
// trigger the 24 hour delay,
|
||||
$('.dismiss-24').on('click', function (ev) {
|
||||
var target = $(ev.target);
|
||||
var reminderId = target.data('id');
|
||||
|
||||
// post dismissal for 24 hours.
|
||||
$.post('reminders/postpone/' + target.data('id')).success(function (data) {
|
||||
$('.reminder-row-' + data).hide(200);
|
||||
}).fail(function () {
|
||||
alert('Could not postpone, please try later.');
|
||||
});
|
||||
});
|
||||
|
||||
// trigger the 'forever' delay
|
||||
$('.dismiss-forever').on('click', function (ev) {
|
||||
var target = $(ev.target);
|
||||
var reminderId = target.data('id');
|
||||
|
||||
$.post('reminders/dismiss/' + target.data('id')).success(function (data) {
|
||||
$('.reminder-row-' + data).hide(200);
|
||||
}).fail(function () {
|
||||
alert('Could not dismiss, please try later.');
|
||||
});
|
||||
});
|
||||
|
||||
// trigger the 'do it' command.
|
||||
$('.do-it').on('click', function (ev) {
|
||||
var target = $(ev.target);
|
||||
var reminderId = target.data('id');
|
||||
window.location = 'reminders/redirect/' + reminderId;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
$('#reminderModalTrigger').on('click', function () {
|
||||
|
||||
|
||||
$('#reminderModal').modal(
|
||||
{
|
||||
remote: 'reminders/dialog'
|
||||
}
|
||||
);
|
||||
|
||||
// trigger on the buttons in the popup
|
||||
|
||||
|
||||
// get some data from somewhere:
|
||||
// $.getJSON('json/reminders').success(function (data) {
|
||||
//
|
||||
// var html = '';
|
||||
// $.each(data,function(i,v) {
|
||||
// html += v.txt;
|
||||
// });
|
||||
//
|
||||
// $('#reminderModal .modal-body').html(html);
|
||||
// $('#reminderModal').modal();
|
||||
// }).fail(function () {
|
||||
// alert('Could not load reminders.');
|
||||
// });
|
||||
//
|
||||
|
||||
});
|
||||
|
||||
});
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use Firefly\Helper\Preferences\PreferencesHelperInterface as PHI;
|
||||
use Firefly\Storage\Account\AccountRepositoryInterface as ARI;
|
||||
use Firefly\Storage\Budget\BudgetRepositoryInterface as BRI;
|
||||
@ -47,6 +48,8 @@ class HomeController extends BaseController
|
||||
\Event::fire('limits.check');
|
||||
\Event::fire('piggybanks.check');
|
||||
|
||||
|
||||
|
||||
// count, maybe we need some introducing text to show:
|
||||
$count = $this->_accounts->count();
|
||||
$start = Session::get('start');
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Firefly\Storage\Account\AccountRepositoryInterface as ARI;
|
||||
use Firefly\Storage\Budget\BudgetRepositoryInterface as Bud;
|
||||
use Firefly\Storage\Category\CategoryRepositoryInterface as Cat;
|
||||
@ -59,5 +60,4 @@ class JsonController extends BaseController
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -84,7 +84,7 @@ class RecurringController extends BaseController
|
||||
*/
|
||||
public function show(RecurringTransaction $recurringTransaction)
|
||||
{
|
||||
return View::make('recurring.show')->with('recurring',$recurringTransaction);
|
||||
return View::make('recurring.show')->with('recurring', $recurringTransaction);
|
||||
|
||||
}
|
||||
|
||||
@ -117,12 +117,18 @@ class RecurringController extends BaseController
|
||||
{
|
||||
/** @var \RecurringTransaction $recurringTransaction */
|
||||
$recurringTransaction = $this->_repository->update($recurringTransaction, Input::all());
|
||||
if($recurringTransaction->errors()->count() == 0) {
|
||||
if ($recurringTransaction->errors()->count() == 0) {
|
||||
Session::flash('success', 'The recurring transaction has been updated.');
|
||||
|
||||
return Redirect::route('recurring.index');
|
||||
} else {
|
||||
Session::flash('error', 'Could not update the recurring transaction: ' . $recurringTransaction->errors()->first());
|
||||
return Redirect::route('recurring.edit',$recurringTransaction->id)->withInput()->withErrors($recurringTransaction->errors());
|
||||
Session::flash(
|
||||
'error', 'Could not update the recurring transaction: ' . $recurringTransaction->errors()->first()
|
||||
);
|
||||
|
||||
return Redirect::route('recurring.edit', $recurringTransaction->id)->withInput()->withErrors(
|
||||
$recurringTransaction->errors()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
89
app/controllers/ReminderController.php
Normal file
89
app/controllers/ReminderController.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Firefly\Storage\Reminder\ReminderRepositoryInterface as RRI;
|
||||
|
||||
/**
|
||||
* Class ReminderController
|
||||
*/
|
||||
class ReminderController extends BaseController
|
||||
{
|
||||
|
||||
protected $_repository;
|
||||
|
||||
public function __construct(RRI $repository)
|
||||
{
|
||||
$this->_repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Reminder $reminder
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function dismiss(\Reminder $reminder)
|
||||
{
|
||||
$reminder = $this->_repository->deactivate($reminder);
|
||||
|
||||
return Response::json($reminder->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reminders currently active for the modal dialog.
|
||||
*/
|
||||
public function modalDialog()
|
||||
{
|
||||
$today = new Carbon;
|
||||
$reminders = $this->_repository->get();
|
||||
|
||||
/** @var \Reminder $reminder */
|
||||
foreach ($reminders as $index => $reminder) {
|
||||
if (\Session::has('dismissal-' . $reminder->id)) {
|
||||
$time = \Session::get('dismissal-' . $reminder->id);
|
||||
if ($time >= $today) {
|
||||
unset($reminders[$index]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return View::make('reminders.popup')->with('reminders', $reminders);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Reminder $reminder
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function postpone(\Reminder $reminder)
|
||||
{
|
||||
$now = new Carbon;
|
||||
$now->addDay();
|
||||
Session::put('dismissal-' . $reminder->id, $now);
|
||||
|
||||
return Response::json($reminder->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Reminder $reminder
|
||||
*/
|
||||
public function redirect(\Reminder $reminder)
|
||||
{
|
||||
if ($reminder instanceof PiggybankReminder) {
|
||||
// fields to prefill:
|
||||
$parameters = [
|
||||
'account_to_id' => $reminder->piggybank->account->id,
|
||||
'amount' => round($reminder->amountToSave(), 2),
|
||||
'description' => 'Money for ' . $reminder->piggybank->name,
|
||||
'piggybank_id' => $reminder->piggybank->id,
|
||||
'reminder_id' => $reminder->id
|
||||
];
|
||||
|
||||
return Redirect::to(
|
||||
route('transactions.create', ['what' => 'transfer']) . '?' . http_build_query($parameters)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -43,7 +43,6 @@ class TransactionController extends BaseController
|
||||
$piggyRepository = App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface');
|
||||
$piggies = $piggyRepository->get();
|
||||
|
||||
|
||||
return View::make('transactions.create')->with('accounts', $accounts)->with('budgets', $budgets)->with(
|
||||
'what', $what
|
||||
)->with('piggies', $piggies);
|
||||
@ -188,6 +187,16 @@ class TransactionController extends BaseController
|
||||
$journal = $this->_repository->store($what, Input::all());
|
||||
if ($journal->validate()) {
|
||||
Session::flash('success', 'Transaction "' . $journal->description . '" saved!');
|
||||
|
||||
// if reminder present, deactivate it:
|
||||
if(Input::get('reminder')) {
|
||||
/** @var \Firefly\Storage\Reminder\ReminderRepositoryInterface $reminders */
|
||||
$reminders = App::make('Firefly\Storage\Reminder\ReminderRepositoryInterface');
|
||||
$reminder = $reminders->find(Input::get('reminder'));
|
||||
$reminders->deactivate($reminder);
|
||||
|
||||
}
|
||||
|
||||
if (Input::get('create') == '1') {
|
||||
return Redirect::route('transactions.create', [$what])->withInput();
|
||||
} else {
|
||||
|
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateRemindersTable extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create(
|
||||
'reminders', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
$table->string('class', 30);
|
||||
$table->integer('piggybank_id')->unsigned()->nullable();
|
||||
$table->integer('user_id')->unsigned();
|
||||
$table->date('startdate');
|
||||
$table->date('enddate');
|
||||
$table->boolean('active');
|
||||
|
||||
|
||||
// connect reminders to piggy banks.
|
||||
$table->foreign('piggybank_id')
|
||||
->references('id')->on('piggybanks')
|
||||
->onDelete('set null');
|
||||
|
||||
// connect reminders to users
|
||||
$table->foreign('user_id')
|
||||
->references('id')->on('users')
|
||||
->onDelete('cascade');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('reminders');
|
||||
}
|
||||
|
||||
}
|
@ -7,7 +7,9 @@ App::before(
|
||||
|
||||
if (Auth::check()) {
|
||||
$toolkit = App::make('Firefly\Helper\Toolkit\ToolkitInterface');
|
||||
return $toolkit->getDateRange($request);
|
||||
$toolkit->getDateRange($request);
|
||||
$toolkit->getReminders();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -302,4 +302,26 @@ class Toolkit implements ToolkitInterface
|
||||
return $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getReminders() {
|
||||
// get reminders, for menu, mumble mumble:
|
||||
$today = new Carbon;
|
||||
$reminders = \Auth::user()->reminders()->validOn($today)->get();
|
||||
|
||||
/** @var \Reminder $reminder */
|
||||
foreach($reminders as $index => $reminder) {
|
||||
if(\Session::has('dismissal-' . $reminder->id)) {
|
||||
$time = \Session::get('dismissal-' . $reminder->id);
|
||||
if($time >= $today) {
|
||||
unset($reminders[$index]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
\Session::put('reminderCount',count($reminders));
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -23,4 +23,9 @@ interface ToolkitInterface
|
||||
*/
|
||||
public function getDateRangeDates();
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getReminders();
|
||||
|
||||
}
|
@ -136,7 +136,18 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
$account = isset($data['account_id']) ? $accounts->find($data['account_id']) : null;
|
||||
|
||||
|
||||
|
||||
|
||||
$piggyBank = new \Piggybank($data);
|
||||
|
||||
if(!is_null($piggyBank->reminder) && is_null($piggyBank->startdate) && is_null($piggyBank->targetdate)) {
|
||||
|
||||
$piggyBank->errors()->add('reminder','Cannot create reminders without start ~ AND target date.');
|
||||
return $piggyBank;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if($piggyBank->repeats && !isset($data['targetdate'])) {
|
||||
$piggyBank->errors()->add('targetdate','Target date is mandatory!');
|
||||
return $piggyBank;
|
||||
|
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Firefly\Storage\Reminder;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
||||
/**
|
||||
* Class EloquentReminderRepository
|
||||
*
|
||||
* @package Firefly\Storage\Reminder
|
||||
*/
|
||||
class EloquentReminderRepository implements ReminderRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param \Reminder $reminder
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function deactivate(\Reminder $reminder)
|
||||
{
|
||||
$reminder->active = 0;
|
||||
$reminder->save();
|
||||
|
||||
return $reminder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function find($id)
|
||||
{
|
||||
return \Reminder::find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$today = new Carbon;
|
||||
|
||||
return \Auth::user()->reminders()->validOn($today)->get();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: sander
|
||||
* Date: 23/08/14
|
||||
* Time: 20:59
|
||||
*/
|
||||
|
||||
namespace Firefly\Storage\Reminder;
|
||||
|
||||
|
||||
/**
|
||||
* Interface ReminderRepositoryInterface
|
||||
*
|
||||
* @package Firefly\Storage\Reminder
|
||||
*/
|
||||
interface ReminderRepositoryInterface {
|
||||
|
||||
/**
|
||||
* @param \Reminder $reminder
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function deactivate(\Reminder $reminder);
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function get();
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function find($id);
|
||||
|
||||
}
|
@ -36,6 +36,10 @@ class StorageServiceProvider extends ServiceProvider
|
||||
'Firefly\Storage\RecurringTransaction\EloquentRecurringTransactionRepository'
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\Reminder\ReminderRepositoryInterface',
|
||||
'Firefly\Storage\Reminder\EloquentReminderRepository'
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\Account\AccountRepositoryInterface',
|
||||
|
@ -85,7 +85,7 @@ class EloquentLimitTrigger
|
||||
*/
|
||||
public function madeRepetition(\LimitRepetition $repetition)
|
||||
{
|
||||
\Log::info('TRIGGER: Created a limit repetition (#' . $repetition->id . ')');
|
||||
\Log::info('TRIGGER: Created a limit repetition (#' . $repetition->id . ')');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,8 +109,8 @@ class EloquentLimitTrigger
|
||||
//$events->listen('budgets.change', 'Firefly\Trigger\Limits\EloquentLimitTrigger@updateLimitRepetitions');
|
||||
$events->listen('limits.destroy', 'Firefly\Trigger\Limits\EloquentLimitTrigger@destroy');
|
||||
$events->listen('limits.store', 'Firefly\Trigger\Limits\EloquentLimitTrigger@store');
|
||||
$events->listen('limits.update', 'Firefly\Trigger\Limits\EloquentLimitTrigger@update');
|
||||
$events->listen('limits.check', 'Firefly\Trigger\Limits\EloquentLimitTrigger@checkRepeatingLimits');
|
||||
$events->listen('limits.update', 'Firefly\Trigger\Limits\EloquentLimitTrigger@update');
|
||||
$events->listen('limits.check', 'Firefly\Trigger\Limits\EloquentLimitTrigger@checkRepeatingLimits');
|
||||
$events->listen('limits.repetition', 'Firefly\Trigger\Limits\EloquentLimitTrigger@madeRepetition');
|
||||
//\Event::fire('limits.repetition', [$repetition]);
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Firefly\Trigger\Piggybanks;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Events\Dispatcher;
|
||||
|
||||
/**
|
||||
@ -116,8 +117,64 @@ class EloquentPiggybankTrigger
|
||||
*/
|
||||
public function madeRep(\PiggybankRepetition $rep)
|
||||
{
|
||||
// do something.
|
||||
\Log::info('TRIGGER: Created a piggybank repetition (#' . $rep->id . ')');
|
||||
// do something with reminders?
|
||||
$piggyBank = $rep->piggybank;
|
||||
if (is_null(($piggyBank->reminder))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$current = clone $rep->startdate;
|
||||
$today = new Carbon;
|
||||
while ($current <= $rep->targetdate) {
|
||||
|
||||
// when do we start reminding?
|
||||
// X days before $current:
|
||||
$reminderStart = clone $current;
|
||||
switch ($piggyBank->reminder) {
|
||||
case 'day':
|
||||
$reminderStart->subDay();
|
||||
break;
|
||||
case 'week':
|
||||
$reminderStart->subDays(4);
|
||||
break;
|
||||
case 'month':
|
||||
$reminderStart->subDays(21);
|
||||
break;
|
||||
case 'year':
|
||||
$reminderStart->subMonths(9);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($current >= $today) {
|
||||
$reminder = new \PiggybankReminder;
|
||||
$reminder->piggybank()->associate($piggyBank);
|
||||
$reminder->user()->associate(\Auth::user());
|
||||
$reminder->startdate = $reminderStart;
|
||||
$reminder->enddate = $current;
|
||||
try {
|
||||
$reminder->save();
|
||||
|
||||
} catch (QueryException $e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch ($piggyBank->reminder) {
|
||||
case 'day':
|
||||
$current->addDays($piggyBank->reminder_skip);
|
||||
break;
|
||||
case 'week':
|
||||
$current->addWeeks($piggyBank->reminder_skip);
|
||||
break;
|
||||
case 'month':
|
||||
$current->addMonths($piggyBank->reminder_skip);
|
||||
break;
|
||||
case 'year':
|
||||
$current->addYears($piggyBank->reminder_skip);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -166,14 +223,6 @@ class EloquentPiggybankTrigger
|
||||
$piggyBank->createRepetition($piggyBank->startdate, $piggyBank->targetdate);
|
||||
|
||||
return true;
|
||||
$rep = new \PiggybankRepetition;
|
||||
$rep->piggybank()->associate($piggyBank);
|
||||
$rep->targetdate = $piggyBank->targetdate;
|
||||
$rep->startdate = $piggyBank->startdate;
|
||||
$rep->currentamount = 0;
|
||||
$rep->save();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
use Firefly\Database\SingleTableInheritanceEntity;
|
||||
|
||||
/**
|
||||
* Component
|
||||
@ -20,7 +21,7 @@
|
||||
* @method static \Illuminate\Database\Query\Builder|\Component whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Component whereClass($value)
|
||||
*/
|
||||
class Component extends Firefly\Database\SingleTableInheritanceEntity
|
||||
class Component extends SingleTableInheritanceEntity
|
||||
{
|
||||
|
||||
public static $rules
|
||||
|
63
app/models/PiggybankReminder.php
Normal file
63
app/models/PiggybankReminder.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
|
||||
/**
|
||||
* Class PiggybankReminder
|
||||
*/
|
||||
class PiggybankReminder extends Reminder
|
||||
{
|
||||
protected $isSubclass = true;
|
||||
|
||||
|
||||
public function amountToSave()
|
||||
{
|
||||
/** @var \Piggybank $piggyBank */
|
||||
$piggyBank = $this->piggybank;
|
||||
/** @var \PiggybankRepetition $repetition */
|
||||
$repetition = $piggyBank->currentRelevantRep();
|
||||
|
||||
$today = new Carbon;
|
||||
$diff = $today->diff($repetition->targetdate);
|
||||
$left = $piggyBank->targetamount - $repetition->currentamount;
|
||||
// to prevent devide by zero:
|
||||
$piggyBank->reminder_skip = $piggyBank->reminder_skip < 1 ? 1 : $piggyBank->reminder_skip;
|
||||
$toSave = 0;
|
||||
switch ($piggyBank->reminder) {
|
||||
case 'day':
|
||||
throw new \Firefly\Exception\FireflyException('No impl day reminder/ PiggyBankReminder Render');
|
||||
break;
|
||||
case 'week':
|
||||
throw new \Firefly\Exception\FireflyException('No impl week reminder/ PiggyBankReminder Render');
|
||||
break;
|
||||
case 'month':
|
||||
$toSave = $left / ($diff->m / $piggyBank->reminder_skip);
|
||||
break;
|
||||
case 'year':
|
||||
throw new \Firefly\Exception\FireflyException('No impl year reminder/ PiggyBankReminder Render');
|
||||
break;
|
||||
}
|
||||
return floatval($toSave);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws Firefly\Exception\FireflyException
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
/** @var \Piggybank $piggyBank */
|
||||
$piggyBank = $this->piggybank;
|
||||
|
||||
|
||||
$fullText
|
||||
= 'In order to save enough money for <a href="' . route('piggybanks.show', $piggyBank->id) . '">"' . e(
|
||||
$piggyBank->name
|
||||
) . '"</a> you';
|
||||
|
||||
$fullText .= ' should save at least ' . mf($this->amountToSave(), false) . ' this ' . $piggyBank->reminder
|
||||
. ', before ' . $this->enddate->format('M jS, Y');
|
||||
|
||||
return $fullText;
|
||||
}
|
||||
|
||||
}
|
56
app/models/Reminder.php
Normal file
56
app/models/Reminder.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Firefly\Database\SingleTableInheritanceEntity;
|
||||
|
||||
|
||||
/**
|
||||
* Class Reminder
|
||||
* // reminder for: recurring, piggybank.
|
||||
*/
|
||||
class Reminder extends SingleTableInheritanceEntity
|
||||
{
|
||||
|
||||
protected $table = 'reminders';
|
||||
protected $subclassField = 'class';
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDates()
|
||||
{
|
||||
return ['created_at', 'updated_at', 'startdate', 'enddate'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function piggybank()
|
||||
{
|
||||
return $this->belongsTo('Piggybank');
|
||||
}
|
||||
|
||||
public function render() {
|
||||
return '';
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function scopeValidOn($query, Carbon $date)
|
||||
{
|
||||
return $query->where('startdate', '<=', $date->format('Y-m-d'))->where('enddate', '>=', $date->format('Y-m-d'))
|
||||
->where('active', 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* User
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('User');
|
||||
}
|
||||
}
|
@ -76,6 +76,22 @@ class User extends Ardent implements UserInterface, RemindableInterface
|
||||
return $this->hasMany('Budget');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function reminders()
|
||||
{
|
||||
return $this->hasMany('Reminder');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function piggybankreminders()
|
||||
{
|
||||
return $this->hasMany('PiggybankReminder');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
|
@ -43,6 +43,16 @@ Route::bind('budget', function($value, $route)
|
||||
return null;
|
||||
});
|
||||
|
||||
Route::bind('reminder', function($value, $route)
|
||||
{
|
||||
if(Auth::check()) {
|
||||
return Reminder::
|
||||
where('id', $value)->
|
||||
where('user_id',Auth::user()->id)->first();
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
Route::bind('category', function($value, $route)
|
||||
{
|
||||
if(Auth::check()) {
|
||||
@ -180,6 +190,12 @@ Route::group(['before' => 'auth'], function () {
|
||||
Route::get('/recurring/edit/{recurring}',['uses' => 'RecurringController@edit','as' => 'recurring.edit']);
|
||||
Route::get('/recurring/delete/{recurring}',['uses' => 'RecurringController@delete','as' => 'recurring.delete']);
|
||||
|
||||
// reminder controller
|
||||
Route::get('/reminders/dialog',['uses' => 'ReminderController@modalDialog']);
|
||||
Route::post('/reminders/postpone/{reminder}',['uses' => 'ReminderController@postpone']);
|
||||
Route::post('/reminders/dismiss/{reminder}',['uses' => 'ReminderController@dismiss']);
|
||||
Route::get('/reminders/redirect/{reminder}',['uses' => 'ReminderController@redirect']);
|
||||
|
||||
// report controller:
|
||||
Route::get('/reports',['uses' => 'ReportController@index','as' => 'reports.index']);
|
||||
|
||||
|
@ -311,6 +311,13 @@ class PiggybankControllerTest extends TestCase
|
||||
public function teststorePiggybank()
|
||||
{
|
||||
$piggy = f::create('Piggybank');
|
||||
$piggy->repeats = 0;
|
||||
$piggy->save();
|
||||
Event::shouldReceive('fire')->with('piggybanks.storePiggy',[$piggy])->once();
|
||||
//Event::fire('piggybanks.storePiggy',[$piggyBank]);
|
||||
//Event::fire('piggybanks.storeRepeated',[$piggyBank]);
|
||||
|
||||
|
||||
$this->_piggybanks->shouldReceive('store')->once()->andReturn($piggy);
|
||||
$this->action('POST', 'PiggybankController@storePiggybank');
|
||||
$this->assertResponseStatus(302);
|
||||
@ -319,6 +326,9 @@ class PiggybankControllerTest extends TestCase
|
||||
public function testStoreRepeated()
|
||||
{
|
||||
$piggy = f::create('Piggybank');
|
||||
$piggy->repeats = 1;
|
||||
$piggy->save();
|
||||
Event::shouldReceive('fire')->with('piggybanks.storeRepeated',[$piggy])->once();
|
||||
$this->_piggybanks->shouldReceive('store')->once()->andReturn($piggy);
|
||||
$this->action('POST', 'PiggybankController@storeRepeated');
|
||||
$this->assertResponseStatus(302);
|
||||
|
@ -10,13 +10,6 @@
|
||||
<?php echo stylesheet_link_tag(); ?>
|
||||
@yield('styles')
|
||||
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<!--
|
||||
<link href="assets/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="assets/css/site.css" rel="stylesheet">
|
||||
-->
|
||||
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
@ -32,6 +25,17 @@
|
||||
@include('partials.flashes')
|
||||
@yield('content')
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="reminderModal" tabindex="-1" role="dialog"
|
||||
aria-labelledby="reminderModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
|
||||
<?php echo javascript_include_tag(); ?>
|
||||
@yield('scripts')
|
||||
</body>
|
||||
|
@ -54,9 +54,13 @@ $r = Route::current()->getName();
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!--
|
||||
<p style="cursor:pointer;" class="navbar-text"><span class="label label-danger">1 reminder</span> </p>
|
||||
-->
|
||||
@if(Session::get('reminderCount') == 1)
|
||||
<p style="cursor:pointer;" id="reminderModalTrigger" class="navbar-text"><span class="label label-danger">1 reminder</span> </p>
|
||||
@endif
|
||||
@if(Session::get('reminderCount') > 1)
|
||||
<p style="cursor:pointer;" id="reminderModalTrigger" class="navbar-text"><span class="label label-danger">{{Session::get('reminderCount')}}
|
||||
reminders</span> </p>
|
||||
@endif
|
||||
|
||||
@if(\Auth::user() && \Auth::check())
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
|
@ -68,8 +68,6 @@
|
||||
@if($piggyBank->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>
|
||||
@endif
|
||||
<a href="{{route('piggybanks.edit',$piggyBank->id)}}" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span></a>
|
||||
<a href="{{route('piggybanks.delete',$piggyBank->id)}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span></a>
|
||||
</div>
|
||||
</td>
|
||||
<td style="width:40%;">
|
||||
@ -80,7 +78,12 @@
|
||||
@endif
|
||||
|
||||
</td>
|
||||
<td></td>
|
||||
<td>
|
||||
<div class="btn-group btn-group-xs">
|
||||
<a href="{{route('piggybanks.edit',$piggyBank->id)}}" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span></a>
|
||||
<a href="{{route('piggybanks.delete',$piggyBank->id)}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@endif
|
||||
@ -125,8 +128,7 @@
|
||||
@if($repeated->currentRelevantRep()->currentamount > 0)
|
||||
<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
|
||||
<a href="{{route('piggybanks.edit',$repeated->id)}}" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span></a>
|
||||
<a href="{{route('piggybanks.delete',$repeated->id)}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span></a>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
<td style="width:40%;">
|
||||
@ -137,7 +139,12 @@
|
||||
@endif
|
||||
|
||||
</td>
|
||||
<td></td>
|
||||
<td>
|
||||
<div class="btn-group btn-group-xs">
|
||||
<a href="{{route('piggybanks.edit',$repeated->id)}}" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span></a>
|
||||
<a href="{{route('piggybanks.delete',$repeated->id)}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@endif
|
||||
|
24
app/views/reminders/popup.blade.php
Normal file
24
app/views/reminders/popup.blade.php
Normal file
@ -0,0 +1,24 @@
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close"
|
||||
data-dismiss="modal"><span aria-hidden="true">×</span>
|
||||
<span class="sr-only">Close</span></button>
|
||||
<h4 class="modal-title">Reminders</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table">
|
||||
@foreach($reminders as $reminder)
|
||||
<tr class="reminder-row-{{$reminder->id}}">
|
||||
<td>{{$reminder->render()}}</td>
|
||||
<td style="width:50%;">
|
||||
<a href="#" data-id="{{$reminder->id}}" class="dismiss-24 btn btn-danger btn-sm">Postpone (24hrs)</a>
|
||||
<a href="#" data-id="{{$reminder->id}}" class="dismiss-forever btn btn-danger btn-sm">Dismiss (forever)</a>
|
||||
<a href="#" data-id="{{$reminder->id}}" class="do-it btn btn-success btn-sm">I want to do this</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
@ -28,6 +28,7 @@
|
||||
</div>
|
||||
|
||||
{{Form::open(['class' => 'form-horizontal','url' => route('transactions.store',$what)])}}
|
||||
{{Form::hidden('reminder',Input::get('reminder_id'))}}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||
@ -37,7 +38,7 @@
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-sm-4 control-label">Description</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" name="description" value="{{{Input::old('description')}}}" autocomplete="off" class="form-control" placeholder="Description" />
|
||||
<input type="text" name="description" value="{{{Input::old('description') ?: Input::get('description')}}}" autocomplete="off" class="form-control" placeholder="Description" />
|
||||
@if($errors->has('description'))
|
||||
<p class="text-danger">{{$errors->first('description')}}</p>
|
||||
@endif
|
||||
@ -56,7 +57,7 @@
|
||||
@endif
|
||||
</label>
|
||||
<div class="col-sm-8">
|
||||
{{Form::select('account_id',$accounts,Input::old('account_id') ?: Input::get('account'),['class' => 'form-control'])}}
|
||||
{{Form::select('account_id',$accounts,Input::old('account_id') ?: Input::get('account_id'),['class' => 'form-control'])}}
|
||||
@if($errors->has('account_id'))
|
||||
<p class="text-danger">{{$errors->first('account_id')}}</p>
|
||||
@endif
|
||||
@ -91,7 +92,7 @@
|
||||
<div class="form-group">
|
||||
<label for="account_from_id" class="col-sm-4 control-label">Account from</label>
|
||||
<div class="col-sm-8">
|
||||
{{Form::select('account_from_id',$accounts,Input::old('account_from_id'),['class' => 'form-control'])}}
|
||||
{{Form::select('account_from_id',$accounts,Input::old('account_from_id') ?: Input::get('account_from_id'),['class' => 'form-control'])}}
|
||||
@if($errors->has('account_from_id'))
|
||||
<p class="text-danger">{{$errors->first('account_from_id')}}</p>
|
||||
@endif
|
||||
@ -101,7 +102,7 @@
|
||||
<div class="form-group">
|
||||
<label for="account_to_id" class="col-sm-4 control-label">Account to</label>
|
||||
<div class="col-sm-8">
|
||||
{{Form::select('account_to_id',$accounts,Input::old('account_to_id'),['class' => 'form-control'])}}
|
||||
{{Form::select('account_to_id',$accounts,Input::old('account_to_id') ?: Input::get('account_to_id'),['class' => 'form-control'])}}
|
||||
@if($errors->has('account_to_id'))
|
||||
<p class="text-danger">{{$errors->first('account_to_id')}}</p>
|
||||
@endif
|
||||
@ -123,7 +124,7 @@
|
||||
@endif
|
||||
</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="number" name="amount" min="0.01" value="{{Input::old('amount')}}" step="any" class="form-control" />
|
||||
<input type="number" name="amount" min="0.01" value="{{Input::old('amount') ?: Input::get('amount')}}" step="any" class="form-control" />
|
||||
@if($errors->has('amount'))
|
||||
<p class="text-danger">{{$errors->first('amount')}}</p>
|
||||
@endif
|
||||
@ -185,7 +186,7 @@
|
||||
<select name="piggybank_id" class="form-control">
|
||||
<option value="0" label="(no piggy bank)">(no piggy bank)</option>
|
||||
@foreach($piggies as $piggy)
|
||||
@if($piggy->id == Input::old('piggybank_id'))
|
||||
@if($piggy->id == Input::old('piggybank_id') || $piggy->id == Input::get('piggybank_id'))
|
||||
<option value="{{$piggy->id}}" label="{{{$piggy->name}}}" selected="selected ">{{{$piggy->name}}}</option>
|
||||
@else
|
||||
<option value="{{$piggy->id}}" label="{{{$piggy->name}}}">{{{$piggy->name}}}</option>
|
||||
|
Loading…
Reference in New Issue
Block a user