Compare commits

...

39 Commits

Author SHA1 Message Date
James Cole
d485270e1f Merge branch 'release/3.5.0' 2015-08-13 17:37:55 +02:00
James Cole
3716668e0c Updated read me. 2015-08-13 17:37:45 +02:00
James Cole
ae7fd18c34 New composer file. 2015-08-13 17:35:48 +02:00
James Cole
4f59b1d32f No Google thing when no Analytics ID present. 2015-08-13 17:35:41 +02:00
James Cole
90cb3279df Better example env file. 2015-08-13 17:34:08 +02:00
James Cole
cf0c7ef6b2 New version. 2015-08-13 17:32:22 +02:00
James Cole
47c23781d9 Fixed password reset. 2015-08-13 17:32:15 +02:00
James Cole
e258c050f7 Merge branch 'release/3.4.11' 2015-08-10 20:13:38 +02:00
James Cole
57801b2f34 Merge branch 'release/3.4.11' into develop 2015-08-10 20:13:38 +02:00
James Cole
710e9c9423 new version. 2015-08-10 20:13:33 +02:00
James Cole
deefef83bd Added sum for the current period, see issue #99 2015-08-09 17:01:12 +02:00
James Cole
51e30aed66 Added a sum of the current page and the sum of the entire category, in reference to issue #99. 2015-08-09 16:56:38 +02:00
James Cole
8d109a3cfe Fixed a null pointer exception. 2015-08-09 13:54:58 +02:00
James Cole
3424e019b5 Removed animation, again [skip ci] 2015-08-06 16:39:53 +02:00
James Cole
c6b4bceb67 Animation test [skip ci] 2015-08-06 16:39:06 +02:00
James Cole
afb4155015 Remove animation thing. [skip ci] 2015-08-06 16:37:53 +02:00
James Cole
8d99baf38a Update charts.js 2015-08-05 09:02:33 +02:00
James Cole
b91cb60328 Fix translations [skip ci] 2015-08-02 09:01:13 +02:00
James Cole
c0d62237fc Made the date thing throw a FF error. 2015-08-02 08:53:34 +02:00
James Cole
223ea80860 Fixed some embarrassing spelling errors in the CSV importer. [skip ci] 2015-08-02 08:53:19 +02:00
James Cole
5a77bef494 Sort chart and code cleanup [skip ci] 2015-08-02 07:41:47 +02:00
James Cole
80c0efe821 Small rearrangement of front page boxes. [skip ci] 2015-08-02 07:35:09 +02:00
James Cole
8044d89557 Display correct amount [skip ci] 2015-08-02 07:08:47 +02:00
James Cole
4f0ed97410 Fixed a bug where the category list in a monthly report would be empty. 2015-08-02 07:04:43 +02:00
James Cole
af7952f204 Removed old references to Google [skip ci] 2015-08-01 07:22:48 +02:00
James Cole
d8dcae856b Remove log. 2015-08-01 07:12:34 +02:00
James Cole
7296796ed9 Fix chart. 2015-08-01 07:12:03 +02:00
James Cole
a2c2bb4948 Forgot a dot [skip ci] 2015-08-01 07:09:51 +02:00
James Cole
72ebfdc20e Debug log. 2015-08-01 07:09:12 +02:00
James Cole
16b95ea78a New chart. 2015-08-01 07:04:41 +02:00
James Cole
c04f08dfd8 Filter empty budgets. 2015-07-31 18:18:54 +02:00
James Cole
a30793e818 Fix chart. Related to #99 2015-07-31 18:14:24 +02:00
James Cole
e39e1eaf21 Included opening balance. 2015-07-31 18:10:55 +02:00
James Cole
ab22d2cbaa Fixed the overview chart for categories, so it will properly reflect income and expenses. See bug #99 2015-07-31 14:26:22 +02:00
James Cole
96ddbe7227 Reorganized the category charts in the year report to properly reflect income and expenses. Necessary to facilitate the changes needed for bug #99 2015-07-31 14:20:18 +02:00
James Cole
4d09235aef Update composer.lock 2015-07-31 14:17:49 +02:00
James Cole
136b8975e3 Sort piggy bank list. 2015-07-31 13:44:56 +02:00
James Cole
e21b1eca17 Remove script. 2015-07-31 07:31:05 +02:00
James Cole
244b90b1d4 Fix bug #98 2015-07-30 21:32:58 +02:00
56 changed files with 806 additions and 1225 deletions

View File

@@ -1,6 +1,6 @@
APP_ENV=production APP_ENV=production
APP_DEBUG=false APP_DEBUG=false
APP_KEY=SomeRandomString APP_KEY=SomeRandomStringOf32CharsExactly
DB_CONNECTION=mysql DB_CONNECTION=mysql
DB_HOST=localhost DB_HOST=localhost

View File

@@ -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)**. and the **[first use guide](https://github.com/JC5/firefly-iii/wiki/First-use)**.
If you want to try out Firefly III, you can do so on [this dedicated website](https://geld.nder.be/). If you want to try out Firefly III, you can do so on [this dedicated website](https://geld.nder.be/).
This site always runs the latest version of Firefly III. If you want to use it, please read the [privacy considerations](https://github.com/JC5/firefly-iii/wiki/Privacy-on-demo-site) for this demo-site. This site always runs the latest version of Firefly III. If you want to use it, please read the [privacy considerations](https://github.com/JC5/firefly-iii/wiki/Privacy-on-demo-site) for this demo-site. Accounts on the demo sites will stop working after one week.
## Credits ## Credits

View File

@@ -40,4 +40,13 @@ interface AccountChartGenerator
* @return array * @return array
*/ */
public function single(Account $account, Carbon $start, Carbon $end); 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);
} }

View File

@@ -32,6 +32,65 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
return $this->frontpage($accounts, $start, $end); 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 Collection $accounts
* @param Carbon $start * @param Carbon $start

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -40,5 +40,13 @@ interface CategoryChartGenerator
* *
* @return array * @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);
} }

View File

@@ -29,19 +29,30 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
$format = Config::get('firefly.' . $dateFormat . '.' . $language); $format = Config::get('firefly.' . $dateFormat . '.' . $language);
$data = [ $data = [
'count' => 1, 'count' => 2,
'labels' => [], 'labels' => [],
'datasets' => [ 'datasets' => [
[ [
'label' => trans('firefly.spent'), 'label' => trans('firefly.spent'),
'data' => [] 'data' => []
],
[
'label' => trans('firefly.earned'),
'data' => []
] ]
], ],
]; ];
foreach ($entries as $entry) { foreach ($entries as $entry) {
$data['labels'][] = $entry[0]->formatLocalized($format); $data['labels'][] = $entry[0]->formatLocalized($format);
$data['datasets'][0]['data'][] = round($entry[1], 2); $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; return $data;
@@ -93,7 +104,41 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
* *
* @return array * @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: // language:

View File

@@ -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();
}
}

View File

@@ -9,7 +9,7 @@ use Preferences;
/** /**
* Class GooglePiggyBankChartGenerator * Class ChartJsPiggyBankChartGenerator
* *
* @package FireflyIII\Generator\Chart\PiggyBank * @package FireflyIII\Generator\Chart\PiggyBank
*/ */

View File

@@ -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();
}
}

View File

@@ -7,7 +7,7 @@ use Illuminate\Support\Collection;
use Preferences; use Preferences;
/** /**
* Class GoogleReportChartGenerator * Class ChartJsReportChartGenerator
* *
* @package FireflyIII\Generator\Chart\Report * @package FireflyIII\Generator\Chart\Report
*/ */

View File

@@ -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();
}
}

View File

@@ -34,7 +34,8 @@ class Category
*/ */
public function addCategory(CategoryModel $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); $this->categories->push($category);
} }
} }

View File

