mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'release/3.4.6'
This commit is contained in:
commit
f15932b2ac
20
README.md
20
README.md
@ -1,4 +1,4 @@
|
|||||||
# Firefly III (v3.4.5)
|
# Firefly III (v3.4.6)
|
||||||
|
|
||||||
[](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master)
|
[](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master)
|
||||||
[](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master)
|
[](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master)
|
||||||
@ -82,11 +82,25 @@ and the **[first use guide](https://github.com/JC5/firefly-iii/wiki/First-use)**
|
|||||||
If you want to try out Firefly III, you can do so on [this dedicated website](https://geld.nder.be/).
|
If you want to try out Firefly III, you can do so on [this dedicated website](https://geld.nder.be/).
|
||||||
This site always runs the latest version of Firefly III. If you want to use it, please read the [privacy considerations](https://github.com/JC5/firefly-iii/wiki/Privacy-on-demo-site) for this demo-site.
|
This site always runs the latest version of Firefly III. If you want to use it, please read the [privacy considerations](https://github.com/JC5/firefly-iii/wiki/Privacy-on-demo-site) for this demo-site.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
Firefly III uses the following libraries and tools:
|
||||||
|
|
||||||
|
* The AdminLTE template by [Almsaseed Studio](https://almsaeedstudio.com/)
|
||||||
|
* The [Google charts](https://developers.google.com/chart/) library.
|
||||||
|
* [Bootstrap](http://getbootstrap.com/)
|
||||||
|
* [Laravel](http://laravel.com/)
|
||||||
|
* [Twig](http://twig.sensiolabs.org/)
|
||||||
|
* For development, some of the excellent tools made by [Barry van den Heuvel](https://github.com/barryvdh)
|
||||||
|
* [Bootstrap sortable](https://github.com/drvic10k/bootstrap-sortable) by [Matúš Brliť](https://github.com/drvic10k).
|
||||||
|
* [Date range picker](https://github.com/dangrossman/bootstrap-daterangepicker/) by [Dan Grossman](https://github.com/dangrossman)
|
||||||
|
* The [real favicon generator](http://realfavicongenerator.net/)
|
||||||
|
* Various other open source components (see [composer.json](https://github.com/JC5/firefly-iii/blob/master/composer.json))
|
||||||
|
|
||||||
|
|
||||||
## Current state
|
## Current state
|
||||||
|
|
||||||
Firefly III is pretty much all grown up. Full test coverage (nerd alert!) is coming. One of the things on the todo-list
|
Firefly III is pretty much all grown up. Full test coverage (nerd alert!) is coming. Translations are a work in progress.
|
||||||
is adding translations.
|
|
||||||
|
|
||||||
Questions, ideas, bugs or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)!
|
Questions, ideas, bugs or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)!
|
||||||
|
|
||||||
|
43
app/Generator/Chart/Account/AccountChartGenerator.php
Normal file
43
app/Generator/Chart/Account/AccountChartGenerator.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Account;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use FireflyIII\Models\Account;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface AccountChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Account
|
||||||
|
*/
|
||||||
|
interface AccountChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $accounts
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function all(Collection $accounts, Carbon $start, Carbon $end);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $accounts
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function frontpage(Collection $accounts, Carbon $start, Carbon $end);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Account $account
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function single(Account $account, Carbon $start, Carbon $end);
|
||||||
|
}
|
114
app/Generator/Chart/Account/ChartJsAccountChartGenerator.php
Normal file
114
app/Generator/Chart/Account/ChartJsAccountChartGenerator.php
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Account;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Config;
|
||||||
|
use FireflyIII\Models\Account;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Preferences;
|
||||||
|
use Steam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ChartJsAccountChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Account
|
||||||
|
*/
|
||||||
|
class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
* @param Collection $accounts
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function all(Collection $accounts, Carbon $start, Carbon $end)
|
||||||
|
{
|
||||||
|
return $this->frontpage($accounts, $start, $end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $accounts
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function frontpage(Collection $accounts, Carbon $start, Carbon $end)
|
||||||
|
{
|
||||||
|
// language:
|
||||||
|
$language = Preferences::get('language', 'en')->data;
|
||||||
|
$format = Config::get('firefly.monthAndDay.' . $language);
|
||||||
|
$data = [
|
||||||
|
'count' => 0,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [],
|
||||||
|
];
|
||||||
|
$current = clone $start;
|
||||||
|
while ($current <= $end) {
|
||||||
|
$data['labels'][] = $current->formatLocalized($format);
|
||||||
|
$current->addDay();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($accounts as $account) {
|
||||||
|
$set = [
|
||||||
|
'label' => $account->name,
|
||||||
|
'fillColor' => 'rgba(220,220,220,0.2)',
|
||||||
|
'strokeColor' => 'rgba(220,220,220,1)',
|
||||||
|
'pointColor' => 'rgba(220,220,220,1)',
|
||||||
|
'pointStrokeColor' => '#fff',
|
||||||
|
'pointHighlightFill' => '#fff',
|
||||||
|
'pointHighlightStroke' => 'rgba(220,220,220,1)',
|
||||||
|
'data' => [],
|
||||||
|
];
|
||||||
|
$current = clone $start;
|
||||||
|
while ($current <= $end) {
|
||||||
|
$set['data'][] = Steam::balance($account, $current);
|
||||||
|
$current->addDay();
|
||||||
|
}
|
||||||
|
$data['datasets'][] = $set;
|
||||||
|
}
|
||||||
|
$data['count'] = count($data['datasets']);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Account $account
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function single(Account $account, Carbon $start, Carbon $end)
|
||||||
|
{
|
||||||
|
// language:
|
||||||
|
$language = Preferences::get('language', 'en')->data;
|
||||||
|
$format = Config::get('firefly.monthAndDay.' . $language);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'count' => 1,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [
|
||||||
|
[
|
||||||
|
'label' => $account->name,
|
||||||
|
'data' => []
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$current = clone $start;
|
||||||
|
|
||||||
|
while ($end >= $current) {
|
||||||
|
$data['labels'][] = $current->formatLocalized($format);
|
||||||
|
$data['datasets'][0]['data'][] = Steam::balance($account, $current);
|
||||||
|
$current->addDay();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
122
app/Generator/Chart/Account/GoogleAccountChartGenerator.php
Normal file
122
app/Generator/Chart/Account/GoogleAccountChartGenerator.php
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Account;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use FireflyIII\Models\Account;
|
||||||
|
use Grumpydictator\Gchart\GChart;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Steam;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GoogleAccountChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Account
|
||||||
|
*/
|
||||||
|
class GoogleAccountChartGenerator implements AccountChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $accounts
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function all(Collection $accounts, Carbon $start, Carbon $end)
|
||||||
|
{
|
||||||
|
// make chart (original code):
|
||||||
|
$chart = new GChart;
|
||||||
|
$chart->addColumn(trans('firefly.dayOfMonth'), 'date');
|
||||||
|
$index = 1;
|
||||||
|
/** @var Account $account */
|
||||||
|
foreach ($accounts as $account) {
|
||||||
|
$chart->addColumn(trans('firefly.balanceFor', ['name' => $account->name]), 'number');
|
||||||
|
$chart->addCertainty($index);
|
||||||
|
$index++;
|
||||||
|
}
|
||||||
|
$current = clone $start;
|
||||||
|
$current->subDay();
|
||||||
|
$today = Carbon::now();
|
||||||
|
while ($end >= $current) {
|
||||||
|
$row = [clone $current];
|
||||||
|
$certain = $current < $today;
|
||||||
|
foreach ($accounts as $account) {
|
||||||
|
$row[] = Steam::balance($account, $current);
|
||||||
|
$row[] = $certain;
|
||||||
|
}
|
||||||
|
$chart->addRowArray($row);
|
||||||
|
$current->addDay();
|
||||||
|
}
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $accounts
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function frontpage(Collection $accounts, Carbon $start, Carbon $end)
|
||||||
|
{
|
||||||
|
$chart = new GChart;
|
||||||
|
$chart->addColumn(trans('firefly.dayOfMonth'), 'date');
|
||||||
|
|
||||||
|
$index = 1;
|
||||||
|
/** @var Account $account */
|
||||||
|
foreach ($accounts as $account) {
|
||||||
|
$chart->addColumn(trans('firefly.balanceFor', ['name' => $account->name]), 'number');
|
||||||
|
$chart->addCertainty($index);
|
||||||
|
$index++;
|
||||||
|
}
|
||||||
|
$current = clone $start;
|
||||||
|
$current->subDay();
|
||||||
|
$today = Carbon::now();
|
||||||
|
while ($end >= $current) {
|
||||||
|
$row = [clone $current];
|
||||||
|
$certain = $current < $today;
|
||||||
|
foreach ($accounts as $account) {
|
||||||
|
$row[] = Steam::balance($account, $current);
|
||||||
|
$row[] = $certain;
|
||||||
|
}
|
||||||
|
$chart->addRowArray($row);
|
||||||
|
$current->addDay();
|
||||||
|
}
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Account $account
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function single(Account $account, Carbon $start, Carbon $end)
|
||||||
|
{
|
||||||
|
$current = clone $start;
|
||||||
|
$today = new Carbon;
|
||||||
|
$chart = new GChart;
|
||||||
|
$chart->addColumn(trans('firefly.dayOfMonth'), 'date');
|
||||||
|
$chart->addColumn(trans('firefly.balanceFor', ['name' => $account->name]), 'number');
|
||||||
|
$chart->addCertainty(1);
|
||||||
|
|
||||||
|
while ($end >= $current) {
|
||||||
|
$certain = $current < $today;
|
||||||
|
$chart->addRow(clone $current, Steam::balance($account, $current), $certain);
|
||||||
|
$current->addDay();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
}
|
||||||
|
}
|
32
app/Generator/Chart/Bill/BillChartGenerator.php
Normal file
32
app/Generator/Chart/Bill/BillChartGenerator.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
namespace FireflyIII\Generator\Chart\Bill;
|
||||||
|
|
||||||
|
|
||||||
|
use FireflyIII\Models\Bill;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface BillChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Bill
|
||||||
|
*/
|
||||||
|
interface BillChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $paid
|
||||||
|
* @param Collection $unpaid
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function frontpage(Collection $paid, Collection $unpaid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Bill $bill
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function single(Bill $bill, Collection $entries);
|
||||||
|
|
||||||
|
}
|
125
app/Generator/Chart/Bill/ChartJsBillChartGenerator.php
Normal file
125
app/Generator/Chart/Bill/ChartJsBillChartGenerator.php
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: sander
|
||||||
|
* Date: 27/06/15
|
||||||
|
* Time: 17:21
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Bill;
|
||||||
|
|
||||||
|
use Config;
|
||||||
|
use FireflyIII\Models\Bill;
|
||||||
|
use FireflyIII\Models\TransactionJournal;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Preferences;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ChartJsBillChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Bill
|
||||||
|
*/
|
||||||
|
class ChartJsBillChartGenerator implements BillChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $paid
|
||||||
|
* @param Collection $unpaid
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function frontpage(Collection $paid, Collection $unpaid)
|
||||||
|
{
|
||||||
|
|
||||||
|
// loop paid and create single entry:
|
||||||
|
$paidDescriptions = [];
|
||||||
|
$paidAmount = 0;
|
||||||
|
$unpaidDescriptions = [];
|
||||||
|
$unpaidAmount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/** @var TransactionJournal $entry */
|
||||||
|
foreach ($paid as $entry) {
|
||||||
|
|
||||||
|
$paidDescriptions[] = $entry->description;
|
||||||
|
$paidAmount += floatval($entry->amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop unpaid:
|
||||||
|
/** @var Bill $entry */
|
||||||
|
foreach ($unpaid as $entry) {
|
||||||
|
$description = $entry[0]->name . ' (' . $entry[1]->format('jS M Y') . ')';
|
||||||
|
$amount = ($entry[0]->amount_max + $entry[0]->amount_min) / 2;
|
||||||
|
$unpaidDescriptions[] = $description;
|
||||||
|
$unpaidAmount += $amount;
|
||||||
|
unset($amount, $description);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
[
|
||||||
|
'value' => $unpaidAmount,
|
||||||
|
'color' => 'rgba(53, 124, 165,0.7)',
|
||||||
|
'highlight' => 'rgba(53, 124, 165,0.9)',
|
||||||
|
'label' => trans('firefly.unpaid'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'value' => $paidAmount,
|
||||||
|
'color' => 'rgba(0, 141, 76, 0.7)',
|
||||||
|
'highlight' => 'rgba(0, 141, 76, 0.9)',
|
||||||
|
'label' => trans('firefly.paid'),
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Bill $bill
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function single(Bill $bill, Collection $entries)
|
||||||
|
{
|
||||||
|
// language:
|
||||||
|
$language = Preferences::get('language', 'en')->data;
|
||||||
|
$format = Config::get('firefly.month.' . $language);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'count' => 3,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
// dataset: max amount
|
||||||
|
// dataset: min amount
|
||||||
|
// dataset: actual amount
|
||||||
|
|
||||||
|
$minAmount = [];
|
||||||
|
$maxAmount = [];
|
||||||
|
$actualAmount = [];
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$data['labels'][] = $entry->date->formatLocalized($format);
|
||||||
|
$minAmount[] = round($bill->amount_min, 2);
|
||||||
|
$maxAmount[] = round($bill->amount_max, 2);
|
||||||
|
$actualAmount[] = round($entry->amount, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['datasets'][] = [
|
||||||
|
'label' => trans('firefly.minAmount'),
|
||||||
|
'data' => $minAmount,
|
||||||
|
];
|
||||||
|
$data['datasets'][] = [
|
||||||
|
'label' => trans('firefly.billEntry'),
|
||||||
|
'data' => $actualAmount,
|
||||||
|
];
|
||||||
|
$data['datasets'][] = [
|
||||||
|
'label' => trans('firefly.maxAmount'),
|
||||||
|
'data' => $maxAmount,
|
||||||
|
];
|
||||||
|
|
||||||
|
$data['count'] = count($data['datasets']);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
87
app/Generator/Chart/Bill/GoogleBillChartGenerator.php
Normal file
87
app/Generator/Chart/Bill/GoogleBillChartGenerator.php
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Bill;
|
||||||
|
|
||||||
|
use FireflyIII\Models\Bill;
|
||||||
|
use FireflyIII\Models\TransactionJournal;
|
||||||
|
use Grumpydictator\Gchart\GChart;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GoogleBillChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Bill
|
||||||
|
*/
|
||||||
|
class GoogleBillChartGenerator implements BillChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $paid
|
||||||
|
* @param Collection $unpaid
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function frontpage(Collection $paid, Collection $unpaid)
|
||||||
|
{
|
||||||
|
// loop paid and create single entry:
|
||||||
|
$paidDescriptions = [];
|
||||||
|
$paidAmount = 0;
|
||||||
|
$unpaidDescriptions = [];
|
||||||
|
$unpaidAmount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/** @var TransactionJournal $entry */
|
||||||
|
foreach ($paid as $entry) {
|
||||||
|
|
||||||
|
$paidDescriptions[] = $entry->description;
|
||||||
|
$paidAmount += floatval($entry->amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop unpaid:
|
||||||
|
/** @var Bill $entry */
|
||||||
|
foreach ($unpaid as $entry) {
|
||||||
|
$description = $entry[0]->name . ' (' . $entry[1]->format('jS M Y') . ')';
|
||||||
|
$amount = ($entry[0]->amount_max + $entry[0]->amount_min) / 2;
|
||||||
|
$unpaidDescriptions[] = $description;
|
||||||
|
$unpaidAmount += $amount;
|
||||||
|
unset($amount, $description);
|
||||||
|
}
|
||||||
|
|
||||||
|
$chart = new GChart;
|
||||||
|
$chart->addColumn(trans('firefly.name'), 'string');
|
||||||
|
$chart->addColumn(trans('firefly.amount'), 'number');
|
||||||
|
|
||||||
|
$chart->addRow(trans('firefly.unpaid') . ': ' . join(', ', $unpaidDescriptions), $unpaidAmount);
|
||||||
|
$chart->addRow(trans('firefly.paid') . ': ' . join(', ', $paidDescriptions), $paidAmount);
|
||||||
|
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Bill $bill
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function single(Bill $bill, Collection $entries)
|
||||||
|
{
|
||||||
|
// make chart:
|
||||||
|
$chart = new GChart;
|
||||||
|
$chart->addColumn(trans('firefly.date'), 'date');
|
||||||
|
$chart->addColumn(trans('firefly.maxAmount'), 'number');
|
||||||
|
$chart->addColumn(trans('firefly.minAmount'), 'number');
|
||||||
|
$chart->addColumn(trans('firefly.billEntry'), 'number');
|
||||||
|
|
||||||
|
/** @var TransactionJournal $result */
|
||||||
|
foreach ($entries as $result) {
|
||||||
|
$chart->addRow(clone $result->date, floatval($bill->amount_max), floatval($bill->amount_min), floatval($result->amount));
|
||||||
|
}
|
||||||
|
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
}
|
||||||
|
}
|
43
app/Generator/Chart/Budget/BudgetChartGenerator.php
Normal file
43
app/Generator/Chart/Budget/BudgetChartGenerator.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Budget;
|
||||||
|
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface BudgetChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Budget
|
||||||
|
*/
|
||||||
|
interface BudgetChartGenerator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function budget(Collection $entries);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function budgetLimit(Collection $entries);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function frontpage(Collection $entries);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $budgets
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function year(Collection $budgets, Collection $entries);
|
||||||
|
|
||||||
|
}
|
139
app/Generator/Chart/Budget/ChartJsBudgetChartGenerator.php
Normal file
139
app/Generator/Chart/Budget/ChartJsBudgetChartGenerator.php
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Budget;
|
||||||
|
|
||||||
|
|
||||||
|
use Config;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Preferences;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ChartJsBudgetChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Budget
|
||||||
|
*/
|
||||||
|
class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function budget(Collection $entries)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'count' => 1,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [
|
||||||
|
[
|
||||||
|
'label' => 'Amount',
|
||||||
|
'data' => [],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$data['labels'][] = trans('firefly.spent');
|
||||||
|
$data['datasets'][0]['data'][] = $entry[1];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function budgetLimit(Collection $entries)
|
||||||
|
{
|
||||||
|
return $this->budget($entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function frontpage(Collection $entries)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'count' => 0,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [],
|
||||||
|
];
|
||||||
|
// dataset: left
|
||||||
|
// dataset: spent
|
||||||
|
// dataset: overspent
|
||||||
|
$left = [];
|
||||||
|
$spent = [];
|
||||||
|
$overspent = [];
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
if ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0) {
|
||||||
|
$data['labels'][] = $entry[0];
|
||||||
|
$left[] = round($entry[1], 2);
|
||||||
|
$spent[] = round($entry[2], 2);
|
||||||
|
$overspent[] = round($entry[3], 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['datasets'][] = [
|
||||||
|
'label' => trans('firefly.left'),
|
||||||
|
'data' => $left,
|
||||||
|
];
|
||||||
|
$data['datasets'][] = [
|
||||||
|
'label' => trans('firefly.spent'),
|
||||||
|
'data' => $spent,
|
||||||
|
];
|
||||||
|
$data['datasets'][] = [
|
||||||
|
'label' => trans('firefly.overspent'),
|
||||||
|
'data' => $overspent,
|
||||||
|
];
|
||||||
|
|
||||||
|
$data['count'] = count($data['datasets']);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $budgets
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function year(Collection $budgets, Collection $entries)
|
||||||
|
{
|
||||||
|
// language:
|
||||||
|
$language = Preferences::get('language', 'en')->data;
|
||||||
|
$format = Config::get('firefly.month.' . $language);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'count' => 0,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($budgets as $budget) {
|
||||||
|
$data['labels'][] = $budget->name;
|
||||||
|
}
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$array = [
|
||||||
|
'label' => $entry[0]->formatLocalized($format),
|
||||||
|
'data' => [],
|
||||||
|
];
|
||||||
|
array_shift($entry);
|
||||||
|
$array['data'] = $entry;
|
||||||
|
$data['datasets'][] = $array;
|
||||||
|
|
||||||
|
}
|
||||||
|
$data['count'] = count($data['datasets']);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
101
app/Generator/Chart/Budget/GoogleBudgetChartGenerator.php
Normal file
101
app/Generator/Chart/Budget/GoogleBudgetChartGenerator.php
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Budget;
|
||||||
|
|
||||||
|
use Grumpydictator\Gchart\GChart;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GoogleBudgetChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Budget
|
||||||
|
*/
|
||||||
|
class GoogleBudgetChartGenerator implements BudgetChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function budget(Collection $entries)
|
||||||
|
{
|
||||||
|
|
||||||
|
$chart = new GChart;
|
||||||
|
$chart->addColumn(trans('firefly.period'), 'date');
|
||||||
|
$chart->addColumn(trans('firefly.spent'), 'number');
|
||||||
|
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$chart->addRow($entry[0], $entry[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function budgetLimit(Collection $entries)
|
||||||
|
{
|
||||||
|
return $this->budget($entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function frontpage(Collection $entries)
|
||||||
|
{
|
||||||
|
$chart = new GChart;
|
||||||
|
$chart->addColumn(trans('firefly.budget'), 'string');
|
||||||
|
$chart->addColumn(trans('firefly.left'), 'number');
|
||||||
|
$chart->addColumn(trans('firefly.spent'), 'number');
|
||||||
|
$chart->addColumn(trans('firefly.overspent'), 'number');
|
||||||
|
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
if ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0) {
|
||||||
|
$chart->addRow($entry[0], $entry[1], $entry[2], $entry[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $budgets
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function year(Collection $budgets, Collection $entries)
|
||||||
|
{
|
||||||
|
$chart = new GChart;
|
||||||
|
// add columns:
|
||||||
|
$chart->addColumn(trans('firefly.month'), 'date');
|
||||||
|
foreach ($budgets as $budget) {
|
||||||
|
$chart->addColumn($budget->name, 'number');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
|
||||||
|
$chart->addRowArray($entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
}
|
||||||
|
}
|
44
app/Generator/Chart/Category/CategoryChartGenerator.php
Normal file
44
app/Generator/Chart/Category/CategoryChartGenerator.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Category;
|
||||||
|
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface CategoryChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Category
|
||||||
|
*/
|
||||||
|
interface CategoryChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function all(Collection $entries);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function frontpage(Collection $entries);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function month(Collection $entries);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $categories
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function year(Collection $categories, Collection $entries);
|
||||||
|
}
|
116
app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php
Normal file
116
app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Category;
|
||||||
|
|
||||||
|
use Config;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Preferences;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ChartJsCategoryChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Category
|
||||||
|
*/
|
||||||
|
class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function all(Collection $entries)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'count' => 1,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [
|
||||||
|
[
|
||||||
|
'label' => trans('firefly.spent'),
|
||||||
|
'data' => []
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$data['labels'][] = trans('firefly.spent');
|
||||||
|
$data['datasets'][0]['data'][] = round($entry[1], 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function frontpage(Collection $entries)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'count' => 1,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [
|
||||||
|
[
|
||||||
|
'label' => trans('firefly.spent'),
|
||||||
|
'data' => []
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
if ($entry['sum'] != 0) {
|
||||||
|
$data['labels'][] = $entry['name'];
|
||||||
|
$data['datasets'][0]['data'][] = round($entry['sum'], 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function month(Collection $entries)
|
||||||
|
{
|
||||||
|
return $this->all($entries);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $categories
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function year(Collection $categories, Collection $entries)
|
||||||
|
{
|
||||||
|
|
||||||
|
// language:
|
||||||
|
$language = Preferences::get('language', 'en')->data;
|
||||||
|
$format = Config::get('firefly.month.' . $language);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'count' => 0,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($categories as $category) {
|
||||||
|
$data['labels'][] = $category->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$date = $entry[0]->formatLocalized($format);
|
||||||
|
array_shift($entry);
|
||||||
|
$data['count']++;
|
||||||
|
$data['datasets'][] = ['label' => $date, 'data' => $entry];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
105
app/Generator/Chart/Category/GoogleCategoryChartGenerator.php
Normal file
105
app/Generator/Chart/Category/GoogleCategoryChartGenerator.php
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Category;
|
||||||
|
|
||||||
|
use Grumpydictator\Gchart\GChart;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GoogleCategoryChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Category
|
||||||
|
*/
|
||||||
|
class GoogleCategoryChartGenerator implements CategoryChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function all(Collection $entries)
|
||||||
|
{
|
||||||
|
$chart = new GChart;
|
||||||
|
$chart->addColumn(trans('firefly.period'), 'date');
|
||||||
|
$chart->addColumn(trans('firefly.spent'), 'number');
|
||||||
|
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$chart->addRow($entry[0], $entry[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function frontpage(Collection $entries)
|
||||||
|
{
|
||||||
|
$chart = new GChart;
|
||||||
|
$chart->addColumn(trans('firefly.category'), 'string');
|
||||||
|
$chart->addColumn(trans('firefly.spent'), 'number');
|
||||||
|
|
||||||
|
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$sum = $entry['sum'];
|
||||||
|
if ($sum != 0) {
|
||||||
|
$chart->addRow($entry['name'], $sum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function month(Collection $entries)
|
||||||
|
{
|
||||||
|
$chart = new GChart;
|
||||||
|
|
||||||
|
$chart->addColumn(trans('firefly.period'), 'date');
|
||||||
|
$chart->addColumn(trans('firefly.spent'), 'number');
|
||||||
|
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$chart->addRow($entry[0], $entry[1]);
|
||||||
|
}
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $categories
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function year(Collection $categories, Collection $entries)
|
||||||
|
{
|
||||||
|
$chart = new GChart;
|
||||||
|
|
||||||
|
$chart->addColumn(trans('firefly.month'), 'date');
|
||||||
|
foreach ($categories as $category) {
|
||||||
|
$chart->addColumn($category->name, 'number');
|
||||||
|
}
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$chart->addRowArray($entry);
|
||||||
|
}
|
||||||
|
$chart->generate();
|
||||||
|
return $chart->getData();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\PiggyBank;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Config;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Preferences;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GooglePiggyBankChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\PiggyBank
|
||||||
|
*/
|
||||||
|
class ChartJsPiggyBankChartGenerator implements PiggyBankChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $set
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function history(Collection $set)
|
||||||
|
{
|
||||||
|
|
||||||
|
// language:
|
||||||
|
$language = Preferences::get('language', 'en')->data;
|
||||||
|
$format = Config::get('firefly.month.' . $language);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'count' => 1,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [
|
||||||
|
[
|
||||||
|
'label' => 'Diff',
|
||||||
|
'data' => []
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$sum = '0';
|
||||||
|
bcscale(2);
|
||||||
|
foreach ($set as $entry) {
|
||||||
|
$date = new Carbon($entry->date);
|
||||||
|
$sum = bcadd($sum, $entry->sum);
|
||||||
|
$data['labels'][] = $date->formatLocalized($format);
|
||||||
|
$data['datasets'][0]['data'][] = round($sum, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\PiggyBank;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Grumpydictator\Gchart\GChart;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GooglePiggyBankChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\PiggyBank
|
||||||
|
*/
|
||||||
|
class GooglePiggyBankChartGenerator implements PiggyBankChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $set
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function history(Collection $set)
|
||||||
|
{
|
||||||
|
$chart = new GChart;
|
||||||
|
$chart->addColumn(trans('firefly.date'), 'date');
|
||||||
|
$chart->addColumn(trans('firefly.balance'), 'number');
|
||||||
|
|
||||||
|
$sum = '0';
|
||||||
|
bcscale(2);
|
||||||
|
|
||||||
|
foreach ($set as $entry) {
|
||||||
|
$sum = bcadd($sum, $entry->sum);
|
||||||
|
$chart->addRow(new Carbon($entry->date), $sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
}
|
||||||
|
}
|
20
app/Generator/Chart/PiggyBank/PiggyBankChartGenerator.php
Normal file
20
app/Generator/Chart/PiggyBank/PiggyBankChartGenerator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\PiggyBank;
|
||||||
|
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface PiggyBankChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\PiggyBank
|
||||||
|
*/
|
||||||
|
interface PiggyBankChartGenerator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param Collection $set
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function history(Collection $set);
|
||||||
|
}
|
83
app/Generator/Chart/Report/ChartJsReportChartGenerator.php
Normal file
83
app/Generator/Chart/Report/ChartJsReportChartGenerator.php
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Report;
|
||||||
|
|
||||||
|
use Config;
|
||||||
|
use Grumpydictator\Gchart\GChart;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Preferences;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GoogleReportChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Report
|
||||||
|
*/
|
||||||
|
class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function yearInOut(Collection $entries)
|
||||||
|
{
|
||||||
|
// language:
|
||||||
|
$language = Preferences::get('language', 'en')->data;
|
||||||
|
$format = Config::get('firefly.month.' . $language);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'count' => 2,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [
|
||||||
|
[
|
||||||
|
'label' => trans('firefly.income'),
|
||||||
|
'data' => []
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => trans('firefly.expenses'),
|
||||||
|
'data' => []
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$data['labels'][] = $entry[0]->formatLocalized($format);
|
||||||
|
$data['datasets'][0]['data'][] = round($entry[1], 2);
|
||||||
|
$data['datasets'][1]['data'][] = round($entry[2], 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $income
|
||||||
|
* @param string $expense
|
||||||
|
* @param int $count
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function yearInOutSummarized($income, $expense, $count)
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'count' => 2,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [
|
||||||
|
[
|
||||||
|
'label' => trans('firefly.income'),
|
||||||
|
'data' => []
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => trans('firefly.expenses'),
|
||||||
|
'data' => []
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$data['datasets'][0]['data'][] = round($income, 2);
|
||||||
|
$data['datasets'][1]['data'][] = round($expense, 2);
|
||||||
|
$data['datasets'][0]['data'][] = round(($income / $count), 2);
|
||||||
|
$data['datasets'][1]['data'][] = round(($expense / $count), 2);
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
58
app/Generator/Chart/Report/GoogleReportChartGenerator.php
Normal file
58
app/Generator/Chart/Report/GoogleReportChartGenerator.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Report;
|
||||||
|
|
||||||
|
use Grumpydictator\Gchart\GChart;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GoogleReportChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Report
|
||||||
|
*/
|
||||||
|
class GoogleReportChartGenerator implements ReportChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function yearInOut(Collection $entries)
|
||||||
|
{
|
||||||
|
$chart = new GChart;
|
||||||
|
$chart->addColumn(trans('firefly.month'), 'date');
|
||||||
|
$chart->addColumn(trans('firefly.income'), 'number');
|
||||||
|
$chart->addColumn(trans('firefly.expenses'), 'number');
|
||||||
|
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$chart->addRowArray($entry);
|
||||||
|
}
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $income
|
||||||
|
* @param string $expense
|
||||||
|
* @param int $count
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function yearInOutSummarized($income, $expense, $count)
|
||||||
|
{
|
||||||
|
$chart = new GChart;
|
||||||
|
|
||||||
|
$chart->addColumn(trans('firefly.summary'), 'string');
|
||||||
|
$chart->addColumn(trans('firefly.income'), 'number');
|
||||||
|
$chart->addColumn(trans('firefly.expenses'), 'number');
|
||||||
|
$chart->addRow(trans('firefly.sum'), $income, $expense);
|
||||||
|
$chart->addRow(trans('firefly.average'), ($income / $count), ($expense / $count));
|
||||||
|
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
|
}
|
||||||
|
}
|
31
app/Generator/Chart/Report/ReportChartGenerator.php
Normal file
31
app/Generator/Chart/Report/ReportChartGenerator.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Report;
|
||||||
|
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface ReportChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Report
|
||||||
|
*/
|
||||||
|
interface ReportChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function yearInOut(Collection $entries);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $income
|
||||||
|
* @param string $expense
|
||||||
|
* @param int $count
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function yearInOutSummarized($income, $expense, $count);
|
||||||
|
|
||||||
|
}
|
@ -51,9 +51,15 @@ class ConnectJournalToPiggyBank
|
|||||||
if (is_null($repetition)) {
|
if (is_null($repetition)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$amount = $journal->correct_amount;
|
|
||||||
bcscale(2);
|
bcscale(2);
|
||||||
|
|
||||||
|
$amount = $journal->actual_amount;
|
||||||
|
// if piggy account matches source account, the amount is positive
|
||||||
|
if ($piggyBank->account_id == $journal->source_account->id) {
|
||||||
|
$amount = $amount * -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$repetition->currentamount = bcadd($repetition->currentamount, $amount);
|
$repetition->currentamount = bcadd($repetition->currentamount, $amount);
|
||||||
$repetition->save();
|
$repetition->save();
|
||||||
|
|
||||||
|
@ -1,176 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace FireflyIII\Helpers\Reminders;
|
|
||||||
|
|
||||||
use Amount;
|
|
||||||
use Auth;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Config;
|
|
||||||
use FireflyIII\Models\PiggyBank;
|
|
||||||
use FireflyIII\Models\Reminder;
|
|
||||||
use Navigation;
|
|
||||||
use Preferences;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 = count($ranges) == 0 ? $left : $left / count($ranges);
|
|
||||||
} else {
|
|
||||||
$perReminder = null;
|
|
||||||
$ranges = [];
|
|
||||||
$left = 0;
|
|
||||||
}
|
|
||||||
$metaData = [
|
|
||||||
'perReminder' => $perReminder,
|
|
||||||
'rangesCount' => count($ranges),
|
|
||||||
'ranges' => $ranges,
|
|
||||||
'leftToSave' => $left,
|
|
||||||
];
|
|
||||||
|
|
||||||
$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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create all reminders for a piggy bank for a given date.
|
|
||||||
*
|
|
||||||
* @param PiggyBank $piggyBank
|
|
||||||
*
|
|
||||||
* @param Carbon $date
|
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function createReminders(PiggyBank $piggyBank, Carbon $date)
|
|
||||||
{
|
|
||||||
$ranges = $this->getReminderRanges($piggyBank);
|
|
||||||
|
|
||||||
foreach ($ranges as $range) {
|
|
||||||
if ($date < $range['end'] && $date > $range['start']) {
|
|
||||||
// create a reminder here!
|
|
||||||
$this->createReminder($piggyBank, $range['start'], $range['end']);
|
|
||||||
// stop looping, we're done.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
$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)) {
|
|
||||||
return trans('firefly.piggy_bank_not_exists');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_null($piggyBank->targetdate)) {
|
|
||||||
return trans('firefly.add_any_amount_to_piggy', ['amount' => Amount::format($piggyBank->targetamount)]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$lang = Preferences::get('language', 'en')->data;
|
|
||||||
|
|
||||||
return trans(
|
|
||||||
'firefly.add_set_amount_to_piggy',
|
|
||||||
[
|
|
||||||
'amount' => Amount::format($reminder->metadata->perReminder),
|
|
||||||
'date' => $piggyBank->targetdate->formatLocalized(Config::get('firefly.monthAndDay.' . $lang))
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace FireflyIII\Helpers\Reminders;
|
|
||||||
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use FireflyIII\Models\PiggyBank;
|
|
||||||
use FireflyIII\Models\Reminder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create all reminders for a piggy bank for a given date.
|
|
||||||
*
|
|
||||||
* @param PiggyBank $piggyBank
|
|
||||||
*
|
|
||||||
* @param Carbon $date
|
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function createReminders(PiggyBank $piggyBank, Carbon $date);
|
|
||||||
}
|
|
@ -2,17 +2,16 @@
|
|||||||
|
|
||||||
namespace FireflyIII\Http\Controllers\Chart;
|
namespace FireflyIII\Http\Controllers\Chart;
|
||||||
|
|
||||||
|
use App;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Http\Controllers\Controller;
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\CacheProperties;
|
use FireflyIII\Support\CacheProperties;
|
||||||
use Grumpydictator\Gchart\GChart;
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Preferences;
|
use Preferences;
|
||||||
use Response;
|
use Response;
|
||||||
use Session;
|
use Session;
|
||||||
use Steam;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AccountController
|
* Class AccountController
|
||||||
@ -21,10 +20,24 @@ use Steam;
|
|||||||
*/
|
*/
|
||||||
class AccountController extends Controller
|
class AccountController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** @var \FireflyIII\Generator\Chart\Account\AccountChartGenerator */
|
||||||
|
protected $generator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
// create chart generator:
|
||||||
|
$this->generator = App::make('FireflyIII\Generator\Chart\Account\AccountChartGenerator');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the balances for all the user's accounts.
|
* Shows the balances for all the user's accounts.
|
||||||
*
|
*
|
||||||
* @param GChart $chart
|
|
||||||
* @param AccountRepositoryInterface $repository
|
* @param AccountRepositoryInterface $repository
|
||||||
*
|
*
|
||||||
* @param $year
|
* @param $year
|
||||||
@ -33,7 +46,7 @@ class AccountController extends Controller
|
|||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function all(GChart $chart, AccountRepositoryInterface $repository, $year, $month, $shared = false)
|
public function all(AccountRepositoryInterface $repository, $year, $month, $shared = false)
|
||||||
{
|
{
|
||||||
$start = new Carbon($year . '-' . $month . '-01');
|
$start = new Carbon($year . '-' . $month . '-01');
|
||||||
$end = clone $start;
|
$end = clone $start;
|
||||||
@ -49,9 +62,6 @@ class AccountController extends Controller
|
|||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$chart->addColumn(trans('firefly.dayOfMonth'), 'date');
|
|
||||||
|
|
||||||
/** @var Collection $accounts */
|
/** @var Collection $accounts */
|
||||||
$accounts = $repository->getAccounts(['Default account', 'Asset account']);
|
$accounts = $repository->getAccounts(['Default account', 'Asset account']);
|
||||||
if ($shared === false) {
|
if ($shared === false) {
|
||||||
@ -63,31 +73,8 @@ class AccountController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// make chart:
|
||||||
|
$data = $this->generator->all($accounts, $start, $end);
|
||||||
$index = 1;
|
|
||||||
/** @var Account $account */
|
|
||||||
foreach ($accounts as $account) {
|
|
||||||
$chart->addColumn(trans('firefly.balanceFor', ['name' => $account->name]), 'number');
|
|
||||||
$chart->addCertainty($index);
|
|
||||||
$index++;
|
|
||||||
}
|
|
||||||
$current = clone $start;
|
|
||||||
$current->subDay();
|
|
||||||
$today = Carbon::now();
|
|
||||||
while ($end >= $current) {
|
|
||||||
$row = [clone $current];
|
|
||||||
$certain = $current < $today;
|
|
||||||
foreach ($accounts as $account) {
|
|
||||||
$row[] = Steam::balance($account, $current);
|
|
||||||
$row[] = $certain;
|
|
||||||
}
|
|
||||||
$chart->addRowArray($row);
|
|
||||||
$current->addDay();
|
|
||||||
}
|
|
||||||
$chart->generate();
|
|
||||||
|
|
||||||
$data = $chart->getData();
|
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return Response::json($data);
|
return Response::json($data);
|
||||||
@ -96,18 +83,15 @@ class AccountController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Shows the balances for all the user's frontpage accounts.
|
* Shows the balances for all the user's frontpage accounts.
|
||||||
*
|
*
|
||||||
* @param GChart $chart
|
|
||||||
* @param AccountRepositoryInterface $repository
|
* @param AccountRepositoryInterface $repository
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function frontpage(GChart $chart, AccountRepositoryInterface $repository)
|
public function frontpage(AccountRepositoryInterface $repository)
|
||||||
{
|
{
|
||||||
$chart->addColumn(trans('firefly.dayOfMonth'), 'date');
|
|
||||||
|
|
||||||
$frontPage = Preferences::get('frontPageAccounts', []);
|
$frontPage = Preferences::get('frontPageAccounts', []);
|
||||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
$start = clone Session::get('start', Carbon::now()->startOfMonth());
|
||||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
$end = clone Session::get('end', Carbon::now()->endOfMonth());
|
||||||
$accounts = $repository->getFrontpageAccounts($frontPage);
|
$accounts = $repository->getFrontpageAccounts($frontPage);
|
||||||
|
|
||||||
// chart properties for cache:
|
// chart properties for cache:
|
||||||
@ -120,30 +104,7 @@ class AccountController extends Controller
|
|||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$data = $this->generator->frontpage($accounts, $start, $end);
|
||||||
$index = 1;
|
|
||||||
/** @var Account $account */
|
|
||||||
foreach ($accounts as $account) {
|
|
||||||
$chart->addColumn(trans('firefly.balanceFor', ['name' => $account->name]), 'number');
|
|
||||||
$chart->addCertainty($index);
|
|
||||||
$index++;
|
|
||||||
}
|
|
||||||
$current = clone $start;
|
|
||||||
$current->subDay();
|
|
||||||
$today = Carbon::now();
|
|
||||||
while ($end >= $current) {
|
|
||||||
$row = [clone $current];
|
|
||||||
$certain = $current < $today;
|
|
||||||
foreach ($accounts as $account) {
|
|
||||||
$row[] = Steam::balance($account, $current);
|
|
||||||
$row[] = $certain;
|
|
||||||
}
|
|
||||||
$chart->addRowArray($row);
|
|
||||||
$current->addDay();
|
|
||||||
}
|
|
||||||
$chart->generate();
|
|
||||||
|
|
||||||
$data = $chart->getData();
|
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return Response::json($data);
|
return Response::json($data);
|
||||||
@ -153,21 +114,16 @@ class AccountController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Shows an account's balance for a single month.
|
* Shows an account's balance for a single month.
|
||||||
*
|
*
|
||||||
* @param GChart $chart
|
|
||||||
* @param Account $account
|
* @param Account $account
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function single(GChart $chart, Account $account)
|
public function single(Account $account)
|
||||||
{
|
{
|
||||||
$chart->addColumn(trans('firefly.dayOfMonth'), 'date');
|
|
||||||
$chart->addColumn(trans('firefly.balanceFor', ['name' => $account->name]), 'number');
|
|
||||||
$chart->addCertainty(1);
|
|
||||||
|
|
||||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
|
||||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||||
$current = clone $start;
|
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||||
$today = new Carbon;
|
|
||||||
|
|
||||||
// chart properties for cache:
|
// chart properties for cache:
|
||||||
$cache = new CacheProperties();
|
$cache = new CacheProperties();
|
||||||
@ -180,16 +136,7 @@ class AccountController extends Controller
|
|||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($end >= $current) {
|
$data = $this->generator->single($account, $start, $end);
|
||||||
$certain = $current < $today;
|
|
||||||
$chart->addRow(clone $current, Steam::balance($account, $current), $certain);
|
|
||||||
$current->addDay();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$chart->generate();
|
|
||||||
|
|
||||||
$data = $chart->getData();
|
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return Response::json($data);
|
return Response::json($data);
|
||||||
|
@ -2,14 +2,13 @@
|
|||||||
|
|
||||||
namespace FireflyIII\Http\Controllers\Chart;
|
namespace FireflyIII\Http\Controllers\Chart;
|
||||||
|
|
||||||
|
use App;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Http\Controllers\Controller;
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
use FireflyIII\Support\CacheProperties;
|
use FireflyIII\Support\CacheProperties;
|
||||||
use Grumpydictator\Gchart\GChart;
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Response;
|
use Response;
|
||||||
use Session;
|
use Session;
|
||||||
@ -22,60 +21,30 @@ use Steam;
|
|||||||
*/
|
*/
|
||||||
class BillController extends Controller
|
class BillController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** @var \FireflyIII\Generator\Chart\Bill\BillChartGenerator */
|
||||||
|
protected $generator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the overview for a bill. The min/max amount and matched journals.
|
* @codeCoverageIgnore
|
||||||
*
|
|
||||||
* @param GChart $chart
|
|
||||||
* @param BillRepositoryInterface $repository
|
|
||||||
* @param Bill $bill
|
|
||||||
*
|
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
|
||||||
*/
|
*/
|
||||||
public function single(GChart $chart, BillRepositoryInterface $repository, Bill $bill)
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
parent::__construct();
|
||||||
$chart->addColumn(trans('firefly.date'), 'date');
|
// create chart generator:
|
||||||
$chart->addColumn(trans('firefly.maxAmount'), 'number');
|
$this->generator = App::make('FireflyIII\Generator\Chart\Bill\BillChartGenerator');
|
||||||
$chart->addColumn(trans('firefly.minAmount'), 'number');
|
|
||||||
$chart->addColumn(trans('firefly.billEntry'), 'number');
|
|
||||||
|
|
||||||
$cache = new CacheProperties;
|
|
||||||
$cache->addProperty('single');
|
|
||||||
$cache->addProperty('bill');
|
|
||||||
$cache->addProperty($bill->id);
|
|
||||||
if ($cache->has()) {
|
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
|
||||||
}
|
|
||||||
|
|
||||||
// get first transaction or today for start:
|
|
||||||
$results = $repository->getJournals($bill);
|
|
||||||
/** @var TransactionJournal $result */
|
|
||||||
foreach ($results as $result) {
|
|
||||||
$chart->addRow(clone $result->date, floatval($bill->amount_max), floatval($bill->amount_min), floatval($result->amount));
|
|
||||||
}
|
|
||||||
|
|
||||||
$chart->generate();
|
|
||||||
|
|
||||||
$data = $chart->getData();
|
|
||||||
$cache->store($data);
|
|
||||||
|
|
||||||
return Response::json($data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows all bills and whether or not theyve been paid this month (pie chart).
|
* Shows all bills and whether or not theyve been paid this month (pie chart).
|
||||||
*
|
*
|
||||||
* @param GChart $chart
|
|
||||||
*
|
|
||||||
* @param BillRepositoryInterface $repository
|
* @param BillRepositoryInterface $repository
|
||||||
* @param AccountRepositoryInterface $accounts
|
* @param AccountRepositoryInterface $accounts
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function frontpage(GChart $chart, BillRepositoryInterface $repository, AccountRepositoryInterface $accounts)
|
public function frontpage(BillRepositoryInterface $repository, AccountRepositoryInterface $accounts)
|
||||||
{
|
{
|
||||||
$chart->addColumn(trans('firefly.name'), 'string');
|
|
||||||
$chart->addColumn(trans('firefly.amount'), 'number');
|
|
||||||
|
|
||||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||||
@ -88,17 +57,13 @@ class BillController extends Controller
|
|||||||
$cache->addProperty('bills');
|
$cache->addProperty('bills');
|
||||||
$cache->addProperty('frontpage');
|
$cache->addProperty('frontpage');
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
$bills = $repository->getActiveBills();
|
$bills = $repository->getActiveBills();
|
||||||
$paid = new Collection; // journals.
|
$paid = new Collection; // journals.
|
||||||
$unpaid = new Collection; // bills
|
$unpaid = new Collection; // bills
|
||||||
// loop paid and create single entry:
|
|
||||||
$paidDescriptions = [];
|
|
||||||
$paidAmount = 0;
|
|
||||||
$unpaidDescriptions = [];
|
|
||||||
$unpaidAmount = 0;
|
|
||||||
|
|
||||||
/** @var Bill $bill */
|
/** @var Bill $bill */
|
||||||
foreach ($bills as $bill) {
|
foreach ($bills as $bill) {
|
||||||
@ -136,30 +101,35 @@ class BillController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build chart:
|
||||||
|
$data = $this->generator->frontpage($paid, $unpaid);
|
||||||
|
$cache->store($data);
|
||||||
|
|
||||||
/** @var TransactionJournal $entry */
|
return Response::json($data);
|
||||||
foreach ($paid as $entry) {
|
}
|
||||||
|
|
||||||
$paidDescriptions[] = $entry->description;
|
/**
|
||||||
$paidAmount += floatval($entry->amount);
|
* Shows the overview for a bill. The min/max amount and matched journals.
|
||||||
|
*
|
||||||
|
* @param BillRepositoryInterface $repository
|
||||||
|
* @param Bill $bill
|
||||||
|
*
|
||||||
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
|
*/
|
||||||
|
public function single(BillRepositoryInterface $repository, Bill $bill)
|
||||||
|
{
|
||||||
|
$cache = new CacheProperties;
|
||||||
|
$cache->addProperty('single');
|
||||||
|
$cache->addProperty('bill');
|
||||||
|
$cache->addProperty($bill->id);
|
||||||
|
if ($cache->has()) {
|
||||||
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop unpaid:
|
// get first transaction or today for start:
|
||||||
/** @var Bill $entry */
|
$results = $repository->getJournals($bill);
|
||||||
foreach ($unpaid as $entry) {
|
|
||||||
$description = $entry[0]->name . ' (' . $entry[1]->format('jS M Y') . ')';
|
|
||||||
$amount = ($entry[0]->amount_max + $entry[0]->amount_min) / 2;
|
|
||||||
$unpaidDescriptions[] = $description;
|
|
||||||
$unpaidAmount += $amount;
|
|
||||||
unset($amount, $description);
|
|
||||||
}
|
|
||||||
|
|
||||||
$chart->addRow(trans('firefly.unpaid') . ': ' . join(', ', $unpaidDescriptions), $unpaidAmount);
|
$data = $this->generator->single($bill, $results);
|
||||||
$chart->addRow(trans('firefly.paid') . ': ' . join(', ', $paidDescriptions), $paidAmount);
|
|
||||||
|
|
||||||
$chart->generate();
|
|
||||||
|
|
||||||
$data = $chart->getData();
|
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return Response::json($data);
|
return Response::json($data);
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
namespace FireflyIII\Http\Controllers\Chart;
|
namespace FireflyIII\Http\Controllers\Chart;
|
||||||
|
|
||||||
|
use App;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Http\Controllers\Controller;
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
use FireflyIII\Models\Budget;
|
use FireflyIII\Models\Budget;
|
||||||
use FireflyIII\Models\LimitRepetition;
|
use FireflyIII\Models\LimitRepetition;
|
||||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
use FireflyIII\Support\CacheProperties;
|
use FireflyIII\Support\CacheProperties;
|
||||||
use Grumpydictator\Gchart\GChart;
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Navigation;
|
use Navigation;
|
||||||
use Preferences;
|
use Preferences;
|
||||||
@ -22,19 +22,30 @@ use Session;
|
|||||||
*/
|
*/
|
||||||
class BudgetController extends Controller
|
class BudgetController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** @var \FireflyIII\Generator\Chart\Budget\BudgetChartGenerator */
|
||||||
|
protected $generator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
// create chart generator:
|
||||||
|
$this->generator = App::make('FireflyIII\Generator\Chart\Budget\BudgetChartGenerator');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param GChart $chart
|
|
||||||
* @param BudgetRepositoryInterface $repository
|
* @param BudgetRepositoryInterface $repository
|
||||||
* @param Budget $budget
|
* @param Budget $budget
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function budget(GChart $chart, BudgetRepositoryInterface $repository, Budget $budget)
|
public function budget(BudgetRepositoryInterface $repository, Budget $budget)
|
||||||
{
|
{
|
||||||
$chart->addColumn(trans('firefly.period'), 'date');
|
|
||||||
$chart->addColumn(trans('firefly.spent'), 'number');
|
|
||||||
|
|
||||||
|
|
||||||
|
// dates and times
|
||||||
$first = $repository->getFirstBudgetLimitDate($budget);
|
$first = $repository->getFirstBudgetLimitDate($budget);
|
||||||
$range = Preferences::get('viewRange', '1M')->data;
|
$range = Preferences::get('viewRange', '1M')->data;
|
||||||
$last = Session::get('end', new Carbon);
|
$last = Session::get('end', new Carbon);
|
||||||
@ -47,33 +58,23 @@ class BudgetController extends Controller
|
|||||||
$cache->addProperty($first);
|
$cache->addProperty($first);
|
||||||
$cache->addProperty($last);
|
$cache->addProperty($last);
|
||||||
$cache->addProperty('budget');
|
$cache->addProperty('budget');
|
||||||
$cache->addProperty('budget');
|
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$entries = new Collection;
|
||||||
|
|
||||||
while ($first < $last) {
|
while ($first < $last) {
|
||||||
$end = Navigation::addPeriod($first, $range, 0);
|
$end = Navigation::addPeriod($first, $range, 0);
|
||||||
$end->subDay();
|
$end->subDay();
|
||||||
|
|
||||||
// start date for chart.
|
|
||||||
$chartDate = clone $end;
|
$chartDate = clone $end;
|
||||||
$chartDate->startOfMonth();
|
$chartDate->startOfMonth();
|
||||||
|
|
||||||
$spent = $repository->spentInPeriodCorrected($budget, $first, $end);
|
$spent = $repository->spentInPeriodCorrected($budget, $first, $end);
|
||||||
$chart->addRow($chartDate, $spent);
|
$entries->push([$chartDate, $spent]);
|
||||||
|
|
||||||
$first = Navigation::addPeriod($first, $range, 0);
|
$first = Navigation::addPeriod($first, $range, 0);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$chart->generate();
|
$data = $this->generator->budget($entries);
|
||||||
|
|
||||||
$data = $chart->getData();
|
|
||||||
|
|
||||||
|
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return Response::json($data);
|
return Response::json($data);
|
||||||
@ -82,14 +83,13 @@ class BudgetController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Shows the amount left in a specific budget limit.
|
* Shows the amount left in a specific budget limit.
|
||||||
*
|
*
|
||||||
* @param GChart $chart
|
|
||||||
* @param BudgetRepositoryInterface $repository
|
* @param BudgetRepositoryInterface $repository
|
||||||
* @param Budget $budget
|
* @param Budget $budget
|
||||||
* @param LimitRepetition $repetition
|
* @param LimitRepetition $repetition
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function budgetLimit(GChart $chart, BudgetRepositoryInterface $repository, Budget $budget, LimitRepetition $repetition)
|
public function budgetLimit(BudgetRepositoryInterface $repository, Budget $budget, LimitRepetition $repetition)
|
||||||
{
|
{
|
||||||
$start = clone $repetition->startdate;
|
$start = clone $repetition->startdate;
|
||||||
$end = $repetition->enddate;
|
$end = $repetition->enddate;
|
||||||
@ -106,11 +106,8 @@ class BudgetController extends Controller
|
|||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
$chart->addColumn(trans('firefly.day'), 'date');
|
$entries = new Collection;
|
||||||
$chart->addColumn(trans('firefly.left'), 'number');
|
$amount = $repetition->amount;
|
||||||
|
|
||||||
|
|
||||||
$amount = $repetition->amount;
|
|
||||||
|
|
||||||
while ($start <= $end) {
|
while ($start <= $end) {
|
||||||
/*
|
/*
|
||||||
@ -118,12 +115,11 @@ class BudgetController extends Controller
|
|||||||
*/
|
*/
|
||||||
$sum = $repository->expensesOnDayCorrected($budget, $start);
|
$sum = $repository->expensesOnDayCorrected($budget, $start);
|
||||||
$amount += $sum;
|
$amount += $sum;
|
||||||
$chart->addRow(clone $start, $amount);
|
$entries->push([clone $start, $amount]);
|
||||||
$start->addDay();
|
$start->addDay();
|
||||||
}
|
}
|
||||||
$chart->generate();
|
|
||||||
|
|
||||||
$data = $chart->getData();
|
$data = $this->generator->budgetLimit($entries);
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return Response::json($data);
|
return Response::json($data);
|
||||||
@ -133,18 +129,12 @@ class BudgetController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Shows a budget list with spent/left/overspent.
|
* Shows a budget list with spent/left/overspent.
|
||||||
*
|
*
|
||||||
* @param GChart $chart
|
|
||||||
* @param BudgetRepositoryInterface $repository
|
* @param BudgetRepositoryInterface $repository
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function frontpage(GChart $chart, BudgetRepositoryInterface $repository)
|
public function frontpage(BudgetRepositoryInterface $repository)
|
||||||
{
|
{
|
||||||
$chart->addColumn(trans('firefly.budget'), 'string');
|
|
||||||
$chart->addColumn(trans('firefly.left'), 'number');
|
|
||||||
$chart->addColumn(trans('firefly.spent'), 'number');
|
|
||||||
$chart->addColumn(trans('firefly.overspent'), 'number');
|
|
||||||
|
|
||||||
$budgets = $repository->getBudgets();
|
$budgets = $repository->getBudgets();
|
||||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||||
@ -160,43 +150,38 @@ class BudgetController extends Controller
|
|||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bcscale(2);
|
||||||
|
|
||||||
/** @var Budget $budget */
|
/** @var Budget $budget */
|
||||||
foreach ($budgets as $budget) {
|
foreach ($budgets as $budget) {
|
||||||
$repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end);
|
$repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end);
|
||||||
if ($repetitions->count() == 0) {
|
if ($repetitions->count() == 0) {
|
||||||
$expenses = $repository->spentInPeriodCorrected($budget, $start, $end, true);
|
$expenses = $repository->spentInPeriodCorrected($budget, $start, $end, true);
|
||||||
$allEntries->push([$budget->name, 0, 0, $expenses]);
|
$allEntries->push([$budget->name, 0, 0, $expenses, 0, 0]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/** @var LimitRepetition $repetition */
|
/** @var LimitRepetition $repetition */
|
||||||
foreach ($repetitions as $repetition) {
|
foreach ($repetitions as $repetition) {
|
||||||
$expenses = $repository->spentInPeriodCorrected($budget, $repetition->startdate, $repetition->enddate, true);
|
$expenses = $repository->spentInPeriodCorrected($budget, $repetition->startdate, $repetition->enddate, true);
|
||||||
$left = $expenses < floatval($repetition->amount) ? floatval($repetition->amount) - $expenses : 0;
|
// $left can be less than zero.
|
||||||
$spent = $expenses > floatval($repetition->amount) ? floatval($repetition->amount) : $expenses;
|
// $overspent can be more than zero ( = overspending)
|
||||||
$overspent = $expenses > floatval($repetition->amount) ? $expenses - floatval($repetition->amount) : 0;
|
|
||||||
$allEntries->push(
|
$left = max(bcsub($repetition->amount, $expenses), 0); // limited at zero.
|
||||||
[$budget->name . ' (' . $repetition->startdate->formatLocalized($this->monthAndDayFormat) . ')',
|
$overspent = max(bcsub($expenses, $repetition->amount), 0); // limited at zero.
|
||||||
$left,
|
$name = $budget->name;
|
||||||
$spent,
|
|
||||||
$overspent
|
// $spent is maxed to the repetition amount:
|
||||||
]
|
$spent = $expenses > $repetition->amount ? $repetition->amount : $expenses;
|
||||||
);
|
|
||||||
|
|
||||||
|
$allEntries->push([$name, $left, $spent, $overspent, $repetition->amount, $expenses]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$noBudgetExpenses = $repository->getWithoutBudgetSum($start, $end) * -1;
|
$noBudgetExpenses = $repository->getWithoutBudgetSum($start, $end) * -1;
|
||||||
$allEntries->push([trans('firefly.noBudget'), 0, 0, $noBudgetExpenses]);
|
$allEntries->push([trans('firefly.noBudget'), 0, 0, $noBudgetExpenses, 0, 0]);
|
||||||
|
|
||||||
foreach ($allEntries as $entry) {
|
$data = $this->generator->frontpage($allEntries);
|
||||||
if ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0) {
|
|
||||||
$chart->addRow($entry[0], $entry[1], $entry[2], $entry[3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$chart->generate();
|
|
||||||
|
|
||||||
$data = $chart->getData();
|
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return Response::json($data);
|
return Response::json($data);
|
||||||
@ -206,14 +191,13 @@ class BudgetController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Show a yearly overview for a budget.
|
* Show a yearly overview for a budget.
|
||||||
*
|
*
|
||||||
* @param GChart $chart
|
|
||||||
* @param BudgetRepositoryInterface $repository
|
* @param BudgetRepositoryInterface $repository
|
||||||
* @param $year
|
* @param $year
|
||||||
* @param bool $shared
|
* @param bool $shared
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function year(GChart $chart, BudgetRepositoryInterface $repository, $year, $shared = false)
|
public function year(BudgetRepositoryInterface $repository, $year, $shared = false)
|
||||||
{
|
{
|
||||||
$start = new Carbon($year . '-01-01');
|
$start = new Carbon($year . '-01-01');
|
||||||
$end = new Carbon($year . '-12-31');
|
$end = new Carbon($year . '-12-31');
|
||||||
@ -230,17 +214,12 @@ class BudgetController extends Controller
|
|||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
// add columns:
|
$entries = new Collection;
|
||||||
$chart->addColumn(trans('firefly.month'), 'date');
|
|
||||||
foreach ($budgets as $budget) {
|
|
||||||
$chart->addColumn($budget->name, 'number');
|
|
||||||
}
|
|
||||||
|
|
||||||
while ($start < $end) {
|
while ($start < $end) {
|
||||||
// month is the current end of the period:
|
// month is the current end of the period:
|
||||||
$month = clone $start;
|
$month = clone $start;
|
||||||
$month->endOfMonth();
|
$month->endOfMonth();
|
||||||
// make a row:
|
|
||||||
$row = [clone $start];
|
$row = [clone $start];
|
||||||
|
|
||||||
// each budget, fill the row:
|
// each budget, fill the row:
|
||||||
@ -248,14 +227,11 @@ class BudgetController extends Controller
|
|||||||
$spent = $repository->spentInPeriodCorrected($budget, $start, $month, $shared);
|
$spent = $repository->spentInPeriodCorrected($budget, $start, $month, $shared);
|
||||||
$row[] = $spent;
|
$row[] = $spent;
|
||||||
}
|
}
|
||||||
$chart->addRowArray($row);
|
$entries->push($row);
|
||||||
|
|
||||||
$start->endOfMonth()->addDay();
|
$start->endOfMonth()->addDay();
|
||||||
}
|
}
|
||||||
|
|
||||||
$chart->generate();
|
$data = $this->generator->year($budgets, $entries);
|
||||||
|
|
||||||
$data = $chart->getData();
|
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return Response::json($data);
|
return Response::json($data);
|
||||||
|
@ -3,12 +3,13 @@
|
|||||||
namespace FireflyIII\Http\Controllers\Chart;
|
namespace FireflyIII\Http\Controllers\Chart;
|
||||||
|
|
||||||
|
|
||||||
|
use App;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Http\Controllers\Controller;
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
use FireflyIII\Models\Category;
|
use FireflyIII\Models\Category;
|
||||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||||
use FireflyIII\Support\CacheProperties;
|
use FireflyIII\Support\CacheProperties;
|
||||||
use Grumpydictator\Gchart\GChart;
|
use Illuminate\Support\Collection;
|
||||||
use Navigation;
|
use Navigation;
|
||||||
use Preferences;
|
use Preferences;
|
||||||
use Response;
|
use Response;
|
||||||
@ -21,42 +22,61 @@ use Session;
|
|||||||
*/
|
*/
|
||||||
class CategoryController extends Controller
|
class CategoryController extends Controller
|
||||||
{
|
{
|
||||||
|
/** @var \FireflyIII\Generator\Chart\Category\CategoryChartGenerator */
|
||||||
|
protected $generator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
// create chart generator:
|
||||||
|
$this->generator = App::make('FireflyIII\Generator\Chart\Category\CategoryChartGenerator');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show an overview for a category for all time, per month/week/year.
|
* Show an overview for a category for all time, per month/week/year.
|
||||||
*
|
*
|
||||||
* @param GChart $chart
|
|
||||||
* @param CategoryRepositoryInterface $repository
|
* @param CategoryRepositoryInterface $repository
|
||||||
* @param Category $category
|
* @param Category $category
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function all(GChart $chart, CategoryRepositoryInterface $repository, Category $category)
|
public function all(CategoryRepositoryInterface $repository, Category $category)
|
||||||
{
|
{
|
||||||
// oldest transaction in category:
|
// oldest transaction in category:
|
||||||
$start = $repository->getFirstActivityDate($category);
|
$start = $repository->getFirstActivityDate($category);
|
||||||
$range = Preferences::get('viewRange', '1M')->data;
|
$range = Preferences::get('viewRange', '1M')->data;
|
||||||
// jump to start of week / month / year / etc
|
|
||||||
$start = Navigation::startOfPeriod($start, $range);
|
$start = Navigation::startOfPeriod($start, $range);
|
||||||
|
$end = new Carbon;
|
||||||
|
|
||||||
$chart->addColumn(trans('firefly.period'), 'date');
|
$entries = new Collection;
|
||||||
$chart->addColumn(trans('firefly.spent'), 'number');
|
|
||||||
|
|
||||||
|
|
||||||
$end = new Carbon;
|
// chart properties for cache:
|
||||||
while ($start <= $end) {
|
$cache = new CacheProperties();
|
||||||
|
$cache->addProperty($start);
|
||||||
$currentEnd = Navigation::endOfPeriod($start, $range);
|
$cache->addProperty($end);
|
||||||
$spent = $repository->spentInPeriodCorrected($category, $start, $currentEnd);
|
$cache->addProperty('all');
|
||||||
$chart->addRow(clone $start, $spent);
|
$cache->addProperty('categories');
|
||||||
|
if ($cache->has()) {
|
||||||
$start = Navigation::addPeriod($start, $range, 0);
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
$chart->generate();
|
while ($start <= $end) {
|
||||||
|
$currentEnd = Navigation::endOfPeriod($start, $range);
|
||||||
|
$spent = $repository->spentInPeriodCorrected($category, $start, $currentEnd);
|
||||||
|
$entries->push([clone $start, $spent]);
|
||||||
|
$start = Navigation::addPeriod($start, $range, 0);
|
||||||
|
|
||||||
return Response::json($chart->getData());
|
}
|
||||||
|
|
||||||
|
$data = $this->generator->all($entries);
|
||||||
|
$cache->store($data);
|
||||||
|
|
||||||
|
return Response::json($data);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -64,15 +84,12 @@ class CategoryController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Show this month's category overview.
|
* Show this month's category overview.
|
||||||
*
|
*
|
||||||
* @param GChart $chart
|
|
||||||
* @param CategoryRepositoryInterface $repository
|
* @param CategoryRepositoryInterface $repository
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function frontpage(GChart $chart, CategoryRepositoryInterface $repository)
|
public function frontpage(CategoryRepositoryInterface $repository)
|
||||||
{
|
{
|
||||||
$chart->addColumn(trans('firefly.category'), 'string');
|
|
||||||
$chart->addColumn(trans('firefly.spent'), 'number');
|
|
||||||
|
|
||||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||||
@ -87,11 +104,10 @@ class CategoryController extends Controller
|
|||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
$set = $repository->getCategoriesAndExpensesCorrected($start, $end);
|
$array = $repository->getCategoriesAndExpensesCorrected($start, $end);
|
||||||
|
|
||||||
// sort by callback:
|
// sort by callback:
|
||||||
uasort(
|
uasort(
|
||||||
$set,
|
$array,
|
||||||
function ($left, $right) {
|
function ($left, $right) {
|
||||||
if ($left['sum'] == $right['sum']) {
|
if ($left['sum'] == $right['sum']) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -100,48 +116,48 @@ class CategoryController extends Controller
|
|||||||
return ($left['sum'] < $right['sum']) ? 1 : -1;
|
return ($left['sum'] < $right['sum']) ? 1 : -1;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
$set = new Collection($array);
|
||||||
|
$data = $this->generator->frontpage($set);
|
||||||
foreach ($set as $entry) {
|
|
||||||
$sum = floatval($entry['sum']);
|
|
||||||
if ($sum != 0) {
|
|
||||||
$chart->addRow($entry['name'], $sum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$chart->generate();
|
|
||||||
|
|
||||||
$data = $chart->getData();
|
|
||||||
$cache->store($data);
|
|
||||||
|
|
||||||
return Response::json($data);
|
return Response::json($data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param GChart $chart
|
|
||||||
* @param CategoryRepositoryInterface $repository
|
* @param CategoryRepositoryInterface $repository
|
||||||
* @param Category $category
|
* @param Category $category
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function month(GChart $chart, CategoryRepositoryInterface $repository, Category $category)
|
public function month(CategoryRepositoryInterface $repository, Category $category)
|
||||||
{
|
{
|
||||||
$start = clone Session::get('start', Carbon::now()->startOfMonth());
|
$start = clone Session::get('start', Carbon::now()->startOfMonth());
|
||||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||||
|
|
||||||
$chart->addColumn(trans('firefly.period'), 'date');
|
// chart properties for cache:
|
||||||
$chart->addColumn(trans('firefly.spent'), 'number');
|
$cache = new CacheProperties;
|
||||||
|
$cache->addProperty($start);
|
||||||
|
$cache->addProperty($end);
|
||||||
|
$cache->addProperty($category->id);
|
||||||
|
$cache->addProperty('category');
|
||||||
|
$cache->addProperty('month');
|
||||||
|
if ($cache->has()) {
|
||||||
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
$entries = new Collection;
|
||||||
|
|
||||||
|
|
||||||
while ($start <= $end) {
|
while ($start <= $end) {
|
||||||
$spent = $repository->spentOnDaySumCorrected($category, $start);
|
$spent = $repository->spentOnDaySumCorrected($category, $start);
|
||||||
$chart->addRow(clone $start, $spent);
|
|
||||||
|
$entries->push([clone $start, $spent]);
|
||||||
$start->addDay();
|
$start->addDay();
|
||||||
}
|
}
|
||||||
|
|
||||||
$chart->generate();
|
$data = $this->generator->month($entries);
|
||||||
|
$cache->store($data);
|
||||||
|
|
||||||
return Response::json($chart->getData());
|
return Response::json($data);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -149,25 +165,31 @@ class CategoryController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This chart will only show expenses.
|
* This chart will only show expenses.
|
||||||
*
|
*
|
||||||
* @param GChart $chart
|
|
||||||
* @param CategoryRepositoryInterface $repository
|
* @param CategoryRepositoryInterface $repository
|
||||||
* @param $year
|
* @param $year
|
||||||
* @param bool $shared
|
* @param bool $shared
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function year(GChart $chart, CategoryRepositoryInterface $repository, $year, $shared = false)
|
public function year(CategoryRepositoryInterface $repository, $year, $shared = false)
|
||||||
{
|
{
|
||||||
$start = new Carbon($year . '-01-01');
|
$start = new Carbon($year . '-01-01');
|
||||||
$end = new Carbon($year . '-12-31');
|
$end = new Carbon($year . '-12-31');
|
||||||
|
|
||||||
|
|
||||||
|
// chart properties for cache:
|
||||||
|
$cache = new CacheProperties;
|
||||||
|
$cache->addProperty($start);
|
||||||
|
$cache->addProperty($end);
|
||||||
|
$cache->addProperty('category');
|
||||||
|
$cache->addProperty('year');
|
||||||
|
if ($cache->has()) {
|
||||||
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
$shared = $shared == 'shared' ? true : false;
|
$shared = $shared == 'shared' ? true : false;
|
||||||
$categories = $repository->getCategories();
|
$categories = $repository->getCategories();
|
||||||
|
$entries = new Collection;
|
||||||
// add columns:
|
|
||||||
$chart->addColumn(trans('firefly.month'), 'date');
|
|
||||||
foreach ($categories as $category) {
|
|
||||||
$chart->addColumn($category->name, 'number');
|
|
||||||
}
|
|
||||||
|
|
||||||
while ($start < $end) {
|
while ($start < $end) {
|
||||||
// month is the current end of the period:
|
// month is the current end of the period:
|
||||||
@ -181,13 +203,14 @@ class CategoryController extends Controller
|
|||||||
$spent = $repository->spentInPeriodCorrected($category, $start, $month, $shared);
|
$spent = $repository->spentInPeriodCorrected($category, $start, $month, $shared);
|
||||||
$row[] = $spent;
|
$row[] = $spent;
|
||||||
}
|
}
|
||||||
$chart->addRowArray($row);
|
$entries->push($row);
|
||||||
|
|
||||||
$start->addMonth();
|
$start->addMonth();
|
||||||
}
|
}
|
||||||
|
|
||||||
$chart->generate();
|
$data = $this->generator->year($categories, $entries);
|
||||||
|
$cache->store($data);
|
||||||
|
|
||||||
return Response::json($chart->getData());
|
return Response::json($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
namespace FireflyIII\Http\Controllers\Chart;
|
namespace FireflyIII\Http\Controllers\Chart;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use App;
|
||||||
use FireflyIII\Http\Controllers\Controller;
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
use FireflyIII\Models\PiggyBank;
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||||
use Grumpydictator\Gchart\GChart;
|
use FireflyIII\Support\CacheProperties;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Response;
|
use Response;
|
||||||
|
|
||||||
@ -18,32 +18,44 @@ use Response;
|
|||||||
*/
|
*/
|
||||||
class PiggyBankController extends Controller
|
class PiggyBankController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** @var \FireflyIII\Generator\Chart\PiggyBank\PiggyBankChartGenerator */
|
||||||
|
protected $generator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
// create chart generator:
|
||||||
|
$this->generator = App::make('FireflyIII\Generator\Chart\PiggyBank\PiggyBankChartGenerator');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the piggy bank history.
|
* Shows the piggy bank history.
|
||||||
*
|
*
|
||||||
* @param GChart $chart
|
|
||||||
* @param PiggyBankRepositoryInterface $repository
|
* @param PiggyBankRepositoryInterface $repository
|
||||||
* @param PiggyBank $piggyBank
|
* @param PiggyBank $piggyBank
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function history(GChart $chart, PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank)
|
public function history(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank)
|
||||||
{
|
{
|
||||||
$chart->addColumn(trans('firefly.date'), 'date');
|
// chart properties for cache:
|
||||||
$chart->addColumn(trans('firefly.balance'), 'number');
|
$cache = new CacheProperties;
|
||||||
|
$cache->addProperty('piggy-history');
|
||||||
/** @var Collection $set */
|
$cache->addProperty($piggyBank->id);
|
||||||
$set = $repository->getEventSummarySet($piggyBank);
|
if ($cache->has()) {
|
||||||
$sum = 0;
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
|
|
||||||
foreach ($set as $entry) {
|
|
||||||
$sum += floatval($entry->sum);
|
|
||||||
$chart->addRow(new Carbon($entry->date), $sum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$chart->generate();
|
/** @var Collection $set */
|
||||||
|
$set = new Collection($repository->getEventSummarySet($piggyBank));
|
||||||
|
$data = $this->generator->history($set);
|
||||||
|
$cache->store($data);
|
||||||
|
|
||||||
return Response::json($chart->getData());
|
return Response::json($data);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
namespace FireflyIII\Http\Controllers\Chart;
|
namespace FireflyIII\Http\Controllers\Chart;
|
||||||
|
|
||||||
|
|
||||||
|
use App;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Helpers\Report\ReportQueryInterface;
|
use FireflyIII\Helpers\Report\ReportQueryInterface;
|
||||||
use FireflyIII\Http\Controllers\Controller;
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
use Grumpydictator\Gchart\GChart;
|
use FireflyIII\Support\CacheProperties;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Response;
|
use Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,85 +19,108 @@ use Response;
|
|||||||
class ReportController extends Controller
|
class ReportController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** @var \FireflyIII\Generator\Chart\Report\ReportChartGenerator */
|
||||||
|
protected $generator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
// create chart generator:
|
||||||
|
$this->generator = App::make('FireflyIII\Generator\Chart\Report\ReportChartGenerator');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Summarizes all income and expenses, per month, for a given year.
|
* Summarizes all income and expenses, per month, for a given year.
|
||||||
*
|
*
|
||||||
* @param GChart $chart
|
|
||||||
* @param ReportQueryInterface $query
|
* @param ReportQueryInterface $query
|
||||||
* @param $year
|
* @param $year
|
||||||
* @param bool $shared
|
* @param bool $shared
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function yearInOut(GChart $chart, ReportQueryInterface $query, $year, $shared = false)
|
public function yearInOut(ReportQueryInterface $query, $year, $shared = false)
|
||||||
{
|
{
|
||||||
// get start and end of year
|
// get start and end of year
|
||||||
$start = new Carbon($year . '-01-01');
|
$start = new Carbon($year . '-01-01');
|
||||||
$end = new Carbon($year . '-12-31');
|
$end = new Carbon($year . '-12-31');
|
||||||
$shared = $shared == 'shared' ? true : false;
|
$shared = $shared == 'shared' ? true : false;
|
||||||
|
|
||||||
$chart->addColumn(trans('firefly.month'), 'date');
|
// chart properties for cache:
|
||||||
$chart->addColumn(trans('firefly.income'), 'number');
|
$cache = new CacheProperties;
|
||||||
$chart->addColumn(trans('firefly.expenses'), 'number');
|
$cache->addProperty('yearInOut');
|
||||||
|
$cache->addProperty($year);
|
||||||
|
$cache->addProperty($shared);
|
||||||
|
if ($cache->has()) {
|
||||||
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
$entries = new Collection;
|
||||||
while ($start < $end) {
|
while ($start < $end) {
|
||||||
$month = clone $start;
|
$month = clone $start;
|
||||||
$month->endOfMonth();
|
$month->endOfMonth();
|
||||||
// total income and total expenses:
|
// total income and total expenses:
|
||||||
$incomeSum = floatval($query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount'));
|
$incomeSum = $query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount');
|
||||||
$expenseSum = floatval($query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount'));
|
$expenseSum = $query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount');
|
||||||
|
|
||||||
$chart->addRow(clone $start, $incomeSum, $expenseSum);
|
$entries->push([clone $start, $incomeSum, $expenseSum]);
|
||||||
$start->addMonth();
|
$start->addMonth();
|
||||||
}
|
}
|
||||||
$chart->generate();
|
|
||||||
|
|
||||||
return Response::json($chart->getData());
|
$data = $this->generator->yearInOut($entries);
|
||||||
|
$cache->store($data);
|
||||||
|
|
||||||
|
return Response::json($data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Summarizes all income and expenses for a given year. Gives a total and an average.
|
* Summarizes all income and expenses for a given year. Gives a total and an average.
|
||||||
*
|
*
|
||||||
* @param GChart $chart
|
|
||||||
* @param ReportQueryInterface $query
|
* @param ReportQueryInterface $query
|
||||||
* @param $year
|
* @param $year
|
||||||
* @param bool $shared
|
* @param bool $shared
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function yearInOutSummarized(GChart $chart, ReportQueryInterface $query, $year, $shared = false)
|
public function yearInOutSummarized(ReportQueryInterface $query, $year, $shared = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// chart properties for cache:
|
||||||
|
$cache = new CacheProperties;
|
||||||
|
$cache->addProperty('yearInOutSummarized');
|
||||||
|
$cache->addProperty($year);
|
||||||
|
$cache->addProperty($shared);
|
||||||
|
if ($cache->has()) {
|
||||||
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
$start = new Carbon($year . '-01-01');
|
$start = new Carbon($year . '-01-01');
|
||||||
$end = new Carbon($year . '-12-31');
|
$end = new Carbon($year . '-12-31');
|
||||||
$shared = $shared == 'shared' ? true : false;
|
$shared = $shared == 'shared' ? true : false;
|
||||||
$income = 0;
|
$income = '0';
|
||||||
$expense = 0;
|
$expense = '0';
|
||||||
$count = 0;
|
$count = 0;
|
||||||
|
|
||||||
$chart->addColumn(trans('firefly.summary'), 'string');
|
bcscale(2);
|
||||||
$chart->addColumn(trans('firefly.income'), 'number');
|
|
||||||
$chart->addColumn(trans('firefly.expenses'), 'number');
|
|
||||||
|
|
||||||
while ($start < $end) {
|
while ($start < $end) {
|
||||||
$month = clone $start;
|
$month = clone $start;
|
||||||
$month->endOfMonth();
|
$month->endOfMonth();
|
||||||
// total income and total expenses:
|
// total income and total expenses:
|
||||||
$income += floatval($query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount'));
|
$income = bcadd($income, $query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount'));
|
||||||
$expense += floatval($query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount'));
|
$expense = bcadd($expense, $query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount'));
|
||||||
$count++;
|
$count++;
|
||||||
$start->addMonth();
|
$start->addMonth();
|
||||||
}
|
}
|
||||||
|
|
||||||
// add total + average:
|
$data = $this->generator->yearInOutSummarized($income, $expense, $count);
|
||||||
$chart->addRow(trans('firefly.sum'), $income, $expense);
|
$cache->store($data);
|
||||||
$count = $count > 0 ? $count : 1;
|
|
||||||
$chart->addRow(trans('firefly.average'), ($income / $count), ($expense / $count));
|
|
||||||
|
|
||||||
$chart->generate();
|
return Response::json($data);
|
||||||
|
|
||||||
return Response::json($chart->getData());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,8 +142,6 @@ class PiggyBankController extends Controller
|
|||||||
'account_id' => $piggyBank->account_id,
|
'account_id' => $piggyBank->account_id,
|
||||||
'targetamount' => $piggyBank->targetamount,
|
'targetamount' => $piggyBank->targetamount,
|
||||||
'targetdate' => $targetDate,
|
'targetdate' => $targetDate,
|
||||||
'reminder' => $piggyBank->reminder,
|
|
||||||
'remind_me' => intval($piggyBank->remind_me) == 1 && !is_null($piggyBank->reminder) ? true : false
|
|
||||||
];
|
];
|
||||||
Session::flash('preFilled', $preFilled);
|
Session::flash('preFilled', $preFilled);
|
||||||
Session::flash('gaEventCategory', 'piggy-banks');
|
Session::flash('gaEventCategory', 'piggy-banks');
|
||||||
@ -299,12 +297,7 @@ class PiggyBankController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function show(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank)
|
public function show(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank)
|
||||||
{
|
{
|
||||||
$events = $repository->getEvents($piggyBank);
|
$events = $repository->getEvents($piggyBank);
|
||||||
|
|
||||||
/*
|
|
||||||
* Number of reminders:
|
|
||||||
*/
|
|
||||||
|
|
||||||
$subTitle = e($piggyBank->name);
|
$subTitle = e($piggyBank->name);
|
||||||
|
|
||||||
return view('piggy-banks.show', compact('piggyBank', 'events', 'subTitle'));
|
return view('piggy-banks.show', compact('piggyBank', 'events', 'subTitle'));
|
||||||
@ -321,13 +314,13 @@ class PiggyBankController extends Controller
|
|||||||
{
|
{
|
||||||
|
|
||||||
$piggyBankData = [
|
$piggyBankData = [
|
||||||
'name' => $request->get('name'),
|
'name' => $request->get('name'),
|
||||||
'startdate' => new Carbon,
|
'startdate' => new Carbon,
|
||||||
'account_id' => intval($request->get('account_id')),
|
'account_id' => intval($request->get('account_id')),
|
||||||
'targetamount' => floatval($request->get('targetamount')),
|
'targetamount' => floatval($request->get('targetamount')),
|
||||||
'targetdate' => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
|
'remind_me' => false,
|
||||||
'reminder' => $request->get('reminder'),
|
'reminder_skip' => 0,
|
||||||
'remind_me' => $request->get('remind_me'),
|
'targetdate' => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
|
||||||
];
|
];
|
||||||
|
|
||||||
$piggyBank = $repository->store($piggyBankData);
|
$piggyBank = $repository->store($piggyBankData);
|
||||||
@ -356,13 +349,13 @@ class PiggyBankController extends Controller
|
|||||||
public function update(PiggyBankRepositoryInterface $repository, PiggyBankFormRequest $request, PiggyBank $piggyBank)
|
public function update(PiggyBankRepositoryInterface $repository, PiggyBankFormRequest $request, PiggyBank $piggyBank)
|
||||||
{
|
{
|
||||||
$piggyBankData = [
|
$piggyBankData = [
|
||||||
'name' => $request->get('name'),
|
'name' => $request->get('name'),
|
||||||
'startdate' => is_null($piggyBank->startdate) ? $piggyBank->created_at : $piggyBank->startdate,
|
'startdate' => is_null($piggyBank->startdate) ? $piggyBank->created_at : $piggyBank->startdate,
|
||||||
'account_id' => intval($request->get('account_id')),
|
'account_id' => intval($request->get('account_id')),
|
||||||
'targetamount' => floatval($request->get('targetamount')),
|
'targetamount' => floatval($request->get('targetamount')),
|
||||||
'targetdate' => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
|
'remind_me' => false,
|
||||||
'reminder' => $request->get('reminder'),
|
'reminder_skip' => 0,
|
||||||
'remind_me' => $request->get('remind_me')
|
'targetdate' => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
|
||||||
];
|
];
|
||||||
|
|
||||||
$piggyBank = $repository->update($piggyBank, $piggyBankData);
|
$piggyBank = $repository->update($piggyBank, $piggyBankData);
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
<?php namespace FireflyIII\Http\Controllers;
|
|
||||||
|
|
||||||
use FireflyIII\Models\Reminder;
|
|
||||||
use FireflyIII\Repositories\Reminder\ReminderRepositoryInterface;
|
|
||||||
use Redirect;
|
|
||||||
use Session;
|
|
||||||
use URL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ReminderController
|
|
||||||
*
|
|
||||||
* @package FireflyIII\Http\Controllers
|
|
||||||
*/
|
|
||||||
class ReminderController extends Controller
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Reminder $reminder
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
*/
|
|
||||||
public function act(Reminder $reminder)
|
|
||||||
{
|
|
||||||
$data = [
|
|
||||||
'description' => 'Money for piggy bank "' . $reminder->remindersable->name . '"',
|
|
||||||
'amount' => round($reminder->metadata->perReminder, 2),
|
|
||||||
'account_to_id' => $reminder->remindersable->account_id,
|
|
||||||
'piggy_bank_id' => $reminder->remindersable_id,
|
|
||||||
'reminder_id' => $reminder->id,
|
|
||||||
];
|
|
||||||
Session::flash('_old_input', $data);
|
|
||||||
|
|
||||||
return Redirect::route('transactions.create', ['transfer']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Reminder $reminder
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
*/
|
|
||||||
public function dismiss(Reminder $reminder)
|
|
||||||
{
|
|
||||||
$reminder->notnow = true;
|
|
||||||
$reminder->save();
|
|
||||||
|
|
||||||
return Redirect::to(URL::previous());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ReminderRepositoryInterface $repository
|
|
||||||
*
|
|
||||||
* @return \Illuminate\View\View
|
|
||||||
*/
|
|
||||||
public function index(ReminderRepositoryInterface $repository)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
$active = $repository->getActiveReminders();
|
|
||||||
$expired = $repository->getExpiredReminders();
|
|
||||||
$inactive = $repository->getInactiveReminders();
|
|
||||||
$dismissed = $repository->getDismissedReminders();
|
|
||||||
|
|
||||||
$title = 'Reminders';
|
|
||||||
$mainTitleIcon = 'fa-clock-o';
|
|
||||||
|
|
||||||
return view('reminders.index', compact('dismissed', 'expired', 'inactive', 'active', 'title', 'mainTitleIcon'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Reminder $reminder
|
|
||||||
*
|
|
||||||
* @return \Illuminate\View\View
|
|
||||||
*/
|
|
||||||
public function show(Reminder $reminder)
|
|
||||||
{
|
|
||||||
$title = trans('firefly.reminder');
|
|
||||||
$mainTitleIcon = 'fa-clock-o';
|
|
||||||
if ($reminder->notnow === true) {
|
|
||||||
$subTitle = trans('firefly.dismissed_reminder_for_piggy', ['name' => $reminder->remindersable->name]);
|
|
||||||
} else {
|
|
||||||
$subTitle = trans('firefly.reminder_for_piggy', ['name' => $reminder->remindersable->name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('reminders.show', compact('reminder', 'title', 'subTitle', 'mainTitleIcon'));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -180,12 +180,12 @@ class TagController extends Controller
|
|||||||
$helpHidden = $helpHiddenPref->data;
|
$helpHidden = $helpHiddenPref->data;
|
||||||
|
|
||||||
// group years.
|
// group years.
|
||||||
$types = ['nothing','balancingAct', 'advancePayment'];
|
$types = ['nothing', 'balancingAct', 'advancePayment'];
|
||||||
|
|
||||||
// loop each types and get the tags, group them by year.
|
// loop each types and get the tags, group them by year.
|
||||||
$collection = [];
|
$collection = [];
|
||||||
foreach ($types as $type) {
|
foreach ($types as $type) {
|
||||||
$tags = Auth::user()->tags()->where('tagMode', $type)->orderBy('date','ASC')->get();
|
$tags = Auth::user()->tags()->where('tagMode', $type)->orderBy('date', 'ASC')->get();
|
||||||
/** @var Tag $tag */
|
/** @var Tag $tag */
|
||||||
foreach ($tags as $tag) {
|
foreach ($tags as $tag) {
|
||||||
$year = is_null($tag->date) ? trans('firefly.no_year') : $tag->date->year;
|
$year = is_null($tag->date) ? trans('firefly.no_year') : $tag->date->year;
|
||||||
@ -195,7 +195,7 @@ class TagController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return view('tags.index', compact('title', 'mainTitleIcon','types', 'helpHidden', 'collection'));
|
return view('tags.index', compact('title', 'mainTitleIcon', 'types', 'helpHidden', 'collection'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,7 +208,7 @@ class TagController extends Controller
|
|||||||
$subTitle = $tag->tag;
|
$subTitle = $tag->tag;
|
||||||
$subTitleIcon = 'fa-tag';
|
$subTitleIcon = 'fa-tag';
|
||||||
|
|
||||||
return view('tags.show', compact('tag', 'subTitle','types', 'subTitleIcon'));
|
return view('tags.show', compact('tag', 'subTitle', 'subTitleIcon'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -159,20 +159,12 @@ class TransactionController extends Controller
|
|||||||
|
|
||||||
if ($journal->transactionType->type == 'Withdrawal') {
|
if ($journal->transactionType->type == 'Withdrawal') {
|
||||||
$preFilled['account_id'] = $journal->source_account->id;
|
$preFilled['account_id'] = $journal->source_account->id;
|
||||||
$preFilled['expense_account'] = $journal->destination_account->name;
|
$preFilled['expense_account'] = $journal->destination_account->name_for_editform;
|
||||||
} else {
|
} else {
|
||||||
$preFilled['account_id'] = $journal->destination_account->id;
|
$preFilled['account_id'] = $journal->destination_account->id;
|
||||||
$preFilled['revenue_account'] = $journal->source_account->name;
|
$preFilled['revenue_account'] = $journal->source_account->name_for_editform;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($journal->destination_account->accountType->type == 'Cash account') {
|
|
||||||
$preFilled['expense_account'] = '';
|
|
||||||
}
|
|
||||||
if ($journal->source_account->accountType->type == 'Cash account') {
|
|
||||||
$preFilled['revenue_account'] = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$preFilled['account_from_id'] = $journal->source_account->id;
|
$preFilled['account_from_id'] = $journal->source_account->id;
|
||||||
$preFilled['account_to_id'] = $journal->destination_account->id;
|
$preFilled['account_to_id'] = $journal->destination_account->id;
|
||||||
|
|
||||||
@ -296,8 +288,6 @@ class TransactionController extends Controller
|
|||||||
event(new JournalCreated($journal, intval($request->get('piggy_bank_id'))));
|
event(new JournalCreated($journal, intval($request->get('piggy_bank_id'))));
|
||||||
}
|
}
|
||||||
|
|
||||||
$repository->deactivateReminder($request->get('reminder_id'));
|
|
||||||
|
|
||||||
Session::flash('success', 'New transaction "' . $journal->description . '" stored!');
|
Session::flash('success', 'New transaction "' . $journal->description . '" stored!');
|
||||||
Preferences::mark();
|
Preferences::mark();
|
||||||
|
|
||||||
|
@ -37,7 +37,6 @@ class Kernel extends HttpKernel
|
|||||||
'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
|
'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
|
||||||
'guest' => 'FireflyIII\Http\Middleware\RedirectIfAuthenticated',
|
'guest' => 'FireflyIII\Http\Middleware\RedirectIfAuthenticated',
|
||||||
'range' => 'FireflyIII\Http\Middleware\Range',
|
'range' => 'FireflyIII\Http\Middleware\Range',
|
||||||
'reminders' => 'FireflyIII\Http\Middleware\Reminders',
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -1,96 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace FireflyIII\Http\Middleware;
|
|
||||||
|
|
||||||
use App;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Closure;
|
|
||||||
use FireflyIII\Models\PiggyBank;
|
|
||||||
use FireflyIII\Models\Reminder;
|
|
||||||
use FireflyIII\Support\CacheProperties;
|
|
||||||
use FireflyIII\User;
|
|
||||||
use Illuminate\Contracts\Auth\Guard;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use View;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class Reminders
|
|
||||||
*
|
|
||||||
* @package FireflyIII\Http\Middleware
|
|
||||||
*/
|
|
||||||
class Reminders
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The Guard implementation.
|
|
||||||
*
|
|
||||||
* @var Guard
|
|
||||||
*/
|
|
||||||
protected $auth;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new filter instance.
|
|
||||||
*
|
|
||||||
* @param Guard $auth
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public function __construct(Guard $auth)
|
|
||||||
{
|
|
||||||
$this->auth = $auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle an incoming request.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @param \Closure $next
|
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function handle(Request $request, Closure $next)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
$user = $this->auth->user();
|
|
||||||
if ($this->auth->check() && !$request->isXmlHttpRequest() && $user instanceof User) {
|
|
||||||
// do reminders stuff.
|
|
||||||
|
|
||||||
// abuse CacheProperties to find out if we need to do this:
|
|
||||||
$cache = new CacheProperties;
|
|
||||||
|
|
||||||
$cache->addProperty('reminders');
|
|
||||||
if ($cache->has()) {
|
|
||||||
$reminders = $cache->get();
|
|
||||||
View::share('reminders', $reminders);
|
|
||||||
|
|
||||||
return $next($request);
|
|
||||||
}
|
|
||||||
|
|
||||||
$piggyBanks = $user->piggyBanks()->where('remind_me', 1)->get();
|
|
||||||
|
|
||||||
/** @var \FireflyIII\Helpers\Reminders\ReminderHelperInterface $helper */
|
|
||||||
$helper = App::make('FireflyIII\Helpers\Reminders\ReminderHelperInterface');
|
|
||||||
|
|
||||||
/** @var PiggyBank $piggyBank */
|
|
||||||
foreach ($piggyBanks as $piggyBank) {
|
|
||||||
$helper->createReminders($piggyBank, new Carbon);
|
|
||||||
}
|
|
||||||
// delete invalid reminders
|
|
||||||
// this is a construction SQLITE cannot handle :(
|
|
||||||
if (env('DB_CONNECTION') != 'sqlite') {
|
|
||||||
Reminder::whereUserId($user->id)->leftJoin('piggy_banks', 'piggy_banks.id', '=', 'remindersable_id')->whereNull('piggy_banks.id')->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get and list active reminders:
|
|
||||||
$reminders = $user->reminders()->today()->get();
|
|
||||||
$reminders->each(
|
|
||||||
function (Reminder $reminder) use ($helper) {
|
|
||||||
$reminder->description = $helper->getReminderText($reminder);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
$cache->store($reminders);
|
|
||||||
View::share('reminders', $reminders);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $next($request);
|
|
||||||
}
|
|
||||||
}
|
|
@ -61,7 +61,6 @@ class JournalFormRequest extends Request
|
|||||||
'what' => 'required|in:withdrawal,deposit,transfer',
|
'what' => 'required|in:withdrawal,deposit,transfer',
|
||||||
'amount' => 'numeric|required|min:0.01',
|
'amount' => 'numeric|required|min:0.01',
|
||||||
'date' => 'required|date',
|
'date' => 'required|date',
|
||||||
'reminder_id' => 'numeric|exists:reminders,id',
|
|
||||||
'amount_currency_id' => 'required|exists:transaction_currencies,id',
|
'amount_currency_id' => 'required|exists:transaction_currencies,id',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -42,9 +42,6 @@ class PiggyBankFormRequest extends Request
|
|||||||
'amount_currency_id' => 'exists:transaction_currencies,id',
|
'amount_currency_id' => 'exists:transaction_currencies,id',
|
||||||
'startdate' => 'date',
|
'startdate' => 'date',
|
||||||
'targetdate' => $targetDateRule,
|
'targetdate' => $targetDateRule,
|
||||||
'reminder' => 'in:day,week,quarter,month,year',
|
|
||||||
'reminder_skip' => 'integer|min:0|max:99',
|
|
||||||
'remind_me' => 'boolean|piggyBankReminder',
|
|
||||||
'order' => 'integer|min:1',
|
'order' => 'integer|min:1',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -7,7 +7,6 @@ use FireflyIII\Models\Budget;
|
|||||||
use FireflyIII\Models\Category;
|
use FireflyIII\Models\Category;
|
||||||
use FireflyIII\Models\LimitRepetition;
|
use FireflyIII\Models\LimitRepetition;
|
||||||
use FireflyIII\Models\PiggyBank;
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\Models\Reminder;
|
|
||||||
use FireflyIII\Models\Tag;
|
use FireflyIII\Models\Tag;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
@ -286,25 +285,6 @@ Breadcrumbs::register(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// reminders
|
|
||||||
Breadcrumbs::register(
|
|
||||||
'reminders.index', function (Generator $breadcrumbs) {
|
|
||||||
$breadcrumbs->parent('home');
|
|
||||||
$breadcrumbs->push(trans('breadcrumbs.reminders'), route('reminders.index'));
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// reminders
|
|
||||||
Breadcrumbs::register(
|
|
||||||
'reminders.show', function (Generator $breadcrumbs, Reminder $reminder) {
|
|
||||||
$breadcrumbs->parent('reminders.index');
|
|
||||||
$breadcrumbs->push(trans('breadcrumbs.reminder', ['id' => e($reminder->id)]), route('reminders.show', [$reminder->id]));
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// reports
|
// reports
|
||||||
Breadcrumbs::register(
|
Breadcrumbs::register(
|
||||||
'reports.index', function (Generator $breadcrumbs) {
|
'reports.index', function (Generator $breadcrumbs) {
|
||||||
|
@ -5,7 +5,6 @@ use FireflyIII\Models\Budget;
|
|||||||
use FireflyIII\Models\Category;
|
use FireflyIII\Models\Category;
|
||||||
use FireflyIII\Models\LimitRepetition;
|
use FireflyIII\Models\LimitRepetition;
|
||||||
use FireflyIII\Models\PiggyBank;
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\Models\Reminder;
|
|
||||||
use FireflyIII\Models\Tag;
|
use FireflyIII\Models\Tag;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
@ -81,19 +80,6 @@ Route::bind(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
Route::bind(
|
|
||||||
'reminder', function ($value) {
|
|
||||||
if (Auth::check()) {
|
|
||||||
$object = Reminder::where('id', $value)->where('user_id', Auth::user()->id)->first();
|
|
||||||
if ($object) {
|
|
||||||
return $object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new NotFoundHttpException;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
Route::bind(
|
Route::bind(
|
||||||
'limitrepetition', function ($value) {
|
'limitrepetition', function ($value) {
|
||||||
if (Auth::check()) {
|
if (Auth::check()) {
|
||||||
@ -140,23 +126,6 @@ Route::bind(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
/** @noinspection PhpUnusedParameterInspection */
|
|
||||||
Route::bind(
|
|
||||||
'reminder', function ($value) {
|
|
||||||
if (Auth::check()) {
|
|
||||||
/** @var \FireflyIII\Models\Reminder $object */
|
|
||||||
$object = Reminder::find($value);
|
|
||||||
if ($object) {
|
|
||||||
if ($object->remindersable->account->user_id == Auth::user()->id) {
|
|
||||||
return $object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new NotFoundHttpException;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
Route::bind(
|
Route::bind(
|
||||||
'tag', function ($value) {
|
'tag', function ($value) {
|
||||||
if (Auth::check()) {
|
if (Auth::check()) {
|
||||||
@ -185,7 +154,7 @@ Route::controllers(
|
|||||||
|
|
||||||
|
|
||||||
Route::group(
|
Route::group(
|
||||||
['middleware' => ['auth', 'range', 'reminders']], function () {
|
['middleware' => ['auth', 'range']], function () {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Home Controller
|
* Home Controller
|
||||||
@ -355,14 +324,6 @@ Route::group(
|
|||||||
Route::post('/profile/delete-account', ['uses' => 'ProfileController@postDeleteAccount', 'as' => 'delete-account-post']);
|
Route::post('/profile/delete-account', ['uses' => 'ProfileController@postDeleteAccount', 'as' => 'delete-account-post']);
|
||||||
Route::post('/profile/change-password', ['uses' => 'ProfileController@postChangePassword', 'as' => 'change-password-post']);
|
Route::post('/profile/change-password', ['uses' => 'ProfileController@postChangePassword', 'as' => 'change-password-post']);
|
||||||
|
|
||||||
/**
|
|
||||||
* 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/act/{reminder}', ['uses' => 'ReminderController@act', 'as' => 'reminders.act']);
|
|
||||||
Route::get('/reminder/{reminder}', ['uses' => 'ReminderController@show', 'as' => 'reminders.show']);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report Controller
|
* Report Controller
|
||||||
*/
|
*/
|
||||||
|
@ -180,6 +180,20 @@ class Account extends Model
|
|||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getNameForEditformAttribute()
|
||||||
|
{
|
||||||
|
$name = $this->name;
|
||||||
|
if ($this->accountType->type == 'Cash account') {
|
||||||
|
$name = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
* FireflyIII\Models\Bill
|
* FireflyIII\Models\Bill
|
||||||
*
|
*
|
||||||
* @codeCoverageIgnore Class Bill
|
* @codeCoverageIgnore Class Bill
|
||||||
* @package FireflyIII\Models
|
* @package FireflyIII\Models
|
||||||
* @property integer $id
|
* @property integer $id
|
||||||
* @property \Carbon\Carbon $created_at
|
* @property \Carbon\Carbon $created_at
|
||||||
* @property \Carbon\Carbon $updated_at
|
* @property \Carbon\Carbon $updated_at
|
||||||
|
@ -19,15 +19,11 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* @property string $targetamount_encrypted
|
* @property string $targetamount_encrypted
|
||||||
* @property \Carbon\Carbon $startdate
|
* @property \Carbon\Carbon $startdate
|
||||||
* @property \Carbon\Carbon $targetdate
|
* @property \Carbon\Carbon $targetdate
|
||||||
* @property string $reminder
|
|
||||||
* @property integer $reminder_skip
|
|
||||||
* @property boolean $remind_me
|
|
||||||
* @property integer $order
|
* @property integer $order
|
||||||
* @property boolean $encrypted
|
* @property boolean $encrypted
|
||||||
* @property-read \FireflyIII\Models\Account $account
|
* @property-read \FireflyIII\Models\Account $account
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBankRepetition[] $piggyBankRepetitions
|
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBankRepetition[] $piggyBankRepetitions
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBankEvent[] $piggyBankEvents
|
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBankEvent[] $piggyBankEvents
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Reminder[] $reminders
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereId($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereId($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereCreatedAt($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereCreatedAt($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereUpdatedAt($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereUpdatedAt($value)
|
||||||
@ -38,9 +34,6 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereTargetamountEncrypted($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereTargetamountEncrypted($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereStartdate($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereStartdate($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereTargetdate($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereTargetdate($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereReminder($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereReminderSkip($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereRemindMe($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereOrder($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereOrder($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereEncrypted($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereEncrypted($value)
|
||||||
* @property PiggyBankRepetition currentRep
|
* @property PiggyBankRepetition currentRep
|
||||||
@ -50,7 +43,7 @@ class PiggyBank extends Model
|
|||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
|
||||||
protected $fillable
|
protected $fillable
|
||||||
= ['name', 'account_id', 'order', 'reminder_skip', 'targetamount', 'startdate', 'targetdate', 'reminder', 'remind_me'];
|
= ['name', 'account_id', 'order', 'targetamount', 'startdate', 'targetdate', 'remind_me', 'reminder_skip'];
|
||||||
protected $hidden = ['targetamount_encrypted', 'encrypted'];
|
protected $hidden = ['targetamount_encrypted', 'encrypted'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,17 +105,6 @@ class PiggyBank extends Model
|
|||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param $value
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function getRemindMeAttribute($value)
|
|
||||||
{
|
|
||||||
return intval($value) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
*/
|
*/
|
||||||
@ -131,14 +113,6 @@ class PiggyBank extends Model
|
|||||||
return $this->hasMany('FireflyIII\Models\PiggyBankEvent');
|
return $this->hasMany('FireflyIII\Models\PiggyBankEvent');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
|
|
||||||
*/
|
|
||||||
public function reminders()
|
|
||||||
{
|
|
||||||
return $this->morphMany('FireflyIII\Models\Reminder', 'remindersable');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param $value
|
* @param $value
|
||||||
|
@ -1,148 +0,0 @@
|
|||||||
<?php namespace FireflyIII\Models;
|
|
||||||
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Crypt;
|
|
||||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class Reminder
|
|
||||||
*
|
|
||||||
* @codeCoverageIgnore
|
|
||||||
* @package FireflyIII\Models
|
|
||||||
* @property integer $id
|
|
||||||
* @property \Carbon\Carbon $created_at
|
|
||||||
* @property \Carbon\Carbon $updated_at
|
|
||||||
* @property integer $user_id
|
|
||||||
* @property \Carbon\Carbon $startdate
|
|
||||||
* @property \Carbon\Carbon $enddate
|
|
||||||
* @property boolean $active
|
|
||||||
* @property boolean $notnow
|
|
||||||
* @property integer $remindersable_id
|
|
||||||
* @property string $remindersable_type
|
|
||||||
* @property string $metadata
|
|
||||||
* @property boolean $encrypted
|
|
||||||
* @property-read \ $remindersable
|
|
||||||
* @property-read \FireflyIII\User $user
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Reminder whereId($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Reminder whereCreatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Reminder whereUpdatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Reminder whereUserId($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Reminder whereStartdate($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Reminder whereEnddate($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Reminder whereActive($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Reminder whereNotnow($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Reminder whereRemindersableId($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Reminder whereRemindersableType($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Reminder whereMetadata($value)
|
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Reminder whereEncrypted($value)
|
|
||||||
* @method static \FireflyIII\Models\Reminder onDates($start, $end)
|
|
||||||
* @method static \FireflyIII\Models\Reminder today()
|
|
||||||
* @property string description
|
|
||||||
*/
|
|
||||||
class Reminder extends Model
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
protected $fillable = ['user_id', 'startdate', 'metadata', 'enddate', 'active', 'notnow', 'remindersable_id', 'remindersable_type',];
|
|
||||||
protected $hidden = ['encrypted'];
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param $value
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getActiveAttribute($value)
|
|
||||||
{
|
|
||||||
return intval($value) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getDates()
|
|
||||||
{
|
|
||||||
return ['created_at', 'updated_at', 'startdate', 'enddate'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param $value
|
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getMetadataAttribute($value)
|
|
||||||
{
|
|
||||||
if (intval($this->encrypted) == 1) {
|
|
||||||
return json_decode(Crypt::decrypt($value));
|
|
||||||
}
|
|
||||||
|
|
||||||
return json_decode($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param $value
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function getNotnowAttribute($value)
|
|
||||||
{
|
|
||||||
return intval($value) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
|
||||||
*/
|
|
||||||
public function remindersable()
|
|
||||||
{
|
|
||||||
return $this->morphTo();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param EloquentBuilder $query
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function scopeOnDates(EloquentBuilder $query, Carbon $start, Carbon $end)
|
|
||||||
{
|
|
||||||
return $query->where('reminders.startdate', '=', $start->format('Y-m-d 00:00:00'))->where('reminders.enddate', '=', $end->format('Y-m-d 00:00:00'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param EloquentBuilder $query
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function scopeToday(EloquentBuilder $query)
|
|
||||||
{
|
|
||||||
$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)
|
|
||||||
->where('notnow', 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param $value
|
|
||||||
*/
|
|
||||||
public function setMetadataAttribute($value)
|
|
||||||
{
|
|
||||||
$this->attributes['encrypted'] = true;
|
|
||||||
$this->attributes['metadata'] = Crypt::encrypt(json_encode($value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
||||||
*/
|
|
||||||
public function user()
|
|
||||||
{
|
|
||||||
return $this->belongsTo('FireflyIII\User');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -159,12 +159,12 @@ class TransactionJournal extends Model
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->tag_count === 1) {
|
if (intval($this->tag_count) === 1) {
|
||||||
// get amount for single tag:
|
// get amount for single tag:
|
||||||
$amount = $this->amountByTag($this->tags()->first(), $amount);
|
$amount = $this->amountByTag($this->tags()->first(), $amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->tag_count > 1) {
|
if (intval($this->tag_count) > 1) {
|
||||||
// get amount for either tag.
|
// get amount for either tag.
|
||||||
$amount = $this->amountByTags($amount);
|
$amount = $this->amountByTags($amount);
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ use FireflyIII\Models\BudgetLimit;
|
|||||||
use FireflyIII\Models\LimitRepetition;
|
use FireflyIII\Models\LimitRepetition;
|
||||||
use FireflyIII\Models\PiggyBank;
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\Models\PiggyBankRepetition;
|
use FireflyIII\Models\PiggyBankRepetition;
|
||||||
use FireflyIII\Models\Reminder;
|
|
||||||
use FireflyIII\Models\Transaction;
|
use FireflyIII\Models\Transaction;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use FireflyIII\Support\Facades\Navigation;
|
use FireflyIII\Support\Facades\Navigation;
|
||||||
@ -53,8 +52,6 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
$this->registerCreateEvents();
|
$this->registerCreateEvents();
|
||||||
BudgetLimit::saved(
|
BudgetLimit::saved(
|
||||||
function (BudgetLimit $budgetLimit) {
|
function (BudgetLimit $budgetLimit) {
|
||||||
Log::debug('Saved!');
|
|
||||||
|
|
||||||
$end = Navigation::addPeriod(clone $budgetLimit->startdate, $budgetLimit->repeat_freq, 0);
|
$end = Navigation::addPeriod(clone $budgetLimit->startdate, $budgetLimit->repeat_freq, 0);
|
||||||
$end->subDay();
|
$end->subDay();
|
||||||
$set = $budgetLimit->limitrepetitions()
|
$set = $budgetLimit->limitrepetitions()
|
||||||
@ -101,15 +98,6 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
PiggyBank::deleting(
|
|
||||||
function (PiggyBank $piggyBank) {
|
|
||||||
$reminders = $piggyBank->reminders()->get();
|
|
||||||
/** @var Reminder $reminder */
|
|
||||||
foreach ($reminders as $reminder) {
|
|
||||||
$reminder->delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
Account::deleted(
|
Account::deleted(
|
||||||
function (Account $account) {
|
function (Account $account) {
|
||||||
|
@ -89,12 +89,19 @@ class FireflyServiceProvider extends ServiceProvider
|
|||||||
$this->app->bind('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface', 'FireflyIII\Repositories\PiggyBank\PiggyBankRepository');
|
$this->app->bind('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface', 'FireflyIII\Repositories\PiggyBank\PiggyBankRepository');
|
||||||
$this->app->bind('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface', 'FireflyIII\Repositories\Currency\CurrencyRepository');
|
$this->app->bind('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface', 'FireflyIII\Repositories\Currency\CurrencyRepository');
|
||||||
$this->app->bind('FireflyIII\Repositories\Tag\TagRepositoryInterface', 'FireflyIII\Repositories\Tag\TagRepository');
|
$this->app->bind('FireflyIII\Repositories\Tag\TagRepositoryInterface', 'FireflyIII\Repositories\Tag\TagRepository');
|
||||||
$this->app->bind('FireflyIII\Repositories\Reminder\ReminderRepositoryInterface', 'FireflyIII\Repositories\Reminder\ReminderRepository');
|
|
||||||
$this->app->bind('FireflyIII\Support\Search\SearchInterface', 'FireflyIII\Support\Search\Search');
|
$this->app->bind('FireflyIII\Support\Search\SearchInterface', 'FireflyIII\Support\Search\Search');
|
||||||
|
|
||||||
|
// make charts:
|
||||||
|
// alternative is Google instead of ChartJs
|
||||||
|
$this->app->bind('FireflyIII\Generator\Chart\Account\AccountChartGenerator', 'FireflyIII\Generator\Chart\Account\ChartJsAccountChartGenerator');
|
||||||
|
$this->app->bind('FireflyIII\Generator\Chart\Bill\BillChartGenerator', 'FireflyIII\Generator\Chart\Bill\ChartJsBillChartGenerator');
|
||||||
|
$this->app->bind('FireflyIII\Generator\Chart\Budget\BudgetChartGenerator', 'FireflyIII\Generator\Chart\Budget\ChartJsBudgetChartGenerator');
|
||||||
|
$this->app->bind('FireflyIII\Generator\Chart\Category\CategoryChartGenerator', 'FireflyIII\Generator\Chart\Category\ChartJsCategoryChartGenerator');
|
||||||
|
$this->app->bind('FireflyIII\Generator\Chart\PiggyBank\PiggyBankChartGenerator', 'FireflyIII\Generator\Chart\PiggyBank\ChartJsPiggyBankChartGenerator');
|
||||||
|
$this->app->bind('FireflyIII\Generator\Chart\Report\ReportChartGenerator', 'FireflyIII\Generator\Chart\Report\ChartJsReportChartGenerator');
|
||||||
|
|
||||||
|
|
||||||
$this->app->bind('FireflyIII\Helpers\Help\HelpInterface', 'FireflyIII\Helpers\Help\Help');
|
$this->app->bind('FireflyIII\Helpers\Help\HelpInterface', 'FireflyIII\Helpers\Help\Help');
|
||||||
$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\ReportHelperInterface', 'FireflyIII\Helpers\Report\ReportHelper');
|
||||||
$this->app->bind('FireflyIII\Helpers\Report\ReportQueryInterface', 'FireflyIII\Helpers\Report\ReportQuery');
|
$this->app->bind('FireflyIII\Helpers\Report\ReportQueryInterface', 'FireflyIII\Helpers\Report\ReportQuery');
|
||||||
|
|
||||||
|
@ -225,6 +225,7 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
$accountIds = DB::table('piggy_banks')->distinct()->get(['piggy_banks.account_id']);
|
$accountIds = DB::table('piggy_banks')->distinct()->get(['piggy_banks.account_id']);
|
||||||
$accounts = new Collection;
|
$accounts = new Collection;
|
||||||
|
|
||||||
|
/** @var PiggyBank $id */
|
||||||
foreach ($accountIds as $id) {
|
foreach ($accountIds as $id) {
|
||||||
$ids[] = intval($id->account_id);
|
$ids[] = intval($id->account_id);
|
||||||
}
|
}
|
||||||
@ -432,7 +433,6 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
$account->virtual_balance = $data['virtualBalance'];
|
$account->virtual_balance = $data['virtualBalance'];
|
||||||
$account->save();
|
$account->save();
|
||||||
|
|
||||||
// update meta data:
|
|
||||||
$this->updateMetadata($account, $data);
|
$this->updateMetadata($account, $data);
|
||||||
$openingBalance = $this->openingBalanceTransaction($account);
|
$openingBalance = $this->openingBalanceTransaction($account);
|
||||||
|
|
||||||
|
@ -26,21 +26,6 @@ use Log;
|
|||||||
class JournalRepository implements JournalRepositoryInterface
|
class JournalRepository implements JournalRepositoryInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $reminderId
|
|
||||||
*
|
|
||||||
* @return boolean|null
|
|
||||||
*/
|
|
||||||
public function deactivateReminder($reminderId)
|
|
||||||
{
|
|
||||||
$reminder = Auth::user()->reminders()->find($reminderId);
|
|
||||||
if ($reminder) {
|
|
||||||
$reminder->active = 0;
|
|
||||||
$reminder->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TransactionJournal $journal
|
* @param TransactionJournal $journal
|
||||||
*
|
*
|
||||||
|
@ -16,13 +16,6 @@ use Illuminate\Support\Collection;
|
|||||||
*/
|
*/
|
||||||
interface JournalRepositoryInterface
|
interface JournalRepositoryInterface
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @param int $reminderId
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function deactivateReminder($reminderId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TransactionJournal $journal
|
* @param TransactionJournal $journal
|
||||||
*
|
*
|
||||||
|
@ -116,8 +116,10 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function store(array $data)
|
public function store(array $data)
|
||||||
{
|
{
|
||||||
$data['remind_me'] = isset($data['remind_me']) && $data['remind_me'] == '1' ? true : false;
|
$data['remind_me'] = false;
|
||||||
$piggyBank = PiggyBank::create($data);
|
$data['reminder_skip'] = 0;
|
||||||
|
|
||||||
|
$piggyBank = PiggyBank::create($data);
|
||||||
|
|
||||||
return $piggyBank;
|
return $piggyBank;
|
||||||
}
|
}
|
||||||
@ -130,21 +132,12 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function update(PiggyBank $piggyBank, array $data)
|
public function update(PiggyBank $piggyBank, array $data)
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* 'rep_length' => $request->get('rep_length'),
|
|
||||||
* 'rep_every' => intval($request->get('rep_every')),
|
|
||||||
* 'rep_times' => intval($request->get('rep_times')),
|
|
||||||
* 'remind_me' => intval($request->get('remind_me')) == 1 ? true : false ,
|
|
||||||
* 'reminder' => $request->get('reminder'),
|
|
||||||
*/
|
|
||||||
|
|
||||||
$piggyBank->name = $data['name'];
|
$piggyBank->name = $data['name'];
|
||||||
$piggyBank->account_id = intval($data['account_id']);
|
$piggyBank->account_id = intval($data['account_id']);
|
||||||
$piggyBank->targetamount = floatval($data['targetamount']);
|
$piggyBank->targetamount = floatval($data['targetamount']);
|
||||||
$piggyBank->targetdate = $data['targetdate'];
|
$piggyBank->targetdate = $data['targetdate'];
|
||||||
$piggyBank->reminder = $data['reminder'];
|
|
||||||
$piggyBank->startdate = $data['startdate'];
|
$piggyBank->startdate = $data['startdate'];
|
||||||
$piggyBank->remind_me = isset($data['remind_me']) && $data['remind_me'] == '1' ? 1 : 0;
|
|
||||||
|
|
||||||
$piggyBank->save();
|
$piggyBank->save();
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ namespace FireflyIII\Repositories\PiggyBank;
|
|||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Models\PiggyBankRepetition;
|
use FireflyIII\Models\PiggyBankRepetition;
|
||||||
use FireflyIII\Models\Reminder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class PiggyBankPart
|
* Class PiggyBankPart
|
||||||
@ -20,8 +19,6 @@ class PiggyBankPart
|
|||||||
public $cumulativeAmount;
|
public $cumulativeAmount;
|
||||||
/** @var float */
|
/** @var float */
|
||||||
public $currentamount;
|
public $currentamount;
|
||||||
/** @var Reminder */
|
|
||||||
public $reminder;
|
|
||||||
|
|
||||||
/** @var PiggyBankRepetition */
|
/** @var PiggyBankRepetition */
|
||||||
public $repetition;
|
public $repetition;
|
||||||
@ -33,25 +30,19 @@ class PiggyBankPart
|
|||||||
public $targetdate;
|
public $targetdate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Reminder
|
* @return PiggyBankRepetition
|
||||||
*/
|
*/
|
||||||
public function getReminder()
|
public function getRepetition()
|
||||||
{
|
{
|
||||||
if (is_null($this->reminder)) {
|
return $this->repetition;
|
||||||
$this->reminder = $this->repetition->piggyBank->reminders()->where('startdate', $this->getStartdate()->format('Y-m-d'))->where(
|
|
||||||
'enddate', $this->getTargetdate()->format('Y-m-d')
|
|
||||||
)->first();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->reminder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Reminder $reminder
|
* @param PiggyBankRepetition $repetition
|
||||||
*/
|
*/
|
||||||
public function setReminder($reminder)
|
public function setRepetition($repetition)
|
||||||
{
|
{
|
||||||
$this->reminder = $reminder;
|
$this->repetition = $repetition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,30 +77,6 @@ class PiggyBankPart
|
|||||||
$this->targetdate = $targetdate;
|
$this->targetdate = $targetdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return PiggyBankRepetition
|
|
||||||
*/
|
|
||||||
public function getRepetition()
|
|
||||||
{
|
|
||||||
return $this->repetition;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param PiggyBankRepetition $repetition
|
|
||||||
*/
|
|
||||||
public function setRepetition($repetition)
|
|
||||||
{
|
|
||||||
$this->repetition = $repetition;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function hasReminder()
|
|
||||||
{
|
|
||||||
return !is_null($this->reminder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return float|int
|
* @return float|int
|
||||||
*/
|
*/
|
||||||
|
@ -1,116 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace FireflyIII\Repositories\Reminder;
|
|
||||||
|
|
||||||
use App;
|
|
||||||
use Auth;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use FireflyIII\Models\Reminder;
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ReminderRepository
|
|
||||||
*
|
|
||||||
* @package FireflyIII\Repositories\Reminder
|
|
||||||
*/
|
|
||||||
class ReminderRepository implements ReminderRepositoryInterface
|
|
||||||
{
|
|
||||||
/** @var \FireflyIII\Helpers\Reminders\ReminderHelperInterface */
|
|
||||||
protected $helper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @codeCoverageIgnore
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
/** @var \FireflyIII\Helpers\Reminders\ReminderHelperInterface helper */
|
|
||||||
$this->helper = App::make('FireflyIII\Helpers\Reminders\ReminderHelperInterface');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getActiveReminders()
|
|
||||||
{
|
|
||||||
$today = new Carbon;
|
|
||||||
// active reminders:
|
|
||||||
$active = Auth::user()->reminders()
|
|
||||||
->where('notnow', 0)
|
|
||||||
->where('active', 1)
|
|
||||||
->where('startdate', '<=', $today->format('Y-m-d 00:00:00'))
|
|
||||||
->where('enddate', '>=', $today->format('Y-m-d 00:00:00'))
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$active->each(
|
|
||||||
function (Reminder $reminder) {
|
|
||||||
$reminder->description = $this->helper->getReminderText($reminder);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return $active;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getDismissedReminders()
|
|
||||||
{
|
|
||||||
$dismissed = Auth::user()->reminders()
|
|
||||||
->where('notnow', 1)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$dismissed->each(
|
|
||||||
function (Reminder $reminder) {
|
|
||||||
$reminder->description = $this->helper->getReminderText($reminder);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return $dismissed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getExpiredReminders()
|
|
||||||
{
|
|
||||||
|
|
||||||
$expired = Auth::user()->reminders()
|
|
||||||
->where('notnow', 0)
|
|
||||||
->where('active', 1)
|
|
||||||
->where(
|
|
||||||
function (Builder $q) {
|
|
||||||
$today = new Carbon;
|
|
||||||
$q->where('startdate', '>', $today->format('Y-m-d 00:00:00'));
|
|
||||||
$q->orWhere('enddate', '<', $today->format('Y-m-d 00:00:00'));
|
|
||||||
}
|
|
||||||
)->get();
|
|
||||||
|
|
||||||
$expired->each(
|
|
||||||
function (Reminder $reminder) {
|
|
||||||
$reminder->description = $this->helper->getReminderText($reminder);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return $expired;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getInactiveReminders()
|
|
||||||
{
|
|
||||||
$inactive = Auth::user()->reminders()
|
|
||||||
->where('active', 0)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$inactive->each(
|
|
||||||
function (Reminder $reminder) {
|
|
||||||
$reminder->description = $this->helper->getReminderText($reminder);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return $inactive;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace FireflyIII\Repositories\Reminder;
|
|
||||||
|
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface ReminderRepositoryInterface
|
|
||||||
*
|
|
||||||
* @package FireflyIII\Repositories\Reminder
|
|
||||||
*/
|
|
||||||
interface ReminderRepositoryInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getActiveReminders();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getDismissedReminders();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getExpiredReminders();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getInactiveReminders();
|
|
||||||
|
|
||||||
}
|
|
@ -40,7 +40,7 @@ class ExpandedForm
|
|||||||
$currencies = Amt::getAllCurrencies();
|
$currencies = Amt::getAllCurrencies();
|
||||||
unset($options['currency']);
|
unset($options['currency']);
|
||||||
unset($options['placeholder']);
|
unset($options['placeholder']);
|
||||||
$html = View::make('form.amount', compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
|
$html = View::make('form.amount', compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
|
||||||
|
|
||||||
return $html;
|
return $html;
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ class ExpandedForm
|
|||||||
$currencies = Amt::getAllCurrencies();
|
$currencies = Amt::getAllCurrencies();
|
||||||
unset($options['currency']);
|
unset($options['currency']);
|
||||||
unset($options['placeholder']);
|
unset($options['placeholder']);
|
||||||
$html = View::make('form.balance', compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
|
$html = View::make('form.balance', compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
|
||||||
|
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
@ -186,7 +186,7 @@ class ExpandedForm
|
|||||||
$classes = $this->getHolderClasses($name);
|
$classes = $this->getHolderClasses($name);
|
||||||
$value = $this->fillFieldValue($name, $value);
|
$value = $this->fillFieldValue($name, $value);
|
||||||
unset($options['placeholder']);
|
unset($options['placeholder']);
|
||||||
$html = View::make('form.date', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
$html = View::make('form.date', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
||||||
|
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
@ -323,7 +323,7 @@ class ExpandedForm
|
|||||||
$selected = $this->fillFieldValue($name, $selected);
|
$selected = $this->fillFieldValue($name, $selected);
|
||||||
unset($options['autocomplete']);
|
unset($options['autocomplete']);
|
||||||
unset($options['placeholder']);
|
unset($options['placeholder']);
|
||||||
$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;
|
return $html;
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ class Navigation
|
|||||||
$subDay = ['week', 'weekly', '1W', 'month', 'monthly', '1M', '3M', 'quarter', 'quarterly', '6M', 'half-year', 'year', 'yearly'];
|
$subDay = ['week', 'weekly', '1W', 'month', 'monthly', '1M', '3M', 'quarter', 'quarterly', '6M', 'half-year', 'year', 'yearly'];
|
||||||
|
|
||||||
if (!isset($functionMap[$repeatFreq])) {
|
if (!isset($functionMap[$repeatFreq])) {
|
||||||
throw new FireflyException('Cannot do endOfPeriod for $repeat_freq ' . $repeatFreq);
|
throw new FireflyException('Cannot do endOfPeriod for $repeat_freq "' . $repeatFreq.'"');
|
||||||
}
|
}
|
||||||
$function = $functionMap[$repeatFreq];
|
$function = $functionMap[$repeatFreq];
|
||||||
if (isset($modifierMap[$repeatFreq])) {
|
if (isset($modifierMap[$repeatFreq])) {
|
||||||
@ -119,7 +119,6 @@ class Navigation
|
|||||||
'year' => 'endOfYear',
|
'year' => 'endOfYear',
|
||||||
'yearly' => 'endOfYear',
|
'yearly' => 'endOfYear',
|
||||||
];
|
];
|
||||||
$specials = ['mont', 'monthly'];
|
|
||||||
|
|
||||||
$currentEnd = clone $theCurrentEnd;
|
$currentEnd = clone $theCurrentEnd;
|
||||||
|
|
||||||
@ -128,12 +127,7 @@ class Navigation
|
|||||||
$currentEnd->$function();
|
$currentEnd->$function();
|
||||||
|
|
||||||
}
|
}
|
||||||
if (isset($specials[$repeatFreq])) {
|
|
||||||
$currentEnd->endOfYear();
|
|
||||||
if ($theCurrentEnd->month <= 6) {
|
|
||||||
$currentEnd->subMonths(6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($currentEnd > $maxDate) {
|
if ($currentEnd > $maxDate) {
|
||||||
return clone $maxDate;
|
return clone $maxDate;
|
||||||
}
|
}
|
||||||
@ -142,7 +136,7 @@ class Navigation
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Carbon $date
|
* @param \Carbon\Carbon $date
|
||||||
* @param $repeatFrequency
|
* @param $repeatFrequency
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
@ -210,7 +204,7 @@ class Navigation
|
|||||||
|
|
||||||
return $date;
|
return $date;
|
||||||
}
|
}
|
||||||
throw new FireflyException('Cannot do startOfPeriod for $repeat_freq ' . $repeatFreq);
|
throw new FireflyException('Cannot do startOfPeriod for $repeat_freq "' . $repeatFreq.'"');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -252,7 +246,7 @@ class Navigation
|
|||||||
return $date;
|
return $date;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new FireflyException('Cannot do subtractPeriod for $repeat_freq ' . $repeatFreq);
|
throw new FireflyException('Cannot do subtractPeriod for $repeat_freq "' . $repeatFreq.'"');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -288,7 +282,7 @@ class Navigation
|
|||||||
|
|
||||||
return $end;
|
return $end;
|
||||||
}
|
}
|
||||||
throw new FireflyException('updateEndDate cannot handle $range ' . $range);
|
throw new FireflyException('updateEndDate cannot handle $range "' . $range.'"');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -322,7 +316,7 @@ class Navigation
|
|||||||
|
|
||||||
return $start;
|
return $start;
|
||||||
}
|
}
|
||||||
throw new FireflyException('updateStartDate cannot handle $range ' . $range);
|
throw new FireflyException('updateStartDate cannot handle $range "' . $range.'"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class Steam
|
|||||||
|
|
||||||
bcscale(2);
|
bcscale(2);
|
||||||
|
|
||||||
$balance = $account->transactions()->leftJoin(
|
$balance = $account->transactions()->leftJoin(
|
||||||
'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
|
'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
|
||||||
)->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount');
|
)->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount');
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ use Twig_Extension;
|
|||||||
use Twig_SimpleFunction;
|
use Twig_SimpleFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
* Class Budget
|
* Class Budget
|
||||||
*
|
*
|
||||||
* @package FireflyIII\Support\Twig
|
* @package FireflyIII\Support\Twig
|
||||||
|
@ -14,6 +14,8 @@ use Twig_SimpleFilter;
|
|||||||
use Twig_SimpleFunction;
|
use Twig_SimpleFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*
|
||||||
* Class TwigSupport
|
* Class TwigSupport
|
||||||
*
|
*
|
||||||
* @package FireflyIII\Support
|
* @package FireflyIII\Support
|
||||||
@ -204,10 +206,10 @@ class General extends Twig_Extension
|
|||||||
$route = $args[0]; // name of the route.
|
$route = $args[0]; // name of the route.
|
||||||
|
|
||||||
if (Route::getCurrentRoute()->getName() == $route) {
|
if (Route::getCurrentRoute()->getName() == $route) {
|
||||||
return 'active because-route-matches-strict';
|
return 'active';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'not-xxx-at-all';
|
return '';
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -225,10 +227,10 @@ class General extends Twig_Extension
|
|||||||
$args = func_get_args();
|
$args = func_get_args();
|
||||||
$route = $args[0]; // name of the route.
|
$route = $args[0]; // name of the route.
|
||||||
if (!(strpos(Route::getCurrentRoute()->getName(), $route) === false)) {
|
if (!(strpos(Route::getCurrentRoute()->getName(), $route) === false)) {
|
||||||
return 'active because-route-matches-non-strict';
|
return 'active';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'not-xxx-at-all';
|
return '';
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -249,10 +251,10 @@ class General extends Twig_Extension
|
|||||||
$activeWhat = isset($context['what']) ? $context['what'] : false;
|
$activeWhat = isset($context['what']) ? $context['what'] : false;
|
||||||
|
|
||||||
if ($what == $activeWhat && !(strpos(Route::getCurrentRoute()->getName(), $route) === false)) {
|
if ($what == $activeWhat && !(strpos(Route::getCurrentRoute()->getName(), $route) === false)) {
|
||||||
return 'active because-route-matches-non-strict-what';
|
return 'active';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'not-xxx-at-all';
|
return '';
|
||||||
}, ['needs_context' => true]
|
}, ['needs_context' => true]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ use Twig_SimpleFilter;
|
|||||||
use Twig_SimpleFunction;
|
use Twig_SimpleFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*
|
||||||
* Class Journal
|
* Class Journal
|
||||||
*
|
*
|
||||||
* @package FireflyIII\Support\Twig
|
* @package FireflyIII\Support\Twig
|
||||||
@ -71,16 +73,16 @@ class Journal extends Twig_Extension
|
|||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case 'Withdrawal':
|
case 'Withdrawal':
|
||||||
$txt = '<span class="glyphicon glyphicon-arrow-left" title="' . trans('firefly.withdrawal') . '"></span>';
|
$txt = '<i class="fa fa-long-arrow-left fa-fw" title="' . trans('firefly.withdrawal') . '"></i>';
|
||||||
break;
|
break;
|
||||||
case 'Deposit':
|
case 'Deposit':
|
||||||
$txt = '<span class="glyphicon glyphicon-arrow-right" title="' . trans('firefly.deposit') . '"></span>';
|
$txt = '<i class="fa fa-long-arrow-right fa-fw" title="' . trans('firefly.deposit') . '"></i>';
|
||||||
break;
|
break;
|
||||||
case 'Transfer':
|
case 'Transfer':
|
||||||
$txt = '<i class="fa fa-fw fa-exchange" title="' . trans('firefly.transfer') . '"></i>';
|
$txt = '<i class="fa fa-fw fa-exchange" title="' . trans('firefly.transfer') . '"></i>';
|
||||||
break;
|
break;
|
||||||
case 'Opening balance':
|
case 'Opening balance':
|
||||||
$txt = '<span class="glyphicon glyphicon-ban-circle" title="' . trans('firefly.openingBalance') . '"></span>';
|
$txt = '<i class="fa-fw fa fa-ban" title="' . trans('firefly.openingBalance') . '"></i>';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$txt = '';
|
$txt = '';
|
||||||
|
@ -7,6 +7,8 @@ use Twig_Extension;
|
|||||||
use Twig_SimpleFunction;
|
use Twig_SimpleFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*
|
||||||
* Class PiggyBank
|
* Class PiggyBank
|
||||||
*
|
*
|
||||||
* @package FireflyIII\Support\Twig
|
* @package FireflyIII\Support\Twig
|
||||||
|
@ -6,6 +6,8 @@ use Twig_Extension;
|
|||||||
use Twig_SimpleFilter;
|
use Twig_SimpleFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*
|
||||||
* Class Budget
|
* Class Budget
|
||||||
*
|
*
|
||||||
* @package FireflyIII\Support\Twig
|
* @package FireflyIII\Support\Twig
|
||||||
|
11
app/User.php
11
app/User.php
@ -10,6 +10,8 @@ use Zizaco\Entrust\Traits\EntrustUserTrait;
|
|||||||
/**
|
/**
|
||||||
* Class User
|
* Class User
|
||||||
*
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*
|
||||||
* @package FireflyIII
|
* @package FireflyIII
|
||||||
* @property integer $id
|
* @property integer $id
|
||||||
* @property \Carbon\Carbon $created_at
|
* @property \Carbon\Carbon $created_at
|
||||||
@ -24,7 +26,6 @@ use Zizaco\Entrust\Traits\EntrustUserTrait;
|
|||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Budget[] $budgets
|
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Budget[] $budgets
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Category[] $categories
|
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Category[] $categories
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Preference[] $preferences
|
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Preference[] $preferences
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Reminder[] $reminders
|
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionJournal[] $transactionjournals
|
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionJournal[] $transactionjournals
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\User whereId($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\User whereId($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\User whereCreatedAt($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\User whereCreatedAt($value)
|
||||||
@ -123,14 +124,6 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
|||||||
return $this->hasMany('FireflyIII\Models\Preference');
|
return $this->hasMany('FireflyIII\Models\Preference');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
|
||||||
*/
|
|
||||||
public function reminders()
|
|
||||||
{
|
|
||||||
return $this->hasMany('FireflyIII\Models\Reminder');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
*/
|
*/
|
||||||
|
@ -3,16 +3,15 @@
|
|||||||
namespace FireflyIII\Validation;
|
namespace FireflyIII\Validation;
|
||||||
|
|
||||||
use Auth;
|
use Auth;
|
||||||
use Carbon\Carbon;
|
|
||||||
use Config;
|
use Config;
|
||||||
use Crypt;
|
use Crypt;
|
||||||
use DB;
|
use DB;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\AccountType;
|
use FireflyIII\Models\AccountType;
|
||||||
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Contracts\Encryption\DecryptException;
|
use Illuminate\Contracts\Encryption\DecryptException;
|
||||||
use Illuminate\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use Navigation;
|
|
||||||
use Symfony\Component\Translation\TranslatorInterface;
|
use Symfony\Component\Translation\TranslatorInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,35 +54,6 @@ class FireflyValidator extends Validator
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function validatePiggyBankReminder()
|
|
||||||
{
|
|
||||||
$array = $this->data;
|
|
||||||
// no reminder? dont care.
|
|
||||||
if (!isset($array['remind_me'])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get or set start date & target date:
|
|
||||||
$startDate = isset($array['startdate']) ? new Carbon($array['startdate']) : new Carbon;
|
|
||||||
$targetDate = isset($array['targetdate']) && strlen($array['targetdate']) > 0 ? new Carbon($array['targetdate']) : null;
|
|
||||||
|
|
||||||
// target date is null? reminder period is always good.
|
|
||||||
if ($array['remind_me'] == '1' && is_null($targetDate)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$nextReminder = Navigation::addPeriod($startDate, $array['reminder'], 0);
|
|
||||||
// reminder is beyond target?
|
|
||||||
if ($nextReminder > $targetDate) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $attribute
|
* @param $attribute
|
||||||
* @param $value
|
* @param $value
|
||||||
@ -105,6 +75,10 @@ class FireflyValidator extends Validator
|
|||||||
if (isset($this->data['account_type_id'])) {
|
if (isset($this->data['account_type_id'])) {
|
||||||
return $this->validateByAccountTypeId($value, $parameters);
|
return $this->validateByAccountTypeId($value, $parameters);
|
||||||
}
|
}
|
||||||
|
if (isset($this->data['id'])) {
|
||||||
|
return $this->validateByAccountId($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -197,6 +171,33 @@ class FireflyValidator extends Validator
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $value
|
||||||
|
* @param $parameters
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function validateByAccountId($value)
|
||||||
|
{
|
||||||
|
/** @var Account $existingAccount */
|
||||||
|
$existingAccount = Account::find($this->data['id']);
|
||||||
|
|
||||||
|
$type = $existingAccount->accountType;
|
||||||
|
$ignore = $existingAccount->id;
|
||||||
|
$value = $this->tryDecrypt($value);
|
||||||
|
|
||||||
|
$set = Auth::user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore)->get();
|
||||||
|
/** @var Account $entry */
|
||||||
|
foreach ($set as $entry) {
|
||||||
|
if ($entry->name == $value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $attribute
|
* @param $attribute
|
||||||
* @param $value
|
* @param $value
|
||||||
@ -273,6 +274,7 @@ class FireflyValidator extends Validator
|
|||||||
}
|
}
|
||||||
$set = $query->get(['piggy_banks.*']);
|
$set = $query->get(['piggy_banks.*']);
|
||||||
|
|
||||||
|
/** @var PiggyBank $entry */
|
||||||
foreach ($set as $entry) {
|
foreach ($set as $entry) {
|
||||||
$fieldValue = $this->tryDecrypt($entry->name);
|
$fieldValue = $this->tryDecrypt($entry->name);
|
||||||
if ($fieldValue == $value) {
|
if ($fieldValue == $value) {
|
||||||
|
@ -28,7 +28,6 @@ $app = new Illuminate\Foundation\Application(
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$app->singleton(
|
$app->singleton(
|
||||||
'Illuminate\Contracts\Http\Kernel',
|
'Illuminate\Contracts\Http\Kernel',
|
||||||
'FireflyIII\Http\Kernel'
|
'FireflyIII\Http\Kernel'
|
||||||
@ -45,8 +44,6 @@ $app->singleton(
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Return The Application
|
| Return The Application
|
||||||
|
@ -14,7 +14,7 @@ define('LARAVEL_START', microtime(true));
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require __DIR__.'/../vendor/autoload.php';
|
require __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -27,9 +27,8 @@ require __DIR__.'/../vendor/autoload.php';
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$compiledPath = __DIR__.'/cache/compiled.php';
|
$compiledPath = __DIR__ . '/cache/compiled.php';
|
||||||
|
|
||||||
if (file_exists($compiledPath))
|
if (file_exists($compiledPath)) {
|
||||||
{
|
require $compiledPath;
|
||||||
require $compiledPath;
|
|
||||||
}
|
}
|
||||||
|
110
config/auth.php
110
config/auth.php
@ -2,67 +2,67 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Authentication Driver
|
| Default Authentication Driver
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| This option controls the authentication driver that will be utilized.
|
| This option controls the authentication driver that will be utilized.
|
||||||
| This driver manages the retrieval and authentication of the users
|
| This driver manages the retrieval and authentication of the users
|
||||||
| attempting to get access to protected areas of your application.
|
| attempting to get access to protected areas of your application.
|
||||||
|
|
|
|
||||||
| Supported: "database", "eloquent"
|
| Supported: "database", "eloquent"
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'driver' => 'eloquent',
|
'driver' => 'eloquent',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Authentication Model
|
| Authentication Model
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| When using the "Eloquent" authentication driver, we need to know which
|
| When using the "Eloquent" authentication driver, we need to know which
|
||||||
| Eloquent model should be used to retrieve your users. Of course, it
|
| Eloquent model should be used to retrieve your users. Of course, it
|
||||||
| is often just the "User" model but you may use whatever you like.
|
| is often just the "User" model but you may use whatever you like.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'model' => 'FireflyIII\User',
|
'model' => 'FireflyIII\User',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Authentication Table
|
| Authentication Table
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| When using the "Database" authentication driver, we need to know which
|
| When using the "Database" authentication driver, we need to know which
|
||||||
| table should be used to retrieve your users. We have chosen a basic
|
| table should be used to retrieve your users. We have chosen a basic
|
||||||
| default value but you may easily change it to any table you like.
|
| default value but you may easily change it to any table you like.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'table' => 'users',
|
'table' => 'users',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Password Reset Settings
|
| Password Reset Settings
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Here you may set the options for resetting passwords including the view
|
| Here you may set the options for resetting passwords including the view
|
||||||
| that is your password reset e-mail. You can also set the name of the
|
| that is your password reset e-mail. You can also set the name of the
|
||||||
| table that maintains all of the reset tokens for your application.
|
| table that maintains all of the reset tokens for your application.
|
||||||
|
|
|
|
||||||
| The expire time is the number of minutes that the reset token should be
|
| The expire time is the number of minutes that the reset token should be
|
||||||
| considered valid. This security feature keeps tokens short-lived so
|
| considered valid. This security feature keeps tokens short-lived so
|
||||||
| they have less time to be guessed. You may change this as needed.
|
| they have less time to be guessed. You may change this as needed.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'password' => [
|
'password' => [
|
||||||
'email' => 'emails.password',
|
'email' => 'emails.password',
|
||||||
'table' => 'password_resets',
|
'table' => 'password_resets',
|
||||||
'expire' => 60,
|
'expire' => 60,
|
||||||
],
|
],
|
||||||
'allow_register' => true
|
'allow_register' => true
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
'view' => 'breadcrumbs::bootstrap3',
|
'view' => 'breadcrumbs::bootstrap3',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
122
config/cache.php
122
config/cache.php
@ -2,78 +2,78 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Cache Store
|
| Default Cache Store
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| This option controls the default cache connection that gets used while
|
| This option controls the default cache connection that gets used while
|
||||||
| using this caching library. This connection is used when another is
|
| using this caching library. This connection is used when another is
|
||||||
| not explicitly specified when executing a given caching function.
|
| not explicitly specified when executing a given caching function.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'default' => env('CACHE_DRIVER', 'file'),
|
'default' => env('CACHE_DRIVER', 'file'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Cache Stores
|
| Cache Stores
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Here you may define all of the cache "stores" for your application as
|
| Here you may define all of the cache "stores" for your application as
|
||||||
| well as their drivers. You may even define multiple stores for the
|
| well as their drivers. You may even define multiple stores for the
|
||||||
| same cache driver to group types of items stored in your caches.
|
| same cache driver to group types of items stored in your caches.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'stores' => [
|
'stores' => [
|
||||||
|
|
||||||
'apc' => [
|
'apc' => [
|
||||||
'driver' => 'apc'
|
'driver' => 'apc'
|
||||||
],
|
],
|
||||||
|
|
||||||
'array' => [
|
'array' => [
|
||||||
'driver' => 'array'
|
'driver' => 'array'
|
||||||
],
|
],
|
||||||
|
|
||||||
'database' => [
|
'database' => [
|
||||||
'driver' => 'database',
|
'driver' => 'database',
|
||||||
'table' => 'cache',
|
'table' => 'cache',
|
||||||
'connection' => null,
|
'connection' => null,
|
||||||
],
|
],
|
||||||
|
|
||||||
'file' => [
|
'file' => [
|
||||||
'driver' => 'file',
|
'driver' => 'file',
|
||||||
'path' => storage_path().'/framework/cache',
|
'path' => storage_path() . '/framework/cache',
|
||||||
],
|
],
|
||||||
|
|
||||||
'memcached' => [
|
'memcached' => [
|
||||||
'driver' => 'memcached',
|
'driver' => 'memcached',
|
||||||
'servers' => [
|
'servers' => [
|
||||||
[
|
[
|
||||||
'host' => '127.0.0.1', 'port' => 11211, 'weight' => 100
|
'host' => '127.0.0.1', 'port' => 11211, 'weight' => 100
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
'redis' => [
|
'redis' => [
|
||||||
'driver' => 'redis',
|
'driver' => 'redis',
|
||||||
'connection' => 'default',
|
'connection' => 'default',
|
||||||
],
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Cache Key Prefix
|
| Cache Key Prefix
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| When utilizing a RAM based store such as APC or Memcached, there might
|
| When utilizing a RAM based store such as APC or Memcached, there might
|
||||||
| be other applications utilizing the same cache. So, we'll specify a
|
| be other applications utilizing the same cache. So, we'll specify a
|
||||||
| value to get prefixed to all our keys so we can avoid collisions.
|
| value to get prefixed to all our keys so we can avoid collisions.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'prefix' => 'laravel',
|
'prefix' => 'laravel',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -2,40 +2,40 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Additional Compiled Classes
|
| Additional Compiled Classes
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Here you may specify additional classes to include in the compiled file
|
| Here you may specify additional classes to include in the compiled file
|
||||||
| generated by the `artisan optimize` command. These should be classes
|
| generated by the `artisan optimize` command. These should be classes
|
||||||
| that are included on basically every request into the application.
|
| that are included on basically every request into the application.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'files' => [
|
'files' => [
|
||||||
|
|
||||||
realpath(__DIR__.'/../app/Providers/AppServiceProvider.php'),
|
realpath(__DIR__ . '/../app/Providers/AppServiceProvider.php'),
|
||||||
realpath(__DIR__.'/../app/Providers/BusServiceProvider.php'),
|
realpath(__DIR__ . '/../app/Providers/BusServiceProvider.php'),
|
||||||
realpath(__DIR__.'/../app/Providers/ConfigServiceProvider.php'),
|
realpath(__DIR__ . '/../app/Providers/ConfigServiceProvider.php'),
|
||||||
realpath(__DIR__.'/../app/Providers/EventServiceProvider.php'),
|
realpath(__DIR__ . '/../app/Providers/EventServiceProvider.php'),
|
||||||
realpath(__DIR__.'/../app/Providers/RouteServiceProvider.php'),
|
realpath(__DIR__ . '/../app/Providers/RouteServiceProvider.php'),
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Compiled File Providers
|
| Compiled File Providers
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Here you may list service providers which define a "compiles" function
|
| Here you may list service providers which define a "compiles" function
|
||||||
| that returns additional files that should be compiled, providing an
|
| that returns additional files that should be compiled, providing an
|
||||||
| easy way to get common files from any packages you are utilizing.
|
| easy way to get common files from any packages you are utilizing.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'providers' => [
|
'providers' => [
|
||||||
//
|
//
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -48,7 +48,7 @@ return [
|
|||||||
|
|
||||||
'sqlite' => [
|
'sqlite' => [
|
||||||
'driver' => 'sqlite',
|
'driver' => 'sqlite',
|
||||||
'database' => __DIR__.'/../storage/database/testing.db',
|
'database' => __DIR__ . '/../storage/database/testing.db',
|
||||||
'prefix' => '',
|
'prefix' => '',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ return [
|
|||||||
| the role if it is in a different namespace.
|
| the role if it is in a different namespace.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
'role' => 'FireflyIII\Models\Role',
|
'role' => 'FireflyIII\Models\Role',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -29,7 +29,7 @@ return [
|
|||||||
| This is the roles table used by Entrust to save roles to the database.
|
| This is the roles table used by Entrust to save roles to the database.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
'roles_table' => 'roles',
|
'roles_table' => 'roles',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -40,7 +40,7 @@ return [
|
|||||||
| Update the permission if it is in a different namespace.
|
| Update the permission if it is in a different namespace.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
'permission' => 'FireflyIII\Models\Permission',
|
'permission' => 'FireflyIII\Models\Permission',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -51,7 +51,7 @@ return [
|
|||||||
| database.
|
| database.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
'permissions_table' => 'permissions',
|
'permissions_table' => 'permissions',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -73,6 +73,6 @@ return [
|
|||||||
| database.
|
| database.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
'role_user_table' => 'role_user',
|
'role_user_table' => 'role_user',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -2,69 +2,69 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Filesystem Disk
|
| Default Filesystem Disk
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Here you may specify the default filesystem disk that should be used
|
| Here you may specify the default filesystem disk that should be used
|
||||||
| by the framework. A "local" driver, as well as a variety of cloud
|
| by the framework. A "local" driver, as well as a variety of cloud
|
||||||
| based drivers are available for your choosing. Just store away!
|
| based drivers are available for your choosing. Just store away!
|
||||||
|
|
|
|
||||||
| Supported: "local", "s3", "rackspace"
|
| Supported: "local", "s3", "rackspace"
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'default' => 'local',
|
'default' => 'local',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Cloud Filesystem Disk
|
| Default Cloud Filesystem Disk
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Many applications store files both locally and in the cloud. For this
|
| Many applications store files both locally and in the cloud. For this
|
||||||
| reason, you may specify a default "cloud" driver here. This driver
|
| reason, you may specify a default "cloud" driver here. This driver
|
||||||
| will be bound as the Cloud disk implementation in the container.
|
| will be bound as the Cloud disk implementation in the container.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'cloud' => 's3',
|
'cloud' => 's3',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Filesystem Disks
|
| Filesystem Disks
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Here you may configure as many filesystem "disks" as you wish, and you
|
| Here you may configure as many filesystem "disks" as you wish, and you
|
||||||
| may even configure multiple disks of the same driver. Defaults have
|
| may even configure multiple disks of the same driver. Defaults have
|
||||||
| been setup for each driver as an example of the required options.
|
| been setup for each driver as an example of the required options.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'disks' => [
|
'disks' => [
|
||||||
|
|
||||||
'local' => [
|
'local' => [
|
||||||
'driver' => 'local',
|
'driver' => 'local',
|
||||||
'root' => storage_path().'/app',
|
'root' => storage_path() . '/app',
|
||||||
],
|
],
|
||||||
|
|
||||||
's3' => [
|
's3' => [
|
||||||
'driver' => 's3',
|
'driver' => 's3',
|
||||||
'key' => 'your-key',
|
'key' => 'your-key',
|
||||||
'secret' => 'your-secret',
|
'secret' => 'your-secret',
|
||||||
'region' => 'your-region',
|
'region' => 'your-region',
|
||||||
'bucket' => 'your-bucket',
|
'bucket' => 'your-bucket',
|
||||||
],
|
],
|
||||||
|
|
||||||
'rackspace' => [
|
'rackspace' => [
|
||||||
'driver' => 'rackspace',
|
'driver' => 'rackspace',
|
||||||
'username' => 'your-username',
|
'username' => 'your-username',
|
||||||
'key' => 'your-key',
|
'key' => 'your-key',
|
||||||
'container' => 'your-container',
|
'container' => 'your-container',
|
||||||
'endpoint' => 'https://identity.api.rackspacecloud.com/v2.0/',
|
'endpoint' => 'https://identity.api.rackspacecloud.com/v2.0/',
|
||||||
'region' => 'IAD',
|
'region' => 'IAD',
|
||||||
],
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'version' => '3.4.5',
|
'chart' => 'chartjs', // or 'chartjs'
|
||||||
|
'version' => '3.4.6',
|
||||||
'index_periods' => ['1D', '1W', '1M', '3M', '6M', '1Y', 'custom'],
|
'index_periods' => ['1D', '1W', '1M', '3M', '6M', '1Y', 'custom'],
|
||||||
'budget_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
|
'budget_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
|
||||||
'piggy_bank_periods' => [
|
'piggy_bank_periods' => [
|
||||||
@ -57,7 +58,7 @@ return [
|
|||||||
'asset' => 'Asset accounts',
|
'asset' => 'Asset accounts',
|
||||||
'expense' => 'Expense accounts',
|
'expense' => 'Expense accounts',
|
||||||
'revenue' => 'Revenue accounts',
|
'revenue' => 'Revenue accounts',
|
||||||
'cash' => 'Cash accounts',
|
'cash' => 'Cash accounts',
|
||||||
],
|
],
|
||||||
'subIconsByIdentifier' =>
|
'subIconsByIdentifier' =>
|
||||||
[
|
[
|
||||||
|
148
config/queue.php
148
config/queue.php
@ -2,91 +2,91 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Queue Driver
|
| Default Queue Driver
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| The Laravel queue API supports a variety of back-ends via an unified
|
| The Laravel queue API supports a variety of back-ends via an unified
|
||||||
| API, giving you convenient access to each back-end using the same
|
| API, giving you convenient access to each back-end using the same
|
||||||
| syntax for each one. Here you may set the default queue driver.
|
| syntax for each one. Here you may set the default queue driver.
|
||||||
|
|
|
|
||||||
| Supported: "null", "sync", "database", "beanstalkd",
|
| Supported: "null", "sync", "database", "beanstalkd",
|
||||||
| "sqs", "iron", "redis"
|
| "sqs", "iron", "redis"
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'default' => env('QUEUE_DRIVER', 'sync'),
|
'default' => env('QUEUE_DRIVER', 'sync'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Queue Connections
|
| Queue Connections
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Here you may configure the connection information for each server that
|
| Here you may configure the connection information for each server that
|
||||||
| is used by your application. A default configuration has been added
|
| is used by your application. A default configuration has been added
|
||||||
| for each back-end shipped with Laravel. You are free to add more.
|
| for each back-end shipped with Laravel. You are free to add more.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'connections' => [
|
'connections' => [
|
||||||
|
|
||||||
'sync' => [
|
'sync' => [
|
||||||
'driver' => 'sync',
|
'driver' => 'sync',
|
||||||
],
|
],
|
||||||
|
|
||||||
'database' => [
|
'database' => [
|
||||||
'driver' => 'database',
|
'driver' => 'database',
|
||||||
'table' => 'jobs',
|
'table' => 'jobs',
|
||||||
'queue' => 'default',
|
'queue' => 'default',
|
||||||
'expire' => 60,
|
'expire' => 60,
|
||||||
],
|
],
|
||||||
|
|
||||||
'beanstalkd' => [
|
'beanstalkd' => [
|
||||||
'driver' => 'beanstalkd',
|
'driver' => 'beanstalkd',
|
||||||
'host' => 'localhost',
|
'host' => 'localhost',
|
||||||
'queue' => 'default',
|
'queue' => 'default',
|
||||||
'ttr' => 60,
|
'ttr' => 60,
|
||||||
],
|
],
|
||||||
|
|
||||||
'sqs' => [
|
'sqs' => [
|
||||||
'driver' => 'sqs',
|
'driver' => 'sqs',
|
||||||
'key' => 'your-public-key',
|
'key' => 'your-public-key',
|
||||||
'secret' => 'your-secret-key',
|
'secret' => 'your-secret-key',
|
||||||
'queue' => 'your-queue-url',
|
'queue' => 'your-queue-url',
|
||||||
'region' => 'us-east-1',
|
'region' => 'us-east-1',
|
||||||
],
|
],
|
||||||
|
|
||||||
'iron' => [
|
'iron' => [
|
||||||
'driver' => 'iron',
|
'driver' => 'iron',
|
||||||
'host' => 'mq-aws-us-east-1.iron.io',
|
'host' => 'mq-aws-us-east-1.iron.io',
|
||||||
'token' => 'your-token',
|
'token' => 'your-token',
|
||||||
'project' => 'your-project-id',
|
'project' => 'your-project-id',
|
||||||
'queue' => 'your-queue-name',
|
'queue' => 'your-queue-name',
|
||||||
'encrypt' => true,
|
'encrypt' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'redis' => [
|
'redis' => [
|
||||||
'driver' => 'redis',
|
'driver' => 'redis',
|
||||||
'queue' => 'default',
|
'queue' => 'default',
|
||||||
'expire' => 60,
|
'expire' => 60,
|
||||||
],
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Failed Queue Jobs
|
| Failed Queue Jobs
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| These options configure the behavior of failed queue job logging so you
|
| These options configure the behavior of failed queue job logging so you
|
||||||
| can control which database and table are used to store the jobs that
|
| can control which database and table are used to store the jobs that
|
||||||
| have failed. You may change them to any database / table you wish.
|
| have failed. You may change them to any database / table you wish.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'failed' => [
|
'failed' => [
|
||||||
'database' => 'mysql', 'table' => 'failed_jobs',
|
'database' => 'mysql', 'table' => 'failed_jobs',
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -2,36 +2,36 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Third Party Services
|
| Third Party Services
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| This file is for storing the credentials for third party services such
|
| This file is for storing the credentials for third party services such
|
||||||
| as Stripe, Mailgun, Mandrill, and others. This file provides a sane
|
| as Stripe, Mailgun, Mandrill, and others. This file provides a sane
|
||||||
| default location for this type of information, allowing packages
|
| default location for this type of information, allowing packages
|
||||||
| to have a conventional place to find your various credentials.
|
| to have a conventional place to find your various credentials.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'mailgun' => [
|
'mailgun' => [
|
||||||
'domain' => '',
|
'domain' => '',
|
||||||
'secret' => '',
|
'secret' => '',
|
||||||
],
|
],
|
||||||
|
|
||||||
'mandrill' => [
|
'mandrill' => [
|
||||||
'secret' => '',
|
'secret' => '',
|
||||||
],
|
],
|
||||||
|
|
||||||
'ses' => [
|
'ses' => [
|
||||||
'key' => '',
|
'key' => '',
|
||||||
'secret' => '',
|
'secret' => '',
|
||||||
'region' => 'us-east-1',
|
'region' => 'us-east-1',
|
||||||
],
|
],
|
||||||
|
|
||||||
'stripe' => [
|
'stripe' => [
|
||||||
'model' => 'User',
|
'model' => 'User',
|
||||||
'secret' => '',
|
'secret' => '',
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -2,152 +2,152 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Session Driver
|
| Default Session Driver
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| This option controls the default session "driver" that will be used on
|
| This option controls the default session "driver" that will be used on
|
||||||
| requests. By default, we will use the lightweight native driver but
|
| requests. By default, we will use the lightweight native driver but
|
||||||
| you may specify any of the other wonderful drivers provided here.
|
| you may specify any of the other wonderful drivers provided here.
|
||||||
|
|
|
|
||||||
| Supported: "file", "cookie", "database", "apc",
|
| Supported: "file", "cookie", "database", "apc",
|
||||||
| "memcached", "redis", "array"
|
| "memcached", "redis", "array"
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'driver' => env('SESSION_DRIVER', 'file'),
|
'driver' => env('SESSION_DRIVER', 'file'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Session Lifetime
|
| Session Lifetime
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Here you may specify the number of minutes that you wish the session
|
| Here you may specify the number of minutes that you wish the session
|
||||||
| to be allowed to remain idle before it expires. If you want them
|
| to be allowed to remain idle before it expires. If you want them
|
||||||
| to immediately expire on the browser closing, set that option.
|
| to immediately expire on the browser closing, set that option.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'lifetime' => 120,
|
'lifetime' => 120,
|
||||||
|
|
||||||
'expire_on_close' => false,
|
'expire_on_close' => false,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Session Encryption
|
| Session Encryption
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| This option allows you to easily specify that all of your session data
|
| This option allows you to easily specify that all of your session data
|
||||||
| should be encrypted before it is stored. All encryption will be run
|
| should be encrypted before it is stored. All encryption will be run
|
||||||
| automatically by Laravel and you can use the Session like normal.
|
| automatically by Laravel and you can use the Session like normal.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'encrypt' => false,
|
'encrypt' => false,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Session File Location
|
| Session File Location
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| When using the native session driver, we need a location where session
|
| When using the native session driver, we need a location where session
|
||||||
| files may be stored. A default has been set for you but a different
|
| files may be stored. A default has been set for you but a different
|
||||||
| location may be specified. This is only needed for file sessions.
|
| location may be specified. This is only needed for file sessions.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'files' => storage_path().'/framework/sessions',
|
'files' => storage_path() . '/framework/sessions',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Session Database Connection
|
| Session Database Connection
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| When using the "database" or "redis" session drivers, you may specify a
|
| When using the "database" or "redis" session drivers, you may specify a
|
||||||
| connection that should be used to manage these sessions. This should
|
| connection that should be used to manage these sessions. This should
|
||||||
| correspond to a connection in your database configuration options.
|
| correspond to a connection in your database configuration options.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'connection' => null,
|
'connection' => null,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Session Database Table
|
| Session Database Table
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| When using the "database" session driver, you may specify the table we
|
| When using the "database" session driver, you may specify the table we
|
||||||
| should use to manage the sessions. Of course, a sensible default is
|
| should use to manage the sessions. Of course, a sensible default is
|
||||||
| provided for you; however, you are free to change this as needed.
|
| provided for you; however, you are free to change this as needed.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'table' => 'sessions',
|
'table' => 'sessions',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Session Sweeping Lottery
|
| Session Sweeping Lottery
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Some session drivers must manually sweep their storage location to get
|
| Some session drivers must manually sweep their storage location to get
|
||||||
| rid of old sessions from storage. Here are the chances that it will
|
| rid of old sessions from storage. Here are the chances that it will
|
||||||
| happen on a given request. By default, the odds are 2 out of 100.
|
| happen on a given request. By default, the odds are 2 out of 100.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'lottery' => [2, 100],
|
'lottery' => [2, 100],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Session Cookie Name
|
| Session Cookie Name
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Here you may change the name of the cookie used to identify a session
|
| Here you may change the name of the cookie used to identify a session
|
||||||
| instance by ID. The name specified here will get used every time a
|
| instance by ID. The name specified here will get used every time a
|
||||||
| new session cookie is created by the framework for every driver.
|
| new session cookie is created by the framework for every driver.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'cookie' => 'laravel_session',
|
'cookie' => 'laravel_session',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Session Cookie Path
|
| Session Cookie Path
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| The session cookie path determines the path for which the cookie will
|
| The session cookie path determines the path for which the cookie will
|
||||||
| be regarded as available. Typically, this will be the root path of
|
| be regarded as available. Typically, this will be the root path of
|
||||||
| your application but you are free to change this when necessary.
|
| your application but you are free to change this when necessary.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'path' => '/',
|
'path' => '/',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Session Cookie Domain
|
| Session Cookie Domain
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Here you may change the domain of the cookie used to identify a session
|
| Here you may change the domain of the cookie used to identify a session
|
||||||
| in your application. This will determine which domains the cookie is
|
| in your application. This will determine which domains the cookie is
|
||||||
| available to in your application. A sensible default has been set.
|
| available to in your application. A sensible default has been set.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'domain' => null,
|
'domain' => null,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| HTTPS Only Cookies
|
| HTTPS Only Cookies
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| By setting this option to true, session cookies will only be sent back
|
| By setting this option to true, session cookies will only be sent back
|
||||||
| to the server if the browser has a HTTPS connection. This will keep
|
| to the server if the browser has a HTTPS connection. This will keep
|
||||||
| the cookie from being sent to you if it can not be done securely.
|
| the cookie from being sent to you if it can not be done securely.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'secure' => false,
|
'secure' => false,
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -2,32 +2,32 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| View Storage Paths
|
| View Storage Paths
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Most templating systems load templates from disk. Here you may specify
|
| Most templating systems load templates from disk. Here you may specify
|
||||||
| an array of paths that should be checked for your views. Of course
|
| an array of paths that should be checked for your views. Of course
|
||||||
| the usual Laravel view path has already been registered for you.
|
| the usual Laravel view path has already been registered for you.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'paths' => [
|
'paths' => [
|
||||||
realpath(base_path('resources/twig'))
|
realpath(base_path('resources/twig'))
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Compiled View Path
|
| Compiled View Path
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| This option determines where all the compiled Blade templates will be
|
| This option determines where all the compiled Blade templates will be
|
||||||
| stored for your application. Typically, this is within the storage
|
| stored for your application. Typically, this is within the storage
|
||||||
| directory. However, as usual, you are free to change this value.
|
| directory. However, as usual, you are free to change this value.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'compiled' => realpath(storage_path().'/framework/views'),
|
'compiled' => realpath(storage_path() . '/framework/views'),
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -37,7 +37,7 @@ class CreateTransactionGroupsTable extends Migration
|
|||||||
$table->integer('user_id')->unsigned();
|
$table->integer('user_id')->unsigned();
|
||||||
$table->enum('relation', ['balance']);
|
$table->enum('relation', ['balance']);
|
||||||
|
|
||||||
// connect reminders to users
|
// connect groups to users
|
||||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -57,7 +57,7 @@ class ChangesForV3310 extends Migration
|
|||||||
$table->decimal('longitude', 18, 12)->nullable();
|
$table->decimal('longitude', 18, 12)->nullable();
|
||||||
$table->smallInteger('zoomLevel', false, true)->nullable();
|
$table->smallInteger('zoomLevel', false, true)->nullable();
|
||||||
|
|
||||||
// connect reminders to users
|
// connect tags to users
|
||||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -7,58 +7,6 @@ use Illuminate\Database\Schema\Blueprint;
|
|||||||
*/
|
*/
|
||||||
class EntrustSetupTables extends Migration
|
class EntrustSetupTables extends Migration
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
// Create table for storing roles
|
|
||||||
Schema::create('roles', function (Blueprint $table) {
|
|
||||||
$table->increments('id');
|
|
||||||
$table->string('name')->unique();
|
|
||||||
$table->string('display_name')->nullable();
|
|
||||||
$table->string('description')->nullable();
|
|
||||||
$table->timestamps();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create table for associating roles to users (Many-to-Many)
|
|
||||||
Schema::create('role_user', function (Blueprint $table) {
|
|
||||||
$table->integer('user_id')->unsigned();
|
|
||||||
$table->integer('role_id')->unsigned();
|
|
||||||
|
|
||||||
$table->foreign('user_id')->references('id')->on('users')
|
|
||||||
->onUpdate('cascade')->onDelete('cascade');
|
|
||||||
$table->foreign('role_id')->references('id')->on('roles')
|
|
||||||
->onUpdate('cascade')->onDelete('cascade');
|
|
||||||
|
|
||||||
$table->primary(['user_id', 'role_id']);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create table for storing permissions
|
|
||||||
Schema::create('permissions', function (Blueprint $table) {
|
|
||||||
$table->increments('id');
|
|
||||||
$table->string('name')->unique();
|
|
||||||
$table->string('display_name')->nullable();
|
|
||||||
$table->string('description')->nullable();
|
|
||||||
$table->timestamps();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create table for associating permissions to roles (Many-to-Many)
|
|
||||||
Schema::create('permission_role', function (Blueprint $table) {
|
|
||||||
$table->integer('permission_id')->unsigned();
|
|
||||||
$table->integer('role_id')->unsigned();
|
|
||||||
|
|
||||||
$table->foreign('permission_id')->references('id')->on('permissions')
|
|
||||||
->onUpdate('cascade')->onDelete('cascade');
|
|
||||||
$table->foreign('role_id')->references('id')->on('roles')
|
|
||||||
->onUpdate('cascade')->onDelete('cascade');
|
|
||||||
|
|
||||||
$table->primary(['permission_id', 'role_id']);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverse the migrations.
|
* Reverse the migrations.
|
||||||
*
|
*
|
||||||
@ -71,4 +19,64 @@ class EntrustSetupTables extends Migration
|
|||||||
Schema::drop('role_user');
|
Schema::drop('role_user');
|
||||||
Schema::drop('roles');
|
Schema::drop('roles');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
// Create table for storing roles
|
||||||
|
Schema::create(
|
||||||
|
'roles', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->string('name')->unique();
|
||||||
|
$table->string('display_name')->nullable();
|
||||||
|
$table->string('description')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create table for associating roles to users (Many-to-Many)
|
||||||
|
Schema::create(
|
||||||
|
'role_user', function (Blueprint $table) {
|
||||||
|
$table->integer('user_id')->unsigned();
|
||||||
|
$table->integer('role_id')->unsigned();
|
||||||
|
|
||||||
|
$table->foreign('user_id')->references('id')->on('users')
|
||||||
|
->onUpdate('cascade')->onDelete('cascade');
|
||||||
|
$table->foreign('role_id')->references('id')->on('roles')
|
||||||
|
->onUpdate('cascade')->onDelete('cascade');
|
||||||
|
|
||||||
|
$table->primary(['user_id', 'role_id']);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create table for storing permissions
|
||||||
|
Schema::create(
|
||||||
|
'permissions', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->string('name')->unique();
|
||||||
|
$table->string('display_name')->nullable();
|
||||||
|
$table->string('description')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create table for associating permissions to roles (Many-to-Many)
|
||||||
|
Schema::create(
|
||||||
|
'permission_role', function (Blueprint $table) {
|
||||||
|
$table->integer('permission_id')->unsigned();
|
||||||
|
$table->integer('role_id')->unsigned();
|
||||||
|
|
||||||
|
$table->foreign('permission_id')->references('id')->on('permissions')
|
||||||
|
->onUpdate('cascade')->onDelete('cascade');
|
||||||
|
$table->foreign('role_id')->references('id')->on('roles')
|
||||||
|
->onUpdate('cascade')->onDelete('cascade');
|
||||||
|
|
||||||
|
$table->primary(['permission_id', 'role_id']);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
33
database/migrations/2015_06_23_050233_changes_for_v3451.php
Normal file
33
database/migrations/2015_06_23_050233_changes_for_v3451.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ChangesForV3451
|
||||||
|
*/
|
||||||
|
class ChangesForV3451 extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//$table->smallInteger('reminder_skip')->unsigned();
|
||||||
|
//$table->boolean('remind_me');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@ class PermissionSeeder extends Seeder
|
|||||||
{
|
{
|
||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
$owner = new Role;
|
$owner = new Role;
|
||||||
$owner->name = 'owner';
|
$owner->name = 'owner';
|
||||||
$owner->display_name = 'Site Owner';
|
$owner->display_name = 'Site Owner';
|
||||||
$owner->description = 'User runs this instance of FF3'; // optional
|
$owner->description = 'User runs this instance of FF3'; // optional
|
||||||
|
@ -88,7 +88,6 @@ class TestDataSeeder extends Seeder
|
|||||||
$this->createBudgets();
|
$this->createBudgets();
|
||||||
$this->createCategories();
|
$this->createCategories();
|
||||||
$this->createPiggyBanks();
|
$this->createPiggyBanks();
|
||||||
$this->createReminders();
|
|
||||||
$this->createBills();
|
$this->createBills();
|
||||||
$this->createExpenseAccounts();
|
$this->createExpenseAccounts();
|
||||||
$this->createRevenueAccounts();
|
$this->createRevenueAccounts();
|
||||||
@ -264,7 +263,6 @@ class TestDataSeeder extends Seeder
|
|||||||
'targetamount' => 2000,
|
'targetamount' => 2000,
|
||||||
'startdate' => $this->som,
|
'startdate' => $this->som,
|
||||||
'targetdate' => null,
|
'targetdate' => null,
|
||||||
'reminder' => null,
|
|
||||||
'reminder_skip' => 0,
|
'reminder_skip' => 0,
|
||||||
'remind_me' => 0,
|
'remind_me' => 0,
|
||||||
'order' => 0,
|
'order' => 0,
|
||||||
@ -281,7 +279,6 @@ class TestDataSeeder extends Seeder
|
|||||||
'targetamount' => 2000,
|
'targetamount' => 2000,
|
||||||
'startdate' => $this->som,
|
'startdate' => $this->som,
|
||||||
'targetdate' => $end,
|
'targetdate' => $end,
|
||||||
'reminder' => null,
|
|
||||||
'reminder_skip' => 0,
|
'reminder_skip' => 0,
|
||||||
'remind_me' => 0,
|
'remind_me' => 0,
|
||||||
'order' => 0,
|
'order' => 0,
|
||||||
@ -292,7 +289,6 @@ class TestDataSeeder extends Seeder
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* New: create no less than eight piggy banks that
|
* New: create no less than eight piggy banks that
|
||||||
* create all sorts of reminders
|
|
||||||
*/
|
*/
|
||||||
$list = ['week', 'quarter', 'month', 'year'];
|
$list = ['week', 'quarter', 'month', 'year'];
|
||||||
$nextYear = clone $this->_startOfMonth;
|
$nextYear = clone $this->_startOfMonth;
|
||||||
@ -306,9 +302,8 @@ class TestDataSeeder extends Seeder
|
|||||||
'targetamount' => 1000,
|
'targetamount' => 1000,
|
||||||
'startdate' => $this->som,
|
'startdate' => $this->som,
|
||||||
'targetdate' => $nextYear,
|
'targetdate' => $nextYear,
|
||||||
'reminder' => $entry,
|
|
||||||
'reminder_skip' => 0,
|
'reminder_skip' => 0,
|
||||||
'remind_me' => 1,
|
'remind_me' => 0,
|
||||||
'order' => 0,
|
'order' => 0,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
@ -319,9 +314,8 @@ class TestDataSeeder extends Seeder
|
|||||||
'targetamount' => 1000,
|
'targetamount' => 1000,
|
||||||
'startdate' => $this->som,
|
'startdate' => $this->som,
|
||||||
'targetdate' => null,
|
'targetdate' => null,
|
||||||
'reminder' => $entry,
|
|
||||||
'reminder_skip' => 0,
|
'reminder_skip' => 0,
|
||||||
'remind_me' => 1,
|
'remind_me' => 0,
|
||||||
'order' => 0,
|
'order' => 0,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
@ -348,14 +342,6 @@ class TestDataSeeder extends Seeder
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public function createReminders()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -444,7 +430,8 @@ class TestDataSeeder extends Seeder
|
|||||||
$user = User::whereEmail('thegrumpydictator@gmail.com')->first();
|
$user = User::whereEmail('thegrumpydictator@gmail.com')->first();
|
||||||
|
|
||||||
Tag::create(
|
Tag::create(
|
||||||
['tag' => 'TagOne', 'tagMode' => 'nothing', 'user_id' => $user->id]);
|
['tag' => 'TagOne', 'tagMode' => 'nothing', 'user_id' => $user->id]
|
||||||
|
);
|
||||||
|
|
||||||
Tag::create(['tag' => 'TagTwo', 'tagMode' => 'nothing', 'user_id' => $user->id]);
|
Tag::create(['tag' => 'TagTwo', 'tagMode' => 'nothing', 'user_id' => $user->id]);
|
||||||
Tag::create(['tag' => 'TagThree', 'tagMode' => 'nothing', 'user_id' => $user->id]);
|
Tag::create(['tag' => 'TagThree', 'tagMode' => 'nothing', 'user_id' => $user->id]);
|
||||||
@ -541,9 +528,10 @@ class TestDataSeeder extends Seeder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $tag
|
* @param $tagName
|
||||||
*
|
*
|
||||||
* @return Tag|null
|
* @return Tag|null
|
||||||
|
* @internal param $tag
|
||||||
*/
|
*/
|
||||||
protected function findTag($tagName)
|
protected function findTag($tagName)
|
||||||
{
|
{
|
||||||
|
2
pu.sh
2
pu.sh
@ -10,7 +10,7 @@ then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# directories to look in:
|
# directories to look in:
|
||||||
dirs=("controllers" "database" "factories" "helpers" "models" "middleware" "repositories" "support")
|
dirs=("controllers" "database" "factories" "generators" "helpers" "models" "middleware" "repositories" "support")
|
||||||
|
|
||||||
if [ ! -z "$1" ]
|
if [ ! -z "$1" ]
|
||||||
then
|
then
|
||||||
|
13
public/bootstrap/css/bootstrap.min.css
vendored
Normal file → Executable file
13
public/bootstrap/css/bootstrap.min.css
vendored
Normal file → Executable file
File diff suppressed because one or more lines are too long
11
public/bootstrap/js/bootstrap.min.js
vendored
Normal file → Executable file
11
public/bootstrap/js/bootstrap.min.js
vendored
Normal file → Executable file
File diff suppressed because one or more lines are too long
@ -7,42 +7,42 @@
|
|||||||
* Built for http://www.improvely.com
|
* Built for http://www.improvely.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.daterangepicker.dropdown-menu {
|
.daterangepicker.dropdown-menu {
|
||||||
max-width: none;
|
max-width: none;
|
||||||
z-index: 3000;
|
z-index: 3000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker.opensleft .ranges, .daterangepicker.opensleft .calendar {
|
.daterangepicker.opensleft .ranges, .daterangepicker.opensleft .calendar {
|
||||||
float: left;
|
float: left;
|
||||||
margin: 4px;
|
margin: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker.opensright .ranges, .daterangepicker.opensright .calendar,
|
.daterangepicker.opensright .ranges, .daterangepicker.opensright .calendar,
|
||||||
.daterangepicker.openscenter .ranges, .daterangepicker.openscenter .calendar {
|
.daterangepicker.openscenter .ranges, .daterangepicker.openscenter .calendar {
|
||||||
float: right;
|
float: right;
|
||||||
margin: 4px;
|
margin: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker.single .ranges, .daterangepicker.single .calendar {
|
.daterangepicker.single .ranges, .daterangepicker.single .calendar {
|
||||||
float: none;
|
float: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .ranges {
|
.daterangepicker .ranges {
|
||||||
width: 160px;
|
width: 160px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .ranges .range_inputs>div {
|
.daterangepicker .ranges .range_inputs>div {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .ranges .range_inputs>div:nth-child(2) {
|
.daterangepicker .ranges .range_inputs>div:nth-child(2) {
|
||||||
padding-left: 11px;
|
padding-left: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .calendar {
|
.daterangepicker .calendar {
|
||||||
display: none;
|
display: none;
|
||||||
max-width: 270px;
|
max-width: 270px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker.show-calendar .calendar {
|
.daterangepicker.show-calendar .calendar {
|
||||||
@ -50,270 +50,286 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .calendar.single .calendar-date {
|
.daterangepicker .calendar.single .calendar-date {
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .calendar th, .daterangepicker .calendar td {
|
.daterangepicker .calendar th, .daterangepicker .calendar td {
|
||||||
font-family: Roboto, 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
min-width: 32px;
|
min-width: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .daterangepicker_start_input label,
|
.daterangepicker .daterangepicker_start_input label,
|
||||||
.daterangepicker .daterangepicker_end_input label {
|
.daterangepicker .daterangepicker_end_input label {
|
||||||
color: #333;
|
color: #333;
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
text-shadow: #fff 1px 1px 0px;
|
text-shadow: #fff 1px 1px 0px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
width: 74px;
|
width: 74px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .ranges input {
|
.daterangepicker .ranges input {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .ranges .input-mini {
|
.daterangepicker .ranges .input-mini {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
color: #555;
|
color: #555;
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin: 0 0 10px 0;
|
margin: 0 0 10px 0;
|
||||||
padding: 0 6px;
|
padding: 0 6px;
|
||||||
width: 74px;
|
width: 74px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .ranges ul {
|
.daterangepicker .ranges ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .ranges li {
|
.daterangepicker .ranges li {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
border: 1px solid #f5f5f5;
|
border: 1px solid #f5f5f5;
|
||||||
color: #08c;
|
color: #08c;
|
||||||
padding: 3px 12px;
|
padding: 3px 12px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
-webkit-border-radius: 5px;
|
-webkit-border-radius: 5px;
|
||||||
-moz-border-radius: 5px;
|
-moz-border-radius: 5px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .ranges li.active, .daterangepicker .ranges li:hover {
|
.daterangepicker .ranges li.active, .daterangepicker .ranges li:hover {
|
||||||
background: #08c;
|
background: #08c;
|
||||||
border: 1px solid #08c;
|
border: 1px solid #08c;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .calendar-date {
|
.daterangepicker .calendar-date {
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker .calendar-time {
|
.daterangepicker .calendar-time {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 8px auto 0 auto;
|
margin: 8px auto 0 auto;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker {
|
.daterangepicker {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
top: 100px;
|
top: 100px;
|
||||||
left: 20px;
|
left: 20px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
-webkit-border-radius: 4px;
|
-webkit-border-radius: 4px;
|
||||||
-moz-border-radius: 4px;
|
-moz-border-radius: 4px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker.opensleft:before {
|
.daterangepicker.opensleft:before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -7px;
|
top: -7px;
|
||||||
right: 9px;
|
right: 9px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border-right: 7px solid transparent;
|
border-right: 7px solid transparent;
|
||||||
border-bottom: 7px solid #ccc;
|
border-bottom: 7px solid #ccc;
|
||||||
border-left: 7px solid transparent;
|
border-left: 7px solid transparent;
|
||||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||||
content: '';
|
content: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker.opensleft:after {
|
.daterangepicker.opensleft:after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -6px;
|
top: -6px;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border-right: 6px solid transparent;
|
border-right: 6px solid transparent;
|
||||||
border-bottom: 6px solid #fff;
|
border-bottom: 6px solid #fff;
|
||||||
border-left: 6px solid transparent;
|
border-left: 6px solid transparent;
|
||||||
content: '';
|
content: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker.openscenter:before {
|
.daterangepicker.openscenter:before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -7px;
|
top: -7px;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
width: 0;
|
width: 0;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border-right: 7px solid transparent;
|
border-right: 7px solid transparent;
|
||||||
border-bottom: 7px solid #ccc;
|
border-bottom: 7px solid #ccc;
|
||||||
border-left: 7px solid transparent;
|
border-left: 7px solid transparent;
|
||||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||||
content: '';
|
content: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker.openscenter:after {
|
.daterangepicker.openscenter:after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -6px;
|
top: -6px;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
width: 0;
|
width: 0;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border-right: 6px solid transparent;
|
border-right: 6px solid transparent;
|
||||||
border-bottom: 6px solid #fff;
|
border-bottom: 6px solid #fff;
|
||||||
border-left: 6px solid transparent;
|
border-left: 6px solid transparent;
|
||||||
content: '';
|
content: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker.opensright:before {
|
.daterangepicker.opensright:before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -7px;
|
top: -7px;
|
||||||
left: 9px;
|
left: 9px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border-right: 7px solid transparent;
|
border-right: 7px solid transparent;
|
||||||
border-bottom: 7px solid #ccc;
|
border-bottom: 7px solid #ccc;
|
||||||
border-left: 7px solid transparent;
|
border-left: 7px solid transparent;
|
||||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||||
content: '';
|
content: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker.opensright:after {
|
.daterangepicker.opensright:after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -6px;
|
top: -6px;
|
||||||
left: 10px;
|
left: 10px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border-right: 6px solid transparent;
|
border-right: 6px solid transparent;
|
||||||
border-bottom: 6px solid #fff;
|
border-bottom: 6px solid #fff;
|
||||||
border-left: 6px solid transparent;
|
border-left: 6px solid transparent;
|
||||||
content: '';
|
content: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker.dropup{
|
||||||
|
margin-top: -5px;
|
||||||
|
}
|
||||||
|
.daterangepicker.dropup:before{
|
||||||
|
top: initial;
|
||||||
|
bottom:-7px;
|
||||||
|
border-bottom: initial;
|
||||||
|
border-top: 7px solid #ccc;
|
||||||
|
}
|
||||||
|
.daterangepicker.dropup:after{
|
||||||
|
top: initial;
|
||||||
|
bottom:-6px;
|
||||||
|
border-bottom: initial;
|
||||||
|
border-top: 6px solid #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker table {
|
.daterangepicker table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker td, .daterangepicker th {
|
.daterangepicker td, .daterangepicker th {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
-webkit-border-radius: 4px;
|
-webkit-border-radius: 4px;
|
||||||
-moz-border-radius: 4px;
|
-moz-border-radius: 4px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker td.off {
|
.daterangepicker td.off {
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker td.disabled, .daterangepicker option.disabled {
|
.daterangepicker td.disabled, .daterangepicker option.disabled {
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker td.available:hover, .daterangepicker th.available:hover {
|
.daterangepicker td.available:hover, .daterangepicker th.available:hover {
|
||||||
background: #eee;
|
background: #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker td.in-range {
|
.daterangepicker td.in-range {
|
||||||
background: #ebf4f8;
|
background: #ebf4f8;
|
||||||
-webkit-border-radius: 0;
|
-webkit-border-radius: 0;
|
||||||
-moz-border-radius: 0;
|
-moz-border-radius: 0;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker td.start-date {
|
.daterangepicker td.start-date {
|
||||||
-webkit-border-radius: 4px 0 0 4px;
|
-webkit-border-radius: 4px 0 0 4px;
|
||||||
-moz-border-radius: 4px 0 0 4px;
|
-moz-border-radius: 4px 0 0 4px;
|
||||||
border-radius: 4px 0 0 4px;
|
border-radius: 4px 0 0 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker td.end-date {
|
.daterangepicker td.end-date {
|
||||||
-webkit-border-radius: 0 4px 4px 0;
|
-webkit-border-radius: 0 4px 4px 0;
|
||||||
-moz-border-radius: 0 4px 4px 0;
|
-moz-border-radius: 0 4px 4px 0;
|
||||||
border-radius: 0 4px 4px 0;
|
border-radius: 0 4px 4px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker td.start-date.end-date {
|
.daterangepicker td.start-date.end-date {
|
||||||
-webkit-border-radius: 4px;
|
-webkit-border-radius: 4px;
|
||||||
-moz-border-radius: 4px;
|
-moz-border-radius: 4px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker td.active, .daterangepicker td.active:hover {
|
.daterangepicker td.active, .daterangepicker td.active:hover {
|
||||||
background-color: #357ebd;
|
background-color: #357ebd;
|
||||||
border-color: #3071a9;
|
border-color: #3071a9;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker td.week, .daterangepicker th.week {
|
.daterangepicker td.week, .daterangepicker th.week {
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker select.monthselect, .daterangepicker select.yearselect {
|
.daterangepicker select.monthselect, .daterangepicker select.yearselect {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
height: auto;
|
height: auto;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker select.monthselect {
|
.daterangepicker select.monthselect {
|
||||||
margin-right: 2%;
|
margin-right: 2%;
|
||||||
width: 56%;
|
width: 56%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker select.yearselect {
|
.daterangepicker select.yearselect {
|
||||||
width: 40%;
|
width: 40%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect {
|
.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker_start_input {
|
.daterangepicker_start_input {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker_end_input {
|
.daterangepicker_end_input {
|
||||||
float: left;
|
float: left;
|
||||||
padding-left: 11px
|
padding-left: 11px
|
||||||
}
|
}
|
||||||
|
|
||||||
.daterangepicker th.month {
|
.daterangepicker th.month {
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
556
public/js/Chart.StackedBar.js
Normal file
556
public/js/Chart.StackedBar.js
Normal file
@ -0,0 +1,556 @@
|
|||||||
|
(function (factory) {
|
||||||
|
"use strict";
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
// AMD. Register as an anonymous module.
|
||||||
|
define(['chart.js'], factory);
|
||||||
|
} else if (typeof exports === 'object') {
|
||||||
|
// Node/CommonJS
|
||||||
|
module.exports = factory(require('chart.js'));
|
||||||
|
} else {
|
||||||
|
// Global browser
|
||||||
|
factory(Chart);
|
||||||
|
}
|
||||||
|
}(function (Chart) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var helpers = Chart.helpers;
|
||||||
|
|
||||||
|
var defaultConfig = {
|
||||||
|
scaleBeginAtZero : true,
|
||||||
|
|
||||||
|
//Boolean - Whether grid lines are shown across the chart
|
||||||
|
scaleShowGridLines : true,
|
||||||
|
|
||||||
|
//String - Colour of the grid lines
|
||||||
|
scaleGridLineColor : "rgba(0,0,0,.05)",
|
||||||
|
|
||||||
|
//Number - Width of the grid lines
|
||||||
|
scaleGridLineWidth : 1,
|
||||||
|
|
||||||
|
//Boolean - Whether to show horizontal lines (except X axis)
|
||||||
|
scaleShowHorizontalLines: true,
|
||||||
|
|
||||||
|
//Boolean - Whether to show vertical lines (except Y axis)
|
||||||
|
scaleShowVerticalLines: true,
|
||||||
|
|
||||||
|
//Boolean - If there is a stroke on each bar
|
||||||
|
barShowStroke : true,
|
||||||
|
|
||||||
|
//Number - Pixel width of the bar stroke
|
||||||
|
barStrokeWidth : 2,
|
||||||
|
|
||||||
|
//Number - Spacing between each of the X value sets
|
||||||
|
barValueSpacing : 5,
|
||||||
|
|
||||||
|
//Boolean - Whether bars should be rendered on a percentage base
|
||||||
|
relativeBars : false,
|
||||||
|
|
||||||
|
//String - A legend template
|
||||||
|
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>",
|
||||||
|
|
||||||
|
//Boolean - Show total legend
|
||||||
|
showTotal: false,
|
||||||
|
|
||||||
|
//String - Color of total legend
|
||||||
|
totalColor: '#fff',
|
||||||
|
|
||||||
|
//String - Total Label
|
||||||
|
totalLabel: 'Total',
|
||||||
|
|
||||||
|
//Boolean - Hide labels with value set to 0
|
||||||
|
tooltipHideZero: false
|
||||||
|
};
|
||||||
|
|
||||||
|
Chart.Type.extend({
|
||||||
|
name: "StackedBar",
|
||||||
|
defaults : defaultConfig,
|
||||||
|
initialize: function(data){
|
||||||
|
//Expose options as a scope variable here so we can access it in the ScaleClass
|
||||||
|
var options = this.options;
|
||||||
|
|
||||||
|
// Save data as a source for updating of values & methods
|
||||||
|
this.data = data;
|
||||||
|
|
||||||
|
this.ScaleClass = Chart.Scale.extend({
|
||||||
|
offsetGridLines : true,
|
||||||
|
calculateBarX : function(barIndex){
|
||||||
|
return this.calculateX(barIndex);
|
||||||
|
},
|
||||||
|
calculateBarY : function(datasets, dsIndex, barIndex, value){
|
||||||
|
var offset = 0,
|
||||||
|
sum = 0;
|
||||||
|
|
||||||
|
for(var i = 0; i < datasets.length; i++) {
|
||||||
|
sum += datasets[i].bars[barIndex].value;
|
||||||
|
}
|
||||||
|
for(i = dsIndex; i < datasets.length; i++) {
|
||||||
|
if(i === dsIndex && value) {
|
||||||
|
offset += value;
|
||||||
|
} else {
|
||||||
|
offset = +offset + +datasets[i].bars[barIndex].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(options.relativeBars) {
|
||||||
|
offset = offset / sum * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.calculateY(offset);
|
||||||
|
},
|
||||||
|
calculateBaseWidth : function(){
|
||||||
|
return (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);
|
||||||
|
},
|
||||||
|
calculateBaseHeight : function(){
|
||||||
|
return (this.calculateY(1) - this.calculateY(0));
|
||||||
|
},
|
||||||
|
calculateBarWidth : function(datasetCount){
|
||||||
|
//The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
|
||||||
|
return this.calculateBaseWidth();
|
||||||
|
},
|
||||||
|
calculateBarHeight : function(datasets, dsIndex, barIndex, value) {
|
||||||
|
var sum = 0;
|
||||||
|
|
||||||
|
for(var i = 0; i < datasets.length; i++) {
|
||||||
|
sum += datasets[i].bars[barIndex].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!value) {
|
||||||
|
value = datasets[dsIndex].bars[barIndex].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(options.relativeBars) {
|
||||||
|
value = value / sum * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.calculateY(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.datasets = [];
|
||||||
|
|
||||||
|
//Set up tooltip events on the chart
|
||||||
|
if (this.options.showTooltips){
|
||||||
|
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
|
||||||
|
var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];
|
||||||
|
|
||||||
|
this.eachBars(function(bar){
|
||||||
|
bar.restore(['fillColor', 'strokeColor']);
|
||||||
|
});
|
||||||
|
helpers.each(activeBars, function(activeBar){
|
||||||
|
activeBar.fillColor = activeBar.highlightFill;
|
||||||
|
activeBar.strokeColor = activeBar.highlightStroke;
|
||||||
|
});
|
||||||
|
this.showTooltip(activeBars);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Declare the extension of the default point, to cater for the options passed in to the constructor
|
||||||
|
this.BarClass = Chart.Rectangle.extend({
|
||||||
|
strokeWidth : this.options.barStrokeWidth,
|
||||||
|
showStroke : this.options.barShowStroke,
|
||||||
|
ctx : this.chart.ctx
|
||||||
|
});
|
||||||
|
|
||||||
|
//Iterate through each of the datasets, and build this into a property of the chart
|
||||||
|
helpers.each(data.datasets,function(dataset,datasetIndex){
|
||||||
|
|
||||||
|
var datasetObject = {
|
||||||
|
label : dataset.label || null,
|
||||||
|
fillColor : dataset.fillColor,
|
||||||
|
strokeColor : dataset.strokeColor,
|
||||||
|
bars : []
|
||||||
|
};
|
||||||
|
|
||||||
|
this.datasets.push(datasetObject);
|
||||||
|
|
||||||
|
helpers.each(dataset.data,function(dataPoint,index){
|
||||||
|
if(!helpers.isNumber(dataPoint)){
|
||||||
|
dataPoint = 0;
|
||||||
|
}
|
||||||
|
//Add a new point for each piece of data, passing any required data to draw.
|
||||||
|
//Add 0 as value if !isNumber (e.g. empty values are useful when 0 values should be hidden in tooltip)
|
||||||
|
datasetObject.bars.push(new this.BarClass({
|
||||||
|
value : dataPoint,
|
||||||
|
label : data.labels[index],
|
||||||
|
datasetLabel: dataset.label,
|
||||||
|
strokeColor : dataset.strokeColor,
|
||||||
|
fillColor : dataset.fillColor,
|
||||||
|
highlightFill : dataset.highlightFill || dataset.fillColor,
|
||||||
|
highlightStroke : dataset.highlightStroke || dataset.strokeColor
|
||||||
|
}));
|
||||||
|
},this);
|
||||||
|
|
||||||
|
},this);
|
||||||
|
|
||||||
|
this.buildScale(data.labels);
|
||||||
|
|
||||||
|
this.eachBars(function(bar, index, datasetIndex){
|
||||||
|
helpers.extend(bar, {
|
||||||
|
base: this.scale.endPoint,
|
||||||
|
height: 0,
|
||||||
|
width : this.scale.calculateBarWidth(this.datasets.length),
|
||||||
|
x: this.scale.calculateBarX(index),
|
||||||
|
y: this.scale.endPoint
|
||||||
|
});
|
||||||
|
bar.save();
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.render();
|
||||||
|
},
|
||||||
|
showTooltip : function(ChartElements, forceRedraw){
|
||||||
|
// Only redraw the chart if we've actually changed what we're hovering on.
|
||||||
|
if (typeof this.activeElements === 'undefined') this.activeElements = [];
|
||||||
|
|
||||||
|
helpers = Chart.helpers;
|
||||||
|
|
||||||
|
var isChanged = (function(Elements){
|
||||||
|
var changed = false;
|
||||||
|
|
||||||
|
if (Elements.length !== this.activeElements.length){
|
||||||
|
changed = true;
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
helpers.each(Elements, function(element, index){
|
||||||
|
if (element !== this.activeElements[index]){
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
return changed;
|
||||||
|
}).call(this, ChartElements);
|
||||||
|
|
||||||
|
if (!isChanged && !forceRedraw){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
this.activeElements = ChartElements;
|
||||||
|
}
|
||||||
|
this.draw();
|
||||||
|
if(this.options.customTooltips){
|
||||||
|
this.options.customTooltips(false);
|
||||||
|
}
|
||||||
|
if (ChartElements.length > 0){
|
||||||
|
// If we have multiple datasets, show a MultiTooltip for all of the data points at that index
|
||||||
|
if (this.datasets && this.datasets.length > 1) {
|
||||||
|
var dataArray,
|
||||||
|
dataIndex;
|
||||||
|
|
||||||
|
for (var i = this.datasets.length - 1; i >= 0; i--) {
|
||||||
|
dataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments;
|
||||||
|
dataIndex = helpers.indexOf(dataArray, ChartElements[0]);
|
||||||
|
if (dataIndex !== -1){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var tooltipLabels = [],
|
||||||
|
tooltipColors = [],
|
||||||
|
medianPosition = (function(index) {
|
||||||
|
|
||||||
|
// Get all the points at that particular index
|
||||||
|
var Elements = [],
|
||||||
|
dataCollection,
|
||||||
|
xPositions = [],
|
||||||
|
yPositions = [],
|
||||||
|
xMax,
|
||||||
|
yMax,
|
||||||
|
xMin,
|
||||||
|
yMin;
|
||||||
|
helpers.each(this.datasets, function(dataset){
|
||||||
|
dataCollection = dataset.points || dataset.bars || dataset.segments;
|
||||||
|
if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){
|
||||||
|
Elements.push(dataCollection[dataIndex]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var total = {
|
||||||
|
datasetLabel: this.options.totalLabel,
|
||||||
|
value: 0,
|
||||||
|
fillColor: this.options.totalColor,
|
||||||
|
strokeColor: this.options.totalColor
|
||||||
|
};
|
||||||
|
|
||||||
|
helpers.each(Elements, function(element) {
|
||||||
|
if (this.options.tooltipHideZero && element.value === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xPositions.push(element.x);
|
||||||
|
yPositions.push(element.y);
|
||||||
|
|
||||||
|
total.value += element.value;
|
||||||
|
|
||||||
|
//Include any colour information about the element
|
||||||
|
tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));
|
||||||
|
tooltipColors.push({
|
||||||
|
fill: element._saved.fillColor || element.fillColor,
|
||||||
|
stroke: element._saved.strokeColor || element.strokeColor
|
||||||
|
});
|
||||||
|
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
if (this.options.showTotal) {
|
||||||
|
tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, total));
|
||||||
|
tooltipColors.push({
|
||||||
|
fill: total.fillColor,
|
||||||
|
stroke: total.strokeColor
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
yMin = helpers.min(yPositions);
|
||||||
|
yMax = helpers.max(yPositions);
|
||||||
|
|
||||||
|
xMin = helpers.min(xPositions);
|
||||||
|
xMax = helpers.max(xPositions);
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: (xMin > this.chart.width/2) ? xMin : xMax,
|
||||||
|
y: (yMin + yMax)/2
|
||||||
|
};
|
||||||
|
}).call(this, dataIndex);
|
||||||
|
|
||||||
|
new Chart.MultiTooltip({
|
||||||
|
x: medianPosition.x,
|
||||||
|
y: medianPosition.y,
|
||||||
|
xPadding: this.options.tooltipXPadding,
|
||||||
|
yPadding: this.options.tooltipYPadding,
|
||||||
|
xOffset: this.options.tooltipXOffset,
|
||||||
|
fillColor: this.options.tooltipFillColor,
|
||||||
|
textColor: this.options.tooltipFontColor,
|
||||||
|
fontFamily: this.options.tooltipFontFamily,
|
||||||
|
fontStyle: this.options.tooltipFontStyle,
|
||||||
|
fontSize: this.options.tooltipFontSize,
|
||||||
|
titleTextColor: this.options.tooltipTitleFontColor,
|
||||||
|
titleFontFamily: this.options.tooltipTitleFontFamily,
|
||||||
|
titleFontStyle: this.options.tooltipTitleFontStyle,
|
||||||
|
titleFontSize: this.options.tooltipTitleFontSize,
|
||||||
|
cornerRadius: this.options.tooltipCornerRadius,
|
||||||
|
labels: tooltipLabels,
|
||||||
|
legendColors: tooltipColors,
|
||||||
|
legendColorBackground : this.options.multiTooltipKeyBackground,
|
||||||
|
title: ChartElements[0].label,
|
||||||
|
chart: this.chart,
|
||||||
|
ctx: this.chart.ctx,
|
||||||
|
custom: this.options.customTooltips
|
||||||
|
}).draw();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
helpers.each(ChartElements, function(Element) {
|
||||||
|
var tooltipPosition = Element.tooltipPosition();
|
||||||
|
new Chart.Tooltip({
|
||||||
|
x: Math.round(tooltipPosition.x),
|
||||||
|
y: Math.round(tooltipPosition.y),
|
||||||
|
xPadding: this.options.tooltipXPadding,
|
||||||
|
yPadding: this.options.tooltipYPadding,
|
||||||
|
fillColor: this.options.tooltipFillColor,
|
||||||
|
textColor: this.options.tooltipFontColor,
|
||||||
|
fontFamily: this.options.tooltipFontFamily,
|
||||||
|
fontStyle: this.options.tooltipFontStyle,
|
||||||
|
fontSize: this.options.tooltipFontSize,
|
||||||
|
caretHeight: this.options.tooltipCaretSize,
|
||||||
|
cornerRadius: this.options.tooltipCornerRadius,
|
||||||
|
text: helpers.template(this.options.tooltipTemplate, Element),
|
||||||
|
chart: this.chart,
|
||||||
|
custom: this.options.customTooltips
|
||||||
|
}).draw();
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
update : function(){
|
||||||
|
|
||||||
|
//Iterate through each of the datasets, and build this into a property of the chart
|
||||||
|
helpers.each(this.data.datasets,function(dataset,datasetIndex){
|
||||||
|
|
||||||
|
helpers.extend(this.datasets[datasetIndex], {
|
||||||
|
label : dataset.label || null,
|
||||||
|
fillColor : dataset.fillColor,
|
||||||
|
strokeColor : dataset.strokeColor,
|
||||||
|
});
|
||||||
|
|
||||||
|
helpers.each(dataset.data,function(dataPoint,index){
|
||||||
|
helpers.extend(this.datasets[datasetIndex].bars[index], {
|
||||||
|
value : dataPoint,
|
||||||
|
label : this.data.labels[index],
|
||||||
|
datasetLabel: dataset.label,
|
||||||
|
strokeColor : dataset.strokeColor,
|
||||||
|
fillColor : dataset.fillColor,
|
||||||
|
highlightFill : dataset.highlightFill || dataset.fillColor,
|
||||||
|
highlightStroke : dataset.highlightStroke || dataset.strokeColor
|
||||||
|
});
|
||||||
|
},this);
|
||||||
|
|
||||||
|
},this);
|
||||||
|
|
||||||
|
|
||||||
|
this.scale.update();
|
||||||
|
// Reset any highlight colours before updating.
|
||||||
|
helpers.each(this.activeElements, function(activeElement){
|
||||||
|
activeElement.restore(['fillColor', 'strokeColor']);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.eachBars(function(bar){
|
||||||
|
bar.save();
|
||||||
|
});
|
||||||
|
this.render();
|
||||||
|
},
|
||||||
|
eachBars : function(callback){
|
||||||
|
helpers.each(this.datasets,function(dataset, datasetIndex){
|
||||||
|
helpers.each(dataset.bars, callback, this, datasetIndex);
|
||||||
|
},this);
|
||||||
|
},
|
||||||
|
getBarsAtEvent : function(e){
|
||||||
|
var barsArray = [],
|
||||||
|
eventPosition = helpers.getRelativePosition(e),
|
||||||
|
datasetIterator = function(dataset){
|
||||||
|
barsArray.push(dataset.bars[barIndex]);
|
||||||
|
},
|
||||||
|
barIndex;
|
||||||
|
|
||||||
|
for (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {
|
||||||
|
for (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {
|
||||||
|
if (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){
|
||||||
|
helpers.each(this.datasets, datasetIterator);
|
||||||
|
return barsArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return barsArray;
|
||||||
|
},
|
||||||
|
buildScale : function(labels){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var dataTotal = function(){
|
||||||
|
var values = [];
|
||||||
|
helpers.each(self.datasets, function(dataset) {
|
||||||
|
helpers.each(dataset.bars, function(bar, barIndex) {
|
||||||
|
if(!values[barIndex]) values[barIndex] = 0;
|
||||||
|
if(self.options.relativeBars) {
|
||||||
|
values[barIndex] = 100;
|
||||||
|
} else {
|
||||||
|
values[barIndex] = +values[barIndex] + +bar.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return values;
|
||||||
|
};
|
||||||
|
|
||||||
|
var scaleOptions = {
|
||||||
|
templateString : this.options.scaleLabel,
|
||||||
|
height : this.chart.height,
|
||||||
|
width : this.chart.width,
|
||||||
|
ctx : this.chart.ctx,
|
||||||
|
textColor : this.options.scaleFontColor,
|
||||||
|
fontSize : this.options.scaleFontSize,
|
||||||
|
fontStyle : this.options.scaleFontStyle,
|
||||||
|
fontFamily : this.options.scaleFontFamily,
|
||||||
|
valuesCount : labels.length,
|
||||||
|
beginAtZero : this.options.scaleBeginAtZero,
|
||||||
|
integersOnly : this.options.scaleIntegersOnly,
|
||||||
|
calculateYRange: function(currentHeight){
|
||||||
|
var updatedRanges = helpers.calculateScaleRange(
|
||||||
|
dataTotal(),
|
||||||
|
currentHeight,
|
||||||
|
this.fontSize,
|
||||||
|
this.beginAtZero,
|
||||||
|
this.integersOnly
|
||||||
|
);
|
||||||
|
helpers.extend(this, updatedRanges);
|
||||||
|
},
|
||||||
|
xLabels : this.options.xLabels || labels,
|
||||||
|
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
|
||||||
|
lineWidth : this.options.scaleLineWidth,
|
||||||
|
lineColor : this.options.scaleLineColor,
|
||||||
|
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
|
||||||
|
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
|
||||||
|
showHorizontalLines : this.options.scaleShowHorizontalLines,
|
||||||
|
showVerticalLines : this.options.scaleShowVerticalLines,
|
||||||
|
padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,
|
||||||
|
showLabels : this.options.scaleShowLabels,
|
||||||
|
display : this.options.showScale
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.options.scaleOverride){
|
||||||
|
helpers.extend(scaleOptions, {
|
||||||
|
calculateYRange: helpers.noop,
|
||||||
|
steps: this.options.scaleSteps,
|
||||||
|
stepValue: this.options.scaleStepWidth,
|
||||||
|
min: this.options.scaleStartValue,
|
||||||
|
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.scale = new this.ScaleClass(scaleOptions);
|
||||||
|
},
|
||||||
|
addData : function(valuesArray,label){
|
||||||
|
//Map the values array for each of the datasets
|
||||||
|
helpers.each(valuesArray,function(value,datasetIndex){
|
||||||
|
if (helpers.isNumber(value)){
|
||||||
|
//Add a new point for each piece of data, passing any required data to draw.
|
||||||
|
//Add 0 as value if !isNumber (e.g. empty values are useful when 0 values should be hidden in tooltip)
|
||||||
|
this.datasets[datasetIndex].bars.push(new this.BarClass({
|
||||||
|
value : helpers.isNumber(value)?value:0,
|
||||||
|
label : label,
|
||||||
|
x: this.scale.calculateBarX(this.scale.valuesCount+1),
|
||||||
|
y: this.scale.endPoint,
|
||||||
|
width : this.scale.calculateBarWidth(this.datasets.length),
|
||||||
|
base : this.scale.endPoint,
|
||||||
|
strokeColor : this.datasets[datasetIndex].strokeColor,
|
||||||
|
fillColor : this.datasets[datasetIndex].fillColor
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},this);
|
||||||
|
|
||||||
|
this.scale.addXLabel(label);
|
||||||
|
//Then re-render the chart.
|
||||||
|
this.update();
|
||||||
|
},
|
||||||
|
removeData : function(){
|
||||||
|
this.scale.removeXLabel();
|
||||||
|
//Then re-render the chart.
|
||||||
|
helpers.each(this.datasets,function(dataset){
|
||||||
|
dataset.bars.shift();
|
||||||
|
},this);
|
||||||
|
this.update();
|
||||||
|
},
|
||||||
|
reflow : function(){
|
||||||
|
helpers.extend(this.BarClass.prototype,{
|
||||||
|
y: this.scale.endPoint,
|
||||||
|
base : this.scale.endPoint
|
||||||
|
});
|
||||||
|
var newScaleProps = helpers.extend({
|
||||||
|
height : this.chart.height,
|
||||||
|
width : this.chart.width
|
||||||
|
});
|
||||||
|
this.scale.update(newScaleProps);
|
||||||
|
},
|
||||||
|
draw : function(ease){
|
||||||
|
var easingDecimal = ease || 1;
|
||||||
|
this.clear();
|
||||||
|
|
||||||
|
var ctx = this.chart.ctx;
|
||||||
|
|
||||||
|
this.scale.draw(easingDecimal);
|
||||||
|
|
||||||
|
//Draw all the bars for each dataset
|
||||||
|
helpers.each(this.datasets,function(dataset,datasetIndex){
|
||||||
|
helpers.each(dataset.bars,function(bar,index){
|
||||||
|
var y = this.scale.calculateBarY(this.datasets, datasetIndex, index, bar.value),
|
||||||
|
height = this.scale.calculateBarHeight(this.datasets, datasetIndex, index, bar.value);
|
||||||
|
|
||||||
|
//Transition then draw
|
||||||
|
if(bar.value > 0) {
|
||||||
|
bar.transition({
|
||||||
|
base : this.scale.endPoint - (Math.abs(height) - Math.abs(y)),
|
||||||
|
x : this.scale.calculateBarX(index),
|
||||||
|
y : Math.abs(y),
|
||||||
|
height : Math.abs(height),
|
||||||
|
width : this.scale.calculateBarWidth(this.datasets.length)
|
||||||
|
}, easingDecimal).draw();
|
||||||
|
}
|
||||||
|
},this);
|
||||||
|
},this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}));
|
11
public/js/Chart.min.js
vendored
Normal file
11
public/js/Chart.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
|||||||
/* global $, googleLineChart, accountID, token */
|
/* global $, lineChart, accountID, token */
|
||||||
|
|
||||||
|
|
||||||
// Return a helper with preserved width of cells
|
// Return a helper with preserved width of cells
|
||||||
@ -12,8 +12,8 @@ var fixHelper = function (e, ui) {
|
|||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
if (typeof(googleLineChart) === "function" && typeof accountID !== 'undefined') {
|
if (typeof(lineChart) === "function" && typeof accountID !== 'undefined') {
|
||||||
googleLineChart('chart/account/' + accountID, 'overview-chart');
|
lineChart('chart/account/' + accountID, 'overview-chart');
|
||||||
}
|
}
|
||||||
|
|
||||||
// sortable!
|
// sortable!
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/* global googleComboChart, billID */
|
/* global comboChart, billID */
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
if (typeof(googleComboChart) === 'function' && typeof(billID) !== 'undefined') {
|
if (typeof(comboChart) === 'function' && typeof(billID) !== 'undefined') {
|
||||||
googleComboChart('chart/bill/' + billID, 'bill-overview');
|
comboChart('chart/bill/' + billID, 'bill-overview');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
@ -1,4 +1,4 @@
|
|||||||
/* globals $, budgeted:true, currencySymbol, budgetIncomeTotal ,budgetedMuch, budgetedPercentage, token, budgetID, repetitionID, spent, googleLineChart */
|
/* globals $, budgeted:true, currencySymbol, budgetIncomeTotal, columnChart, budgetedMuch, budgetedPercentage, token, budgetID, repetitionID, spent, lineChart */
|
||||||
|
|
||||||
function drawSpentBar() {
|
function drawSpentBar() {
|
||||||
"use strict";
|
"use strict";
|
||||||
@ -95,104 +95,19 @@ $(function () {
|
|||||||
$('input[type="number"]').on('input', updateBudgetedAmounts);
|
$('input[type="number"]').on('input', updateBudgetedAmounts);
|
||||||
|
|
||||||
|
|
||||||
//updateRanges();
|
|
||||||
//$('input[type="range"]').on('input', updateSingleRange);
|
|
||||||
//$('input[type="number"]').on('input', updateSingleRange);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Draw the charts, if necessary:
|
Draw the charts, if necessary:
|
||||||
*/
|
*/
|
||||||
if (typeof budgetID !== 'undefined' && typeof repetitionID === 'undefined') {
|
if (typeof budgetID !== 'undefined' && typeof repetitionID === 'undefined') {
|
||||||
googleColumnChart('chart/budget/' + budgetID, 'budgetOverview');
|
columnChart('chart/budget/' + budgetID, 'budgetOverview');
|
||||||
}
|
}
|
||||||
if (typeof budgetID !== 'undefined' && typeof repetitionID !== 'undefined') {
|
if (typeof budgetID !== 'undefined' && typeof repetitionID !== 'undefined') {
|
||||||
googleLineChart('chart/budget/' + budgetID + '/' + repetitionID, 'budgetOverview');
|
lineChart('chart/budget/' + budgetID + '/' + repetitionID, 'budgetOverview');
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function updateIncome() {
|
||||||
//function updateSingleRange(e) {
|
|
||||||
// "use strict";
|
|
||||||
// // get some values:
|
|
||||||
// var input = $(e.target);
|
|
||||||
// var id = input.data('id');
|
|
||||||
// var value = parseInt(input.val());
|
|
||||||
// var spent = parseFloat($('#spent-' + id).data('value'));
|
|
||||||
//
|
|
||||||
// // update small display:
|
|
||||||
// if (value > 0) {
|
|
||||||
// // show the input:
|
|
||||||
// $('#budget-info-' + id + ' span').show();
|
|
||||||
// $('#budget-info-' + id + ' input').show();
|
|
||||||
//
|
|
||||||
// // update the text:
|
|
||||||
// $('#budget-description-' + id).text('Budgeted: ');
|
|
||||||
// } else {
|
|
||||||
// // hide the input:
|
|
||||||
// $('#budget-info-' + id + ' span').hide();
|
|
||||||
// $('#budget-info-' + id + ' input').hide();
|
|
||||||
//
|
|
||||||
// // update the text:
|
|
||||||
// $('#budget-description-' + id).html('<em>No budget</em>');
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // update the range display text:
|
|
||||||
// $('#budget-range-display-' + id).text('\u20AC ' + value.toFixed(2));
|
|
||||||
//
|
|
||||||
// // send a post to Firefly to update the amount:
|
|
||||||
// $.post('budgets/amount/' + id, {amount: value, _token: token}).success(function (data) {
|
|
||||||
// // update the link if relevant:
|
|
||||||
// $('#budget-link-' + id).attr('href', 'budgets/show/' + id + '/' + data.repetition);
|
|
||||||
// });
|
|
||||||
// if (input.attr('type') === 'number') {
|
|
||||||
// // update the range-input:
|
|
||||||
// $('#budget-range-' + id).val(value);
|
|
||||||
// } else {
|
|
||||||
// // update the number-input:
|
|
||||||
// $('#budget-info-' + id + ' input').val(value);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // update or hide the bar, whichever is necessary.
|
|
||||||
// updateTotal();
|
|
||||||
// return value;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//function updateTotal() {
|
|
||||||
// "use strict";
|
|
||||||
// var sum = 0;
|
|
||||||
// $('input[type="range"]').each(function (i, v) {
|
|
||||||
// // get some values:
|
|
||||||
// sum += parseInt($(v).val());
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Update total sum:
|
|
||||||
// */
|
|
||||||
// var totalAmount = parseInt($('#totalAmount').data('value'));
|
|
||||||
// var pct;
|
|
||||||
// if (sum <= totalAmount) {
|
|
||||||
// pct = sum / totalAmount * 100;
|
|
||||||
// $('#progress-bar-default').css('width', pct + '%');
|
|
||||||
// $('#progress-bar-warning').css('width', '0');
|
|
||||||
// $('#progress-bar-danger').css('width', '0');
|
|
||||||
// $('#budgetedAmount').text('\u20AC ' + sum.toFixed(2)).addClass('text-success').removeClass('text-danger');
|
|
||||||
// } else {
|
|
||||||
// // we gaan er X overheen,
|
|
||||||
//
|
|
||||||
// pct = totalAmount / sum * 100;
|
|
||||||
// var danger = 100 - pct;
|
|
||||||
// var err = 100 - danger;
|
|
||||||
// $('#progress-bar-default').css('width', 0);
|
|
||||||
// $('#progress-bar-warning').css('width', err + '%');
|
|
||||||
// $('#progress-bar-danger').css('width', danger + '%');
|
|
||||||
// $('#budgetedAmount').text('\u20AC ' + sum.toFixed(2)).addClass('text-danger').removeClass('text-success');
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
function updateIncome(e) {
|
|
||||||
"use strict";
|
"use strict";
|
||||||
$('#defaultModal').empty().load('budgets/income', function () {
|
$('#defaultModal').empty().load('budgets/income', function () {
|
||||||
$('#defaultModal').modal('show');
|
$('#defaultModal').modal('show');
|
||||||
@ -200,51 +115,3 @@ function updateIncome(e) {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
//function updateRanges() {
|
|
||||||
// "use strict";
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// var sum = 0;
|
|
||||||
// $('input[type="range"]').each(function (i, v) {
|
|
||||||
// // get some values:
|
|
||||||
// var input = $(v);
|
|
||||||
// var id = input.data('id');
|
|
||||||
// var value = parseInt(input.val());
|
|
||||||
//
|
|
||||||
// // calculate sum:
|
|
||||||
// sum += value;
|
|
||||||
//
|
|
||||||
// // update small display:
|
|
||||||
// $('#budget-range-display-' + id).text('\u20AC ' + value.toFixed(2));
|
|
||||||
//
|
|
||||||
// // send a post to Firefly to update the amount:
|
|
||||||
// $.post('budgets/amount/' + id, {amount: value, _token: token});
|
|
||||||
//
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Update total sum:
|
|
||||||
// */
|
|
||||||
// var totalAmount = parseInt($('#totalAmount').data('value'));
|
|
||||||
// var pct;
|
|
||||||
// if (sum <= totalAmount) {
|
|
||||||
// pct = sum / totalAmount * 100;
|
|
||||||
// $('#progress-bar-default').css('width', pct + '%');
|
|
||||||
// $('#progress-bar-warning').css('width', '0');
|
|
||||||
// $('#progress-bar-danger').css('width', '0');
|
|
||||||
// $('#budgetedAmount').text('\u20AC ' + sum.toFixed(2)).addClass('text-success').removeClass('text-danger');
|
|
||||||
// } else {
|
|
||||||
// // we gaan er X overheen,
|
|
||||||
//
|
|
||||||
// pct = totalAmount / sum * 100;
|
|
||||||
// var danger = 100 - pct;
|
|
||||||
// var err = 100 - danger;
|
|
||||||
// $('#progress-bar-default').css('width', 0);
|
|
||||||
// $('#progress-bar-warning').css('width', err + '%');
|
|
||||||
// $('#progress-bar-danger').css('width', danger + '%');
|
|
||||||
// $('#budgetedAmount').text('\u20AC ' + sum.toFixed(2)).addClass('text-danger').removeClass('text-success');
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//}
|
|
@ -1,9 +1,9 @@
|
|||||||
/* globals $, categoryID, googleColumnChart */
|
/* globals $, categoryID, columnChart */
|
||||||
$(function () {
|
$(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
if (typeof categoryID !== 'undefined') {
|
if (typeof categoryID !== 'undefined') {
|
||||||
googleColumnChart('chart/category/' + categoryID + '/all', 'all');
|
columnChart('chart/category/' + categoryID + '/all', 'all');
|
||||||
googleColumnChart('chart/category/' + categoryID + '/month', 'month');
|
columnChart('chart/category/' + categoryID + '/month', 'month');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
294
public/js/charts.js
Normal file
294
public/js/charts.js
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
/* globals $, Chart, currencySymbol */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Make some colours:
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
#555299
|
||||||
|
#4285f4
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#", "#", "#", "#"],
|
||||||
|
*/
|
||||||
|
var colourSet = [
|
||||||
|
[53, 124, 165],
|
||||||
|
[0, 141, 76],
|
||||||
|
[219, 139, 11],
|
||||||
|
[202, 25, 90],
|
||||||
|
[85, 82, 153],
|
||||||
|
[66, 133, 244],
|
||||||
|
[219, 68, 55],
|
||||||
|
[244, 180, 0],
|
||||||
|
[15, 157, 88],
|
||||||
|
[171, 71, 188],
|
||||||
|
[0, 172, 193],
|
||||||
|
[255, 112, 67],
|
||||||
|
[158, 157, 36],
|
||||||
|
[92, 107, 192],
|
||||||
|
[240, 98, 146],
|
||||||
|
[0, 121, 107],
|
||||||
|
[194, 24, 91],
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
var fillColors = [];
|
||||||
|
var strokePointHighColors = [];
|
||||||
|
|
||||||
|
|
||||||
|
for (var i = 0; i < colourSet.length; i++) {
|
||||||
|
fillColors.push("rgba(" + colourSet[i][0] + ", " + colourSet[i][1] + ", " + colourSet[i][2] + ", 0.2)");
|
||||||
|
strokePointHighColors.push("rgba(" + colourSet[i][0] + ", " + colourSet[i][1] + ", " + colourSet[i][2] + ", 0.9)");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set default options:
|
||||||
|
*/
|
||||||
|
var defaultAreaOptions = {
|
||||||
|
scaleShowGridLines: false,
|
||||||
|
pointDotRadius: 2,
|
||||||
|
datasetStrokeWidth: 1,
|
||||||
|
pointHitDetectionRadius: 5,
|
||||||
|
datasetFill: true,
|
||||||
|
scaleFontSize: 10,
|
||||||
|
responsive: false,
|
||||||
|
scaleLabel: " <%= '" + currencySymbol + " ' + Number(value).toFixed(0).replace('.', ',') %>",
|
||||||
|
tooltipFillColor: "rgba(0,0,0,0.5)",
|
||||||
|
multiTooltipTemplate: "<%=datasetLabel%>: <%= '" + currencySymbol + " ' + Number(value).toFixed(2).replace('.', ',') %>"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var defaultPieOptions = {
|
||||||
|
scaleShowGridLines: false,
|
||||||
|
pointDotRadius: 2,
|
||||||
|
datasetStrokeWidth: 1,
|
||||||
|
pointHitDetectionRadius: 5,
|
||||||
|
datasetFill: false,
|
||||||
|
scaleFontSize: 10,
|
||||||
|
responsive: false,
|
||||||
|
tooltipFillColor: "rgba(0,0,0,0.5)",
|
||||||
|
tooltipTemplate: "<%if (label){%><%=label%>: <%}%>" + currencySymbol + " <%= value %>",
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var defaultLineOptions = {
|
||||||
|
scaleShowGridLines: false,
|
||||||
|
pointDotRadius: 2,
|
||||||
|
datasetStrokeWidth: 1,
|
||||||
|
pointHitDetectionRadius: 5,
|
||||||
|
datasetFill: false,
|
||||||
|
scaleFontSize: 10,
|
||||||
|
responsive: false,
|
||||||
|
scaleLabel: "<%= '" + currencySymbol + " ' + Number(value).toFixed(0).replace('.', ',') %>",
|
||||||
|
tooltipFillColor: "rgba(0,0,0,0.5)",
|
||||||
|
tooltipTemplate: "<%if (label){%><%=label%>: <%}%>" + currencySymbol + " <%= value %>",
|
||||||
|
};
|
||||||
|
|
||||||
|
var defaultColumnOptions = {
|
||||||
|
scaleShowGridLines: false,
|
||||||
|
pointDotRadius: 2,
|
||||||
|
barStrokeWidth: 1,
|
||||||
|
pointHitDetectionRadius: 5,
|
||||||
|
datasetFill: false,
|
||||||
|
scaleFontSize: 10,
|
||||||
|
responsive: false,
|
||||||
|
scaleLabel: "<%= '" + currencySymbol + " ' + Number(value).toFixed(0).replace('.', ',') %>",
|
||||||
|
tooltipFillColor: "rgba(0,0,0,0.5)",
|
||||||
|
tooltipTemplate: "<%if (label){%><%=label%>: <%}%>" + currencySymbol + " <%= value %>",
|
||||||
|
multiTooltipTemplate: "<%=datasetLabel%>: " + currencySymbol + " <%= Number(value).toFixed(2).replace('.', ',') %>"
|
||||||
|
};
|
||||||
|
|
||||||
|
var defaultStackedColumnOptions = {
|
||||||
|
scaleShowGridLines: false,
|
||||||
|
pointDotRadius: 2,
|
||||||
|
barStrokeWidth: 1,
|
||||||
|
pointHitDetectionRadius: 5,
|
||||||
|
datasetFill: false,
|
||||||
|
scaleFontSize: 10,
|
||||||
|
responsive: false,
|
||||||
|
scaleLabel: "<%= '" + currencySymbol + " ' + Number(value).toFixed(0).replace('.', ',') %>",
|
||||||
|
tooltipFillColor: "rgba(0,0,0,0.5)",
|
||||||
|
multiTooltipTemplate: "<%=datasetLabel%>: " + currencySymbol + " <%= Number(value).toFixed(2).replace('.', ',') %>"
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to draw a line chart:
|
||||||
|
* @param URL
|
||||||
|
* @param container
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
function lineChart(URL, container, options) {
|
||||||
|
"use strict";
|
||||||
|
options = options || defaultLineOptions;
|
||||||
|
|
||||||
|
$.getJSON(URL).success(function (data) {
|
||||||
|
var ctx = document.getElementById(container).getContext("2d");
|
||||||
|
var newData = {};
|
||||||
|
newData.datasets = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < data.count; i++) {
|
||||||
|
newData.labels = data.labels;
|
||||||
|
var dataset = data.datasets[i];
|
||||||
|
dataset.fillColor = fillColors[i];
|
||||||
|
dataset.strokeColor = strokePointHighColors[i];
|
||||||
|
dataset.pointColor = strokePointHighColors[i];
|
||||||
|
dataset.pointStrokeColor = "#fff";
|
||||||
|
dataset.pointHighlightFill = "#fff";
|
||||||
|
dataset.pointHighlightStroke = strokePointHighColors[i];
|
||||||
|
newData.datasets.push(dataset);
|
||||||
|
}
|
||||||
|
new Chart(ctx).Line(newData, options);
|
||||||
|
|
||||||
|
}).fail(function () {
|
||||||
|
$('#' + container).addClass('google-chart-error');
|
||||||
|
});
|
||||||
|
console.log('URL for line chart : ' + URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to draw an area chart:
|
||||||
|
*
|
||||||
|
* @param URL
|
||||||
|
* @param container
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
function areaChart(URL, container, options) {
|
||||||
|
"use strict";
|
||||||
|
options = options || defaultAreaOptions;
|
||||||
|
|
||||||
|
$.getJSON(URL).success(function (data) {
|
||||||
|
var ctx = document.getElementById(container).getContext("2d");
|
||||||
|
var newData = {};
|
||||||
|
newData.datasets = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < data.count; i++) {
|
||||||
|
newData.labels = data.labels;
|
||||||
|
var dataset = data.datasets[i];
|
||||||
|
dataset.fillColor = fillColors[i];
|
||||||
|
dataset.strokeColor = strokePointHighColors[i];
|
||||||
|
dataset.pointColor = strokePointHighColors[i];
|
||||||
|
dataset.pointStrokeColor = "#fff";
|
||||||
|
dataset.pointHighlightFill = "#fff";
|
||||||
|
dataset.pointHighlightStroke = strokePointHighColors[i];
|
||||||
|
newData.datasets.push(dataset);
|
||||||
|
}
|
||||||
|
new Chart(ctx).Line(newData, options);
|
||||||
|
|
||||||
|
}).fail(function () {
|
||||||
|
$('#' + container).addClass('google-chart-error');
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('URL for area chart: ' + URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param URL
|
||||||
|
* @param container
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
function columnChart(URL, container, options) {
|
||||||
|
"use strict";
|
||||||
|
options = options || defaultColumnOptions;
|
||||||
|
|
||||||
|
$.getJSON(URL).success(function (data) {
|
||||||
|
|
||||||
|
var ctx = document.getElementById(container).getContext("2d");
|
||||||
|
var newData = {};
|
||||||
|
newData.datasets = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < data.count; i++) {
|
||||||
|
newData.labels = data.labels;
|
||||||
|
var dataset = data.datasets[i];
|
||||||
|
dataset.fillColor = fillColors[i];
|
||||||
|
dataset.strokeColor = strokePointHighColors[i];
|
||||||
|
dataset.pointColor = strokePointHighColors[i];
|
||||||
|
dataset.pointStrokeColor = "#fff";
|
||||||
|
dataset.pointHighlightFill = "#fff";
|
||||||
|
dataset.pointHighlightStroke = strokePointHighColors[i];
|
||||||
|
newData.datasets.push(dataset);
|
||||||
|
}
|
||||||
|
new Chart(ctx).Bar(newData, options);
|
||||||
|
|
||||||
|
}).fail(function () {
|
||||||
|
$('#' + container).addClass('google-chart-error');
|
||||||
|
});
|
||||||
|
console.log('URL for column chart : ' + URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param URL
|
||||||
|
* @param container
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
function stackedColumnChart(URL, container, options) {
|
||||||
|
"use strict";
|
||||||
|
options = options || defaultStackedColumnOptions;
|
||||||
|
|
||||||
|
$.getJSON(URL).success(function (data) {
|
||||||
|
|
||||||
|
var ctx = document.getElementById(container).getContext("2d");
|
||||||
|
var newData = {};
|
||||||
|
newData.datasets = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < data.count; i++) {
|
||||||
|
newData.labels = data.labels;
|
||||||
|
var dataset = data.datasets[i];
|
||||||
|
dataset.fillColor = fillColors[i];
|
||||||
|
dataset.strokeColor = strokePointHighColors[i];
|
||||||
|
dataset.pointColor = strokePointHighColors[i];
|
||||||
|
dataset.pointStrokeColor = "#fff";
|
||||||
|
dataset.pointHighlightFill = "#fff";
|
||||||
|
dataset.pointHighlightStroke = strokePointHighColors[i];
|
||||||
|
newData.datasets.push(dataset);
|
||||||
|
}
|
||||||
|
new Chart(ctx).StackedBar(newData, options);
|
||||||
|
|
||||||
|
}).fail(function () {
|
||||||
|
$('#' + container).addClass('google-chart-error');
|
||||||
|
});
|
||||||
|
console.log('URL for stacked column chart : ' + URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param URL
|
||||||
|
* @param container
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
function comboChart(URL, container, options) {
|
||||||
|
"use strict";
|
||||||
|
columnChart(URL, container, options);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param URL
|
||||||
|
* @param container
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
function pieChart(URL, container, options) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
options = options || defaultPieOptions;
|
||||||
|
$.getJSON(URL).success(function (data) {
|
||||||
|
|
||||||
|
var ctx = document.getElementById(container).getContext("2d");
|
||||||
|
new Chart(ctx).Pie(data, options);
|
||||||
|
|
||||||
|
}).fail(function () {
|
||||||
|
$('#' + container).addClass('google-chart-error');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
console.log('URL for pie chart : ' + URL);
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,221 @@
|
|||||||
/* globals currencyCode,defaultAreaChartOptions , language, defaultPieChartOptions, defaultLineChartOptions, defaultColumnChartOptions, defaultBarChartOptions, defaultStackedColumnChartOptions, defaultComboChartOptions */
|
/* globals currencyCode, language */
|
||||||
/* exported googleLineChart, googleBarChart, googleColumnChart, googleStackedColumnChart, googleComboChart, googlePieChart */
|
/* exported lineChart, googleColumnChart, stackedColumnChart, comboChart, pieChart, defaultLineChartOptions, defaultAreaChartOptions, defaultBarChartOptions, defaultComboChartOptions, defaultColumnChartOptions, defaultStackedColumnChartOptions, defaultPieChartOptions */
|
||||||
var google = google || {};
|
var google = google || {};
|
||||||
google.load('visualization', '1.1', {'packages': ['corechart', 'bar', 'line'],'language': language });
|
google.load('visualization', '1.1', {'packages': ['corechart', 'bar', 'line'], 'language': language});
|
||||||
|
|
||||||
|
|
||||||
|
/* exported */
|
||||||
|
|
||||||
|
var defaultLineChartOptions = {
|
||||||
|
curveType: 'function',
|
||||||
|
legend: {
|
||||||
|
position: 'none'
|
||||||
|
},
|
||||||
|
interpolateNulls: true,
|
||||||
|
lineWidth: 1,
|
||||||
|
chartArea: {
|
||||||
|
left: 50,
|
||||||
|
top: 10,
|
||||||
|
width: '95%',
|
||||||
|
height: '90%'
|
||||||
|
},
|
||||||
|
height: 400,
|
||||||
|
colors: ["#357ca5", "#008d4c", "#db8b0b", "#ca195a", "#555299", "#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
||||||
|
hAxis: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#838383',
|
||||||
|
},
|
||||||
|
baselineColor: '#aaaaaa',
|
||||||
|
gridlines: {
|
||||||
|
color: 'transparent'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fontSize: 11,
|
||||||
|
vAxis: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#838383',
|
||||||
|
},
|
||||||
|
baselineColor: '#aaaaaa',
|
||||||
|
format: '\u20AC #'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var defaultAreaChartOptions = {
|
||||||
|
curveType: 'function',
|
||||||
|
legend: {
|
||||||
|
position: 'none'
|
||||||
|
},
|
||||||
|
interpolateNulls: true,
|
||||||
|
lineWidth: 1,
|
||||||
|
chartArea: {
|
||||||
|
left: 50,
|
||||||
|
top: 10,
|
||||||
|
width: '95%',
|
||||||
|
height: '90%'
|
||||||
|
},
|
||||||
|
height: 400,
|
||||||
|
colors: ["#357ca5", "#008d4c", "#db8b0b", "#ca195a", "#555299", "#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
||||||
|
hAxis: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#838383',
|
||||||
|
},
|
||||||
|
baselineColor: '#aaaaaa',
|
||||||
|
gridlines: {
|
||||||
|
color: 'transparent'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fontSize: 11,
|
||||||
|
vAxis: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#838383',
|
||||||
|
},
|
||||||
|
baselineColor: '#aaaaaa',
|
||||||
|
format: '\u20AC #'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var defaultBarChartOptions = {
|
||||||
|
height: 400,
|
||||||
|
bars: 'horizontal',
|
||||||
|
hAxis: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#838383',
|
||||||
|
},
|
||||||
|
baselineColor: '#aaaaaa',
|
||||||
|
format: '\u20AC #'
|
||||||
|
|
||||||
|
},
|
||||||
|
fontSize: 11,
|
||||||
|
colors: ["#357ca5", "#008d4c", "#db8b0b", "#ca195a", "#555299", "#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
||||||
|
vAxis: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#838383'
|
||||||
|
},
|
||||||
|
textPosition: 'in',
|
||||||
|
gridlines: {
|
||||||
|
|
||||||
|
color: 'transparent'
|
||||||
|
},
|
||||||
|
baselineColor: '#aaaaaa'
|
||||||
|
},
|
||||||
|
chartArea: {
|
||||||
|
left: 15,
|
||||||
|
top: 10,
|
||||||
|
width: '100%',
|
||||||
|
height: '90%'
|
||||||
|
},
|
||||||
|
|
||||||
|
legend: {
|
||||||
|
position: 'none'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var defaultComboChartOptions = {
|
||||||
|
height: 300,
|
||||||
|
chartArea: {
|
||||||
|
left: 75,
|
||||||
|
top: 10,
|
||||||
|
width: '100%',
|
||||||
|
height: '90%'
|
||||||
|
},
|
||||||
|
vAxis: {
|
||||||
|
minValue: 0,
|
||||||
|
format: '\u20AC #'
|
||||||
|
},
|
||||||
|
colors: ["#357ca5", "#008d4c", "#db8b0b", "#ca195a", "#555299", "#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
||||||
|
fontSize: 11,
|
||||||
|
legend: {
|
||||||
|
position: 'none'
|
||||||
|
},
|
||||||
|
series: {
|
||||||
|
0: {type: 'line'},
|
||||||
|
1: {type: 'line'},
|
||||||
|
2: {type: 'bars'}
|
||||||
|
},
|
||||||
|
bar: {groupWidth: 20}
|
||||||
|
};
|
||||||
|
|
||||||
|
var defaultColumnChartOptions = {
|
||||||
|
height: 400,
|
||||||
|
chartArea: {
|
||||||
|
left: 50,
|
||||||
|
top: 10,
|
||||||
|
width: '85%',
|
||||||
|
height: '80%'
|
||||||
|
},
|
||||||
|
fontSize: 11,
|
||||||
|
hAxis: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#838383'
|
||||||
|
},
|
||||||
|
gridlines: {
|
||||||
|
color: 'transparent'
|
||||||
|
},
|
||||||
|
baselineColor: '#aaaaaa'
|
||||||
|
|
||||||
|
},
|
||||||
|
colors: ["#357ca5", "#008d4c", "#db8b0b", "#ca195a", "#555299", "#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
||||||
|
vAxis: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#838383'
|
||||||
|
},
|
||||||
|
baselineColor: '#aaaaaa',
|
||||||
|
format: '\u20AC #'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
position: 'none'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var defaultStackedColumnChartOptions = {
|
||||||
|
height: 400,
|
||||||
|
chartArea: {
|
||||||
|
left: 50,
|
||||||
|
top: 10,
|
||||||
|
width: '85%',
|
||||||
|
height: '80%'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
position: 'none'
|
||||||
|
},
|
||||||
|
fontSize: 11,
|
||||||
|
isStacked: true,
|
||||||
|
colors: ["#357ca5", "#008d4c", "#db8b0b", "#ca195a", "#555299", "#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
||||||
|
hAxis: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#838383',
|
||||||
|
},
|
||||||
|
gridlines: {
|
||||||
|
color: 'transparent'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
vAxis: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#838383',
|
||||||
|
},
|
||||||
|
format: '\u20AC #'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var defaultPieChartOptions = {
|
||||||
|
chartArea: {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
width: '100%',
|
||||||
|
height: '100%'
|
||||||
|
},
|
||||||
|
fontSize: 11,
|
||||||
|
height: 200,
|
||||||
|
legend: {
|
||||||
|
position: 'none'
|
||||||
|
},
|
||||||
|
colors: ["#357ca5", "#008d4c", "#db8b0b", "#ca195a", "#555299", "#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
function googleChart(chartType, URL, container, options) {
|
function googleChart(chartType, URL, container, options) {
|
||||||
"use strict";
|
"use strict";
|
||||||
@ -33,7 +247,7 @@ function googleChart(chartType, URL, container, options) {
|
|||||||
chart = new google.visualization.LineChart(document.getElementById(container));
|
chart = new google.visualization.LineChart(document.getElementById(container));
|
||||||
options = options || defaultLineChartOptions;
|
options = options || defaultLineChartOptions;
|
||||||
}
|
}
|
||||||
if(chartType === 'area') {
|
if (chartType === 'area') {
|
||||||
chart = new google.visualization.AreaChart(document.getElementById(container));
|
chart = new google.visualization.AreaChart(document.getElementById(container));
|
||||||
options = options || defaultAreaChartOptions;
|
options = options || defaultAreaChartOptions;
|
||||||
}
|
}
|
||||||
@ -74,38 +288,32 @@ function googleChart(chartType, URL, container, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function googleLineChart(URL, container, options) {
|
function lineChart(URL, container, options) {
|
||||||
"use strict";
|
"use strict";
|
||||||
return googleChart('line', URL, container, options);
|
return googleChart('line', URL, container, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
function googleAreaChart(URL, container, options) {
|
function areaChart(URL, container, options) {
|
||||||
"use strict";
|
"use strict";
|
||||||
return googleChart('area', URL, container, options);
|
return googleChart('area', URL, container, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function columnChart(URL, container, options) {
|
||||||
function googleBarChart(URL, container, options) {
|
|
||||||
"use strict";
|
|
||||||
return googleChart('bar', URL, container, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
function googleColumnChart(URL, container, options) {
|
|
||||||
"use strict";
|
"use strict";
|
||||||
return googleChart('column', URL, container, options);
|
return googleChart('column', URL, container, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
function googleStackedColumnChart(URL, container, options) {
|
function stackedColumnChart(URL, container, options) {
|
||||||
"use strict";
|
"use strict";
|
||||||
return googleChart('stackedColumn', URL, container, options);
|
return googleChart('stackedColumn', URL, container, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
function googleComboChart(URL, container, options) {
|
function comboChart(URL, container, options) {
|
||||||
"use strict";
|
"use strict";
|
||||||
return googleChart('combo', URL, container, options);
|
return googleChart('combo', URL, container, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
function googlePieChart(URL, container, options) {
|
function pieChart(URL, container, options) {
|
||||||
"use strict";
|
"use strict";
|
||||||
return googleChart('pie', URL, container, options);
|
return googleChart('pie', URL, container, options);
|
||||||
}
|
}
|
||||||
|
@ -1,218 +0,0 @@
|
|||||||
/* exported defaultLineChartOptions, defaultAreaChartOptions, defaultBarChartOptions, defaultComboChartOptions, defaultColumnChartOptions, defaultStackedColumnChartOptions, defaultPieChartOptions */
|
|
||||||
|
|
||||||
var defaultLineChartOptions = {
|
|
||||||
curveType: 'function',
|
|
||||||
legend: {
|
|
||||||
position: 'none'
|
|
||||||
},
|
|
||||||
interpolateNulls: true,
|
|
||||||
lineWidth: 1,
|
|
||||||
chartArea: {
|
|
||||||
left: 50,
|
|
||||||
top: 10,
|
|
||||||
width: '95%',
|
|
||||||
height: '90%'
|
|
||||||
},
|
|
||||||
height: 400,
|
|
||||||
colors: ["#357ca5", "#008d4c", "#db8b0b", "#ca195a", "#555299", "#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
|
||||||
hAxis: {
|
|
||||||
textStyle: {
|
|
||||||
color: '#838383',
|
|
||||||
},
|
|
||||||
baselineColor: '#aaaaaa',
|
|
||||||
gridlines: {
|
|
||||||
color: 'transparent'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fontName: 'Roboto',
|
|
||||||
fontSize: 11,
|
|
||||||
vAxis: {
|
|
||||||
textStyle: {
|
|
||||||
color: '#838383',
|
|
||||||
},
|
|
||||||
baselineColor: '#aaaaaa',
|
|
||||||
format: '\u20AC #'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
var defaultAreaChartOptions = {
|
|
||||||
curveType: 'function',
|
|
||||||
legend: {
|
|
||||||
position: 'none'
|
|
||||||
},
|
|
||||||
interpolateNulls: true,
|
|
||||||
lineWidth: 1,
|
|
||||||
chartArea: {
|
|
||||||
left: 50,
|
|
||||||
top: 10,
|
|
||||||
width: '95%',
|
|
||||||
height: '90%'
|
|
||||||
},
|
|
||||||
height: 400,
|
|
||||||
colors: ["#357ca5", "#008d4c", "#db8b0b", "#ca195a", "#555299", "#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
|
||||||
hAxis: {
|
|
||||||
textStyle: {
|
|
||||||
color: '#838383',
|
|
||||||
},
|
|
||||||
baselineColor: '#aaaaaa',
|
|
||||||
gridlines: {
|
|
||||||
color: 'transparent'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fontName: 'Roboto',
|
|
||||||
fontSize: 11,
|
|
||||||
vAxis: {
|
|
||||||
textStyle: {
|
|
||||||
color: '#838383',
|
|
||||||
},
|
|
||||||
baselineColor: '#aaaaaa',
|
|
||||||
format: '\u20AC #'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
var defaultBarChartOptions = {
|
|
||||||
height: 400,
|
|
||||||
bars: 'horizontal',
|
|
||||||
hAxis: {
|
|
||||||
textStyle: {
|
|
||||||
color: '#838383',
|
|
||||||
},
|
|
||||||
baselineColor: '#aaaaaa',
|
|
||||||
format: '\u20AC #'
|
|
||||||
|
|
||||||
},
|
|
||||||
fontName: 'Roboto',
|
|
||||||
fontSize: 11,
|
|
||||||
colors: ["#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
|
||||||
vAxis: {
|
|
||||||
textStyle: {
|
|
||||||
color: '#838383'
|
|
||||||
},
|
|
||||||
textPosition: 'in',
|
|
||||||
gridlines: {
|
|
||||||
|
|
||||||
color: 'transparent'
|
|
||||||
},
|
|
||||||
baselineColor: '#aaaaaa'
|
|
||||||
},
|
|
||||||
chartArea: {
|
|
||||||
left: 15,
|
|
||||||
top: 10,
|
|
||||||
width: '100%',
|
|
||||||
height: '90%'
|
|
||||||
},
|
|
||||||
|
|
||||||
legend: {
|
|
||||||
position: 'none'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var defaultComboChartOptions = {
|
|
||||||
height: 300,
|
|
||||||
chartArea: {
|
|
||||||
left: 75,
|
|
||||||
top: 10,
|
|
||||||
width: '100%',
|
|
||||||
height: '90%'
|
|
||||||
},
|
|
||||||
vAxis: {
|
|
||||||
minValue: 0,
|
|
||||||
format: '\u20AC #'
|
|
||||||
},
|
|
||||||
fontName: 'Roboto',
|
|
||||||
fontSize: 11,
|
|
||||||
legend: {
|
|
||||||
position: 'none'
|
|
||||||
},
|
|
||||||
series: {
|
|
||||||
0: {type: 'line'},
|
|
||||||
1: {type: 'line'},
|
|
||||||
2: {type: 'bars'}
|
|
||||||
},
|
|
||||||
bar: {groupWidth: 20}
|
|
||||||
};
|
|
||||||
|
|
||||||
var defaultColumnChartOptions = {
|
|
||||||
height: 400,
|
|
||||||
chartArea: {
|
|
||||||
left: 50,
|
|
||||||
top: 10,
|
|
||||||
width: '85%',
|
|
||||||
height: '80%'
|
|
||||||
},
|
|
||||||
fontName: 'Roboto',
|
|
||||||
fontSize: 11,
|
|
||||||
hAxis: {
|
|
||||||
textStyle: {
|
|
||||||
color: '#838383'
|
|
||||||
},
|
|
||||||
gridlines: {
|
|
||||||
color: 'transparent'
|
|
||||||
},
|
|
||||||
baselineColor: '#aaaaaa'
|
|
||||||
|
|
||||||
},
|
|
||||||
colors: ["#357ca5", "#008d4c", "#db8b0b", "#ca195a", "#555299", "#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
|
||||||
vAxis: {
|
|
||||||
textStyle: {
|
|
||||||
color: '#838383'
|
|
||||||
},
|
|
||||||
baselineColor: '#aaaaaa',
|
|
||||||
format: '\u20AC #'
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
position: 'none'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var defaultStackedColumnChartOptions = {
|
|
||||||
height: 400,
|
|
||||||
chartArea: {
|
|
||||||
left: 50,
|
|
||||||
top: 10,
|
|
||||||
width: '85%',
|
|
||||||
height: '80%'
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
position: 'none'
|
|
||||||
},
|
|
||||||
fontName: 'Roboto',
|
|
||||||
fontSize: 11,
|
|
||||||
isStacked: true,
|
|
||||||
colors: ["#357ca5", "#008d4c", "#db8b0b", "#ca195a", "#555299", "#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
|
||||||
hAxis: {
|
|
||||||
textStyle: {
|
|
||||||
color: '#838383',
|
|
||||||
},
|
|
||||||
gridlines: {
|
|
||||||
color: 'transparent'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
vAxis: {
|
|
||||||
textStyle: {
|
|
||||||
color: '#838383',
|
|
||||||
},
|
|
||||||
format: '\u20AC #'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var defaultPieChartOptions = {
|
|
||||||
chartArea: {
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
width: '100%',
|
|
||||||
height: '100%'
|
|
||||||
},
|
|
||||||
fontName: 'Roboto',
|
|
||||||
fontSize: 11,
|
|
||||||
height: 200,
|
|
||||||
legend: {
|
|
||||||
position: 'none'
|
|
||||||
},
|
|
||||||
colors: ["#357ca5", "#008d4c", "#db8b0b", "#ca195a", "#555299", "#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
|
||||||
};
|
|
||||||
|
|
@ -1,13 +1,22 @@
|
|||||||
/* globals $, googleColumnChart, google, googleLineChart, googlePieChart, googleStackedColumnChart */
|
/* globals $, columnChart, google, lineChart, pieChart, stackedColumnChart, areaChart */
|
||||||
google.setOnLoadCallback(drawChart);
|
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
"use strict";
|
||||||
|
if (typeof google !== 'undefined') {
|
||||||
|
// do google charts:
|
||||||
|
google.setOnLoadCallback(drawChart);
|
||||||
|
} else {
|
||||||
|
// do chart JS stuff.
|
||||||
|
drawChart();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function drawChart() {
|
function drawChart() {
|
||||||
"use strict";
|
"use strict";
|
||||||
googleAreaChart('chart/account/frontpage', 'accounts-chart');
|
areaChart('chart/account/frontpage', 'accounts-chart');
|
||||||
googlePieChart('chart/bill/frontpage', 'bills-chart');
|
pieChart('chart/bill/frontpage', 'bills-chart');
|
||||||
googleStackedColumnChart('chart/budget/frontpage', 'budgets-chart');
|
stackedColumnChart('chart/budget/frontpage', 'budgets-chart');
|
||||||
googleColumnChart('chart/category/frontpage', 'categories-chart');
|
columnChart('chart/category/frontpage', 'categories-chart');
|
||||||
|
|
||||||
|
|
||||||
getBoxAmounts();
|
getBoxAmounts();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* globals $, googleLineChart, token, piggyBankID */
|
/* globals $, lineChart, token, piggyBankID */
|
||||||
|
|
||||||
// Return a helper with preserved width of cells
|
// Return a helper with preserved width of cells
|
||||||
var fixHelper = function (e, tr) {
|
var fixHelper = function (e, tr) {
|
||||||
@ -17,8 +17,8 @@ $(function () {
|
|||||||
$('.addMoney').on('click', addMoney);
|
$('.addMoney').on('click', addMoney);
|
||||||
$('.removeMoney').on('click', removeMoney);
|
$('.removeMoney').on('click', removeMoney);
|
||||||
|
|
||||||
if (typeof(googleLineChart) === 'function' && typeof(piggyBankID) !== 'undefined') {
|
if (typeof(lineChart) === 'function' && typeof(piggyBankID) !== 'undefined') {
|
||||||
googleLineChart('chart/piggyBank/' + piggyBankID, 'piggy-bank-history');
|
lineChart('chart/piggyBank/' + piggyBankID, 'piggy-bank-history');
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#sortable tbody').sortable(
|
$('#sortable tbody').sortable(
|
||||||
|
@ -1,22 +1,31 @@
|
|||||||
/* globals google, expenseRestShow:true, incomeRestShow:true, year, shared, month, hideTheRest, showTheRest, showTheRestExpense, hideTheRestExpense, googleColumnChart, googleLineChart, googleStackedColumnChart */
|
/* globals google, expenseRestShow:true, incomeRestShow:true, year, shared, month, hideTheRest, showTheRest, showTheRestExpense, hideTheRestExpense, columnChart, lineChart, stackedColumnChart */
|
||||||
if (typeof(google) !== 'undefined') {
|
|
||||||
google.setOnLoadCallback(drawChart);
|
$(function () {
|
||||||
}
|
"use strict";
|
||||||
|
if (typeof(google) !== 'undefined') {
|
||||||
|
google.setOnLoadCallback(drawChart);
|
||||||
|
} else {
|
||||||
|
drawChart();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
function drawChart() {
|
function drawChart() {
|
||||||
"use strict";
|
"use strict";
|
||||||
googleColumnChart('chart/report/in-out/' + year + shared, 'income-expenses-chart');
|
if (typeof columnChart !== undefined) {
|
||||||
googleColumnChart('chart/report/in-out-sum/' + year + shared, 'income-expenses-sum-chart');
|
columnChart('chart/report/in-out/' + year + shared, 'income-expenses-chart');
|
||||||
|
columnChart('chart/report/in-out-sum/' + year + shared, 'income-expenses-sum-chart');
|
||||||
googleStackedColumnChart('chart/budget/year/' + year + shared, 'budgets');
|
}
|
||||||
googleStackedColumnChart('chart/category/year/' + year + shared, 'categories');
|
if (typeof stackedColumnChart !== undefined) {
|
||||||
|
stackedColumnChart('chart/budget/year/' + year + shared, 'budgets');
|
||||||
googleLineChart('/chart/account/month/' + year + '/' + month + shared, 'account-balances-chart');
|
stackedColumnChart('chart/category/year/' + year + shared, 'categories');
|
||||||
|
}
|
||||||
|
if (typeof lineChart !== undefined && typeof month !== 'undefined') {
|
||||||
|
lineChart('/chart/account/month/' + year + '/' + month + shared, 'account-balances-chart');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function openModal(e) {
|
function openModal(e) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var target = $(e.target).parent();
|
var target = $(e.target).parent();
|
||||||
|
@ -33,10 +33,6 @@ return [
|
|||||||
'edit_bill' => 'Edit bill ":name"',
|
'edit_bill' => 'Edit bill ":name"',
|
||||||
'delete_bill' => 'Delete bill ":name"',
|
'delete_bill' => 'Delete bill ":name"',
|
||||||
|
|
||||||
// reminders
|
|
||||||
'reminders' => 'Reminders',
|
|
||||||
'reminder' => 'Reminder #:id',
|
|
||||||
|
|
||||||
// reports
|
// reports
|
||||||
'reports' => 'Reports',
|
'reports' => 'Reports',
|
||||||
'monthly_report' => 'Montly report for :date',
|
'monthly_report' => 'Montly report for :date',
|
||||||
|
@ -147,8 +147,6 @@ return [
|
|||||||
|
|
||||||
// menu and titles, should be recycled as often as possible:
|
// menu and titles, should be recycled as often as possible:
|
||||||
'toggleNavigation' => 'Toggle navigation',
|
'toggleNavigation' => 'Toggle navigation',
|
||||||
'seeAllReminders' => 'See all reminders',
|
|
||||||
'reminders' => 'Reminders',
|
|
||||||
'currency' => 'Currency',
|
'currency' => 'Currency',
|
||||||
'preferences' => 'Preferences',
|
'preferences' => 'Preferences',
|
||||||
'logout' => 'Logout',
|
'logout' => 'Logout',
|
||||||
@ -272,10 +270,6 @@ return [
|
|||||||
'start_date' => 'Start date',
|
'start_date' => 'Start date',
|
||||||
'target_date' => 'Target date',
|
'target_date' => 'Target date',
|
||||||
'no_target_date' => 'No target date',
|
'no_target_date' => 'No target date',
|
||||||
'reminder' => 'Reminder',
|
|
||||||
'no_reminder' => 'No reminder',
|
|
||||||
'reminders_left' => 'Reminders left',
|
|
||||||
'expected_amount_per_reminder' => 'Expected amount per reminder',
|
|
||||||
'todo' => 'to do',
|
'todo' => 'to do',
|
||||||
'table' => 'Table',
|
'table' => 'Table',
|
||||||
'piggy_bank_not_exists' => 'Piggy bank no longer exists.',
|
'piggy_bank_not_exists' => 'Piggy bank no longer exists.',
|
||||||
@ -293,9 +287,5 @@ return [
|
|||||||
'tag_title_balancingAct' => 'Balancing act tags',
|
'tag_title_balancingAct' => 'Balancing act tags',
|
||||||
'tag_title_advancePayment' => 'Advance payment tags',
|
'tag_title_advancePayment' => 'Advance payment tags',
|
||||||
|
|
||||||
// reminders
|
|
||||||
'reminder_for_piggy' => 'Reminder for piggy bank ":name"',
|
|
||||||
'dismissed_reminder_for_piggy' => 'Dismissed reminder for piggy bank ":name"',
|
|
||||||
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user