mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-08-22 05:09:43 +00:00
Compare commits
39 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d485270e1f | ||
|
3716668e0c | ||
|
ae7fd18c34 | ||
|
4f59b1d32f | ||
|
90cb3279df | ||
|
cf0c7ef6b2 | ||
|
47c23781d9 | ||
|
e258c050f7 | ||
|
57801b2f34 | ||
|
710e9c9423 | ||
|
deefef83bd | ||
|
51e30aed66 | ||
|
8d109a3cfe | ||
|
3424e019b5 | ||
|
c6b4bceb67 | ||
|
afb4155015 | ||
|
8d99baf38a | ||
|
b91cb60328 | ||
|
c0d62237fc | ||
|
223ea80860 | ||
|
5a77bef494 | ||
|
80c0efe821 | ||
|
8044d89557 | ||
|
4f0ed97410 | ||
|
af7952f204 | ||
|
d8dcae856b | ||
|
7296796ed9 | ||
|
a2c2bb4948 | ||
|
72ebfdc20e | ||
|
16b95ea78a | ||
|
c04f08dfd8 | ||
|
a30793e818 | ||
|
e39e1eaf21 | ||
|
ab22d2cbaa | ||
|
96ddbe7227 | ||
|
4d09235aef | ||
|
136b8975e3 | ||
|
e21b1eca17 | ||
|
244b90b1d4 |
@@ -1,6 +1,6 @@
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_KEY=SomeRandomString
|
||||
APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=localhost
|
||||
|
@@ -82,7 +82,7 @@ If you're still interested please read [the installation guide](https://github.c
|
||||
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/).
|
||||
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. Accounts on the demo sites will stop working after one week.
|
||||
|
||||
## Credits
|
||||
|
||||
|
@@ -40,4 +40,13 @@ interface AccountChartGenerator
|
||||
* @return array
|
||||
*/
|
||||
public function single(Account $account, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end);
|
||||
}
|
||||
|
@@ -32,6 +32,65 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
return $this->frontpage($accounts, $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
// language:
|
||||
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => []
|
||||
]
|
||||
],
|
||||
];
|
||||
$ids = [];
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$ids[] = $account->id;
|
||||
}
|
||||
$start->subDay();
|
||||
|
||||
$startBalances = Steam::balancesById($ids, $start);
|
||||
$endBalances = Steam::balancesById($ids, $end);
|
||||
|
||||
$accounts->each(
|
||||
function (Account $account) use ($startBalances, $endBalances) {
|
||||
$id = $account->id;
|
||||
$startBalance = isset($startBalances[$id]) ? $startBalances[$id] : 0;
|
||||
$endBalance = isset($endBalances[$id]) ? $endBalances[$id] : 0;
|
||||
$diff = $endBalance - $startBalance;
|
||||
$account->difference = round($diff, 2);
|
||||
}
|
||||
);
|
||||
|
||||
$accounts = $accounts->sortByDesc(
|
||||
function (Account $account) {
|
||||
return $account->difference;
|
||||
}
|
||||
);
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
if ($account->difference > 0) {
|
||||
$data['labels'][] = $account->name;
|
||||
$data['datasets'][0]['data'][] = $account->difference;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
|
@@ -1,97 +0,0 @@
|
||||
<?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)
|
||||
{
|
||||
return $this->all($accounts, $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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();
|
||||
}
|
||||
}
|
@@ -1,94 +0,0 @@
|
||||
<?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;
|
||||
|
||||
bcscale(2);
|
||||
|
||||
|
||||
/** @var TransactionJournal $entry */
|
||||
foreach ($paid as $entry) {
|
||||
|
||||
$paidDescriptions[] = $entry->description;
|
||||
$paidAmount = bcadd($paidAmount, $entry->amount);
|
||||
}
|
||||
|
||||
// loop unpaid:
|
||||
/** @var Bill $entry */
|
||||
foreach ($unpaid as $entry) {
|
||||
$description = $entry[0]->name . ' (' . $entry[1]->format('jS M Y') . ')';
|
||||
$amount = bcdiv(bcadd($entry[0]->amount_max, $entry[0]->amount_min), 2);
|
||||
$unpaidDescriptions[] = $description;
|
||||
$unpaidAmount = bcadd($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,
|
||||
round($bill->amount_max, 2),
|
||||
round($bill->amount_min, 2),
|
||||
round($result->amount, 2)
|
||||
);
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
}
|
||||
}
|
@@ -1,102 +0,0 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
@@ -40,5 +40,13 @@ interface CategoryChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $categories, Collection $entries);
|
||||
public function spentInYear(Collection $categories, Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInYear(Collection $categories, Collection $entries);
|
||||
}
|
||||
|
@@ -29,19 +29,30 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
$format = Config::get('firefly.' . $dateFormat . '.' . $language);
|
||||
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'count' => 2,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => []
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.earned'),
|
||||
'data' => []
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$data['labels'][] = $entry[0]->formatLocalized($format);
|
||||
$data['datasets'][0]['data'][] = round($entry[1], 2);
|
||||
$data['labels'][] = $entry[0]->formatLocalized($format);
|
||||
$amount = round($entry[1], 2);
|
||||
if ($amount > 0) {
|
||||
$data['datasets'][0]['data'][] = null;
|
||||
$data['datasets'][1]['data'][] = $amount;
|
||||
} else {
|
||||
$data['datasets'][0]['data'][] = $amount * -1;
|
||||
$data['datasets'][1]['data'][] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
@@ -93,7 +104,41 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $categories, Collection $entries)
|
||||
public function spentInYear(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;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInYear(Collection $categories, Collection $entries)
|
||||
{
|
||||
|
||||
// language:
|
||||
|
@@ -1,106 +0,0 @@
|
||||
<?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();
|
||||
|
||||
}
|
||||
}
|
@@ -9,7 +9,7 @@ use Preferences;
|
||||
|
||||
|
||||
/**
|
||||
* Class GooglePiggyBankChartGenerator
|
||||
* Class ChartJsPiggyBankChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\PiggyBank
|
||||
*/
|
||||
|
@@ -1,41 +0,0 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
@@ -7,7 +7,7 @@ use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Class GoogleReportChartGenerator
|
||||
* Class ChartJsReportChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Report
|
||||
*/
|
||||
|
@@ -1,58 +0,0 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
@@ -34,7 +34,8 @@ class Category
|
||||
*/
|
||||
public function addCategory(CategoryModel $category)
|
||||
{
|
||||
if ($category->spent > 0) {
|
||||
// spent is minus zero for an expense report:
|
||||
if ($category->spent < 0) {
|
||||
$this->categories->push($category);
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,9 @@
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use InvalidArgumentException;
|
||||
use Log;
|
||||
use Session;
|
||||
|
||||
/**
|
||||
@@ -19,8 +22,16 @@ class Date extends BasicConverter implements ConverterInterface
|
||||
public function convert()
|
||||
{
|
||||
$format = Session::get('csv-date-format');
|
||||
try {
|
||||
$date = Carbon::createFromFormat($format, $this->value);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Log::error('Date conversion error: ' . $e->getMessage() . '. Value was "' . $this->value . '", format was "' . $format . '".');
|
||||
|
||||
$message = trans('firefly.csv_date_parse_error', ['format' => $format, 'value' => $this->value]);
|
||||
|
||||
throw new FireflyException($message);
|
||||
}
|
||||
|
||||
$date = Carbon::createFromFormat($format, $this->value);
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
@@ -124,7 +124,7 @@ class Importer
|
||||
*/
|
||||
protected function parseRow($index)
|
||||
{
|
||||
return (($this->data->hasHeaders() && $index > 1) || !$this->data->hasHeaders());
|
||||
return (($this->data->hasHeaders() && $index >= 1) || !$this->data->hasHeaders());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -263,7 +263,7 @@ class ReportHelper implements ReportHelperInterface
|
||||
|
||||
// no repetition(s) for this budget:
|
||||
if ($repetitions->count() == 0) {
|
||||
$spent = $repository->spentInPeriodCorrected($budget, $start, $end, $shared);
|
||||
$spent = $repository->balanceInPeriod($budget, $start, $end, $shared);
|
||||
$budgetLine = new BudgetLine;
|
||||
$budgetLine->setBudget($budget);
|
||||
$budgetLine->setOverspent($spent);
|
||||
@@ -278,7 +278,7 @@ class ReportHelper implements ReportHelperInterface
|
||||
$budgetLine = new BudgetLine;
|
||||
$budgetLine->setBudget($budget);
|
||||
$budgetLine->setRepetition($repetition);
|
||||
$expenses = $repository->spentInPeriodCorrected($budget, $repetition->startdate, $repetition->enddate, $shared);
|
||||
$expenses = $repository->balanceInPeriod($budget, $repetition->startdate, $repetition->enddate, $shared);
|
||||
$left = $expenses < $repetition->amount ? bcsub($repetition->amount, $expenses) : 0;
|
||||
$spent = $expenses > $repetition->amount ? 0 : $expenses;
|
||||
$overspent = $expenses > $repetition->amount ? bcsub($expenses, $repetition->amount) : 0;
|
||||
@@ -327,7 +327,7 @@ class ReportHelper implements ReportHelperInterface
|
||||
$repository = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
|
||||
$set = $repository->getCategories();
|
||||
foreach ($set as $category) {
|
||||
$spent = $repository->spentInPeriodCorrected($category, $start, $end, $shared);
|
||||
$spent = $repository->balanceInPeriod($category, $start, $end, $shared);
|
||||
$category->spent = $spent;
|
||||
$object->addCategory($category);
|
||||
$object->addTotal($spent);
|
||||
|
@@ -152,7 +152,7 @@ class BudgetController extends Controller
|
||||
foreach ($budgets as $budget) {
|
||||
$date = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$budget->spent = $repository->spentInPeriodCorrected($budget, $date, $end);
|
||||
$budget->spent = $repository->balanceInPeriod($budget, $date, $end);
|
||||
$budget->currentRep = $repository->getCurrentRepetition($budget, $date);
|
||||
if ($budget->currentRep) {
|
||||
$budgeted = bcadd($budgeted, $budget->currentRep->amount);
|
||||
|
@@ -151,10 +151,12 @@ class CategoryController extends Controller
|
||||
$page = intval(Input::get('page'));
|
||||
$set = $repository->getJournals($category, $page);
|
||||
$count = $repository->countJournals($category);
|
||||
$totalSum = $repository->journalsSum($category);
|
||||
$periodSum = $repository->journalsSum($category, Session::get('start'), Session::get('end'));
|
||||
$journals = new LengthAwarePaginator($set, $count, 50, $page);
|
||||
$journals->setPath('categories/show/' . $category->id);
|
||||
|
||||
return view('categories.show', compact('category', 'journals', 'hideCategory'));
|
||||
return view('categories.show', compact('category', 'journals', 'hideCategory', 'totalSum', 'periodSum'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -79,6 +79,36 @@ class AccountController extends Controller
|
||||
return Response::json($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the balances for all the user's expense accounts.
|
||||
*
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function expenseAccounts(AccountRepositoryInterface $repository)
|
||||
{
|
||||
$start = clone Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = clone Session::get('end', Carbon::now()->endOfMonth());
|
||||
$accounts = $repository->getAccounts(['Expense account', 'Beneficiary account']);
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('expenseAccounts');
|
||||
$cache->addProperty('accounts');
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$data = $this->generator->expenseAccounts($accounts, $start, $end);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the balances for all the user's frontpage accounts.
|
||||
*
|
||||
|
@@ -68,7 +68,7 @@ class BudgetController extends Controller
|
||||
$end->subDay();
|
||||
$chartDate = clone $end;
|
||||
$chartDate->startOfMonth();
|
||||
$spent = $repository->spentInPeriodCorrected($budget, $first, $end);
|
||||
$spent = $repository->balanceInPeriod($budget, $first, $end);
|
||||
$entries->push([$chartDate, $spent]);
|
||||
$first = Navigation::addPeriod($first, $range, 0);
|
||||
}
|
||||
@@ -156,13 +156,13 @@ class BudgetController extends Controller
|
||||
foreach ($budgets as $budget) {
|
||||
$repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end);
|
||||
if ($repetitions->count() == 0) {
|
||||
$expenses = $repository->spentInPeriodCorrected($budget, $start, $end, true);
|
||||
$expenses = $repository->balanceInPeriod($budget, $start, $end, true);
|
||||
$allEntries->push([$budget->name, 0, 0, $expenses, 0, 0]);
|
||||
continue;
|
||||
}
|
||||
/** @var LimitRepetition $repetition */
|
||||
foreach ($repetitions as $repetition) {
|
||||
$expenses = $repository->spentInPeriodCorrected($budget, $repetition->startdate, $repetition->enddate, true);
|
||||
$expenses = $repository->balanceInPeriod($budget, $repetition->startdate, $repetition->enddate, true);
|
||||
// $left can be less than zero.
|
||||
// $overspent can be more than zero ( = overspending)
|
||||
|
||||
@@ -199,10 +199,11 @@ class BudgetController extends Controller
|
||||
*/
|
||||
public function year(BudgetRepositoryInterface $repository, $year, $shared = false)
|
||||
{
|
||||
$start = new Carbon($year . '-01-01');
|
||||
$end = new Carbon($year . '-12-31');
|
||||
$shared = $shared == 'shared' ? true : false;
|
||||
$budgets = $repository->getBudgets();
|
||||
$start = new Carbon($year . '-01-01');
|
||||
$end = new Carbon($year . '-12-31');
|
||||
$shared = $shared == 'shared' ? true : false;
|
||||
$allBudgets = $repository->getBudgets();
|
||||
$budgets = new Collection;
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties();
|
||||
@@ -214,6 +215,15 @@ class BudgetController extends Controller
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// filter empty budgets:
|
||||
|
||||
foreach ($allBudgets as $budget) {
|
||||
$spent = $repository->balanceInPeriod($budget, $start, $end, $shared);
|
||||
if ($spent != 0) {
|
||||
$budgets->push($budget);
|
||||
}
|
||||
}
|
||||
|
||||
$entries = new Collection;
|
||||
|
||||
while ($start < $end) {
|
||||
@@ -224,14 +234,14 @@ class BudgetController extends Controller
|
||||
|
||||
// each budget, fill the row:
|
||||
foreach ($budgets as $budget) {
|
||||
$spent = $repository->spentInPeriodCorrected($budget, $start, $month, $shared);
|
||||
$row[] = $spent;
|
||||
$spent = $repository->balanceInPeriod($budget, $start, $month, $shared);
|
||||
$row[] = $spent * -1;
|
||||
}
|
||||
$entries->push($row);
|
||||
$start->endOfMonth()->addDay();
|
||||
}
|
||||
|
||||
$data = $this->generator->year($budgets, $entries);
|
||||
$data = $this->generator->year($allBudgets, $entries);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
|
@@ -46,11 +46,10 @@ class CategoryController extends Controller
|
||||
public function all(CategoryRepositoryInterface $repository, Category $category)
|
||||
{
|
||||
// oldest transaction in category:
|
||||
$start = $repository->getFirstActivityDate($category);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod($start, $range);
|
||||
$end = new Carbon;
|
||||
|
||||
$start = $repository->getFirstActivityDate($category);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod($start, $range);
|
||||
$end = new Carbon;
|
||||
$entries = new Collection;
|
||||
|
||||
|
||||
@@ -66,7 +65,7 @@ class CategoryController extends Controller
|
||||
|
||||
while ($start <= $end) {
|
||||
$currentEnd = Navigation::endOfPeriod($start, $range);
|
||||
$spent = $repository->spentInPeriodCorrected($category, $start, $currentEnd);
|
||||
$spent = $repository->balanceInPeriod($category, $start, $currentEnd);
|
||||
$entries->push([clone $start, $spent]);
|
||||
$start = Navigation::addPeriod($start, $range, 0);
|
||||
|
||||
@@ -170,7 +169,7 @@ class CategoryController extends Controller
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function year(CategoryRepositoryInterface $repository, $year, $shared = false)
|
||||
public function spentInYear(CategoryRepositoryInterface $repository, $year, $shared = false)
|
||||
{
|
||||
$start = new Carbon($year . '-01-01');
|
||||
$end = new Carbon($year . '-12-31');
|
||||
@@ -179,14 +178,24 @@ class CategoryController extends Controller
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('category');
|
||||
$cache->addProperty('year');
|
||||
$cache->addProperty('spent-in-year');
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$shared = $shared == 'shared' ? true : false;
|
||||
$categories = $repository->getCategories();
|
||||
$entries = new Collection;
|
||||
$shared = $shared == 'shared' ? true : false;
|
||||
$allCategories = $repository->getCategories();
|
||||
$entries = new Collection;
|
||||
$categories = $allCategories->filter(
|
||||
function (Category $category) use ($repository, $start, $end, $shared) {
|
||||
$spent = $repository->balanceInPeriod($category, $start, $end, $shared);
|
||||
if ($spent < 0) {
|
||||
return $category;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
while ($start < $end) {
|
||||
$month = clone $start; // month is the current end of the period
|
||||
@@ -194,15 +203,76 @@ class CategoryController extends Controller
|
||||
$row = [clone $start]; // make a row:
|
||||
|
||||
foreach ($categories as $category) { // each budget, fill the row
|
||||
$spent = $repository->spentInPeriodCorrected($category, $start, $month, $shared);
|
||||
$row[] = $spent;
|
||||
$spent = $repository->balanceInPeriod($category, $start, $month, $shared);
|
||||
if ($spent < 0) {
|
||||
$row[] = $spent * -1;
|
||||
} else {
|
||||
$row[] = 0;
|
||||
}
|
||||
}
|
||||
$entries->push($row);
|
||||
|
||||
$start->addMonth();
|
||||
}
|
||||
$data = $this->generator->spentInYear($categories, $entries);
|
||||
$cache->store($data);
|
||||
|
||||
$data = $this->generator->year($categories, $entries);
|
||||
return Response::json($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* This chart will only show income.
|
||||
*
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param $year
|
||||
* @param bool $shared
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function earnedInYear(CategoryRepositoryInterface $repository, $year, $shared = false)
|
||||
{
|
||||
$start = new Carbon($year . '-01-01');
|
||||
$end = new Carbon($year . '-12-31');
|
||||
|
||||
$cache = new CacheProperties; // chart properties for cache:
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('category');
|
||||
$cache->addProperty('earned-in-year');
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$shared = $shared == 'shared' ? true : false;
|
||||
$allCategories = $repository->getCategories();
|
||||
$allEntries = new Collection;
|
||||
$categories = $allCategories->filter(
|
||||
function (Category $category) use ($repository, $start, $end, $shared) {
|
||||
$spent = $repository->balanceInPeriod($category, $start, $end, $shared);
|
||||
if ($spent > 0) {
|
||||
return $category;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
while ($start < $end) {
|
||||
$month = clone $start; // month is the current end of the period
|
||||
$month->endOfMonth();
|
||||
$row = [clone $start]; // make a row:
|
||||
|
||||
foreach ($categories as $category) { // each budget, fill the row
|
||||
$spent = $repository->balanceInPeriod($category, $start, $month, $shared);
|
||||
if ($spent > 0) {
|
||||
$row[] = $spent;
|
||||
} else {
|
||||
$row[] = 0;
|
||||
}
|
||||
}
|
||||
$allEntries->push($row);
|
||||
$start->addMonth();
|
||||
}
|
||||
$data = $this->generator->earnedInYear($categories, $allEntries);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
|
@@ -79,18 +79,16 @@ class HomeController extends Controller
|
||||
return redirect(route('new-user.index'));
|
||||
}
|
||||
|
||||
$title = 'Firefly';
|
||||
$subTitle = trans('firefly.welcomeBack');
|
||||
$mainTitleIcon = 'fa-fire';
|
||||
$transactions = [];
|
||||
$frontPage = Preferences::get('frontPageAccounts', []);
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$showTour = Preferences::get('tour', true)->data;
|
||||
|
||||
$accounts = $repository->getFrontpageAccounts($frontPage);
|
||||
$savings = $repository->getSavingsAccounts();
|
||||
|
||||
$title = 'Firefly';
|
||||
$subTitle = trans('firefly.welcomeBack');
|
||||
$mainTitleIcon = 'fa-fire';
|
||||
$transactions = [];
|
||||
$frontPage = Preferences::get('frontPageAccounts', []);
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$showTour = Preferences::get('tour', true)->data;
|
||||
$accounts = $repository->getFrontpageAccounts($frontPage);
|
||||
$savings = $repository->getSavingsAccounts();
|
||||
$piggyBankAccounts = $repository->getPiggyBankAccounts();
|
||||
|
||||
|
||||
|
@@ -190,7 +190,8 @@ class TagController extends Controller
|
||||
$tags = Auth::user()->tags()->where('tagMode', $type)->orderBy('date', 'ASC')->get();
|
||||
$tags = $tags->sortBy(
|
||||
function (Tag $tag) {
|
||||
$date = $tag->date->format('Ymd');
|
||||
$date = !is_null($tag->date) ? $tag->date->format('Ymd') : '000000';
|
||||
|
||||
|
||||
return strtolower($date . $tag->tag);
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Amount;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
@@ -8,6 +9,7 @@ use FireflyIII\Events\JournalCreated;
|
||||
use FireflyIII\Events\JournalSaved;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Http\Requests\JournalFormRequest;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
@@ -51,11 +53,19 @@ class TransactionController extends Controller
|
||||
$accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account']));
|
||||
$budgets = ExpandedForm::makeSelectList(Auth::user()->budgets()->get());
|
||||
$budgets[0] = trans('form.noBudget');
|
||||
$piggies = ExpandedForm::makeSelectList(Auth::user()->piggyBanks()->get());
|
||||
$piggies[0] = trans('form.noPiggybank');
|
||||
$preFilled = Session::has('preFilled') ? Session::get('preFilled') : [];
|
||||
$respondTo = ['account_id', 'account_from_id'];
|
||||
$subTitle = trans('form.add_new_' . $what);
|
||||
|
||||
// piggy bank list:
|
||||
$piggyBanks = Auth::user()->piggyBanks()->orderBy('order', 'ASC')->get();
|
||||
/** @var PiggyBank $piggy */
|
||||
foreach ($piggyBanks as $piggy) {
|
||||
$piggy->name = $piggy->name . ' (' . Amount::format($piggy->currentRelevantRep()->currentamount, false) . ')';
|
||||
}
|
||||
|
||||
$piggies = ExpandedForm::makeSelectList($piggyBanks);
|
||||
$piggies[0] = trans('form.noPiggybank');
|
||||
$preFilled = Session::has('preFilled') ? Session::get('preFilled') : [];
|
||||
$respondTo = ['account_id', 'account_from_id'];
|
||||
$subTitle = trans('form.add_new_' . $what);
|
||||
|
||||
foreach ($respondTo as $r) {
|
||||
$preFilled[$r] = Input::get($r);
|
||||
|
@@ -162,7 +162,7 @@ Route::get('/cron/sendgrid', ['uses' => 'CronController@sendgrid']);
|
||||
|
||||
Route::controllers(
|
||||
[
|
||||
'auth' => 'Auth\AuthController',
|
||||
'auth' => 'Auth\AuthController',
|
||||
'password' => 'Auth\PasswordController',
|
||||
]
|
||||
);
|
||||
@@ -282,6 +282,7 @@ Route::group(
|
||||
*/
|
||||
// accounts:
|
||||
Route::get('/chart/account/frontpage', ['uses' => 'Chart\AccountController@frontpage']);
|
||||
Route::get('/chart/account/expense', ['uses' => 'Chart\AccountController@expenseAccounts']);
|
||||
Route::get('/chart/account/month/{year}/{month}/{shared?}', ['uses' => 'Chart\AccountController@all'])->where(
|
||||
['year' => '[0-9]{4}', 'month' => '[0-9]{1,2}', 'shared' => 'shared']
|
||||
);
|
||||
@@ -300,7 +301,12 @@ Route::group(
|
||||
|
||||
// categories:
|
||||
Route::get('/chart/category/frontpage', ['uses' => 'Chart\CategoryController@frontpage']);
|
||||
Route::get('/chart/category/year/{year}/{shared?}', ['uses' => 'Chart\CategoryController@year'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']);
|
||||
Route::get('/chart/category/spent-in-year/{year}/{shared?}', ['uses' => 'Chart\CategoryController@spentInYear'])->where(
|
||||
['year' => '[0-9]{4}', 'shared' => 'shared']
|
||||
);
|
||||
Route::get('/chart/category/earned-in-year/{year}/{shared?}', ['uses' => 'Chart\CategoryController@earnedInYear'])->where(
|
||||
['year' => '[0-9]{4}', 'shared' => 'shared']
|
||||
);
|
||||
Route::get('/chart/category/{category}/month', ['uses' => 'Chart\CategoryController@month']); // should be period.
|
||||
Route::get('/chart/category/{category}/all', ['uses' => 'Chart\CategoryController@all']);
|
||||
|
||||
|
@@ -25,7 +25,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereEncrypted($value)
|
||||
* @property-read float $spent
|
||||
* @property-read \Carbon\Carbon $lastActivity
|
||||
* @property \Carbon\Carbon $lastActivity
|
||||
*/
|
||||
class Category extends Model
|
||||
{
|
||||
|
@@ -98,7 +98,6 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
$this->app->bind('FireflyIII\Helpers\Attachments\AttachmentHelperInterface', 'FireflyIII\Helpers\Attachments\AttachmentHelper');
|
||||
|
||||
// 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');
|
||||
|
@@ -313,9 +313,9 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function spentInPeriodCorrected(Budget $budget, Carbon $start, Carbon $end, $shared = true)
|
||||
public function balanceInPeriod(Budget $budget, Carbon $start, Carbon $end, $shared = true)
|
||||
{
|
||||
return $this->spentInPeriod($budget, $start, $end, $shared);
|
||||
return $this->commonBalanceInPeriod($budget, $start, $end, $shared);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -136,7 +136,7 @@ interface BudgetRepositoryInterface
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function spentInPeriodCorrected(Budget $budget, Carbon $start, Carbon $end, $shared = true);
|
||||
public function balanceInPeriod(Budget $budget, Carbon $start, Carbon $end, $shared = true);
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
|
@@ -57,6 +57,7 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito
|
||||
return $set;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Carbon $start
|
||||
@@ -64,7 +65,7 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCategoriesAndExpensesCorrected($start, $end)
|
||||
public function getCategoriesAndExpensesCorrected(Carbon $start, Carbon $end)
|
||||
{
|
||||
$set = Auth::user()->transactionjournals()
|
||||
->leftJoin(
|
||||
@@ -183,9 +184,9 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function spentInPeriodCorrected(Category $category, Carbon $start, Carbon $end, $shared = false)
|
||||
public function balanceInPeriod(Category $category, Carbon $start, Carbon $end, $shared = false)
|
||||
{
|
||||
return $this->spentInPeriod($category, $start, $end, $shared);
|
||||
return $this->commonBalanceInPeriod($category, $start, $end, $shared);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,7 +199,7 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito
|
||||
*/
|
||||
public function spentOnDaySumCorrected(Category $category, Carbon $date)
|
||||
{
|
||||
return $category->transactionjournals()->onDate($date)->get(['transaction_journals.*'])->sum('amount');
|
||||
return $category->transactionjournals()->onDate($date)->get(['transaction_journals.*'])->sum('correct_amount');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,4 +234,32 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito
|
||||
|
||||
return $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the sum of the journals in the category, optionally
|
||||
* limited by a start or end date.
|
||||
*
|
||||
* @param Category $category
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function journalsSum(Category $category, Carbon $start = null, Carbon $end = null)
|
||||
{
|
||||
$query = $category->transactionJournals()
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order', 'ASC')
|
||||
->orderBy('transaction_journals.id', 'DESC');
|
||||
if (!is_null($start)) {
|
||||
$query->after($start);
|
||||
}
|
||||
|
||||
if (!is_null($end)) {
|
||||
$query->before($end);
|
||||
}
|
||||
|
||||
return $query->get(['transaction_journals.*'])->sum('correct_amount');
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -40,7 +40,7 @@ interface CategoryRepositoryInterface
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCategoriesAndExpensesCorrected($start, $end);
|
||||
public function getCategoriesAndExpensesCorrected(Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
@@ -57,6 +57,18 @@ interface CategoryRepositoryInterface
|
||||
*/
|
||||
public function getJournals(Category $category, $page);
|
||||
|
||||
/**
|
||||
* This method returns the sum of the journals in the category, optionally
|
||||
* limited by a start or end date.
|
||||
*
|
||||
* @param Category $category
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function journalsSum(Category $category, Carbon $start = null, Carbon $end = null);
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
@@ -83,7 +95,7 @@ interface CategoryRepositoryInterface
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function spentInPeriodCorrected(Category $category, Carbon $start, Carbon $end, $shared = false);
|
||||
public function balanceInPeriod(Category $category, Carbon $start, Carbon $end, $shared = false);
|
||||
|
||||
/**
|
||||
*
|
||||
|
@@ -24,7 +24,7 @@ class ComponentRepository
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function spentInPeriod($object, Carbon $start, Carbon $end, $shared = false)
|
||||
protected function commonBalanceInPeriod($object, Carbon $start, Carbon $end, $shared = false)
|
||||
{
|
||||
$cache = new CacheProperties; // we must cache this.
|
||||
$cache->addProperty($object->id);
|
||||
@@ -32,7 +32,7 @@ class ComponentRepository
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty($shared);
|
||||
$cache->addProperty('spentInPeriod');
|
||||
$cache->addProperty('balanceInPeriod');
|
||||
|
||||
if ($cache->has()) {
|
||||
return $cache->get(); // @codeCoverageIgnore
|
||||
@@ -45,14 +45,14 @@ class ComponentRepository
|
||||
// do something else, SEE budgets.
|
||||
// get all journals in this month where the asset account is NOT shared.
|
||||
$sum = $object->transactionjournals()->before($end)->after($start)
|
||||
->transactionTypes(['Withdrawal'])
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->transactionTypes(['Withdrawal', 'Deposit', 'Opening balance'])
|
||||
->leftJoin(
|
||||
'account_meta', function (JoinClause $join) {
|
||||
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
|
||||
}
|
||||
)->where('account_meta.data', '!=', '"sharedAsset"')->get(['transaction_journals.*'])->sum('amount');
|
||||
)->where('account_meta.data', '!=', '"sharedAsset"')->get(['transaction_journals.*'])->sum('correct_amount');
|
||||
}
|
||||
|
||||
$cache->store($sum);
|
||||
|
214
composer.lock
generated
214
composer.lock
generated
@@ -62,26 +62,26 @@
|
||||
},
|
||||
{
|
||||
"name": "codeception/codeception",
|
||||
"version": "2.1.1",
|
||||
"version": "2.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Codeception/Codeception.git",
|
||||
"reference": "6c22380326421947fba0d6116c13a5c24d214adb"
|
||||
"reference": "521adbb2ee34e9debdd8508a2c41ab2b5c2f042b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/6c22380326421947fba0d6116c13a5c24d214adb",
|
||||
"reference": "6c22380326421947fba0d6116c13a5c24d214adb",
|
||||
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/521adbb2ee34e9debdd8508a2c41ab2b5c2f042b",
|
||||
"reference": "521adbb2ee34e9debdd8508a2c41ab2b5c2f042b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"facebook/webdriver": "~1.0",
|
||||
"facebook/webdriver": ">=1.0.1",
|
||||
"guzzlehttp/guzzle": ">=4.0|<7.0",
|
||||
"guzzlehttp/psr7": "~1.0",
|
||||
"php": ">=5.4.0",
|
||||
"phpunit/phpunit": "~4.7.0",
|
||||
"phpunit/phpunit": "~4.8.0",
|
||||
"symfony/browser-kit": "~2.4",
|
||||
"symfony/console": "~2.4",
|
||||
"symfony/css-selector": "~2.4",
|
||||
@@ -138,7 +138,7 @@
|
||||
"functional testing",
|
||||
"unit testing"
|
||||
],
|
||||
"time": "2015-07-14 11:24:17"
|
||||
"time": "2015-08-09 13:48:55"
|
||||
},
|
||||
{
|
||||
"name": "danielstjules/stringy",
|
||||
@@ -803,16 +803,16 @@
|
||||
},
|
||||
{
|
||||
"name": "facebook/webdriver",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facebook/php-webdriver.git",
|
||||
"reference": "8eb1952d6be0725e1064c4fe0630d0d4d1de7639"
|
||||
"reference": "fe1bbbc5dde804d08a8593f1d9d0d3b05f5c84f5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/8eb1952d6be0725e1064c4fe0630d0d4d1de7639",
|
||||
"reference": "8eb1952d6be0725e1064c4fe0630d0d4d1de7639",
|
||||
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/fe1bbbc5dde804d08a8593f1d9d0d3b05f5c84f5",
|
||||
"reference": "fe1bbbc5dde804d08a8593f1d9d0d3b05f5c84f5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -842,7 +842,7 @@
|
||||
"selenium",
|
||||
"webdriver"
|
||||
],
|
||||
"time": "2015-07-16 19:31:12"
|
||||
"time": "2015-08-12 20:21:31"
|
||||
},
|
||||
{
|
||||
"name": "grumpydictator/gchart",
|
||||
@@ -1244,16 +1244,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v5.1.8",
|
||||
"version": "v5.1.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "c4ce8d7a3ac6e655e8b5f0ff3ee07d24fab765ba"
|
||||
"reference": "d47ccc8de10ccb6f328cc90f901ca5e47e077c93"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/c4ce8d7a3ac6e655e8b5f0ff3ee07d24fab765ba",
|
||||
"reference": "c4ce8d7a3ac6e655e8b5f0ff3ee07d24fab765ba",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/d47ccc8de10ccb6f328cc90f901ca5e47e077c93",
|
||||
"reference": "d47ccc8de10ccb6f328cc90f901ca5e47e077c93",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1368,7 +1368,7 @@
|
||||
"framework",
|
||||
"laravel"
|
||||
],
|
||||
"time": "2015-07-21 18:33:13"
|
||||
"time": "2015-08-12 18:16:08"
|
||||
},
|
||||
{
|
||||
"name": "league/commonmark",
|
||||
@@ -1488,16 +1488,16 @@
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"version": "1.0.10",
|
||||
"version": "1.0.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem.git",
|
||||
"reference": "3475ce0b1b5cab41f012905c4c58ad645088f7c9"
|
||||
"reference": "c16222fdc02467eaa12cb6d6d0e65527741f6040"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3475ce0b1b5cab41f012905c4c58ad645088f7c9",
|
||||
"reference": "3475ce0b1b5cab41f012905c4c58ad645088f7c9",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/c16222fdc02467eaa12cb6d6d0e65527741f6040",
|
||||
"reference": "c16222fdc02467eaa12cb6d6d0e65527741f6040",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1565,20 +1565,20 @@
|
||||
"sftp",
|
||||
"storage"
|
||||
],
|
||||
"time": "2015-07-21 19:35:53"
|
||||
"time": "2015-07-28 20:41:58"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "1.15.0",
|
||||
"version": "1.16.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "dc5150cc608f2334c72c3b6a553ec9668a4156b0"
|
||||
"reference": "c0c0b4bee3aabce7182876b0d912ef2595563db7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/dc5150cc608f2334c72c3b6a553ec9668a4156b0",
|
||||
"reference": "dc5150cc608f2334c72c3b6a553ec9668a4156b0",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/c0c0b4bee3aabce7182876b0d912ef2595563db7",
|
||||
"reference": "c0c0b4bee3aabce7182876b0d912ef2595563db7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1615,7 +1615,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.15.x-dev"
|
||||
"dev-master": "1.16.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -1641,7 +1641,7 @@
|
||||
"logging",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2015-07-12 13:54:09"
|
||||
"time": "2015-08-09 17:44:44"
|
||||
},
|
||||
{
|
||||
"name": "mtdowling/cron-expression",
|
||||
@@ -1830,16 +1830,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "v1.4.1",
|
||||
"version": "v1.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/prophecy.git",
|
||||
"reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373"
|
||||
"reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373",
|
||||
"reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7",
|
||||
"reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1886,20 +1886,20 @@
|
||||
"spy",
|
||||
"stub"
|
||||
],
|
||||
"time": "2015-04-27 22:15:08"
|
||||
"time": "2015-08-13 10:07:40"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "2.1.9",
|
||||
"version": "2.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "5bd48b86cd282da411bb80baac1398ce3fefac41"
|
||||
"reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5bd48b86cd282da411bb80baac1398ce3fefac41",
|
||||
"reference": "5bd48b86cd282da411bb80baac1398ce3fefac41",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2d7c03c0e4e080901b8f33b2897b0577be18a13c",
|
||||
"reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1907,7 +1907,7 @@
|
||||
"phpunit/php-file-iterator": "~1.3",
|
||||
"phpunit/php-text-template": "~1.2",
|
||||
"phpunit/php-token-stream": "~1.3",
|
||||
"sebastian/environment": "~1.0",
|
||||
"sebastian/environment": "^1.3.2",
|
||||
"sebastian/version": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
@@ -1922,7 +1922,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1.x-dev"
|
||||
"dev-master": "2.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -1948,7 +1948,7 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-07-26 12:54:47"
|
||||
"time": "2015-08-04 03:42:39"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
@@ -2081,16 +2081,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-token-stream",
|
||||
"version": "1.4.3",
|
||||
"version": "1.4.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
||||
"reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9"
|
||||
"reference": "09fc125d65c344c53a7c7ad8f261e3f3af9f76c5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/7a9b0969488c3c54fd62b4d504b3ec758fd005d9",
|
||||
"reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/09fc125d65c344c53a7c7ad8f261e3f3af9f76c5",
|
||||
"reference": "09fc125d65c344c53a7c7ad8f261e3f3af9f76c5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2126,20 +2126,20 @@
|
||||
"keywords": [
|
||||
"tokenizer"
|
||||
],
|
||||
"time": "2015-06-19 03:43:16"
|
||||
"time": "2015-08-13 14:23:08"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "4.7.7",
|
||||
"version": "4.8.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "9b97f9d807b862c2de2a36e86690000801c85724"
|
||||
"reference": "fd3050e26e3105f416d74c4d33aea659b406c59d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9b97f9d807b862c2de2a36e86690000801c85724",
|
||||
"reference": "9b97f9d807b862c2de2a36e86690000801c85724",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fd3050e26e3105f416d74c4d33aea659b406c59d",
|
||||
"reference": "fd3050e26e3105f416d74c4d33aea659b406c59d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2149,7 +2149,7 @@
|
||||
"ext-reflection": "*",
|
||||
"ext-spl": "*",
|
||||
"php": ">=5.3.3",
|
||||
"phpspec/prophecy": "~1.3,>=1.3.1",
|
||||
"phpspec/prophecy": "^1.3.1",
|
||||
"phpunit/php-code-coverage": "~2.1",
|
||||
"phpunit/php-file-iterator": "~1.4",
|
||||
"phpunit/php-text-template": "~1.2",
|
||||
@@ -2157,7 +2157,7 @@
|
||||
"phpunit/phpunit-mock-objects": "~2.3",
|
||||
"sebastian/comparator": "~1.1",
|
||||
"sebastian/diff": "~1.2",
|
||||
"sebastian/environment": "~1.2",
|
||||
"sebastian/environment": "~1.3",
|
||||
"sebastian/exporter": "~1.2",
|
||||
"sebastian/global-state": "~1.0",
|
||||
"sebastian/version": "~1.0",
|
||||
@@ -2172,7 +2172,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.7.x-dev"
|
||||
"dev-master": "4.8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2198,7 +2198,7 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-07-13 11:28:34"
|
||||
"time": "2015-08-10 09:16:56"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit-mock-objects",
|
||||
@@ -2433,7 +2433,7 @@
|
||||
"illuminate/support": "5.0.*|5.1.*",
|
||||
"illuminate/view": "5.0.*|5.1.*",
|
||||
"php": ">=5.4.0",
|
||||
"twig/twig": "~1.15"
|
||||
"twig/twig": "~1.15|~2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/framework": "5.0.*",
|
||||
@@ -2597,16 +2597,16 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/environment",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/environment.git",
|
||||
"reference": "4fe0a44cddd8cc19583a024bdc7374eb2fef0b87"
|
||||
"reference": "6324c907ce7a52478eeeaede764f48733ef5ae44"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4fe0a44cddd8cc19583a024bdc7374eb2fef0b87",
|
||||
"reference": "4fe0a44cddd8cc19583a024bdc7374eb2fef0b87",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44",
|
||||
"reference": "6324c907ce7a52478eeeaede764f48733ef5ae44",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2643,7 +2643,7 @@
|
||||
"environment",
|
||||
"hhvm"
|
||||
],
|
||||
"time": "2015-07-26 06:42:57"
|
||||
"time": "2015-08-03 06:14:51"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/exporter",
|
||||
@@ -2905,7 +2905,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/browser-kit",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/BrowserKit.git",
|
||||
@@ -2960,16 +2960,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Console.git",
|
||||
"reference": "8cf484449130cabfd98dcb4694ca9945802a21ed"
|
||||
"reference": "d6cf02fe73634c96677e428f840704bfbcaec29e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Console/zipball/8cf484449130cabfd98dcb4694ca9945802a21ed",
|
||||
"reference": "8cf484449130cabfd98dcb4694ca9945802a21ed",
|
||||
"url": "https://api.github.com/repos/symfony/Console/zipball/d6cf02fe73634c96677e428f840704bfbcaec29e",
|
||||
"reference": "d6cf02fe73634c96677e428f840704bfbcaec29e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3013,11 +3013,11 @@
|
||||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-07-09 16:07:40"
|
||||
"time": "2015-07-28 15:18:12"
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/CssSelector.git",
|
||||
@@ -3070,7 +3070,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/debug",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Debug.git",
|
||||
@@ -3130,7 +3130,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/dom-crawler",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/DomCrawler.git",
|
||||
@@ -3183,7 +3183,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/EventDispatcher.git",
|
||||
@@ -3241,7 +3241,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Finder.git",
|
||||
@@ -3290,16 +3290,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/HttpFoundation.git",
|
||||
"reference": "88903c0531b90d4ecd90282b18f08c0c77bde0b2"
|
||||
"reference": "863af6898081b34c65d42100c370b9f3c51b70ca"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/88903c0531b90d4ecd90282b18f08c0c77bde0b2",
|
||||
"reference": "88903c0531b90d4ecd90282b18f08c0c77bde0b2",
|
||||
"url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/863af6898081b34c65d42100c370b9f3c51b70ca",
|
||||
"reference": "863af6898081b34c65d42100c370b9f3c51b70ca",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3339,27 +3339,27 @@
|
||||
],
|
||||
"description": "Symfony HttpFoundation Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-07-09 16:07:40"
|
||||
"time": "2015-07-22 10:11:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-kernel",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/HttpKernel.git",
|
||||
"reference": "4a8a6f2a847475b3a38da50363a07f69b5cbf37e"
|
||||
"reference": "405d3e7a59ff7a28ec469441326a0ac79065ea98"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/HttpKernel/zipball/4a8a6f2a847475b3a38da50363a07f69b5cbf37e",
|
||||
"reference": "4a8a6f2a847475b3a38da50363a07f69b5cbf37e",
|
||||
"url": "https://api.github.com/repos/symfony/HttpKernel/zipball/405d3e7a59ff7a28ec469441326a0ac79065ea98",
|
||||
"reference": "405d3e7a59ff7a28ec469441326a0ac79065ea98",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.9",
|
||||
"psr/log": "~1.0",
|
||||
"symfony/debug": "~2.6,>=2.6.2",
|
||||
"symfony/event-dispatcher": "~2.5.9|~2.6,>=2.6.2",
|
||||
"symfony/event-dispatcher": "~2.6,>=2.6.7",
|
||||
"symfony/http-foundation": "~2.5,>=2.5.4"
|
||||
},
|
||||
"conflict": {
|
||||
@@ -3419,11 +3419,11 @@
|
||||
],
|
||||
"description": "Symfony HttpKernel Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-07-13 19:27:49"
|
||||
"time": "2015-07-31 13:24:45"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Process.git",
|
||||
@@ -3472,7 +3472,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/routing",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Routing.git",
|
||||
@@ -3543,7 +3543,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Translation.git",
|
||||
@@ -3604,16 +3604,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "fde603d9f4b2418ff0f0315b93eb039c9aa41205"
|
||||
"reference": "e8903ebba5eb019f5886ffce739ea9e3b7519579"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/fde603d9f4b2418ff0f0315b93eb039c9aa41205",
|
||||
"reference": "fde603d9f4b2418ff0f0315b93eb039c9aa41205",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/e8903ebba5eb019f5886ffce739ea9e3b7519579",
|
||||
"reference": "e8903ebba5eb019f5886ffce739ea9e3b7519579",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3659,20 +3659,20 @@
|
||||
"debug",
|
||||
"dump"
|
||||
],
|
||||
"time": "2015-07-01 12:07:40"
|
||||
"time": "2015-07-28 15:18:12"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Yaml.git",
|
||||
"reference": "4bfbe0ed3909bfddd75b70c094391ec1f142f860"
|
||||
"reference": "71340e996171474a53f3d29111d046be4ad8a0ff"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/4bfbe0ed3909bfddd75b70c094391ec1f142f860",
|
||||
"reference": "4bfbe0ed3909bfddd75b70c094391ec1f142f860",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/71340e996171474a53f3d29111d046be4ad8a0ff",
|
||||
"reference": "71340e996171474a53f3d29111d046be4ad8a0ff",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3708,20 +3708,20 @@
|
||||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-07-01 11:25:50"
|
||||
"time": "2015-07-28 14:07:07"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v1.18.2",
|
||||
"version": "v1.20.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "e8e6575abf6102af53ec283f7f14b89e304fa602"
|
||||
"reference": "1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/e8e6575abf6102af53ec283f7f14b89e304fa602",
|
||||
"reference": "e8e6575abf6102af53ec283f7f14b89e304fa602",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844",
|
||||
"reference": "1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3730,7 +3730,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.18-dev"
|
||||
"dev-master": "1.20-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -3765,7 +3765,7 @@
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2015-06-06 23:31:24"
|
||||
"time": "2015-08-12 15:56:39"
|
||||
},
|
||||
{
|
||||
"name": "vlucas/phpdotenv",
|
||||
@@ -3993,16 +3993,16 @@
|
||||
},
|
||||
{
|
||||
"name": "barryvdh/laravel-ide-helper",
|
||||
"version": "v2.0.6",
|
||||
"version": "v2.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/barryvdh/laravel-ide-helper.git",
|
||||
"reference": "037386153630a7515a1542f29410d8c267651689"
|
||||
"reference": "83999f8467374adcb8893f566c9171c9d9691f50"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/037386153630a7515a1542f29410d8c267651689",
|
||||
"reference": "037386153630a7515a1542f29410d8c267651689",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/83999f8467374adcb8893f566c9171c9d9691f50",
|
||||
"reference": "83999f8467374adcb8893f566c9171c9d9691f50",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4022,7 +4022,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
"dev-master": "2.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -4052,7 +4052,7 @@
|
||||
"phpstorm",
|
||||
"sublime"
|
||||
],
|
||||
"time": "2015-06-25 08:58:59"
|
||||
"time": "2015-08-13 11:40:00"
|
||||
},
|
||||
{
|
||||
"name": "maximebf/debugbar",
|
||||
@@ -4112,7 +4112,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/class-loader",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/ClassLoader.git",
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
return [
|
||||
'chart' => 'chartjs',
|
||||
'version' => '3.4.10',
|
||||
'version' => '3.5.0',
|
||||
'index_periods' => ['1D', '1W', '1M', '3M', '6M', '1Y', 'custom'],
|
||||
'budget_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
|
||||
'csv_import_enabled' => true,
|
||||
|
40
pu.sh
40
pu.sh
@@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# set testing environment
|
||||
cp .env.testing .env
|
||||
|
||||
# test!
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
phpunit --verbose
|
||||
fi
|
||||
|
||||
# directories to look in:
|
||||
dirs=("controllers" "database" "factories" "generators" "helpers" "models" "middleware" "repositories" "support")
|
||||
|
||||
if [ ! -z "$1" ]
|
||||
then
|
||||
for i in "${dirs[@]}"
|
||||
do
|
||||
firstFile="./tests/$i/$1.php"
|
||||
secondFile="./tests/$i/$1Test.php"
|
||||
if [ -f "$firstFile" ]
|
||||
then
|
||||
# run it!
|
||||
phpunit --verbose $firstFile
|
||||
exit $?
|
||||
fi
|
||||
if [ -f "$secondFile" ]
|
||||
then
|
||||
# run it!
|
||||
phpunit --verbose $secondFile
|
||||
exit $?
|
||||
fi
|
||||
|
||||
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
# restore .env file
|
||||
cp .env.local .env
|
@@ -1,5 +1,5 @@
|
||||
#daterange {cursor:pointer;}
|
||||
.google-chart-error {height:30px;background:url('/images/error.png') no-repeat center center;}
|
||||
.general-chart-error {height:30px;background:url('/images/error.png') no-repeat center center;}
|
||||
.handle {cursor:move;}
|
||||
|
||||
.ui-sortable-placeholder {
|
||||
|
@@ -3,18 +3,6 @@
|
||||
/*
|
||||
Make some colours:
|
||||
*/
|
||||
/*
|
||||
#555299
|
||||
#4285f4
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#", "#", "#", "#"],
|
||||
*/
|
||||
var colourSet = [
|
||||
[53, 124, 165],
|
||||
[0, 141, 76],
|
||||
@@ -54,6 +42,7 @@ var defaultAreaOptions = {
|
||||
datasetStrokeWidth: 1,
|
||||
pointHitDetectionRadius: 5,
|
||||
datasetFill: true,
|
||||
animation: false,
|
||||
scaleFontSize: 10,
|
||||
responsive: false,
|
||||
scaleLabel: " <%= '" + currencySymbol + " ' + Number(value).toFixed(0).replace('.', ',') %>",
|
||||
@@ -68,6 +57,7 @@ var defaultPieOptions = {
|
||||
datasetStrokeWidth: 1,
|
||||
pointHitDetectionRadius: 5,
|
||||
datasetFill: false,
|
||||
animation: false,
|
||||
scaleFontSize: 10,
|
||||
responsive: false,
|
||||
tooltipFillColor: "rgba(0,0,0,0.5)",
|
||||
@@ -81,6 +71,7 @@ var defaultLineOptions = {
|
||||
pointDotRadius: 2,
|
||||
datasetStrokeWidth: 1,
|
||||
pointHitDetectionRadius: 5,
|
||||
animation: false,
|
||||
datasetFill: false,
|
||||
scaleFontSize: 10,
|
||||
responsive: false,
|
||||
@@ -98,6 +89,7 @@ var defaultColumnOptions = {
|
||||
datasetFill: false,
|
||||
scaleFontSize: 10,
|
||||
responsive: false,
|
||||
animation: false,
|
||||
scaleLabel: "<%= '" + currencySymbol + " ' + Number(value).toFixed(0).replace('.', ',') %>",
|
||||
tooltipFillColor: "rgba(0,0,0,0.5)",
|
||||
tooltipTemplate: "<%if (label){%><%=label%>: <%}%>" + currencySymbol + " <%= value %>",
|
||||
@@ -110,6 +102,7 @@ var defaultStackedColumnOptions = {
|
||||
barStrokeWidth: 1,
|
||||
pointHitDetectionRadius: 5,
|
||||
datasetFill: false,
|
||||
animation: false,
|
||||
scaleFontSize: 10,
|
||||
responsive: false,
|
||||
scaleLabel: "<%= '" + currencySymbol + " ' + Number(value).toFixed(0).replace('.', ',') %>",
|
||||
@@ -147,7 +140,7 @@ function lineChart(URL, container, options) {
|
||||
new Chart(ctx).Line(newData, options);
|
||||
|
||||
}).fail(function () {
|
||||
$('#' + container).addClass('google-chart-error');
|
||||
$('#' + container).addClass('general-chart-error');
|
||||
});
|
||||
console.log('URL for line chart : ' + URL);
|
||||
}
|
||||
@@ -182,7 +175,7 @@ function areaChart(URL, container, options) {
|
||||
new Chart(ctx).Line(newData, options);
|
||||
|
||||
}).fail(function () {
|
||||
$('#' + container).addClass('google-chart-error');
|
||||
$('#' + container).addClass('general-chart-error');
|
||||
});
|
||||
|
||||
console.log('URL for area chart: ' + URL);
|
||||
@@ -218,7 +211,7 @@ function columnChart(URL, container, options) {
|
||||
new Chart(ctx).Bar(newData, options);
|
||||
|
||||
}).fail(function () {
|
||||
$('#' + container).addClass('google-chart-error');
|
||||
$('#' + container).addClass('general-chart-error');
|
||||
});
|
||||
console.log('URL for column chart : ' + URL);
|
||||
}
|
||||
@@ -253,7 +246,7 @@ function stackedColumnChart(URL, container, options) {
|
||||
new Chart(ctx).StackedBar(newData, options);
|
||||
|
||||
}).fail(function () {
|
||||
$('#' + container).addClass('google-chart-error');
|
||||
$('#' + container).addClass('general-chart-error');
|
||||
});
|
||||
console.log('URL for stacked column chart : ' + URL);
|
||||
}
|
||||
@@ -286,7 +279,7 @@ function pieChart(URL, container, options) {
|
||||
new Chart(ctx).Pie(data, options);
|
||||
|
||||
}).fail(function () {
|
||||
$('#' + container).addClass('google-chart-error');
|
||||
$('#' + container).addClass('general-chart-error');
|
||||
});
|
||||
|
||||
|
||||
|
@@ -1,319 +0,0 @@
|
||||
/* globals currencyCode, language */
|
||||
/* exported lineChart, googleColumnChart, stackedColumnChart, comboChart, pieChart, defaultLineChartOptions, defaultAreaChartOptions, defaultBarChartOptions, defaultComboChartOptions, defaultColumnChartOptions, defaultStackedColumnChartOptions, defaultPieChartOptions */
|
||||
var google = google || {};
|
||||
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) {
|
||||
"use strict";
|
||||
if ($('#' + container).length === 1) {
|
||||
$.getJSON(URL).success(function (data) {
|
||||
/*
|
||||
Get the data from the JSON
|
||||
*/
|
||||
var gdata = new google.visualization.DataTable(data);
|
||||
|
||||
/*
|
||||
Format as money
|
||||
*/
|
||||
var money = new google.visualization.NumberFormat({
|
||||
decimalSymbol: ',',
|
||||
groupingSymbol: '.',
|
||||
prefix: currencyCode + ' '
|
||||
});
|
||||
for (var i = 1; i < gdata.getNumberOfColumns(); i++) {
|
||||
money.format(gdata, i);
|
||||
}
|
||||
|
||||
/*
|
||||
Create a new google charts object.
|
||||
*/
|
||||
var chart = false;
|
||||
var options = false;
|
||||
if (chartType === 'line') {
|
||||
chart = new google.visualization.LineChart(document.getElementById(container));
|
||||
options = options || defaultLineChartOptions;
|
||||
}
|
||||
if (chartType === 'area') {
|
||||
chart = new google.visualization.AreaChart(document.getElementById(container));
|
||||
options = options || defaultAreaChartOptions;
|
||||
}
|
||||
|
||||
if (chartType === 'column') {
|
||||
chart = new google.visualization.ColumnChart(document.getElementById(container));
|
||||
options = options || defaultColumnChartOptions;
|
||||
}
|
||||
if (chartType === 'pie') {
|
||||
chart = new google.visualization.PieChart(document.getElementById(container));
|
||||
options = options || defaultPieChartOptions;
|
||||
}
|
||||
if (chartType === 'bar') {
|
||||
chart = new google.visualization.BarChart(document.getElementById(container));
|
||||
options = options || defaultBarChartOptions;
|
||||
}
|
||||
if (chartType === 'stackedColumn') {
|
||||
chart = new google.visualization.ColumnChart(document.getElementById(container));
|
||||
options = options || defaultStackedColumnChartOptions;
|
||||
}
|
||||
if (chartType === 'combo') {
|
||||
chart = new google.visualization.ComboChart(document.getElementById(container));
|
||||
options = options || defaultComboChartOptions;
|
||||
}
|
||||
|
||||
if (chart === false) {
|
||||
alert('Cannot draw chart of type "' + chartType + '".');
|
||||
} else {
|
||||
chart.draw(gdata, options);
|
||||
}
|
||||
|
||||
}).fail(function () {
|
||||
$('#' + container).addClass('google-chart-error');
|
||||
});
|
||||
} else {
|
||||
console.log('No container found called "' + container + '"');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function lineChart(URL, container, options) {
|
||||
"use strict";
|
||||
return googleChart('line', URL, container, options);
|
||||
}
|
||||
|
||||
function areaChart(URL, container, options) {
|
||||
"use strict";
|
||||
return googleChart('area', URL, container, options);
|
||||
}
|
||||
|
||||
function columnChart(URL, container, options) {
|
||||
"use strict";
|
||||
return googleChart('column', URL, container, options);
|
||||
}
|
||||
|
||||
function stackedColumnChart(URL, container, options) {
|
||||
"use strict";
|
||||
return googleChart('stackedColumn', URL, container, options);
|
||||
}
|
||||
|
||||
function comboChart(URL, container, options) {
|
||||
"use strict";
|
||||
return googleChart('combo', URL, container, options);
|
||||
}
|
||||
|
||||
function pieChart(URL, container, options) {
|
||||
"use strict";
|
||||
return googleChart('pie', URL, container, options);
|
||||
}
|
@@ -2,13 +2,8 @@
|
||||
|
||||
$(function () {
|
||||
"use strict";
|
||||
if (typeof google !== 'undefined') {
|
||||
// do google charts:
|
||||
google.setOnLoadCallback(drawChart);
|
||||
} else {
|
||||
// do chart JS stuff.
|
||||
drawChart();
|
||||
}
|
||||
// do chart JS stuff.
|
||||
drawChart();
|
||||
if (showTour) {
|
||||
$.getJSON('json/tour').success(function (data) {
|
||||
var tour = new Tour(
|
||||
@@ -41,6 +36,7 @@ function drawChart() {
|
||||
pieChart('chart/bill/frontpage', 'bills-chart');
|
||||
stackedColumnChart('chart/budget/frontpage', 'budgets-chart');
|
||||
columnChart('chart/category/frontpage', 'categories-chart');
|
||||
columnChart('chart/account/expense', 'expense-accounts-chart');
|
||||
|
||||
|
||||
getBoxAmounts();
|
||||
|
@@ -2,11 +2,7 @@
|
||||
|
||||
$(function () {
|
||||
"use strict";
|
||||
if (typeof(google) !== 'undefined') {
|
||||
google.setOnLoadCallback(drawChart);
|
||||
} else {
|
||||
drawChart();
|
||||
}
|
||||
drawChart();
|
||||
});
|
||||
|
||||
|
||||
@@ -18,7 +14,8 @@ function drawChart() {
|
||||
}
|
||||
if (typeof stackedColumnChart !== 'undefined' && typeof year !== 'undefined' && typeof month === 'undefined') {
|
||||
stackedColumnChart('chart/budget/year/' + year + shared, 'budgets');
|
||||
stackedColumnChart('chart/category/year/' + year + shared, 'categories');
|
||||
stackedColumnChart('chart/category/spent-in-year/' + year + shared, 'categories-spent-in-year');
|
||||
stackedColumnChart('chart/category/earned-in-year/' + year + shared, 'categories-earned-in-year');
|
||||
}
|
||||
if (typeof lineChart !== 'undefined' && typeof month !== 'undefined') {
|
||||
lineChart('/chart/account/month/' + year + '/' + month + shared, 'account-balances-chart');
|
||||
|
@@ -15,6 +15,8 @@ return [
|
||||
'cancel' => 'Cancel',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'total_sum' => 'Total sum',
|
||||
'period_sum' => 'Sum for period',
|
||||
'showEverything' => 'Show everything',
|
||||
'never' => 'Never',
|
||||
'search_results_for' => 'Search results for ":query"',
|
||||
@@ -117,16 +119,16 @@ return [
|
||||
'onto existing data in Firefly, use the checkbox. The next step will show you what this button does.',
|
||||
'csv_column_roles_table' => 'Column roles',
|
||||
'csv_column' => 'CSV column',
|
||||
'cvs_column_name' => 'CSV column name',
|
||||
'cvs_column_example' => 'Column example data',
|
||||
'cvs_column_role' => 'Column contains?',
|
||||
'csv_column_name' => 'CSV column name',
|
||||
'csv_column_example' => 'Column example data',
|
||||
'csv_column_role' => 'Column contains?',
|
||||
'csv_do_map_value' => 'Map value?',
|
||||
'csv_continue' => 'Continue to the next step',
|
||||
'csv_go_back' => 'Go back to the previous step',
|
||||
'csv_map_title' => 'Map found values to existing values',
|
||||
'csv_map_text' => 'This page allows you to map the values from the CSV file to existing entries in your ' .
|
||||
'database. This ensures that accounts and other things won\'t be created twice.',
|
||||
'cvs_field_value' => 'Field value from CSV',
|
||||
'csv_field_value' => 'Field value from CSV',
|
||||
'csv_field_mapped_to' => 'Must be mapped to...',
|
||||
'csv_do_not_map' => 'Do not map this value',
|
||||
'csv_download_config_title' => 'Download CSV configuration',
|
||||
@@ -140,8 +142,8 @@ return [
|
||||
'csv_unsupported_map' => 'The importer cannot map the column ":columnRole" to existing values in the database.',
|
||||
'csv_unsupported_value' => 'The importer does not know how to handle values in columns marked as ":columnRole".',
|
||||
'csv_cannot_store_value' => 'The importer has not reserved space for columns marked ":columnRole" and will be incapable of processing them.',
|
||||
'csv_process_title' => 'CVS import finished!',
|
||||
'csv_process_text' => 'The CVS importer has finished and has processed :rows rows',
|
||||
'csv_process_title' => 'CSV import finished!',
|
||||
'csv_process_text' => 'The CSV importer has finished and has processed :rows rows',
|
||||
'csv_row' => 'Row',
|
||||
'csv_import_with_errors' => 'There was one error.|There were :errors errors.',
|
||||
'csv_error_see_logs' => 'Check the log files to see details.',
|
||||
@@ -180,6 +182,7 @@ return [
|
||||
'csv_specifix_Dummy' => 'Checking this has no effect whatsoever.',
|
||||
'csv_import_account_help' => 'If your CSV file does NOT contain information about your asset account(s), use this dropdown to select to which'
|
||||
. ' account the transactions in the CSV belong to.',
|
||||
'csv_date_parse_error' => 'Could not parse a valid date from ":value", using the format ":format". Are you sure your CSV is correct?',
|
||||
|
||||
|
||||
// create new stuff:
|
||||
@@ -396,12 +399,15 @@ return [
|
||||
'hideTheRest' => 'Show only the top :number',
|
||||
'sum_of_year' => 'Sum of year',
|
||||
'average_of_year' => 'Average of year',
|
||||
'categories_earned_in_year' => 'Categories (by earnings)',
|
||||
'categories_spent_in_year' => 'Categories (by spendings)',
|
||||
|
||||
// charts:
|
||||
'dayOfMonth' => 'Day of the month',
|
||||
'month' => 'Month',
|
||||
'budget' => 'Budget',
|
||||
'spent' => 'Spent',
|
||||
'earned' => 'Earned',
|
||||
'overspent' => 'Overspent',
|
||||
'left' => 'Left',
|
||||
'noBudget' => '(no budget)',
|
||||
|
@@ -15,6 +15,8 @@ return [
|
||||
'cancel' => 'Annuleren',
|
||||
'from' => 'Van',
|
||||
'to' => 'Tot',
|
||||
'total_sum' => 'Totale som',
|
||||
'period_sum' => 'Som van periode',
|
||||
'showEverything' => 'Laat alles zien',
|
||||
'never' => 'Nooit',
|
||||
'search_results_for' => 'Zoekresultaten voor ":query"',
|
||||
@@ -116,24 +118,24 @@ return [
|
||||
. ' die al in Firefly staan, gebruik dan het vinkje. Tijdens de volgende stap komt Firefly hier dan op terug.',
|
||||
'csv_column_roles_table' => 'Kolominhoud',
|
||||
'csv_column' => 'CSV-kolom',
|
||||
'cvs_column_name' => 'CSV-kolomnaam',
|
||||
'cvs_column_example' => 'Voorbeeldgegevens',
|
||||
'cvs_column_role' => 'Kolom bevat?',
|
||||
'csv_column_name' => 'CSV-kolomnaam',
|
||||
'csv_column_example' => 'Voorbeeldgegevens',
|
||||
'csv_column_role' => 'Kolom bevat?',
|
||||
'csv_do_map_value' => 'Directe relatie?',
|
||||
'csv_continue' => 'Naar de volgende stap',
|
||||
'csv_go_back' => 'Terug naar de vorige stap',
|
||||
'csv_map_title' => 'Leg relaties met kolomwaardes',
|
||||
'csv_map_text' => 'Sommige kolommen bevatten waardes die misschien al in Firefly bestaan. Selecteer hier de juiste combinaties'
|
||||
. 'zodat het importeren netjes aansluit bij je huidige gegevens.',
|
||||
'cvs_field_value' => 'Veldwaarde',
|
||||
'csv_field_value' => 'Veldwaarde',
|
||||
'csv_field_mapped_to' => 'Is gelijk aan',
|
||||
'csv_do_not_map' => 'Geen relatie',
|
||||
'csv_download_config_title' => 'Download importconfiguratie',
|
||||
'csv_download_config_text' => 'Firefly is klaar om je bestand te importeren. De instellingen en selecties die je zojuist hebt gemaakt kan je downloaden'
|
||||
. ' en opslaan. Bij de volgende keer kan je dit bestand ook uploaden. Als je kommagescheiden bestand dezelfde indeling'
|
||||
. ' heeft, zullen alle selecties goed staan. Dat scheelt weer!',
|
||||
'csv_more_information_text' => 'Ook als het importeren fout gaat is dit bestand handig. Na het importeren krijg je nogmaals de gelegenheid dit bestand'
|
||||
. 'te downloaden.',
|
||||
'csv_download_config_text' => 'Firefly is klaar om je bestand te importeren. De instellingen en selecties die je zojuist hebt gemaakt' .
|
||||
' kan je downloaden en opslaan. Bij de volgende keer kan je dit bestand ook uploaden. Als je' .
|
||||
' kommagescheiden bestand dezelfde indeling heeft, zullen alle selecties goed staan. Dat scheelt weer!',
|
||||
'csv_more_information_text' => 'Ook als het importeren fout gaat is dit bestand handig. Na het importeren krijg je nogmaals' .
|
||||
' de gelegenheid dit bestand te downloaden.',
|
||||
'csv_do_download_config' => 'Download het configuratiebestand',
|
||||
'csv_empty_description' => '(geen beschrijving)',
|
||||
'csv_upload_form' => 'CSV upload formulier',
|
||||
@@ -181,6 +183,8 @@ return [
|
||||
'csv_specifix_RabobankDescription' => 'Vink dit aan als je Rabobank bestanden importeert.',
|
||||
'csv_specifix_Dummy' => 'Dit vinkje doet niks (dummy).',
|
||||
'csv_import_account_help' => 'Als jouw CSV bestand geen referenties bevat naar jouw rekening(en), geef dan hier aan om welke rekening het gaat.',
|
||||
'csv_date_parse_error' => 'Kan geen chocola maken van ":value" (met hulp van configuratie ":format").' .
|
||||
' Weet je zeker dat je CSV bestand geen fouten bevat?',
|
||||
|
||||
// create new stuff:
|
||||
'create_new_withdrawal' => 'Nieuwe uitgave',
|
||||
@@ -376,8 +380,8 @@ return [
|
||||
// reports:
|
||||
'reportForYear' => 'Jaaroverzicht :year',
|
||||
'reportForYearShared' => 'Jaaroverzicht :year (inclusief gedeelde rekeningen)',
|
||||
'reportForMonth' => 'Maandoverzicht van :date',
|
||||
'reportForMonthShared' => 'Maandoverzicht van :date (inclusief gedeelde rekeningen)',
|
||||
'reportForMonth' => 'Maandoverzicht voor :month',
|
||||
'reportForMonthShared' => 'Maandoverzicht voor :month (inclusief gedeelde rekeningen)',
|
||||
'incomeVsExpenses' => 'Inkomsten tegenover uitgaven',
|
||||
'accountBalances' => 'Rekeningsaldi',
|
||||
'balanceStartOfYear' => 'Saldo aan het begin van het jaar',
|
||||
@@ -404,12 +408,15 @@ return [
|
||||
'topX' => 'top :number',
|
||||
'showTheRest' => 'Laat alles zien',
|
||||
'hideTheRest' => 'Laat alleen de top :number zien',
|
||||
'categories_earned_in_year' => 'Categorieën (inkomsten)',
|
||||
'categories_spent_in_year' => 'Categorieën (uitgaven)',
|
||||
|
||||
// charts:
|
||||
'dayOfMonth' => 'Dag vd maand',
|
||||
'month' => 'Maand',
|
||||
'budget' => 'Budget',
|
||||
'spent' => 'Uitgegeven',
|
||||
'earned' => 'Verdiend',
|
||||
'overspent' => 'Teveel uitgegeven',
|
||||
'left' => 'Over',
|
||||
'noBudget' => '(geen budget)',
|
||||
|
53
resources/twig/auth/reset.twig
Normal file
53
resources/twig/auth/reset.twig
Normal file
@@ -0,0 +1,53 @@
|
||||
{% extends "./layout/guest.twig" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if errors|length > 0 %}
|
||||
<div class="alert alert-danger">
|
||||
<strong>Whoops!</strong> There were some problems with your input.<br><br>
|
||||
<ul>
|
||||
{% for error in errors.all %}
|
||||
<li>{{ error }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
<div class="register-box-body">
|
||||
<p class="login-box-msg">Reset your password</p>
|
||||
|
||||
<form method="POST" action="/password/reset">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}">
|
||||
<input type="hidden" name="token" value="{{ token }}">
|
||||
|
||||
<div class="form-group has-feedback">
|
||||
<input type="email" name="email" class="form-control" value="{{ old('email') }}" placeholder="Email"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group has-feedback">
|
||||
<input type="password" class="form-control" placeholder="Password" name="password"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group has-feedback">
|
||||
<input type="password" class="form-control" placeholder="Password (again)" name="password_confirmation"/>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<button type="submit" class="btn btn-primary pull-right btn-flat">Reset Password</button>
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<a href="{{ URL.to('/auth/login') }}">I want to login</a><br>
|
||||
{% if Config.get('auth.allow_register') %}
|
||||
<a href="{{ route('register') }}" class="text-center">Register a new account</a><br>
|
||||
{% endif %}
|
||||
</div><!-- /.form-box -->
|
||||
|
||||
{% endblock %}
|
@@ -45,7 +45,7 @@
|
||||
<h3 class="box-title">{{ 'transactions'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body no-padding">
|
||||
{% include 'list/journals' %}
|
||||
{% include 'list/journals' with {showPageSum: true, showTotalSum: true, showPeriodSum: true} %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -45,9 +45,9 @@
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th style="width:20%;">{{ 'cvs_column_name'|_ }}</th>
|
||||
<th style="width:40%;">{{ 'cvs_column_example'|_ }}</th>
|
||||
<th style="width:30%;">{{ 'cvs_column_role'|_ }}</th>
|
||||
<th style="width:20%;">{{ 'csv_column_name'|_ }}</th>
|
||||
<th style="width:40%;">{{ 'csv_column_example'|_ }}</th>
|
||||
<th style="width:30%;">{{ 'csv_column_role'|_ }}</th>
|
||||
<th style="width:10%;">{{ 'csv_do_map_value'|_ }}</th>
|
||||
</thead>
|
||||
{% for index,header in headers %}
|
||||
|
@@ -48,7 +48,7 @@
|
||||
<div class="box-body no-padding">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<th style="width:50%;">{{ 'cvs_field_value'|_ }}</th>
|
||||
<th style="width:50%;">{{ 'csv_field_value'|_ }}</th>
|
||||
<th>{{ 'csv_field_mapped_to'|_ }}</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@@ -1 +1 @@
|
||||
Click here to reset your password: {{ url('password/reset/' . token) }}
|
||||
Click here to reset your password: {{ url('password/reset/' ~ token) }}
|
@@ -67,7 +67,87 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6 col-sm-12">
|
||||
|
||||
<!-- BILLS -->
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'bills'|_ }}</h3>
|
||||
<!-- ACTIONS MENU -->
|
||||
<div class="box-tools pull-right">
|
||||
<button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
{% if Config.get('firefly.chart') == 'google' %}
|
||||
<div id="bills-chart"></div>
|
||||
{% endif %}
|
||||
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||
<canvas id="bills-chart" style="width:100%;height:250px;"></canvas>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TRANSACTIONS -->
|
||||
{% for data in transactions %}
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ data[1].name }}</h3>
|
||||
|
||||
<!-- ACTIONS MENU -->
|
||||
<div class="box-tools pull-right">
|
||||
<button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-box-tool dropdown-toggle" data-toggle="dropdown"><i class="fa fa-ellipsis-v"></i></button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="{{ route('transactions.create','withdrawal') }}?account_id={{ data[1].id }}"><i
|
||||
class="fa fa-long-arrow-left fa-fw"></i> {{ 'newWithdrawal'|_ }}</a></li>
|
||||
<li><a href="{{ route('transactions.create','deposit') }}?account_id={{ data[1].id }}"><i
|
||||
class="fa fa-long-arrow-right fa-fw"></i> {{ 'newDeposit'|_ }}</a></li>
|
||||
<li><a href="{{ route('transactions.create','transfer') }}?account_from_id={{ data[1].id }}"><i
|
||||
class="fa fa-fw fa-exchange"></i> {{ 'newTransfer'|_ }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="box-body no-padding">
|
||||
{% include 'list/journals-tiny.twig' with {'transactions': data[0],'account': data[1]} %}
|
||||
</div>
|
||||
<div class="box-footer clearfix">
|
||||
<a class="btn btn-sm btn-default btn-flat pull-right"
|
||||
href="{{ route('accounts.show',data[1].id) }}">{{ (data[1]|balance)|formatAmountPlain }}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<!-- EXPENSE ACCOUNTS -->
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'expense_accounts'|_ }}</h3>
|
||||
|
||||
<div class="box-tools pull-right">
|
||||
<button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
{% if Config.get('firefly.chart') == 'google' %}
|
||||
<div id="expense-accounts-chart"></div>
|
||||
{% endif %}
|
||||
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||
<canvas id="expense-accounts-chart" style="width:100%;height:400px;"></canvas>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-sm-12 col-md-12">
|
||||
<!-- SAVINGS -->
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
@@ -133,7 +213,8 @@
|
||||
<span class="pull-right">{{ 'sum'|_ }}: {{ savingsTotal|formatAmount }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-lg-6 col-sm-12 col-md-12">
|
||||
<!-- PIGGY BANKS -->
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
@@ -178,63 +259,6 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6 col-sm-12">
|
||||
|
||||
<!-- BILLS -->
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'bills'|_ }}</h3>
|
||||
<!-- ACTIONS MENU -->
|
||||
<div class="box-tools pull-right">
|
||||
<button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
{% if Config.get('firefly.chart') == 'google' %}
|
||||
<div id="bills-chart"></div>
|
||||
{% endif %}
|
||||
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||
<canvas id="bills-chart" style="width:100%;height:250px;"></canvas>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TRANSACTIONS -->
|
||||
{% for data in transactions %}
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ data[1].name }}</h3>
|
||||
|
||||
<!-- ACTIONS MENU -->
|
||||
<div class="box-tools pull-right">
|
||||
<button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-box-tool dropdown-toggle" data-toggle="dropdown"><i class="fa fa-ellipsis-v"></i></button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="{{ route('transactions.create','withdrawal') }}?account_id={{ data[1].id }}"><i
|
||||
class="fa fa-long-arrow-left fa-fw"></i> {{ 'newWithdrawal'|_ }}</a></li>
|
||||
<li><a href="{{ route('transactions.create','deposit') }}?account_id={{ data[1].id }}"><i
|
||||
class="fa fa-long-arrow-right fa-fw"></i> {{ 'newDeposit'|_ }}</a></li>
|
||||
<li><a href="{{ route('transactions.create','transfer') }}?account_from_id={{ data[1].id }}"><i
|
||||
class="fa fa-fw fa-exchange"></i> {{ 'newTransfer'|_ }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="box-body no-padding">
|
||||
{% include 'list/journals-tiny.twig' with {'transactions': data[0],'account': data[1]} %}
|
||||
</div>
|
||||
<div class="box-footer clearfix">
|
||||
<a class="btn btn-sm btn-default btn-flat pull-right"
|
||||
href="{{ route('accounts.show',data[1].id) }}">{{ (data[1]|balance)|formatAmountPlain }}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@@ -187,28 +187,34 @@
|
||||
<script type="text/javascript" src="js/help.js"></script>
|
||||
{% block scripts %}{% endblock %}
|
||||
|
||||
{% if env('ANALYTICS_ID','') != '' %}
|
||||
<script>
|
||||
(function (i, s, o, g, r, a, m) {
|
||||
i['GoogleAnalyticsObject'] = r;
|
||||
i[r] = i[r] || function () {
|
||||
(i[r].q = i[r].q || []).push(arguments)
|
||||
}, i[r].l = 1 * new Date();
|
||||
a = s.createElement(o),
|
||||
m = s.getElementsByTagName(o)[0];
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m)
|
||||
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
|
||||
ga('create', '{{ env('ANALYTICS_ID', 'XXX-XX-X') }}', {'siteSpeedSampleRate': 100});
|
||||
ga('send', 'pageview');
|
||||
// send an event if relevant:
|
||||
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and not Session.has('gaEventLabel') %}
|
||||
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}');
|
||||
{% endif %}
|
||||
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and Session.has('gaEventLabel') %}
|
||||
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}', '{{ Session.get('gaEventLabel') }}');
|
||||
{% endif %}
|
||||
// send pageview
|
||||
(function (i, s, o, g, r, a, m) {
|
||||
i['GoogleAnalyticsObject'] = r;
|
||||
i[r] = i[r] || function () {
|
||||
(i[r].q = i[r].q || []).push(arguments)
|
||||
}, i[r].l = 1 * new Date();
|
||||
a = s.createElement(o),
|
||||
m = s.getElementsByTagName(o)[0];
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m)
|
||||
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
|
||||
ga('create', '{{ env('ANALYTICS_ID', 'XXX-XX-X') }}', {'siteSpeedSampleRate': 100});
|
||||
ga('send', 'pageview');
|
||||
|
||||
// send an event if relevant:
|
||||
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and not Session.has('gaEventLabel') %}
|
||||
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}');
|
||||
{% endif %}
|
||||
|
||||
// send event if relevant:
|
||||
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and Session.has('gaEventLabel') %}
|
||||
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}', '{{ Session.get('gaEventLabel') }}');
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -47,27 +47,33 @@
|
||||
<script type="text/javascript" src="js/jquery-2.1.3.min.js"></script>
|
||||
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<script>
|
||||
(function (i, s, o, g, r, a, m) {
|
||||
i['GoogleAnalyticsObject'] = r;
|
||||
i[r] = i[r] || function () {
|
||||
(i[r].q = i[r].q || []).push(arguments)
|
||||
}, i[r].l = 1 * new Date();
|
||||
a = s.createElement(o),
|
||||
m = s.getElementsByTagName(o)[0];
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m)
|
||||
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
|
||||
ga('create', '{{ env('ANALYTICS_ID', 'XXX-XX-X') }}', {'siteSpeedSampleRate': 100});
|
||||
ga('send', 'pageview');
|
||||
// send an event if relevant:
|
||||
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and not Session.has('gaEventLabel') %}
|
||||
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}');
|
||||
{% endif %}
|
||||
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and Session.has('gaEventLabel') %}
|
||||
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}', '{{ Session.get('gaEventLabel') }}');
|
||||
{% endif %}
|
||||
</script>
|
||||
{% if env('ANALYTICS_ID','') != '' %}
|
||||
<script>
|
||||
// send pageview
|
||||
(function (i, s, o, g, r, a, m) {
|
||||
i['GoogleAnalyticsObject'] = r;
|
||||
i[r] = i[r] || function () {
|
||||
(i[r].q = i[r].q || []).push(arguments)
|
||||
}, i[r].l = 1 * new Date();
|
||||
a = s.createElement(o),
|
||||
m = s.getElementsByTagName(o)[0];
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m)
|
||||
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
|
||||
ga('create', '{{ env('ANALYTICS_ID', 'XXX-XX-X') }}', {'siteSpeedSampleRate': 100});
|
||||
ga('send', 'pageview');
|
||||
|
||||
// send an event if relevant:
|
||||
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and not Session.has('gaEventLabel') %}
|
||||
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}');
|
||||
{% endif %}
|
||||
|
||||
// send event if relevant:
|
||||
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and Session.has('gaEventLabel') %}
|
||||
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}', '{{ Session.get('gaEventLabel') }}');
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endif %}
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -48,27 +48,33 @@
|
||||
<script type="text/javascript" src="js/jquery-2.1.3.min.js"></script>
|
||||
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<script>
|
||||
(function (i, s, o, g, r, a, m) {
|
||||
i['GoogleAnalyticsObject'] = r;
|
||||
i[r] = i[r] || function () {
|
||||
(i[r].q = i[r].q || []).push(arguments)
|
||||
}, i[r].l = 1 * new Date();
|
||||
a = s.createElement(o),
|
||||
m = s.getElementsByTagName(o)[0];
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m)
|
||||
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
|
||||
ga('create', '{{ env('ANALYTICS_ID', 'XXX-XX-X') }}', {'siteSpeedSampleRate': 100});
|
||||
ga('send', 'pageview');
|
||||
// send an event if relevant:
|
||||
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and not Session.has('gaEventLabel') %}
|
||||
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}');
|
||||
{% endif %}
|
||||
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and Session.has('gaEventLabel') %}
|
||||
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}', '{{ Session.get('gaEventLabel') }}');
|
||||
{% endif %}
|
||||
</script>
|
||||
{% if env('ANALYTICS_ID','') != '' %}
|
||||
<script>
|
||||
// send pageview
|
||||
(function (i, s, o, g, r, a, m) {
|
||||
i['GoogleAnalyticsObject'] = r;
|
||||
i[r] = i[r] || function () {
|
||||
(i[r].q = i[r].q || []).push(arguments)
|
||||
}, i[r].l = 1 * new Date();
|
||||
a = s.createElement(o),
|
||||
m = s.getElementsByTagName(o)[0];
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m)
|
||||
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
|
||||
ga('create', '{{ env('ANALYTICS_ID', 'XXX-XX-X') }}', {'siteSpeedSampleRate': 100});
|
||||
ga('send', 'pageview');
|
||||
|
||||
// send an event if relevant:
|
||||
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and not Session.has('gaEventLabel') %}
|
||||
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}');
|
||||
{% endif %}
|
||||
|
||||
// send event if relevant:
|
||||
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and Session.has('gaEventLabel') %}
|
||||
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}', '{{ Session.get('gaEventLabel') }}');
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endif %}
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -1,6 +1,7 @@
|
||||
{{ journals.render|raw }}
|
||||
|
||||
<table class="table table-hover sortable sortable-table">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr class="ignore">
|
||||
<th class="hidden-xs" colspan="2"> </th>
|
||||
<th>{{ trans('list.description') }}</th>
|
||||
@@ -23,6 +24,9 @@
|
||||
<th class="hidden-xs"><i class="fa fa-fw fa-rotate-right" title="{{ trans('list.bill') }}"></i></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% set _sum = 0 %}
|
||||
{% for journal in journals %}
|
||||
{% if invalidJournal(journal) %}
|
||||
<tr class="ignore">
|
||||
@@ -36,6 +40,7 @@
|
||||
<td colspan="7"><em>Invalid journal: Found {{ journal.transactions|length }} transaction(s)</em></td>
|
||||
</tr>
|
||||
{% else %}
|
||||
{% set _sum = _sum + journal.correct_amount %}
|
||||
<tr class="drag" data-date="{{ journal.date.format('Y-m-d') }}" data-id="{{ journal.id }}">
|
||||
<td class="hidden-xs">
|
||||
<div class="btn-group btn-group-xs">
|
||||
@@ -111,8 +116,28 @@
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
{% if showPageSum %}
|
||||
<tr>
|
||||
<td colspan="3" style="text-align: right;"><em>{{ 'sum'|_ }}</em></td>
|
||||
<td colspan="2">{{ _sum|formatAmount }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if showPeriodSum %}
|
||||
<tr>
|
||||
<td colspan="3" style="text-align: right;"><em>{{ 'period_sum'|_ }}</em></td>
|
||||
<td colspan="2">{{ periodSum|formatAmount }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if showTotalSum %}
|
||||
<tr>
|
||||
<td colspan="3" style="text-align: right;"><em>{{ 'total_sum'|_ }}</em></td>
|
||||
<td colspan="2">{{ totalSum|formatAmount }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
{{ journals.render|raw }}
|
||||
|
@@ -16,14 +16,14 @@
|
||||
<td>
|
||||
<a href="{{ route('categories.show',cat.id) }}">{{ cat.name }}</a>
|
||||
</td>
|
||||
<td><span class="text-danger">{{ (cat.spent)|formatAmountPlain }}</span></td>
|
||||
<td><span class="text-danger">{{ (cat.spent * -1)|formatAmountPlain }}</span></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td><em>{{ 'sum'|_ }}</em></td>
|
||||
<td class="text-danger">{{ categories.getTotal|formatAmountPlain }}</td>
|
||||
<td class="text-danger">{{ (categories.getTotal * -1)|formatAmountPlain }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
@@ -56,19 +56,38 @@
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'categories'|_ }}</h3>
|
||||
<h3 class="box-title">{{ 'categories_spent_in_year'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
{% if Config.get('firefly.chart') == 'google' %}
|
||||
<div id="categories"></div>
|
||||
<div id="categories-spent-in-year"></div>
|
||||
{% endif %}
|
||||
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||
<canvas id="categories" style="width:100%;height:400px;"></canvas>
|
||||
<canvas id="categories-spent-in-year" style="width:100%;height:400px;"></canvas>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'categories_earned_in_year'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
{% if Config.get('firefly.chart') == 'google' %}
|
||||
<div id="categories-earned-in-year"></div>
|
||||
{% endif %}
|
||||
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||
<canvas id="categories-earned-in-year" style="width:100%;height:400px;"></canvas>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<div class="box">
|
||||
|
Reference in New Issue
Block a user