@@ -3,6 +3,9 @@
namespace FireflyIII\Helpers\Csv\Converter; namespace FireflyIII\Helpers\Csv\Converter;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use InvalidArgumentException;
use Log;
use Session; use Session;
/** /**
@@ -19,8 +22,16 @@ class Date extends BasicConverter implements ConverterInterface
public function convert() public function convert()
{ {
$format = Session::get('csv-date-format'); $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; return $date;
} }

View File

@@ -124,7 +124,7 @@ class Importer
*/ */
protected function parseRow($index) protected function parseRow($index)
{ {
return (($this->data->hasHeaders() && $index > 1) || !$this->data->hasHeaders()); return (($this->data->hasHeaders() && $index >= 1) || !$this->data->hasHeaders());
} }
/** /**

View File

@@ -263,7 +263,7 @@ class ReportHelper implements ReportHelperInterface
// no repetition(s) for this budget: // no repetition(s) for this budget:
if ($repetitions->count() == 0) { if ($repetitions->count() == 0) {
$spent = $repository->spentInPeriodCorrected($budget, $start, $end, $shared); $spent = $repository->balanceInPeriod($budget, $start, $end, $shared);
$budgetLine = new BudgetLine; $budgetLine = new BudgetLine;
$budgetLine->setBudget($budget); $budgetLine->setBudget($budget);
$budgetLine->setOverspent($spent); $budgetLine->setOverspent($spent);
@@ -278,7 +278,7 @@ class ReportHelper implements ReportHelperInterface
$budgetLine = new BudgetLine; $budgetLine = new BudgetLine;
$budgetLine->setBudget($budget); $budgetLine->setBudget($budget);
$budgetLine->setRepetition($repetition); $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; $left = $expenses < $repetition->amount ? bcsub($repetition->amount, $expenses) : 0;
$spent = $expenses > $repetition->amount ? 0 : $expenses; $spent = $expenses > $repetition->amount ? 0 : $expenses;
$overspent = $expenses > $repetition->amount ? bcsub($expenses, $repetition->amount) : 0; $overspent = $expenses > $repetition->amount ? bcsub($expenses, $repetition->amount) : 0;
@@ -327,7 +327,7 @@ class ReportHelper implements ReportHelperInterface
$repository = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface'); $repository = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
$set = $repository->getCategories(); $set = $repository->getCategories();
foreach ($set as $category) { foreach ($set as $category) {
$spent = $repository->spentInPeriodCorrected($category, $start, $end, $shared); $spent = $repository->balanceInPeriod($category, $start, $end, $shared);
$category->spent = $spent; $category->spent = $spent;
$object->addCategory($category); $object->addCategory($category);
$object->addTotal($spent); $object->addTotal($spent);

View File

@@ -152,7 +152,7 @@ class BudgetController extends Controller
foreach ($budgets as $budget) { foreach ($budgets as $budget) {
$date = Session::get('start', Carbon::now()->startOfMonth()); $date = Session::get('start', Carbon::now()->startOfMonth());
$end = Session::get('end', Carbon::now()->endOfMonth()); $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); $budget->currentRep = $repository->getCurrentRepetition($budget, $date);
if ($budget->currentRep) { if ($budget->currentRep) {
$budgeted = bcadd($budgeted, $budget->currentRep->amount); $budgeted = bcadd($budgeted, $budget->currentRep->amount);

View File

@@ -151,10 +151,12 @@ class CategoryController extends Controller
$page = intval(Input::get('page')); $page = intval(Input::get('page'));
$set = $repository->getJournals($category, $page); $set = $repository->getJournals($category, $page);
$count = $repository->countJournals($category); $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 = new LengthAwarePaginator($set, $count, 50, $page);
$journals->setPath('categories/show/' . $category->id); $journals->setPath('categories/show/' . $category->id);
return view('categories.show', compact('category', 'journals', 'hideCategory')); return view('categories.show', compact('category', 'journals', 'hideCategory', 'totalSum', 'periodSum'));
} }
/** /**

View File

@@ -79,6 +79,36 @@ class AccountController extends Controller
return Response::json($data); 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. * Shows the balances for all the user's frontpage accounts.
* *

View File

@@ -68,7 +68,7 @@ class BudgetController extends Controller
$end->subDay(); $end->subDay();
$chartDate = clone $end; $chartDate = clone $end;
$chartDate->startOfMonth(); $chartDate->startOfMonth();
$spent = $repository->spentInPeriodCorrected($budget, $first, $end); $spent = $repository->balanceInPeriod($budget, $first, $end);
$entries->push([$chartDate, $spent]); $entries->push([$chartDate, $spent]);
$first = Navigation::addPeriod($first, $range, 0); $first = Navigation::addPeriod($first, $range, 0);
} }
@@ -156,13 +156,13 @@ class BudgetController extends Controller
foreach ($budgets as $budget) { foreach ($budgets as $budget) {
$repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end); $repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end);
if ($repetitions->count() == 0) { if ($repetitions->count() == 0) {
$expenses = $repository->spentInPeriodCorrected($budget, $start, $end, true); $expenses = $repository->balanceInPeriod($budget, $start, $end, true);
$allEntries->push([$budget->name, 0, 0, $expenses, 0, 0]); $allEntries->push([$budget->name, 0, 0, $expenses, 0, 0]);
continue; continue;
} }
/** @var LimitRepetition $repetition */ /** @var LimitRepetition $repetition */
foreach ($repetitions as $repetition) { foreach ($repetitions as $repetition) {
$expenses = $repository->spentInPeriodCorrected($budget, $repetition->startdate, $repetition->enddate, true); $expenses = $repository->balanceInPeriod($budget, $repetition->startdate, $repetition->enddate, true);
// $left can be less than zero. // $left can be less than zero.
// $overspent can be more than zero ( = overspending) // $overspent can be more than zero ( = overspending)
@@ -199,10 +199,11 @@ class BudgetController extends Controller
*/ */
public function year(BudgetRepositoryInterface $repository, $year, $shared = false) public function year(BudgetRepositoryInterface $repository, $year, $shared = false)
{ {
$start = new Carbon($year . '-01-01'); $start = new Carbon($year . '-01-01');
$end = new Carbon($year . '-12-31'); $end = new Carbon($year . '-12-31');
$shared = $shared == 'shared' ? true : false; $shared = $shared == 'shared' ? true : false;
$budgets = $repository->getBudgets(); $allBudgets = $repository->getBudgets();
$budgets = new Collection;
// chart properties for cache: // chart properties for cache:
$cache = new CacheProperties(); $cache = new CacheProperties();
@@ -214,6 +215,15 @@ class BudgetController extends Controller
return Response::json($cache->get()); // @codeCoverageIgnore 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; $entries = new Collection;
while ($start < $end) { while ($start < $end) {
@@ -224,14 +234,14 @@ class BudgetController extends Controller
// each budget, fill the row: // each budget, fill the row:
foreach ($budgets as $budget) { foreach ($budgets as $budget) {
$spent = $repository->spentInPeriodCorrected($budget, $start, $month, $shared); $spent = $repository->balanceInPeriod($budget, $start, $month, $shared);
$row[] = $spent; $row[] = $spent * -1;
} }
$entries->push($row); $entries->push($row);
$start->endOfMonth()->addDay(); $start->endOfMonth()->addDay();
} }
$data = $this->generator->year($budgets, $entries); $data = $this->generator->year($allBudgets, $entries);
$cache->store($data); $cache->store($data);
return Response::json($data); return Response::json($data);

View File

@@ -46,11 +46,10 @@ class CategoryController extends Controller
public function all(CategoryRepositoryInterface $repository, Category $category) public function all(CategoryRepositoryInterface $repository, Category $category)
{ {
// oldest transaction in category: // oldest transaction in category:
$start = $repository->getFirstActivityDate($category); $start = $repository->getFirstActivityDate($category);
$range = Preferences::get('viewRange', '1M')->data; $range = Preferences::get('viewRange', '1M')->data;
$start = Navigation::startOfPeriod($start, $range); $start = Navigation::startOfPeriod($start, $range);
$end = new Carbon; $end = new Carbon;
$entries = new Collection; $entries = new Collection;
@@ -66,7 +65,7 @@ class CategoryController extends Controller
while ($start <= $end) { while ($start <= $end) {
$currentEnd = Navigation::endOfPeriod($start, $range); $currentEnd = Navigation::endOfPeriod($start, $range);
$spent = $repository->spentInPeriodCorrected($category, $start, $currentEnd); $spent = $repository->balanceInPeriod($category, $start, $currentEnd);
$entries->push([clone $start, $spent]); $entries->push([clone $start, $spent]);
$start = Navigation::addPeriod($start, $range, 0); $start = Navigation::addPeriod($start, $range, 0);
@@ -170,7 +169,7 @@ class CategoryController extends Controller
* *
* @return \Symfony\Component\HttpFoundation\Response * @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'); $start = new Carbon($year . '-01-01');
$end = new Carbon($year . '-12-31'); $end = new Carbon($year . '-12-31');
@@ -179,14 +178,24 @@ class CategoryController extends Controller
$cache->addProperty($start); $cache->addProperty($start);
$cache->addProperty($end); $cache->addProperty($end);
$cache->addProperty('category'); $cache->addProperty('category');
$cache->addProperty('year'); $cache->addProperty('spent-in-year');
if ($cache->has()) { if ($cache->has()) {
return Response::json($cache->get()); // @codeCoverageIgnore return Response::json($cache->get()); // @codeCoverageIgnore
} }
$shared = $shared == 'shared' ? true : false; $shared = $shared == 'shared' ? true : false;
$categories = $repository->getCategories(); $allCategories = $repository->getCategories();
$entries = new Collection; $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) { while ($start < $end) {
$month = clone $start; // month is the current end of the period $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: $row = [clone $start]; // make a row:
foreach ($categories as $category) { // each budget, fill the row foreach ($categories as $category) { // each budget, fill the row
$spent = $repository->spentInPeriodCorrected($category, $start, $month, $shared); $spent = $repository->balanceInPeriod($category, $start, $month, $shared);
$row[] = $spent; if ($spent < 0) {
$row[] = $spent * -1;
} else {
$row[] = 0;
}
} }
$entries->push($row); $entries->push($row);
$start->addMonth(); $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); $cache->store($data);
return Response::json($data); return Response::json($data);

View File

@@ -79,18 +79,16 @@ class HomeController extends Controller
return redirect(route('new-user.index')); return redirect(route('new-user.index'));
} }
$title = 'Firefly'; $title = 'Firefly';
$subTitle = trans('firefly.welcomeBack'); $subTitle = trans('firefly.welcomeBack');
$mainTitleIcon = 'fa-fire'; $mainTitleIcon = 'fa-fire';
$transactions = []; $transactions = [];
$frontPage = Preferences::get('frontPageAccounts', []); $frontPage = Preferences::get('frontPageAccounts', []);
$start = Session::get('start', Carbon::now()->startOfMonth()); $start = Session::get('start', Carbon::now()->startOfMonth());
$end = Session::get('end', Carbon::now()->endOfMonth()); $end = Session::get('end', Carbon::now()->endOfMonth());
$showTour = Preferences::get('tour', true)->data; $showTour = Preferences::get('tour', true)->data;
$accounts = $repository->getFrontpageAccounts($frontPage);
$accounts = $repository->getFrontpageAccounts($frontPage); $savings = $repository->getSavingsAccounts();
$savings = $repository->getSavingsAccounts();
$piggyBankAccounts = $repository->getPiggyBankAccounts(); $piggyBankAccounts = $repository->getPiggyBankAccounts();

View File

@@ -190,7 +190,8 @@ class TagController extends Controller
$tags = Auth::user()->tags()->where('tagMode', $type)->orderBy('date', 'ASC')->get(); $tags = Auth::user()->tags()->where('tagMode', $type)->orderBy('date', 'ASC')->get();
$tags = $tags->sortBy( $tags = $tags->sortBy(
function (Tag $tag) { function (Tag $tag) {
$date = $tag->date->format('Ymd'); $date = !is_null($tag->date) ? $tag->date->format('Ymd') : '000000';
return strtolower($date . $tag->tag); return strtolower($date . $tag->tag);
} }

View File

@@ -1,5 +1,6 @@
<?php namespace FireflyIII\Http\Controllers; <?php namespace FireflyIII\Http\Controllers;
use Amount;
use Auth; use Auth;
use Carbon\Carbon; use Carbon\Carbon;
use Config; use Config;
@@ -8,6 +9,7 @@ use FireflyIII\Events\JournalCreated;
use FireflyIII\Events\JournalSaved; use FireflyIII\Events\JournalSaved;
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
use FireflyIII\Http\Requests\JournalFormRequest; use FireflyIII\Http\Requests\JournalFormRequest;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
@@ -51,11 +53,19 @@ class TransactionController extends Controller
$accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account'])); $accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account']));
$budgets = ExpandedForm::makeSelectList(Auth::user()->budgets()->get()); $budgets = ExpandedForm::makeSelectList(Auth::user()->budgets()->get());
$budgets[0] = trans('form.noBudget'); $budgets[0] = trans('form.noBudget');
$piggies = ExpandedForm::makeSelectList(Auth::user()->piggyBanks()->get());
$piggies[0] = trans('form.noPiggybank'); // piggy bank list:
$preFilled = Session::has('preFilled') ? Session::get('preFilled') : []; $piggyBanks = Auth::user()->piggyBanks()->orderBy('order', 'ASC')->get();
$respondTo = ['account_id', 'account_from_id']; /** @var PiggyBank $piggy */
$subTitle = trans('form.add_new_' . $what); 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) { foreach ($respondTo as $r) {
$preFilled[$r] = Input::get($r); $preFilled[$r] = Input::get($r);

View File

@@ -162,7 +162,7 @@ Route::get('/cron/sendgrid', ['uses' => 'CronController@sendgrid']);
Route::controllers( Route::controllers(
[ [
'auth' => 'Auth\AuthController', 'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController', 'password' => 'Auth\PasswordController',
] ]
); );
@@ -282,6 +282,7 @@ Route::group(
*/ */
// accounts: // accounts:
Route::get('/chart/account/frontpage', ['uses' => 'Chart\AccountController@frontpage']); 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( Route::get('/chart/account/month/{year}/{month}/{shared?}', ['uses' => 'Chart\AccountController@all'])->where(
['year' => '[0-9]{4}', 'month' => '[0-9]{1,2}', 'shared' => 'shared'] ['year' => '[0-9]{4}', 'month' => '[0-9]{1,2}', 'shared' => 'shared']
); );
@@ -300,7 +301,12 @@ Route::group(
// categories: // categories:
Route::get('/chart/category/frontpage', ['uses' => 'Chart\CategoryController@frontpage']); 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}/month', ['uses' => 'Chart\CategoryController@month']); // should be period.
Route::get('/chart/category/{category}/all', ['uses' => 'Chart\CategoryController@all']); Route::get('/chart/category/{category}/all', ['uses' => 'Chart\CategoryController@all']);

View File

@@ -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 whereUserId($value)
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereEncrypted($value) * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereEncrypted($value)
* @property-read float $spent * @property-read float $spent
* @property-read \Carbon\Carbon $lastActivity * @property \Carbon\Carbon $lastActivity
*/ */
class Category extends Model class Category extends Model
{ {

View File

@@ -98,7 +98,6 @@ class FireflyServiceProvider extends ServiceProvider
$this->app->bind('FireflyIII\Helpers\Attachments\AttachmentHelperInterface', 'FireflyIII\Helpers\Attachments\AttachmentHelper'); $this->app->bind('FireflyIII\Helpers\Attachments\AttachmentHelperInterface', 'FireflyIII\Helpers\Attachments\AttachmentHelper');
// make charts: // 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\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\Bill\BillChartGenerator', 'FireflyIII\Generator\Chart\Bill\ChartJsBillChartGenerator');
$this->app->bind('FireflyIII\Generator\Chart\Budget\BudgetChartGenerator', 'FireflyIII\Generator\Chart\Budget\ChartJsBudgetChartGenerator'); $this->app->bind('FireflyIII\Generator\Chart\Budget\BudgetChartGenerator', 'FireflyIII\Generator\Chart\Budget\ChartJsBudgetChartGenerator');

View File

@@ -313,9 +313,9 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
* *
* @return string * @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);
} }
/** /**

View File

@@ -136,7 +136,7 @@ interface BudgetRepositoryInterface
* *
* @return string * @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 * @param array $data

View File

@@ -57,6 +57,7 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito
return $set; return $set;
} }
/** /**
* *
* @param Carbon $start * @param Carbon $start
@@ -64,7 +65,7 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito
* *
* @return array * @return array
*/ */
public function getCategoriesAndExpensesCorrected($start, $end) public function getCategoriesAndExpensesCorrected(Carbon $start, Carbon $end)
{ {
$set = Auth::user()->transactionjournals() $set = Auth::user()->transactionjournals()
->leftJoin( ->leftJoin(
@@ -183,9 +184,9 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito
* *
* @return string * @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) 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; 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');
}
} }

View File

@@ -40,7 +40,7 @@ interface CategoryRepositoryInterface
* *
* @return array * @return array
*/ */
public function getCategoriesAndExpensesCorrected($start, $end); public function getCategoriesAndExpensesCorrected(Carbon $start, Carbon $end);
/** /**
* @param Category $category * @param Category $category
@@ -57,6 +57,18 @@ interface CategoryRepositoryInterface
*/ */
public function getJournals(Category $category, $page); 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 * @param Category $category
* *
@@ -83,7 +95,7 @@ interface CategoryRepositoryInterface
* *
* @return string * @return string
*/ */
public function spentInPeriodCorrected(Category $category, Carbon $start, Carbon $end, $shared = false); public function balanceInPeriod(Category $category, Carbon $start, Carbon $end, $shared = false);
/** /**
* *

View File

@@ -24,7 +24,7 @@ class ComponentRepository
* *
* @return string * @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 = new CacheProperties; // we must cache this.
$cache->addProperty($object->id); $cache->addProperty($object->id);
@@ -32,7 +32,7 @@ class ComponentRepository
$cache->addProperty($start); $cache->addProperty($start);
$cache->addProperty($end); $cache->addProperty($end);
$cache->addProperty($shared); $cache->addProperty($shared);
$cache->addProperty('spentInPeriod'); $cache->addProperty('balanceInPeriod');
if ($cache->has()) { if ($cache->has()) {
return $cache->get(); // @codeCoverageIgnore return $cache->get(); // @codeCoverageIgnore
@@ -45,14 +45,14 @@ class ComponentRepository
// do something else, SEE budgets. // do something else, SEE budgets.
// get all journals in this month where the asset account is NOT shared. // get all journals in this month where the asset account is NOT shared.
$sum = $object->transactionjournals()->before($end)->after($start) $sum = $object->transactionjournals()->before($end)->after($start)
->transactionTypes(['Withdrawal'])
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
->transactionTypes(['Withdrawal', 'Deposit', 'Opening balance'])
->leftJoin( ->leftJoin(
'account_meta', function (JoinClause $join) { 'account_meta', function (JoinClause $join) {
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole'); $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); $cache->store($sum);

214
composer.lock generated
View File

@@ -62,26 +62,26 @@
}, },
{ {
"name": "codeception/codeception", "name": "codeception/codeception",
"version": "2.1.1", "version": "2.1.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/Codeception/Codeception.git", "url": "https://github.com/Codeception/Codeception.git",
"reference": "6c22380326421947fba0d6116c13a5c24d214adb" "reference": "521adbb2ee34e9debdd8508a2c41ab2b5c2f042b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/6c22380326421947fba0d6116c13a5c24d214adb", "url": "https://api.github.com/repos/Codeception/Codeception/zipball/521adbb2ee34e9debdd8508a2c41ab2b5c2f042b",
"reference": "6c22380326421947fba0d6116c13a5c24d214adb", "reference": "521adbb2ee34e9debdd8508a2c41ab2b5c2f042b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-json": "*", "ext-json": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"facebook/webdriver": "~1.0", "facebook/webdriver": ">=1.0.1",
"guzzlehttp/guzzle": ">=4.0|<7.0", "guzzlehttp/guzzle": ">=4.0|<7.0",
"guzzlehttp/psr7": "~1.0", "guzzlehttp/psr7": "~1.0",
"php": ">=5.4.0", "php": ">=5.4.0",
"phpunit/phpunit": "~4.7.0", "phpunit/phpunit": "~4.8.0",
"symfony/browser-kit": "~2.4", "symfony/browser-kit": "~2.4",
"symfony/console": "~2.4", "symfony/console": "~2.4",
"symfony/css-selector": "~2.4", "symfony/css-selector": "~2.4",
@@ -138,7 +138,7 @@
"functional testing", "functional testing",
"unit testing" "unit testing"
], ],
"time": "2015-07-14 11:24:17" "time": "2015-08-09 13:48:55"
}, },
{ {
"name": "danielstjules/stringy", "name": "danielstjules/stringy",
@@ -803,16 +803,16 @@
}, },
{ {
"name": "facebook/webdriver", "name": "facebook/webdriver",
"version": "1.0.1", "version": "1.0.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/facebook/php-webdriver.git", "url": "https://github.com/facebook/php-webdriver.git",
"reference": "8eb1952d6be0725e1064c4fe0630d0d4d1de7639" "reference": "fe1bbbc5dde804d08a8593f1d9d0d3b05f5c84f5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/8eb1952d6be0725e1064c4fe0630d0d4d1de7639", "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/fe1bbbc5dde804d08a8593f1d9d0d3b05f5c84f5",
"reference": "8eb1952d6be0725e1064c4fe0630d0d4d1de7639", "reference": "fe1bbbc5dde804d08a8593f1d9d0d3b05f5c84f5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -842,7 +842,7 @@
"selenium", "selenium",
"webdriver" "webdriver"
], ],
"time": "2015-07-16 19:31:12" "time": "2015-08-12 20:21:31"
}, },
{ {
"name": "grumpydictator/gchart", "name": "grumpydictator/gchart",
@@ -1244,16 +1244,16 @@
}, },
{ {
"name": "laravel/framework", "name": "laravel/framework",
"version": "v5.1.8", "version": "v5.1.10",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/framework.git", "url": "https://github.com/laravel/framework.git",
"reference": "c4ce8d7a3ac6e655e8b5f0ff3ee07d24fab765ba" "reference": "d47ccc8de10ccb6f328cc90f901ca5e47e077c93"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/c4ce8d7a3ac6e655e8b5f0ff3ee07d24fab765ba", "url": "https://api.github.com/repos/laravel/framework/zipball/d47ccc8de10ccb6f328cc90f901ca5e47e077c93",
"reference": "c4ce8d7a3ac6e655e8b5f0ff3ee07d24fab765ba", "reference": "d47ccc8de10ccb6f328cc90f901ca5e47e077c93",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1368,7 +1368,7 @@
"framework", "framework",
"laravel" "laravel"
], ],
"time": "2015-07-21 18:33:13" "time": "2015-08-12 18:16:08"
}, },
{ {
"name": "league/commonmark", "name": "league/commonmark",
@@ -1488,16 +1488,16 @@
}, },
{ {
"name": "league/flysystem", "name": "league/flysystem",
"version": "1.0.10", "version": "1.0.11",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/flysystem.git", "url": "https://github.com/thephpleague/flysystem.git",
"reference": "3475ce0b1b5cab41f012905c4c58ad645088f7c9" "reference": "c16222fdc02467eaa12cb6d6d0e65527741f6040"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3475ce0b1b5cab41f012905c4c58ad645088f7c9", "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/c16222fdc02467eaa12cb6d6d0e65527741f6040",
"reference": "3475ce0b1b5cab41f012905c4c58ad645088f7c9", "reference": "c16222fdc02467eaa12cb6d6d0e65527741f6040",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1565,20 +1565,20 @@
"sftp", "sftp",
"storage" "storage"
], ],
"time": "2015-07-21 19:35:53" "time": "2015-07-28 20:41:58"
}, },
{ {
"name": "monolog/monolog", "name": "monolog/monolog",
"version": "1.15.0", "version": "1.16.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/Seldaek/monolog.git", "url": "https://github.com/Seldaek/monolog.git",
"reference": "dc5150cc608f2334c72c3b6a553ec9668a4156b0" "reference": "c0c0b4bee3aabce7182876b0d912ef2595563db7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/dc5150cc608f2334c72c3b6a553ec9668a4156b0", "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c0c0b4bee3aabce7182876b0d912ef2595563db7",
"reference": "dc5150cc608f2334c72c3b6a553ec9668a4156b0", "reference": "c0c0b4bee3aabce7182876b0d912ef2595563db7",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1615,7 +1615,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.15.x-dev" "dev-master": "1.16.x-dev"
} }
}, },
"autoload": { "autoload": {
@@ -1641,7 +1641,7 @@
"logging", "logging",
"psr-3" "psr-3"
], ],
"time": "2015-07-12 13:54:09" "time": "2015-08-09 17:44:44"
}, },
{ {
"name": "mtdowling/cron-expression", "name": "mtdowling/cron-expression",
@@ -1830,16 +1830,16 @@
}, },
{ {
"name": "phpspec/prophecy", "name": "phpspec/prophecy",
"version": "v1.4.1", "version": "v1.5.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpspec/prophecy.git", "url": "https://github.com/phpspec/prophecy.git",
"reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373" "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373", "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7",
"reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373", "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1886,20 +1886,20 @@
"spy", "spy",
"stub" "stub"
], ],
"time": "2015-04-27 22:15:08" "time": "2015-08-13 10:07:40"
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
"version": "2.1.9", "version": "2.2.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "5bd48b86cd282da411bb80baac1398ce3fefac41" "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5bd48b86cd282da411bb80baac1398ce3fefac41", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2d7c03c0e4e080901b8f33b2897b0577be18a13c",
"reference": "5bd48b86cd282da411bb80baac1398ce3fefac41", "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1907,7 +1907,7 @@
"phpunit/php-file-iterator": "~1.3", "phpunit/php-file-iterator": "~1.3",
"phpunit/php-text-template": "~1.2", "phpunit/php-text-template": "~1.2",
"phpunit/php-token-stream": "~1.3", "phpunit/php-token-stream": "~1.3",
"sebastian/environment": "~1.0", "sebastian/environment": "^1.3.2",
"sebastian/version": "~1.0" "sebastian/version": "~1.0"
}, },
"require-dev": { "require-dev": {
@@ -1922,7 +1922,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.1.x-dev" "dev-master": "2.2.x-dev"
} }
}, },
"autoload": { "autoload": {
@@ -1948,7 +1948,7 @@
"testing", "testing",
"xunit" "xunit"
], ],
"time": "2015-07-26 12:54:47" "time": "2015-08-04 03:42:39"
}, },
{ {
"name": "phpunit/php-file-iterator", "name": "phpunit/php-file-iterator",
@@ -2081,16 +2081,16 @@
}, },
{ {
"name": "phpunit/php-token-stream", "name": "phpunit/php-token-stream",
"version": "1.4.3", "version": "1.4.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git", "url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9" "reference": "09fc125d65c344c53a7c7ad8f261e3f3af9f76c5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/7a9b0969488c3c54fd62b4d504b3ec758fd005d9", "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/09fc125d65c344c53a7c7ad8f261e3f3af9f76c5",
"reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9", "reference": "09fc125d65c344c53a7c7ad8f261e3f3af9f76c5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2126,20 +2126,20 @@
"keywords": [ "keywords": [
"tokenizer" "tokenizer"
], ],
"time": "2015-06-19 03:43:16" "time": "2015-08-13 14:23:08"
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "4.7.7", "version": "4.8.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "9b97f9d807b862c2de2a36e86690000801c85724" "reference": "fd3050e26e3105f416d74c4d33aea659b406c59d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9b97f9d807b862c2de2a36e86690000801c85724", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fd3050e26e3105f416d74c4d33aea659b406c59d",
"reference": "9b97f9d807b862c2de2a36e86690000801c85724", "reference": "fd3050e26e3105f416d74c4d33aea659b406c59d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2149,7 +2149,7 @@
"ext-reflection": "*", "ext-reflection": "*",
"ext-spl": "*", "ext-spl": "*",
"php": ">=5.3.3", "php": ">=5.3.3",
"phpspec/prophecy": "~1.3,>=1.3.1", "phpspec/prophecy": "^1.3.1",
"phpunit/php-code-coverage": "~2.1", "phpunit/php-code-coverage": "~2.1",
"phpunit/php-file-iterator": "~1.4", "phpunit/php-file-iterator": "~1.4",
"phpunit/php-text-template": "~1.2", "phpunit/php-text-template": "~1.2",
@@ -2157,7 +2157,7 @@
"phpunit/phpunit-mock-objects": "~2.3", "phpunit/phpunit-mock-objects": "~2.3",
"sebastian/comparator": "~1.1", "sebastian/comparator": "~1.1",
"sebastian/diff": "~1.2", "sebastian/diff": "~1.2",
"sebastian/environment": "~1.2", "sebastian/environment": "~1.3",
"sebastian/exporter": "~1.2", "sebastian/exporter": "~1.2",
"sebastian/global-state": "~1.0", "sebastian/global-state": "~1.0",
"sebastian/version": "~1.0", "sebastian/version": "~1.0",
@@ -2172,7 +2172,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "4.7.x-dev" "dev-master": "4.8.x-dev"
} }
}, },
"autoload": { "autoload": {
@@ -2198,7 +2198,7 @@
"testing", "testing",
"xunit" "xunit"
], ],
"time": "2015-07-13 11:28:34" "time": "2015-08-10 09:16:56"
}, },
{ {
"name": "phpunit/phpunit-mock-objects", "name": "phpunit/phpunit-mock-objects",
@@ -2433,7 +2433,7 @@
"illuminate/support": "5.0.*|5.1.*", "illuminate/support": "5.0.*|5.1.*",
"illuminate/view": "5.0.*|5.1.*", "illuminate/view": "5.0.*|5.1.*",
"php": ">=5.4.0", "php": ">=5.4.0",
"twig/twig": "~1.15" "twig/twig": "~1.15|~2.0"
}, },
"require-dev": { "require-dev": {
"laravel/framework": "5.0.*", "laravel/framework": "5.0.*",
@@ -2597,16 +2597,16 @@
}, },
{ {
"name": "sebastian/environment", "name": "sebastian/environment",
"version": "1.3.0", "version": "1.3.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/environment.git", "url": "https://github.com/sebastianbergmann/environment.git",
"reference": "4fe0a44cddd8cc19583a024bdc7374eb2fef0b87" "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4fe0a44cddd8cc19583a024bdc7374eb2fef0b87", "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44",
"reference": "4fe0a44cddd8cc19583a024bdc7374eb2fef0b87", "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2643,7 +2643,7 @@
"environment", "environment",
"hhvm" "hhvm"
], ],
"time": "2015-07-26 06:42:57" "time": "2015-08-03 06:14:51"
}, },
{ {
"name": "sebastian/exporter", "name": "sebastian/exporter",
@@ -2905,7 +2905,7 @@
}, },
{ {
"name": "symfony/browser-kit", "name": "symfony/browser-kit",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/BrowserKit.git", "url": "https://github.com/symfony/BrowserKit.git",
@@ -2960,16 +2960,16 @@
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Console.git", "url": "https://github.com/symfony/Console.git",
"reference": "8cf484449130cabfd98dcb4694ca9945802a21ed" "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/Console/zipball/8cf484449130cabfd98dcb4694ca9945802a21ed", "url": "https://api.github.com/repos/symfony/Console/zipball/d6cf02fe73634c96677e428f840704bfbcaec29e",
"reference": "8cf484449130cabfd98dcb4694ca9945802a21ed", "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3013,11 +3013,11 @@
], ],
"description": "Symfony Console Component", "description": "Symfony Console Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2015-07-09 16:07:40" "time": "2015-07-28 15:18:12"
}, },
{ {
"name": "symfony/css-selector", "name": "symfony/css-selector",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/CssSelector.git", "url": "https://github.com/symfony/CssSelector.git",
@@ -3070,7 +3070,7 @@
}, },
{ {
"name": "symfony/debug", "name": "symfony/debug",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Debug.git", "url": "https://github.com/symfony/Debug.git",
@@ -3130,7 +3130,7 @@
}, },
{ {
"name": "symfony/dom-crawler", "name": "symfony/dom-crawler",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/DomCrawler.git", "url": "https://github.com/symfony/DomCrawler.git",
@@ -3183,7 +3183,7 @@
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/EventDispatcher.git", "url": "https://github.com/symfony/EventDispatcher.git",
@@ -3241,7 +3241,7 @@
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Finder.git", "url": "https://github.com/symfony/Finder.git",
@@ -3290,16 +3290,16 @@
}, },
{ {
"name": "symfony/http-foundation", "name": "symfony/http-foundation",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/HttpFoundation.git", "url": "https://github.com/symfony/HttpFoundation.git",
"reference": "88903c0531b90d4ecd90282b18f08c0c77bde0b2" "reference": "863af6898081b34c65d42100c370b9f3c51b70ca"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/88903c0531b90d4ecd90282b18f08c0c77bde0b2", "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/863af6898081b34c65d42100c370b9f3c51b70ca",
"reference": "88903c0531b90d4ecd90282b18f08c0c77bde0b2", "reference": "863af6898081b34c65d42100c370b9f3c51b70ca",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3339,27 +3339,27 @@
], ],
"description": "Symfony HttpFoundation Component", "description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2015-07-09 16:07:40" "time": "2015-07-22 10:11:00"
}, },
{ {
"name": "symfony/http-kernel", "name": "symfony/http-kernel",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/HttpKernel.git", "url": "https://github.com/symfony/HttpKernel.git",
"reference": "4a8a6f2a847475b3a38da50363a07f69b5cbf37e" "reference": "405d3e7a59ff7a28ec469441326a0ac79065ea98"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/HttpKernel/zipball/4a8a6f2a847475b3a38da50363a07f69b5cbf37e", "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/405d3e7a59ff7a28ec469441326a0ac79065ea98",
"reference": "4a8a6f2a847475b3a38da50363a07f69b5cbf37e", "reference": "405d3e7a59ff7a28ec469441326a0ac79065ea98",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.9", "php": ">=5.3.9",
"psr/log": "~1.0", "psr/log": "~1.0",
"symfony/debug": "~2.6,>=2.6.2", "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" "symfony/http-foundation": "~2.5,>=2.5.4"
}, },
"conflict": { "conflict": {
@@ -3419,11 +3419,11 @@
], ],
"description": "Symfony HttpKernel Component", "description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2015-07-13 19:27:49" "time": "2015-07-31 13:24:45"
}, },
{ {
"name": "symfony/process", "name": "symfony/process",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Process.git", "url": "https://github.com/symfony/Process.git",
@@ -3472,7 +3472,7 @@
}, },
{ {
"name": "symfony/routing", "name": "symfony/routing",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Routing.git", "url": "https://github.com/symfony/Routing.git",
@@ -3543,7 +3543,7 @@
}, },
{ {
"name": "symfony/translation", "name": "symfony/translation",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Translation.git", "url": "https://github.com/symfony/Translation.git",
@@ -3604,16 +3604,16 @@
}, },
{ {
"name": "symfony/var-dumper", "name": "symfony/var-dumper",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
"reference": "fde603d9f4b2418ff0f0315b93eb039c9aa41205" "reference": "e8903ebba5eb019f5886ffce739ea9e3b7519579"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/fde603d9f4b2418ff0f0315b93eb039c9aa41205", "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e8903ebba5eb019f5886ffce739ea9e3b7519579",
"reference": "fde603d9f4b2418ff0f0315b93eb039c9aa41205", "reference": "e8903ebba5eb019f5886ffce739ea9e3b7519579",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3659,20 +3659,20 @@
"debug", "debug",
"dump" "dump"
], ],
"time": "2015-07-01 12:07:40" "time": "2015-07-28 15:18:12"
}, },
{ {
"name": "symfony/yaml", "name": "symfony/yaml",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Yaml.git", "url": "https://github.com/symfony/Yaml.git",
"reference": "4bfbe0ed3909bfddd75b70c094391ec1f142f860" "reference": "71340e996171474a53f3d29111d046be4ad8a0ff"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/4bfbe0ed3909bfddd75b70c094391ec1f142f860", "url": "https://api.github.com/repos/symfony/Yaml/zipball/71340e996171474a53f3d29111d046be4ad8a0ff",
"reference": "4bfbe0ed3909bfddd75b70c094391ec1f142f860", "reference": "71340e996171474a53f3d29111d046be4ad8a0ff",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3708,20 +3708,20 @@
], ],
"description": "Symfony Yaml Component", "description": "Symfony Yaml Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2015-07-01 11:25:50" "time": "2015-07-28 14:07:07"
}, },
{ {
"name": "twig/twig", "name": "twig/twig",
"version": "v1.18.2", "version": "v1.20.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/twigphp/Twig.git", "url": "https://github.com/twigphp/Twig.git",
"reference": "e8e6575abf6102af53ec283f7f14b89e304fa602" "reference": "1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/e8e6575abf6102af53ec283f7f14b89e304fa602", "url": "https://api.github.com/repos/twigphp/Twig/zipball/1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844",
"reference": "e8e6575abf6102af53ec283f7f14b89e304fa602", "reference": "1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3730,7 +3730,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.18-dev" "dev-master": "1.20-dev"
} }
}, },
"autoload": { "autoload": {
@@ -3765,7 +3765,7 @@
"keywords": [ "keywords": [
"templating" "templating"
], ],
"time": "2015-06-06 23:31:24" "time": "2015-08-12 15:56:39"
}, },
{ {
"name": "vlucas/phpdotenv", "name": "vlucas/phpdotenv",
@@ -3993,16 +3993,16 @@
}, },
{ {
"name": "barryvdh/laravel-ide-helper", "name": "barryvdh/laravel-ide-helper",
"version": "v2.0.6", "version": "v2.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/barryvdh/laravel-ide-helper.git", "url": "https://github.com/barryvdh/laravel-ide-helper.git",
"reference": "037386153630a7515a1542f29410d8c267651689" "reference": "83999f8467374adcb8893f566c9171c9d9691f50"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/037386153630a7515a1542f29410d8c267651689", "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/83999f8467374adcb8893f566c9171c9d9691f50",
"reference": "037386153630a7515a1542f29410d8c267651689", "reference": "83999f8467374adcb8893f566c9171c9d9691f50",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4022,7 +4022,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.0-dev" "dev-master": "2.1-dev"
} }
}, },
"autoload": { "autoload": {
@@ -4052,7 +4052,7 @@
"phpstorm", "phpstorm",
"sublime" "sublime"
], ],
"time": "2015-06-25 08:58:59" "time": "2015-08-13 11:40:00"
}, },
{ {
"name": "maximebf/debugbar", "name": "maximebf/debugbar",
@@ -4112,7 +4112,7 @@
}, },
{ {
"name": "symfony/class-loader", "name": "symfony/class-loader",
"version": "v2.7.2", "version": "v2.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/ClassLoader.git", "url": "https://github.com/symfony/ClassLoader.git",

View File

@@ -2,7 +2,7 @@
return [ return [
'chart' => 'chartjs', 'chart' => 'chartjs',
'version' => '3.4.10', 'version' => '3.5.0',
'index_periods' => ['1D', '1W', '1M', '3M', '6M', '1Y', 'custom'], 'index_periods' => ['1D', '1W', '1M', '3M', '6M', '1Y', 'custom'],
'budget_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'], 'budget_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
'csv_import_enabled' => true, 'csv_import_enabled' => true,

40
pu.sh
View File

@@ -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

View File

@@ -1,5 +1,5 @@
#daterange {cursor:pointer;} #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;} .handle {cursor:move;}
.ui-sortable-placeholder { .ui-sortable-placeholder {

View File

@@ -3,18 +3,6 @@
/* /*
Make some colours: Make some colours:
*/ */
/*
#555299
#4285f4
#
#
#
#
#
#
#
#", "#", "#", "#"],
*/
var colourSet = [ var colourSet = [
[53, 124, 165], [53, 124, 165],
[0, 141, 76], [0, 141, 76],
@@ -54,6 +42,7 @@ var defaultAreaOptions = {
datasetStrokeWidth: 1, datasetStrokeWidth: 1,
pointHitDetectionRadius: 5, pointHitDetectionRadius: 5,
datasetFill: true, datasetFill: true,
animation: false,
scaleFontSize: 10, scaleFontSize: 10,
responsive: false, responsive: false,
scaleLabel: " <%= '" + currencySymbol + " ' + Number(value).toFixed(0).replace('.', ',') %>", scaleLabel: " <%= '" + currencySymbol + " ' + Number(value).toFixed(0).replace('.', ',') %>",
@@ -68,6 +57,7 @@ var defaultPieOptions = {
datasetStrokeWidth: 1, datasetStrokeWidth: 1,
pointHitDetectionRadius: 5, pointHitDetectionRadius: 5,
datasetFill: false, datasetFill: false,
animation: false,
scaleFontSize: 10, scaleFontSize: 10,
responsive: false, responsive: false,
tooltipFillColor: "rgba(0,0,0,0.5)", tooltipFillColor: "rgba(0,0,0,0.5)",
@@ -81,6 +71,7 @@ var defaultLineOptions = {
pointDotRadius: 2, pointDotRadius: 2,
datasetStrokeWidth: 1, datasetStrokeWidth: 1,
pointHitDetectionRadius: 5, pointHitDetectionRadius: 5,
animation: false,
datasetFill: false, datasetFill: false,
scaleFontSize: 10, scaleFontSize: 10,
responsive: false, responsive: false,
@@ -98,6 +89,7 @@ var defaultColumnOptions = {
datasetFill: false, datasetFill: false,
scaleFontSize: 10, scaleFontSize: 10,
responsive: false, responsive: false,
animation: false,
scaleLabel: "<%= '" + currencySymbol + " ' + Number(value).toFixed(0).replace('.', ',') %>", scaleLabel: "<%= '" + currencySymbol + " ' + Number(value).toFixed(0).replace('.', ',') %>",
tooltipFillColor: "rgba(0,0,0,0.5)", tooltipFillColor: "rgba(0,0,0,0.5)",
tooltipTemplate: "<%if (label){%><%=label%>: <%}%>" + currencySymbol + " <%= value %>", tooltipTemplate: "<%if (label){%><%=label%>: <%}%>" + currencySymbol + " <%= value %>",
@@ -110,6 +102,7 @@ var defaultStackedColumnOptions = {
barStrokeWidth: 1, barStrokeWidth: 1,
pointHitDetectionRadius: 5, pointHitDetectionRadius: 5,
datasetFill: false, datasetFill: false,
animation: false,
scaleFontSize: 10, scaleFontSize: 10,
responsive: false, responsive: false,
scaleLabel: "<%= '" + currencySymbol + " ' + Number(value).toFixed(0).replace('.', ',') %>", scaleLabel: "<%= '" + currencySymbol + " ' + Number(value).toFixed(0).replace('.', ',') %>",
@@ -147,7 +140,7 @@ function lineChart(URL, container, options) {
new Chart(ctx).Line(newData, options); new Chart(ctx).Line(newData, options);
}).fail(function () { }).fail(function () {
$('#' + container).addClass('google-chart-error'); $('#' + container).addClass('general-chart-error');
}); });
console.log('URL for line chart : ' + URL); console.log('URL for line chart : ' + URL);
} }
@@ -182,7 +175,7 @@ function areaChart(URL, container, options) {
new Chart(ctx).Line(newData, options); new Chart(ctx).Line(newData, options);
}).fail(function () { }).fail(function () {
$('#' + container).addClass('google-chart-error'); $('#' + container).addClass('general-chart-error');
}); });
console.log('URL for area chart: ' + URL); console.log('URL for area chart: ' + URL);
@@ -218,7 +211,7 @@ function columnChart(URL, container, options) {
new Chart(ctx).Bar(newData, options); new Chart(ctx).Bar(newData, options);
}).fail(function () { }).fail(function () {
$('#' + container).addClass('google-chart-error'); $('#' + container).addClass('general-chart-error');
}); });
console.log('URL for column chart : ' + URL); console.log('URL for column chart : ' + URL);
} }
@@ -253,7 +246,7 @@ function stackedColumnChart(URL, container, options) {
new Chart(ctx).StackedBar(newData, options); new Chart(ctx).StackedBar(newData, options);
}).fail(function () { }).fail(function () {
$('#' + container).addClass('google-chart-error'); $('#' + container).addClass('general-chart-error');
}); });
console.log('URL for stacked column chart : ' + URL); console.log('URL for stacked column chart : ' + URL);
} }
@@ -286,7 +279,7 @@ function pieChart(URL, container, options) {
new Chart(ctx).Pie(data, options); new Chart(ctx).Pie(data, options);
}).fail(function () { }).fail(function () {
$('#' + container).addClass('google-chart-error'); $('#' + container).addClass('general-chart-error');
}); });

