mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-03 19:16:51 +00:00
Building a chart for the recurring transactions.
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Firefly\Exception\FireflyException;
|
||||||
use Firefly\Helper\Controllers\ChartInterface;
|
use Firefly\Helper\Controllers\ChartInterface;
|
||||||
use Firefly\Storage\Account\AccountRepositoryInterface;
|
use Firefly\Storage\Account\AccountRepositoryInterface;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ChartController
|
* Class ChartController
|
||||||
@@ -482,4 +484,111 @@ class ChartController extends BaseController
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks all recurring transactions, calculates the current "moment" and returns
|
||||||
|
* a list of yet to be paid (and paid) recurring transactions. This list can be used to show a beautiful chart
|
||||||
|
* to the end user who will love it and cherish it.
|
||||||
|
*
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
public function homeRecurring()
|
||||||
|
{
|
||||||
|
/** @var \Firefly\Helper\Toolkit\ToolkitInterface $toolkit */
|
||||||
|
$toolkit = App::make('Firefly\Helper\Toolkit\ToolkitInterface');
|
||||||
|
$recurringTransactions = \Auth::user()->recurringtransactions()->get();
|
||||||
|
$sessionStart = \Session::get('start');
|
||||||
|
$sessionEnd = \Session::get('end');
|
||||||
|
$paid = [];
|
||||||
|
$unpaid = [];
|
||||||
|
|
||||||
|
/** @var \RecurringTransaction $recurring */
|
||||||
|
foreach ($recurringTransactions as $recurring) {
|
||||||
|
/*
|
||||||
|
* Start a loop starting at the $date.
|
||||||
|
*/
|
||||||
|
$start = clone $recurring->date;
|
||||||
|
$end = Carbon::now();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The jump we make depends on the $repeat_freq
|
||||||
|
*/
|
||||||
|
$current = clone $start;
|
||||||
|
|
||||||
|
\Log::debug('Now looping recurring transaction #' . $recurring->id . ': ' . $recurring->name);
|
||||||
|
|
||||||
|
while ($current <= $end) {
|
||||||
|
/*
|
||||||
|
* Get end of period for $current:
|
||||||
|
*/
|
||||||
|
$currentEnd = clone $current;
|
||||||
|
$toolkit->endOfPeriod($currentEnd, $recurring->repeat_freq);
|
||||||
|
\Log::debug('Now at $current: ' . $current->format('D d F Y') . ' - ' . $currentEnd->format('D d F Y'));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In the current session range?
|
||||||
|
*/
|
||||||
|
if ($sessionEnd >= $current and $currentEnd >= $sessionStart) {
|
||||||
|
/*
|
||||||
|
* Lets see if we've already spent money on this recurring transaction (it hath recurred).
|
||||||
|
*/
|
||||||
|
/** @var Collection $set */
|
||||||
|
$set = \Auth::user()->transactionjournals()->where('recurring_transaction_id', $recurring->id)
|
||||||
|
->after($current)->before($currentEnd)->get();
|
||||||
|
if (count($set) > 1) {
|
||||||
|
\Log::error('Recurring #' . $recurring->id . ', dates [' . $current . ',' . $currentEnd . ']. Found multiple hits. Cannot handle this!');
|
||||||
|
throw new FireflyException('Cannot handle multiple transactions. See logs.');
|
||||||
|
} else if (count($set) == 0) {
|
||||||
|
$unpaid[] = $recurring;
|
||||||
|
} else {
|
||||||
|
$paid[] = $set->get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add some time for the next loop!
|
||||||
|
*/
|
||||||
|
$toolkit->addPeriod($current, $recurring->repeat_freq, intval($recurring->skip));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Loop paid and unpaid to make two haves for a pie chart.
|
||||||
|
*/
|
||||||
|
$unPaidColours = $toolkit->colorRange('AA4643', 'FFFFFF', count($unpaid) == 0 ? 1 : count($unpaid));
|
||||||
|
$paidColours = $toolkit->colorRange('4572A7', 'FFFFFF', count($paid) == 0 ? 1 : count($paid));
|
||||||
|
$serie = [
|
||||||
|
'type' => 'pie',
|
||||||
|
'name' => 'Amount',
|
||||||
|
'data' => []
|
||||||
|
];
|
||||||
|
|
||||||
|
/** @var TransactionJournal $entry */
|
||||||
|
foreach ($paid as $index => $entry) {
|
||||||
|
$transactions = $entry->transactions()->get();
|
||||||
|
$amount = max(floatval($transactions[0]->amount), floatval($transactions[1]->amount));
|
||||||
|
$serie['data'][] = [
|
||||||
|
'name' => $entry->description,
|
||||||
|
'y' => $amount,
|
||||||
|
'color' => $paidColours[$index]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @var RecurringTransaction $entry */
|
||||||
|
foreach ($unpaid as $index => $entry) {
|
||||||
|
$amount = (floatval($entry->amount_max) + floatval($entry->amount_min)) / 2;
|
||||||
|
$serie['data'][] = [
|
||||||
|
'name' => $entry->name,
|
||||||
|
'y' => $amount,
|
||||||
|
'color' => $unPaidColours[$index]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response::json([$serie]);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
@@ -108,6 +108,10 @@ class RecurringController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function rescan(RecurringTransaction $recurringTransaction)
|
public function rescan(RecurringTransaction $recurringTransaction)
|
||||||
{
|
{
|
||||||
|
if (intval($recurringTransaction->active) == 0) {
|
||||||
|
Session::flash('warning', 'Inactive recurring transactions cannot be scanned.');
|
||||||
|
return Redirect::back();
|
||||||
|
}
|
||||||
// do something!
|
// do something!
|
||||||
/** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $repo */
|
/** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $repo */
|
||||||
$repo = App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface');
|
$repo = App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface');
|
||||||
|
@@ -27,7 +27,6 @@ class CreateRemindersTable extends Migration
|
|||||||
'reminders', function (Blueprint $table) {
|
'reminders', function (Blueprint $table) {
|
||||||
$table->increments('id');
|
$table->increments('id');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
$table->string('class', 40);
|
|
||||||
$table->integer('user_id')->unsigned();
|
$table->integer('user_id')->unsigned();
|
||||||
$table->date('startdate');
|
$table->date('startdate');
|
||||||
$table->date('enddate')->nullable();
|
$table->date('enddate')->nullable();
|
||||||
|
@@ -10,6 +10,7 @@ App::before(
|
|||||||
$toolkit = App::make('Firefly\Helper\Toolkit\ToolkitInterface');
|
$toolkit = App::make('Firefly\Helper\Toolkit\ToolkitInterface');
|
||||||
$toolkit->getDateRange();
|
$toolkit->getDateRange();
|
||||||
$toolkit->checkImportJobs();
|
$toolkit->checkImportJobs();
|
||||||
|
Event::fire('recurring.verify');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -355,7 +355,7 @@ class Json implements JsonInterface
|
|||||||
* Loop set and create entries to return.
|
* Loop set and create entries to return.
|
||||||
*/
|
*/
|
||||||
foreach ($set as $entry) {
|
foreach ($set as $entry) {
|
||||||
$data['data'][] = [
|
$set = [
|
||||||
|
|
||||||
'name' => ['name' => $entry->name, 'url' => route('recurring.show', $entry->id)],
|
'name' => ['name' => $entry->name, 'url' => route('recurring.show', $entry->id)],
|
||||||
'match' => explode(' ', $entry->match),
|
'match' => explode(' ', $entry->match),
|
||||||
@@ -370,6 +370,11 @@ class Json implements JsonInterface
|
|||||||
'delete' => route('recurring.delete', $entry->id)
|
'delete' => route('recurring.delete', $entry->id)
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
if (intval($entry->skip) > 0) {
|
||||||
|
$set['repeat_freq'] = $entry->repeat_freq . ' (skip ' . $entry->skip . ')';
|
||||||
|
}
|
||||||
|
$data['data'][] = $set;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
|
@@ -381,4 +381,127 @@ class Toolkit implements ToolkitInterface
|
|||||||
}
|
}
|
||||||
return $selectList;
|
return $selectList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $start
|
||||||
|
* @param string $end
|
||||||
|
* @param int $steps
|
||||||
|
*/
|
||||||
|
public function colorRange($start, $end, $steps = 5)
|
||||||
|
{
|
||||||
|
if (strlen($start) != 6) {
|
||||||
|
throw new FireflyException('Start, ' . e($start) . ' should be a six character HTML colour.');
|
||||||
|
}
|
||||||
|
if (strlen($end) != 6) {
|
||||||
|
throw new FireflyException('End, ' . e($end) . ' should be a six character HTML colour.');
|
||||||
|
}
|
||||||
|
if ($steps < 1) {
|
||||||
|
throw new FireflyException('Steps must be > 1');
|
||||||
|
}
|
||||||
|
|
||||||
|
$start = '#' . $start;
|
||||||
|
$end = '#' . $end;
|
||||||
|
/*
|
||||||
|
* Split html colours.
|
||||||
|
*/
|
||||||
|
list($rs, $gs, $bs) = sscanf($start, "#%02x%02x%02x");
|
||||||
|
list($re, $ge, $be) = sscanf($end, "#%02x%02x%02x");
|
||||||
|
|
||||||
|
$stepr = ($re - $rs) / $steps;
|
||||||
|
$stepg = ($ge - $gs) / $steps;
|
||||||
|
$stepb = ($be - $bs) / $steps;
|
||||||
|
|
||||||
|
$return = [];
|
||||||
|
for ($i = 0; $i <= $steps; $i++) {
|
||||||
|
$cr = $rs + ($stepr * $i);
|
||||||
|
$cg = $gs + ($stepg * $i);
|
||||||
|
$cb = $bs + ($stepb * $i);
|
||||||
|
|
||||||
|
$return[] = $this->rgb2html($cr, $cg, $cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function rgb2html($r, $g = -1, $b = -1)
|
||||||
|
{
|
||||||
|
$r = dechex($r < 0 ? 0 : ($r > 255 ? 255 : $r));
|
||||||
|
$g = dechex($g < 0 ? 0 : ($g > 255 ? 255 : $g));
|
||||||
|
$b = dechex($b < 0 ? 0 : ($b > 255 ? 255 : $b));
|
||||||
|
|
||||||
|
$color = (strlen($r) < 2 ? '0' : '') . $r;
|
||||||
|
$color .= (strlen($g) < 2 ? '0' : '') . $g;
|
||||||
|
$color .= (strlen($b) < 2 ? '0' : '') . $b;
|
||||||
|
return '#' . $color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Carbon $currentEnd
|
||||||
|
* @param $repeatFreq
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
public function endOfPeriod(Carbon $currentEnd, $repeatFreq)
|
||||||
|
{
|
||||||
|
switch ($repeatFreq) {
|
||||||
|
default:
|
||||||
|
throw new FireflyException('Cannot do getFunctionForRepeatFreq for $repeat_freq ' . $repeatFreq);
|
||||||
|
break;
|
||||||
|
case 'daily':
|
||||||
|
$currentEnd->addDay();
|
||||||
|
break;
|
||||||
|
case 'weekly':
|
||||||
|
$currentEnd->addWeek()->subDay();
|
||||||
|
break;
|
||||||
|
case 'monthly':
|
||||||
|
$currentEnd->addMonth()->subDay();
|
||||||
|
break;
|
||||||
|
case 'quarterly':
|
||||||
|
$currentEnd->addMonths(3)->subDay();
|
||||||
|
break;
|
||||||
|
case 'half-year':
|
||||||
|
$currentEnd->addMonths(6)->subDay();
|
||||||
|
break;
|
||||||
|
case 'yearly':
|
||||||
|
$currentEnd->addYear()->subDay();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Carbon $date
|
||||||
|
* @param $repeatFreq
|
||||||
|
* @param $skip
|
||||||
|
* @return Carbon
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
public function addPeriod(Carbon $date, $repeatFreq, $skip)
|
||||||
|
{
|
||||||
|
$add = ($skip + 1);
|
||||||
|
switch ($repeatFreq) {
|
||||||
|
default:
|
||||||
|
throw new FireflyException('Cannot do getFunctionForRepeatFreq for $repeat_freq ' . $repeatFreq);
|
||||||
|
break;
|
||||||
|
case 'daily':
|
||||||
|
$date->addDays($add);
|
||||||
|
break;
|
||||||
|
case 'weekly':
|
||||||
|
$date->addWeeks($add);
|
||||||
|
break;
|
||||||
|
case 'monthly':
|
||||||
|
$date->addMonths($add);
|
||||||
|
break;
|
||||||
|
case 'quarterly':
|
||||||
|
$months = $add * 3;
|
||||||
|
$date->addMonths($months);
|
||||||
|
break;
|
||||||
|
case 'half-year':
|
||||||
|
$months = $add * 6;
|
||||||
|
$date->addMonths($months);
|
||||||
|
break;
|
||||||
|
case 'yearly':
|
||||||
|
$date->addYears($add);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $date;
|
||||||
|
}
|
||||||
}
|
}
|
@@ -33,4 +33,11 @@ interface ToolkitInterface
|
|||||||
|
|
||||||
public function checkImportJobs();
|
public function checkImportJobs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $start
|
||||||
|
* @param string $end
|
||||||
|
* @param int $steps
|
||||||
|
*/
|
||||||
|
public function colorRange($start, $end, $steps = 5);
|
||||||
|
|
||||||
}
|
}
|
@@ -3,6 +3,7 @@
|
|||||||
namespace Firefly\Trigger\Recurring;
|
namespace Firefly\Trigger\Recurring;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Firefly\Exception\FireflyException;
|
||||||
use Illuminate\Events\Dispatcher;
|
use Illuminate\Events\Dispatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,11 +82,7 @@ class EloquentRecurringTrigger
|
|||||||
*/
|
*/
|
||||||
public function subscribe(Dispatcher $events)
|
public function subscribe(Dispatcher $events)
|
||||||
{
|
{
|
||||||
//Event::fire('recurring.rematch', [$recurringTransaction, $journal]);
|
|
||||||
$events->listen('recurring.rescan', 'Firefly\Trigger\Recurring\EloquentRecurringTrigger@rescan');
|
$events->listen('recurring.rescan', 'Firefly\Trigger\Recurring\EloquentRecurringTrigger@rescan');
|
||||||
// $events->listen('recurring.destroy', 'Firefly\Trigger\Recurring\EloquentRecurringTrigger@destroy');
|
|
||||||
// $events->listen('recurring.store', 'Firefly\Trigger\Recurring\EloquentRecurringTrigger@store');
|
|
||||||
// $events->listen('recurring.update', 'Firefly\Trigger\Recurring\EloquentRecurringTrigger@update');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Firefly\Database\SingleTableInheritanceEntity;
|
use Firefly\Database\SingleTableInheritanceEntity;
|
||||||
|
use LaravelBook\Ardent\Ardent;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reminder
|
* Reminder
|
||||||
@@ -10,33 +12,24 @@ use Firefly\Database\SingleTableInheritanceEntity;
|
|||||||
* @property \Carbon\Carbon $created_at
|
* @property \Carbon\Carbon $created_at
|
||||||
* @property \Carbon\Carbon $updated_at
|
* @property \Carbon\Carbon $updated_at
|
||||||
* @property string $class
|
* @property string $class
|
||||||
* @property integer $piggybank_id
|
|
||||||
* @property integer $recurring_transaction_id
|
|
||||||
* @property integer $user_id
|
* @property integer $user_id
|
||||||
* @property \Carbon\Carbon $startdate
|
* @property \Carbon\Carbon $startdate
|
||||||
* @property \Carbon\Carbon $enddate
|
* @property \Carbon\Carbon $enddate
|
||||||
* @property boolean $active
|
* @property boolean $active
|
||||||
* @property-read \Piggybank $piggybank
|
|
||||||
* @property-read \RecurringTransaction $recurringTransaction
|
|
||||||
* @property-read \User $user
|
* @property-read \User $user
|
||||||
* @method static \Illuminate\Database\Query\Builder|\Reminder whereId($value)
|
* @method static \Illuminate\Database\Query\Builder|\Reminder whereId($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\Reminder whereCreatedAt($value)
|
* @method static \Illuminate\Database\Query\Builder|\Reminder whereCreatedAt($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\Reminder whereUpdatedAt($value)
|
* @method static \Illuminate\Database\Query\Builder|\Reminder whereUpdatedAt($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\Reminder whereClass($value)
|
* @method static \Illuminate\Database\Query\Builder|\Reminder whereClass($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\Reminder wherePiggybankId($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\Reminder whereRecurringTransactionId($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\Reminder whereUserId($value)
|
* @method static \Illuminate\Database\Query\Builder|\Reminder whereUserId($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\Reminder whereStartdate($value)
|
* @method static \Illuminate\Database\Query\Builder|\Reminder whereStartdate($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\Reminder whereEnddate($value)
|
* @method static \Illuminate\Database\Query\Builder|\Reminder whereEnddate($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\Reminder whereActive($value)
|
* @method static \Illuminate\Database\Query\Builder|\Reminder whereActive($value)
|
||||||
* @method static \Reminder validOn($date)
|
|
||||||
* @method static \Reminder validOnOrAfter($date)
|
|
||||||
*/
|
*/
|
||||||
class Reminder extends SingleTableInheritanceEntity
|
class Reminder extends Ardent
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $table = 'reminders';
|
protected $table = 'reminders';
|
||||||
protected $subclassField = 'class';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,49 +40,6 @@ class Reminder extends SingleTableInheritanceEntity
|
|||||||
return ['created_at', 'updated_at', 'startdate', 'enddate'];
|
return ['created_at', 'updated_at', 'startdate', 'enddate'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
||||||
*/
|
|
||||||
public function piggybank()
|
|
||||||
{
|
|
||||||
return $this->belongsTo('Piggybank');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function recurringTransaction()
|
|
||||||
{
|
|
||||||
return $this->belongsTo('RecurringTransaction');
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function scopeValidOnOrAfter($query, Carbon $date)
|
|
||||||
{
|
|
||||||
return $query->where(
|
|
||||||
function ($q) use ($date) {
|
|
||||||
$q->where('startdate', '<=', $date->format('Y-m-d'))->where(
|
|
||||||
'enddate', '>=', $date->format('Y-m-d')
|
|
||||||
);
|
|
||||||
$q->orWhere(
|
|
||||||
function ($q) use ($date) {
|
|
||||||
$q->where('startdate', '>=', $date);
|
|
||||||
$q->where('enddate', '>=', $date);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)->where('active', 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User
|
* User
|
||||||
*
|
*
|
||||||
|
@@ -223,6 +223,22 @@ use LaravelBook\Ardent\Builder;
|
|||||||
* 'Budget[] $budgets
|
* 'Budget[] $budgets
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||||
* 'Category[] $categories
|
* 'Category[] $categories
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||||
|
* 'Budget[] $budgets
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||||
|
* 'Category[] $categories
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||||
|
* 'Budget[] $budgets
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||||
|
* 'Category[] $categories
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||||
|
* 'Budget[] $budgets
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||||
|
* 'Category[] $categories
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||||
|
* 'Budget[] $budgets
|
||||||
|
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||||
|
* 'Category[] $categories
|
||||||
*/
|
*/
|
||||||
class TransactionJournal extends Ardent
|
class TransactionJournal extends Ardent
|
||||||
{
|
{
|
||||||
|
@@ -170,6 +170,7 @@ Route::group(['before' => 'auth'], function () {
|
|||||||
Route::get('/chart/home/budgets', ['uses' => 'ChartController@homeBudgets', 'as' => 'chart.budgets']);
|
Route::get('/chart/home/budgets', ['uses' => 'ChartController@homeBudgets', 'as' => 'chart.budgets']);
|
||||||
Route::get('/chart/home/info/{accountnameA}/{day}/{month}/{year}', ['uses' => 'ChartController@homeAccountInfo', 'as' => 'chart.info']);
|
Route::get('/chart/home/info/{accountnameA}/{day}/{month}/{year}', ['uses' => 'ChartController@homeAccountInfo', 'as' => 'chart.info']);
|
||||||
Route::get('/chart/categories/show/{category}', ['uses' => 'ChartController@categoryShowChart','as' => 'chart.showcategory']);
|
Route::get('/chart/categories/show/{category}', ['uses' => 'ChartController@categoryShowChart','as' => 'chart.showcategory']);
|
||||||
|
Route::get('/chart/home/recurring', ['uses' => 'ChartController@homeRecurring', 'as' => 'chart.recurring']);
|
||||||
// (new charts for budgets)
|
// (new charts for budgets)
|
||||||
Route::get('/chart/budget/{budget}/default', ['uses' => 'ChartController@budgetDefault', 'as' => 'chart.budget.default']);
|
Route::get('/chart/budget/{budget}/default', ['uses' => 'ChartController@budgetDefault', 'as' => 'chart.budget.default']);
|
||||||
Route::get('chart/budget/{budget}/no_envelope', ['uses' => 'ChartController@budgetNoLimits', 'as' => 'chart.budget.nolimit']);
|
Route::get('chart/budget/{budget}/no_envelope', ['uses' => 'ChartController@budgetNoLimits', 'as' => 'chart.budget.nolimit']);
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||||
<h2><a href="{{route('accounts.create')}}">Start from scratch</a></h2>
|
<h2><a href="{{route('accounts.create','asset')}}">Start from scratch</a></h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Use this option if you are new to Firefly (III).
|
Use this option if you are new to Firefly (III).
|
||||||
@@ -29,9 +29,10 @@
|
|||||||
@else
|
@else
|
||||||
|
|
||||||
|
|
||||||
<!-- ACCOUNTS -->
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-8 col-md-12 col-sm-12">
|
<div class="col-lg-8 col-md-12 col-sm-12">
|
||||||
|
<!-- ACCOUNTS -->
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<i class="fa fa-credit-card fa-fw"></i> <a href="#">Your accounts</a>
|
<i class="fa fa-credit-card fa-fw"></i> <a href="#">Your accounts</a>
|
||||||
@@ -40,6 +41,7 @@
|
|||||||
<div id="accounts-chart" style="height:300px;"></div>
|
<div id="accounts-chart" style="height:300px;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- BUDGETS -->
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<i class="fa fa-tasks fa-fw"></i> <a href="{{route('budgets.index.date')}}">Budgets and spending</a>
|
<i class="fa fa-tasks fa-fw"></i> <a href="{{route('budgets.index.date')}}">Budgets and spending</a>
|
||||||
@@ -48,6 +50,7 @@
|
|||||||
<div id="budgets"></div>
|
<div id="budgets"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- CATEGORIES -->
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<i class="fa fa-bar-chart fa-fw"></i> <a href="{{route('categories.index')}}">Categories</a>
|
<i class="fa fa-bar-chart fa-fw"></i> <a href="{{route('categories.index')}}">Categories</a>
|
||||||
@@ -55,7 +58,14 @@
|
|||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div id="categories"></div>
|
<div id="categories"></div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<i class="fa fa-line-chart"></i> Savings
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
Bla bla
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@@ -65,6 +75,16 @@
|
|||||||
<!-- time based navigation -->
|
<!-- time based navigation -->
|
||||||
@include('partials.date_nav')
|
@include('partials.date_nav')
|
||||||
|
|
||||||
|
<!-- REMINDERS -->
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<i class="fa fa-line-chart"></i> Recurring transactions
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div id="recurring"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- TRANSACTIONS -->
|
<!-- TRANSACTIONS -->
|
||||||
@foreach($transactions as $data)
|
@foreach($transactions as $data)
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
|
@@ -202,7 +202,7 @@ $(function () {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
enabled: false,
|
enabled: false
|
||||||
},
|
},
|
||||||
credits: {
|
credits: {
|
||||||
enabled: false
|
enabled: false
|
||||||
@@ -211,5 +211,25 @@ $(function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$.getJSON('chart/home/recurring').success(function (data) {
|
||||||
|
$('#recurring').highcharts({
|
||||||
|
title: {
|
||||||
|
text: null
|
||||||
|
},
|
||||||
|
credits: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
plotOptions: {
|
||||||
|
pie: {
|
||||||
|
allowPointSelect: true,
|
||||||
|
cursor: 'pointer',
|
||||||
|
dataLabels: {
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: data
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
Reference in New Issue
Block a user