View File

@@ -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);
}

View File

@@ -2,13 +2,8 @@
$(function () { $(function () {
"use strict"; "use strict";
if (typeof google !== 'undefined') { // do chart JS stuff.
// do google charts: drawChart();
google.setOnLoadCallback(drawChart);
} else {
// do chart JS stuff.
drawChart();
}
if (showTour) { if (showTour) {
$.getJSON('json/tour').success(function (data) { $.getJSON('json/tour').success(function (data) {
var tour = new Tour( var tour = new Tour(
@@ -41,6 +36,7 @@ function drawChart() {
pieChart('chart/bill/frontpage', 'bills-chart'); pieChart('chart/bill/frontpage', 'bills-chart');
stackedColumnChart('chart/budget/frontpage', 'budgets-chart'); stackedColumnChart('chart/budget/frontpage', 'budgets-chart');
columnChart('chart/category/frontpage', 'categories-chart'); columnChart('chart/category/frontpage', 'categories-chart');
columnChart('chart/account/expense', 'expense-accounts-chart');
getBoxAmounts(); getBoxAmounts();

View File

@@ -2,11 +2,7 @@
$(function () { $(function () {
"use strict"; "use strict";
if (typeof(google) !== 'undefined') { drawChart();
google.setOnLoadCallback(drawChart);
} else {
drawChart();
}
}); });
@@ -18,7 +14,8 @@ function drawChart() {
} }
if (typeof stackedColumnChart !== 'undefined' && typeof year !== 'undefined' && typeof month === 'undefined') { if (typeof stackedColumnChart !== 'undefined' && typeof year !== 'undefined' && typeof month === 'undefined') {
stackedColumnChart('chart/budget/year/' + year + shared, 'budgets'); 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') { if (typeof lineChart !== 'undefined' && typeof month !== 'undefined') {
lineChart('/chart/account/month/' + year + '/' + month + shared, 'account-balances-chart'); lineChart('/chart/account/month/' + year + '/' + month + shared, 'account-balances-chart');

View File

@@ -15,6 +15,8 @@ return [
'cancel' => 'Cancel', 'cancel' => 'Cancel',
'from' => 'From', 'from' => 'From',
'to' => 'To', 'to' => 'To',
'total_sum' => 'Total sum',
'period_sum' => 'Sum for period',
'showEverything' => 'Show everything', 'showEverything' => 'Show everything',
'never' => 'Never', 'never' => 'Never',
'search_results_for' => 'Search results for ":query"', '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.', '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_roles_table' => 'Column roles',
'csv_column' => 'CSV column', 'csv_column' => 'CSV column',
'cvs_column_name' => 'CSV column name', 'csv_column_name' => 'CSV column name',
'cvs_column_example' => 'Column example data', 'csv_column_example' => 'Column example data',
'cvs_column_role' => 'Column contains?', 'csv_column_role' => 'Column contains?',
'csv_do_map_value' => 'Map value?', 'csv_do_map_value' => 'Map value?',
'csv_continue' => 'Continue to the next step', 'csv_continue' => 'Continue to the next step',
'csv_go_back' => 'Go back to the previous step', 'csv_go_back' => 'Go back to the previous step',
'csv_map_title' => 'Map found values to existing values', '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 ' . '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.', '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_field_mapped_to' => 'Must be mapped to...',
'csv_do_not_map' => 'Do not map this value', 'csv_do_not_map' => 'Do not map this value',
'csv_download_config_title' => 'Download CSV configuration', '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_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_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_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_title' => 'CSV import finished!',
'csv_process_text' => 'The CVS importer has finished and has processed :rows rows', 'csv_process_text' => 'The CSV importer has finished and has processed :rows rows',
'csv_row' => 'Row', 'csv_row' => 'Row',
'csv_import_with_errors' => 'There was one error.|There were :errors errors.', 'csv_import_with_errors' => 'There was one error.|There were :errors errors.',
'csv_error_see_logs' => 'Check the log files to see details.', '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_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' '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.', . ' 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: // create new stuff:
@@ -396,12 +399,15 @@ return [
'hideTheRest' => 'Show only the top :number', 'hideTheRest' => 'Show only the top :number',
'sum_of_year' => 'Sum of year', 'sum_of_year' => 'Sum of year',
'average_of_year' => 'Average of year', 'average_of_year' => 'Average of year',
'categories_earned_in_year' => 'Categories (by earnings)',
'categories_spent_in_year' => 'Categories (by spendings)',
// charts: // charts:
'dayOfMonth' => 'Day of the month', 'dayOfMonth' => 'Day of the month',
'month' => 'Month', 'month' => 'Month',
'budget' => 'Budget', 'budget' => 'Budget',
'spent' => 'Spent', 'spent' => 'Spent',
'earned' => 'Earned',
'overspent' => 'Overspent', 'overspent' => 'Overspent',
'left' => 'Left', 'left' => 'Left',
'noBudget' => '(no budget)', 'noBudget' => '(no budget)',

View File

@@ -15,6 +15,8 @@ return [
'cancel' => 'Annuleren', 'cancel' => 'Annuleren',
'from' => 'Van', 'from' => 'Van',
'to' => 'Tot', 'to' => 'Tot',
'total_sum' => 'Totale som',
'period_sum' => 'Som van periode',
'showEverything' => 'Laat alles zien', 'showEverything' => 'Laat alles zien',
'never' => 'Nooit', 'never' => 'Nooit',
'search_results_for' => 'Zoekresultaten voor ":query"', '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.', . ' 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_roles_table' => 'Kolominhoud',
'csv_column' => 'CSV-kolom', 'csv_column' => 'CSV-kolom',
'cvs_column_name' => 'CSV-kolomnaam', 'csv_column_name' => 'CSV-kolomnaam',
'cvs_column_example' => 'Voorbeeldgegevens', 'csv_column_example' => 'Voorbeeldgegevens',
'cvs_column_role' => 'Kolom bevat?', 'csv_column_role' => 'Kolom bevat?',
'csv_do_map_value' => 'Directe relatie?', 'csv_do_map_value' => 'Directe relatie?',
'csv_continue' => 'Naar de volgende stap', 'csv_continue' => 'Naar de volgende stap',
'csv_go_back' => 'Terug naar de vorige stap', 'csv_go_back' => 'Terug naar de vorige stap',
'csv_map_title' => 'Leg relaties met kolomwaardes', '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' '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.', . '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_field_mapped_to' => 'Is gelijk aan',
'csv_do_not_map' => 'Geen relatie', 'csv_do_not_map' => 'Geen relatie',
'csv_download_config_title' => 'Download importconfiguratie', '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' 'csv_download_config_text' => 'Firefly is klaar om je bestand te importeren. De instellingen en selecties die je zojuist hebt gemaakt' .
. ' en opslaan. Bij de volgende keer kan je dit bestand ook uploaden. Als je kommagescheiden bestand dezelfde indeling' ' kan je downloaden en opslaan. Bij de volgende keer kan je dit bestand ook uploaden. Als je' .
. ' heeft, zullen alle selecties goed staan. Dat scheelt weer!', ' 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' 'csv_more_information_text' => 'Ook als het importeren fout gaat is dit bestand handig. Na het importeren krijg je nogmaals' .
. 'te downloaden.', ' de gelegenheid dit bestand te downloaden.',
'csv_do_download_config' => 'Download het configuratiebestand', 'csv_do_download_config' => 'Download het configuratiebestand',
'csv_empty_description' => '(geen beschrijving)', 'csv_empty_description' => '(geen beschrijving)',
'csv_upload_form' => 'CSV upload formulier', 'csv_upload_form' => 'CSV upload formulier',
@@ -181,6 +183,8 @@ return [
'csv_specifix_RabobankDescription' => 'Vink dit aan als je Rabobank bestanden importeert.', 'csv_specifix_RabobankDescription' => 'Vink dit aan als je Rabobank bestanden importeert.',
'csv_specifix_Dummy' => 'Dit vinkje doet niks (dummy).', '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_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 stuff:
'create_new_withdrawal' => 'Nieuwe uitgave', 'create_new_withdrawal' => 'Nieuwe uitgave',
@@ -376,8 +380,8 @@ return [
// reports: // reports:
'reportForYear' => 'Jaaroverzicht :year', 'reportForYear' => 'Jaaroverzicht :year',
'reportForYearShared' => 'Jaaroverzicht :year (inclusief gedeelde rekeningen)', 'reportForYearShared' => 'Jaaroverzicht :year (inclusief gedeelde rekeningen)',
'reportForMonth' => 'Maandoverzicht van :date', 'reportForMonth' => 'Maandoverzicht voor :month',
'reportForMonthShared' => 'Maandoverzicht van :date (inclusief gedeelde rekeningen)', 'reportForMonthShared' => 'Maandoverzicht voor :month (inclusief gedeelde rekeningen)',
'incomeVsExpenses' => 'Inkomsten tegenover uitgaven', 'incomeVsExpenses' => 'Inkomsten tegenover uitgaven',
'accountBalances' => 'Rekeningsaldi', 'accountBalances' => 'Rekeningsaldi',
'balanceStartOfYear' => 'Saldo aan het begin van het jaar', 'balanceStartOfYear' => 'Saldo aan het begin van het jaar',
@@ -404,12 +408,15 @@ return [
'topX' => 'top :number', 'topX' => 'top :number',
'showTheRest' => 'Laat alles zien', 'showTheRest' => 'Laat alles zien',
'hideTheRest' => 'Laat alleen de top :number zien', 'hideTheRest' => 'Laat alleen de top :number zien',
'categories_earned_in_year' => 'Categorieën (inkomsten)',
'categories_spent_in_year' => 'Categorieën (uitgaven)',
// charts: // charts:
'dayOfMonth' => 'Dag vd maand', 'dayOfMonth' => 'Dag vd maand',
'month' => 'Maand', 'month' => 'Maand',
'budget' => 'Budget', 'budget' => 'Budget',
'spent' => 'Uitgegeven', 'spent' => 'Uitgegeven',
'earned' => 'Verdiend',
'overspent' => 'Teveel uitgegeven', 'overspent' => 'Teveel uitgegeven',
'left' => 'Over', 'left' => 'Over',
'noBudget' => '(geen budget)', 'noBudget' => '(geen budget)',

View 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 %}

View File

@@ -45,7 +45,7 @@
<h3 class="box-title">{{ 'transactions'|_ }}</h3> <h3 class="box-title">{{ 'transactions'|_ }}</h3>
</div> </div>
<div class="box-body no-padding"> <div class="box-body no-padding">
{% include 'list/journals' %} {% include 'list/journals' with {showPageSum: true, showTotalSum: true, showPeriodSum: true} %}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -45,9 +45,9 @@
<table class="table"> <table class="table">
<thead> <thead>
<th style="width:20%;">{{ 'cvs_column_name'|_ }}</th> <th style="width:20%;">{{ 'csv_column_name'|_ }}</th>
<th style="width:40%;">{{ 'cvs_column_example'|_ }}</th> <th style="width:40%;">{{ 'csv_column_example'|_ }}</th>
<th style="width:30%;">{{ 'cvs_column_role'|_ }}</th> <th style="width:30%;">{{ 'csv_column_role'|_ }}</th>
<th style="width:10%;">{{ 'csv_do_map_value'|_ }}</th> <th style="width:10%;">{{ 'csv_do_map_value'|_ }}</th>
</thead> </thead>
{% for index,header in headers %} {% for index,header in headers %}

View File

@@ -48,7 +48,7 @@
<div class="box-body no-padding"> <div class="box-body no-padding">
<table class="table table-hover"> <table class="table table-hover">
<thead> <thead>
<th style="width:50%;">{{ 'cvs_field_value'|_ }}</th> <th style="width:50%;">{{ 'csv_field_value'|_ }}</th>
<th>{{ 'csv_field_mapped_to'|_ }}</th> <th>{{ 'csv_field_mapped_to'|_ }}</th>
</thead> </thead>
<tbody> <tbody>

View File

@@ -1 +1 @@
Click here to reset your password: {{ url('password/reset/' . token) }} Click here to reset your password: {{ url('password/reset/' ~ token) }}

View File

@@ -67,7 +67,87 @@
{% endif %} {% endif %}
</div> </div>
</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 --> <!-- SAVINGS -->
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
@@ -133,7 +213,8 @@
<span class="pull-right">{{ 'sum'|_ }}: {{ savingsTotal|formatAmount }}</span> <span class="pull-right">{{ 'sum'|_ }}: {{ savingsTotal|formatAmount }}</span>
</div> </div>
</div> </div>
</div>
<div class="col-lg-6 col-sm-12 col-md-12">
<!-- PIGGY BANKS --> <!-- PIGGY BANKS -->
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
@@ -178,63 +259,6 @@
{% endif %} {% endif %}
</div> </div>
</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> </div>

View File

@@ -187,28 +187,34 @@
<script type="text/javascript" src="js/help.js"></script> <script type="text/javascript" src="js/help.js"></script>
{% block scripts %}{% endblock %} {% block scripts %}{% endblock %}
{% if env('ANALYTICS_ID','') != '' %}
<script> <script>
(function (i, s, o, g, r, a, m) { // send pageview
i['GoogleAnalyticsObject'] = r; (function (i, s, o, g, r, a, m) {
i[r] = i[r] || function () { i['GoogleAnalyticsObject'] = r;
(i[r].q = i[r].q || []).push(arguments) i[r] = i[r] || function () {
}, i[r].l = 1 * new Date(); (i[r].q = i[r].q || []).push(arguments)
a = s.createElement(o), }, i[r].l = 1 * new Date();
m = s.getElementsByTagName(o)[0]; a = s.createElement(o),
a.async = 1; m = s.getElementsByTagName(o)[0];
a.src = g; a.async = 1;
m.parentNode.insertBefore(a, m) a.src = g;
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'); m.parentNode.insertBefore(a, m)
ga('create', '{{ env('ANALYTICS_ID', 'XXX-XX-X') }}', {'siteSpeedSampleRate': 100}); })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('send', 'pageview'); ga('create', '{{ env('ANALYTICS_ID', 'XXX-XX-X') }}', {'siteSpeedSampleRate': 100});
// send an event if relevant: ga('send', 'pageview');
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and not Session.has('gaEventLabel') %}
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}'); // send an event if relevant:
{% endif %} {% if Session.has('gaEventCategory') and Session.has('gaEventAction') and not Session.has('gaEventLabel') %}
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and Session.has('gaEventLabel') %} ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}');
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}', '{{ Session.get('gaEventLabel') }}'); {% endif %}
{% 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> </script>
{% endif %}
</body> </body>
</html> </html>

View File

@@ -47,27 +47,33 @@
<script type="text/javascript" src="js/jquery-2.1.3.min.js"></script> <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 type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
<script> {% if env('ANALYTICS_ID','') != '' %}
(function (i, s, o, g, r, a, m) { <script>
i['GoogleAnalyticsObject'] = r; // send pageview
i[r] = i[r] || function () { (function (i, s, o, g, r, a, m) {
(i[r].q = i[r].q || []).push(arguments) i['GoogleAnalyticsObject'] = r;
}, i[r].l = 1 * new Date(); i[r] = i[r] || function () {
a = s.createElement(o), (i[r].q = i[r].q || []).push(arguments)
m = s.getElementsByTagName(o)[0]; }, i[r].l = 1 * new Date();
a.async = 1; a = s.createElement(o),
a.src = g; m = s.getElementsByTagName(o)[0];
m.parentNode.insertBefore(a, m) a.async = 1;
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'); a.src = g;
ga('create', '{{ env('ANALYTICS_ID', 'XXX-XX-X') }}', {'siteSpeedSampleRate': 100}); m.parentNode.insertBefore(a, m)
ga('send', 'pageview'); })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
// send an event if relevant: ga('create', '{{ env('ANALYTICS_ID', 'XXX-XX-X') }}', {'siteSpeedSampleRate': 100});
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and not Session.has('gaEventLabel') %} ga('send', 'pageview');
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}');
{% endif %} // send an event if relevant:
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and Session.has('gaEventLabel') %} {% if Session.has('gaEventCategory') and Session.has('gaEventAction') and not Session.has('gaEventLabel') %}
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}', '{{ Session.get('gaEventLabel') }}'); ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}');
{% endif %} {% endif %}
</script>
// 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> </body>
</html> </html>

View File

@@ -48,27 +48,33 @@
<script type="text/javascript" src="js/jquery-2.1.3.min.js"></script> <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 type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
<script> {% if env('ANALYTICS_ID','') != '' %}
(function (i, s, o, g, r, a, m) { <script>
i['GoogleAnalyticsObject'] = r; // send pageview
i[r] = i[r] || function () { (function (i, s, o, g, r, a, m) {
(i[r].q = i[r].q || []).push(arguments) i['GoogleAnalyticsObject'] = r;
}, i[r].l = 1 * new Date(); i[r] = i[r] || function () {
a = s.createElement(o), (i[r].q = i[r].q || []).push(arguments)
m = s.getElementsByTagName(o)[0]; }, i[r].l = 1 * new Date();
a.async = 1; a = s.createElement(o),
a.src = g; m = s.getElementsByTagName(o)[0];
m.parentNode.insertBefore(a, m) a.async = 1;
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'); a.src = g;
ga('create', '{{ env('ANALYTICS_ID', 'XXX-XX-X') }}', {'siteSpeedSampleRate': 100}); m.parentNode.insertBefore(a, m)
ga('send', 'pageview'); })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
// send an event if relevant: ga('create', '{{ env('ANALYTICS_ID', 'XXX-XX-X') }}', {'siteSpeedSampleRate': 100});
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and not Session.has('gaEventLabel') %} ga('send', 'pageview');
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}');
{% endif %} // send an event if relevant:
{% if Session.has('gaEventCategory') and Session.has('gaEventAction') and Session.has('gaEventLabel') %} {% if Session.has('gaEventCategory') and Session.has('gaEventAction') and not Session.has('gaEventLabel') %}
ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}', '{{ Session.get('gaEventLabel') }}'); ga('send', 'event', '{{Session.get('gaEventCategory')}}', '{{Session.get('gaEventAction')}}');
{% endif %} {% endif %}
</script>
// 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> </body>
</html> </html>

View File

@@ -1,6 +1,7 @@
{{ journals.render|raw }} {{ journals.render|raw }}
<table class="table table-hover sortable sortable-table"> <table class="table table-hover">
<thead>
<tr class="ignore"> <tr class="ignore">
<th class="hidden-xs" colspan="2">&nbsp;</th> <th class="hidden-xs" colspan="2">&nbsp;</th>
<th>{{ trans('list.description') }}</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> <th class="hidden-xs"><i class="fa fa-fw fa-rotate-right" title="{{ trans('list.bill') }}"></i></th>
{% endif %} {% endif %}
</tr> </tr>
</thead>
<tbody>
{% set _sum = 0 %}
{% for journal in journals %} {% for journal in journals %}
{% if invalidJournal(journal) %} {% if invalidJournal(journal) %}
<tr class="ignore"> <tr class="ignore">
@@ -36,6 +40,7 @@
<td colspan="7"><em>Invalid journal: Found {{ journal.transactions|length }} transaction(s)</em></td> <td colspan="7"><em>Invalid journal: Found {{ journal.transactions|length }} transaction(s)</em></td>
</tr> </tr>
{% else %} {% else %}
{% set _sum = _sum + journal.correct_amount %}
<tr class="drag" data-date="{{ journal.date.format('Y-m-d') }}" data-id="{{ journal.id }}"> <tr class="drag" data-date="{{ journal.date.format('Y-m-d') }}" data-id="{{ journal.id }}">
<td class="hidden-xs"> <td class="hidden-xs">
<div class="btn-group btn-group-xs"> <div class="btn-group btn-group-xs">
@@ -111,8 +116,28 @@
{% endif %} {% endif %}
</tr> </tr>
{% endif %} {% endif %}
{% endfor %} {% 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> </table>
{{ journals.render|raw }} {{ journals.render|raw }}

View File

@@ -16,14 +16,14 @@
<td> <td>
<a href="{{ route('categories.show',cat.id) }}">{{ cat.name }}</a> <a href="{{ route('categories.show',cat.id) }}">{{ cat.name }}</a>
</td> </td>
<td><span class="text-danger">{{ (cat.spent)|formatAmountPlain }}</span></td> <td><span class="text-danger">{{ (cat.spent * -1)|formatAmountPlain }}</span></td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<td><em>{{ 'sum'|_ }}</em></td> <td><em>{{ 'sum'|_ }}</em></td>
<td class="text-danger">{{ categories.getTotal|formatAmountPlain }}</td> <td class="text-danger">{{ (categories.getTotal * -1)|formatAmountPlain }}</td>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>

View File

@@ -56,19 +56,38 @@
<div class="col-lg-12 col-md-12 col-sm-12"> <div class="col-lg-12 col-md-12 col-sm-12">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">{{ 'categories'|_ }}</h3> <h3 class="box-title">{{ 'categories_spent_in_year'|_ }}</h3>
</div> </div>
<div class="box-body"> <div class="box-body">
{% if Config.get('firefly.chart') == 'google' %} {% if Config.get('firefly.chart') == 'google' %}
<div id="categories"></div> <div id="categories-spent-in-year"></div>
{% endif %} {% endif %}
{% if Config.get('firefly.chart') == 'chartjs' %} {% 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 %} {% endif %}
</div> </div>
</div> </div>
</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="row">
<div class="col-lg-12 col-md-12 col-sm-12"> <div class="col-lg-12 col-md-12 col-sm-12">
<div class="box"> <div class="box">