Merge branch 'release/3.4.0.8'

This commit is contained in:
James Cole
2015-05-22 18:55:13 +02:00
91 changed files with 1665 additions and 729 deletions

View File

@@ -1,5 +1,5 @@
# Firefly III # Firefly III
#### v3.4.0.7 #### v3.4.0.8
[![Build Status](https://travis-ci.org/JC5/firefly-iii.svg?branch=develop)](https://travis-ci.org/JC5/firefly-iii) [![Build Status](https://travis-ci.org/JC5/firefly-iii.svg?branch=develop)](https://travis-ci.org/JC5/firefly-iii)
[![Project Status](http://stillmaintained.com/JC5/firefly-iii.png?a=b)](http://stillmaintained.com/JC5/firefly-iii) [![Project Status](http://stillmaintained.com/JC5/firefly-iii.png?a=b)](http://stillmaintained.com/JC5/firefly-iii)

View File

@@ -1,6 +1,7 @@
<?php <?php
namespace FireflyIII\Helpers\Collection; namespace FireflyIII\Helpers\Collection;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
/** /**
@@ -60,6 +61,4 @@ class Balance
} }
} }

View File

@@ -17,13 +17,10 @@ class BalanceEntry
/** @var AccountModel */ /** @var AccountModel */
protected $account; protected $account;
/** @var float */
protected $spent = 0.0;
/** @var float */ /** @var float */
protected $left = 0.0; protected $left = 0.0;
/** @var float */
protected $spent = 0.0;
/** /**
* @return AccountModel * @return AccountModel
@@ -41,22 +38,6 @@ class BalanceEntry
$this->account = $account; $this->account = $account;
} }
/**
* @return float
*/
public function getSpent()
{
return $this->spent;
}
/**
* @param float $spent
*/
public function setSpent($spent)
{
$this->spent = $spent;
}
/** /**
* @return float * @return float
*/ */
@@ -73,7 +54,21 @@ class BalanceEntry
$this->left = $left; $this->left = $left;
} }
/**
* @return float
*/
public function getSpent()
{
return $this->spent;
}
/**
* @param float $spent
*/
public function setSpent($spent)
{
$this->spent = $spent;
}
} }

View File

@@ -43,5 +43,4 @@ class BalanceHeader
} }
} }

View File

@@ -7,6 +7,7 @@ use FireflyIII\Models\Bill as BillModel;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
/** /**
* @codeCoverageIgnore
* Class Bill * Class Bill
* *
* @package FireflyIII\Helpers\Collection * @package FireflyIII\Helpers\Collection
@@ -44,6 +45,7 @@ class Bill
function (BillLine $bill) { function (BillLine $bill) {
$active = intval($bill->getBill()->active) == 0 ? 1 : 0; $active = intval($bill->getBill()->active) == 0 ? 1 : 0;
$name = $bill->getBill()->name; $name = $bill->getBill()->name;
return $active . $name; return $active . $name;
} }
); );

View File

@@ -5,6 +5,8 @@ namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Bill as BillModel; use FireflyIII\Models\Bill as BillModel;
/** /**
* @codeCoverageIgnore
*
* Class BillLine * Class BillLine
* *
* @package FireflyIII\Helpers\Collection * @package FireflyIII\Helpers\Collection

View File

@@ -1,6 +1,7 @@
<?php <?php
namespace FireflyIII\Helpers\Collection; namespace FireflyIII\Helpers\Collection;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
/** /**
@@ -71,6 +72,14 @@ class Budget
$this->spent += floatval($add); $this->spent += floatval($add);
} }
/**
* @return \Illuminate\Support\Collection
*/
public function getBudgetLines()
{
return $this->budgetLines;
}
/** /**
* @return float * @return float
*/ */
@@ -135,15 +144,5 @@ class Budget
$this->spent = $spent; $this->spent = $spent;
} }
/**
* @return \Illuminate\Support\Collection
*/
public function getBudgetLines()
{
return $this->budgetLines;
}
} }

View File

@@ -127,8 +127,4 @@ class BudgetLine
} }
} }

View File

@@ -37,14 +37,14 @@ class Expense
$accountId = $entry->account_id; $accountId = $entry->account_id;
if (!$this->expenses->has($accountId)) { if (!$this->expenses->has($accountId)) {
$newObject = new stdClass; $newObject = new stdClass;
$newObject->amount = floatval($entry->queryAmount); $newObject->amount = floatval($entry->amount);
$newObject->name = $entry->name; $newObject->name = $entry->name;
$newObject->count = 1; $newObject->count = 1;
$newObject->id = $accountId; $newObject->id = $accountId;
$this->expenses->put($accountId, $newObject); $this->expenses->put($accountId, $newObject);
} else { } else {
$existing = $this->expenses->get($accountId); $existing = $this->expenses->get($accountId);
$existing->amount += floatval($entry->queryAmount); $existing->amount += floatval($entry->amount);
$existing->count++; $existing->count++;
$this->expenses->put($accountId, $existing); $this->expenses->put($accountId, $existing);
} }
@@ -63,7 +63,7 @@ class Expense
*/ */
public function getExpenses() public function getExpenses()
{ {
$this->expenses->sortBy( $this->expenses->sortByDesc(
function (stdClass $object) { function (stdClass $object) {
return $object->amount; return $object->amount;
} }

View File

@@ -38,14 +38,14 @@ class Income
$accountId = $entry->account_id; $accountId = $entry->account_id;
if (!$this->incomes->has($accountId)) { if (!$this->incomes->has($accountId)) {
$newObject = new stdClass; $newObject = new stdClass;
$newObject->amount = floatval($entry->queryAmount); $newObject->amount = floatval($entry->amount);
$newObject->name = $entry->name; $newObject->name = $entry->name;
$newObject->count = 1; $newObject->count = 1;
$newObject->id = $accountId; $newObject->id = $accountId;
$this->incomes->put($accountId, $newObject); $this->incomes->put($accountId, $newObject);
} else { } else {
$existing = $this->incomes->get($accountId); $existing = $this->incomes->get($accountId);
$existing->amount += floatval($entry->queryAmount); $existing->amount += floatval($entry->amount);
$existing->count++; $existing->count++;
$this->incomes->put($accountId, $existing); $this->incomes->put($accountId, $existing);
} }

View File

@@ -37,7 +37,7 @@ class Help implements HelpInterface
*/ */
public function getFromGithub($route) public function getFromGithub($route)
{ {
$uri = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/' . e($route) . '.md'; $uri = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/en/' . e($route) . '.md';
$content = [ $content = [
'text' => '<p>There is no help for this route!</p>', 'text' => '<p>There is no help for this route!</p>',
'title' => $route, 'title' => $route,

View File

@@ -33,6 +33,7 @@ class ReportHelper implements ReportHelperInterface
protected $query; protected $query;
/** /**
* @codeCoverageIgnore
* @param ReportQueryInterface $query * @param ReportQueryInterface $query
* *
*/ */
@@ -62,6 +63,13 @@ class ReportHelper implements ReportHelperInterface
$end = 0; $end = 0;
$diff = 0; $diff = 0;
// remove cash account, if any:
$accounts =$accounts->filter(function(Account $account) {
if($account->accountType->type != 'Cash account') {
return $account;
}
});
// summarize: // summarize:
foreach ($accounts as $account) { foreach ($accounts as $account) {
$start += $account->startBalance; $start += $account->startBalance;
@@ -129,7 +137,7 @@ class ReportHelper implements ReportHelperInterface
$balanceEntry->setAccount($account); $balanceEntry->setAccount($account);
// get spent: // get spent:
$spent = $this->query->spentInBudget($account, $budget, $start, $end); // I think shared is irrelevant. $spent = $this->query->spentInBudgetCorrected($account, $budget, $start, $end); // I think shared is irrelevant.
$balanceEntry->setSpent($spent); $balanceEntry->setSpent($spent);
$line->addBalanceEntry($balanceEntry); $line->addBalanceEntry($balanceEntry);
@@ -247,7 +255,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->spentInPeriod($budget, $start, $end, $shared); $spent = $repository->spentInPeriodCorrected($budget, $start, $end, $shared);
$budgetLine = new BudgetLine; $budgetLine = new BudgetLine;
$budgetLine->setBudget($budget); $budgetLine->setBudget($budget);
$budgetLine->setOverspent($spent); $budgetLine->setOverspent($spent);
@@ -262,7 +270,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->spentInPeriod($budget, $repetition->startdate, $repetition->enddate, $shared); $expenses = $repository->spentInPeriodCorrected($budget, $repetition->startdate, $repetition->enddate, $shared);
$left = $expenses < floatval($repetition->amount) ? floatval($repetition->amount) - $expenses : 0; $left = $expenses < floatval($repetition->amount) ? floatval($repetition->amount) - $expenses : 0;
$spent = $expenses > floatval($repetition->amount) ? 0 : $expenses; $spent = $expenses > floatval($repetition->amount) ? 0 : $expenses;
$overspent = $expenses > floatval($repetition->amount) ? $expenses - floatval($repetition->amount) : 0; $overspent = $expenses > floatval($repetition->amount) ? $expenses - floatval($repetition->amount) : 0;
@@ -311,7 +319,7 @@ class ReportHelper implements ReportHelperInterface
$repository = App::make('FireflyIII\Repositories\Category\CategoryRepositoryInterface'); $repository = App::make('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
$set = $repository->getCategories(); $set = $repository->getCategories();
foreach ($set as $category) { foreach ($set as $category) {
$spent = $repository->spentInPeriod($category, $start, $end, $shared); $spent = $repository->spentInPeriodCorrected($category, $start, $end, $shared);
$category->spent = $spent; $category->spent = $spent;
$object->addCategory($category); $object->addCategory($category);
$object->addTotal($spent); $object->addTotal($spent);
@@ -332,9 +340,9 @@ class ReportHelper implements ReportHelperInterface
public function getExpenseReport($start, $end, $shared) public function getExpenseReport($start, $end, $shared)
{ {
$object = new Expense; $object = new Expense;
$set = $this->query->expenseInPeriod($start, $end, $shared); $set = $this->query->expenseInPeriodCorrected($start, $end, $shared);
foreach ($set as $entry) { foreach ($set as $entry) {
$object->addToTotal($entry->queryAmount); $object->addToTotal($entry->amount);
$object->addOrCreateExpense($entry); $object->addOrCreateExpense($entry);
} }
@@ -353,9 +361,9 @@ class ReportHelper implements ReportHelperInterface
public function getIncomeReport($start, $end, $shared) public function getIncomeReport($start, $end, $shared)
{ {
$object = new Income; $object = new Income;
$set = $this->query->incomeInPeriod($start, $end, $shared); $set = $this->query->incomeInPeriodCorrected($start, $end, $shared);
foreach ($set as $entry) { foreach ($set as $entry) {
$object->addToTotal($entry->queryAmount); $object->addToTotal($entry->amount);
$object->addOrCreateIncome($entry); $object->addOrCreateIncome($entry);
} }

View File

@@ -22,12 +22,8 @@ use Steam;
*/ */
class ReportQuery implements ReportQueryInterface class ReportQuery implements ReportQueryInterface
{ {
/** /**
* This method returns all "expense" journals in a certain period, which are both transfers to a shared account * See ReportQueryInterface::incomeInPeriodCorrected
* and "ordinary" withdrawals. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does
* not group and returns different fields.
* *
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
@@ -36,7 +32,7 @@ class ReportQuery implements ReportQueryInterface
* @return Collection * @return Collection
* *
*/ */
public function expenseInPeriod(Carbon $start, Carbon $end, $includeShared = false) public function expenseInPeriodCorrected(Carbon $start, Carbon $end, $includeShared = false)
{ {
$query = $this->queryJournalsWithTransactions($start, $end); $query = $this->queryJournalsWithTransactions($start, $end);
if ($includeShared === false) { if ($includeShared === false) {
@@ -59,19 +55,27 @@ class ReportQuery implements ReportQueryInterface
} else { } else {
$query->where('transaction_types.type', 'Withdrawal'); // any withdrawal is fine. $query->where('transaction_types.type', 'Withdrawal'); // any withdrawal is fine.
} }
$query->groupBy('transaction_journals.id')->orderBy('transaction_journals.date'); $query->orderBy('transaction_journals.date');
// get everything, decrypt and return // get everything
$data = $query->get(['transaction_journals.id', 'transaction_journals.description', 'transaction_journals.encrypted', 'transaction_types.type', $data = $query->get(
DB::Raw('SUM(`t_from`.`amount`) as `queryAmount`'), ['transaction_journals.*', 'transaction_types.type', 'ac_to.name as name', 'ac_to.id as account_id', 'ac_to.encrypted as account_encrypted']
'transaction_journals.date', 't_to.account_id as account_id', 'ac_to.name as name', 'ac_to.encrypted as account_encrypted']); );
$data->each( $data->each(
function (Model $object) { function (TransactionJournal $journal) {
$object->name = intval($object->account_encrypted) == 1 ? Crypt::decrypt($object->name) : $object->name; if (intval($journal->account_encrypted) == 1) {
$journal->name = Crypt::decrypt($journal->name);
}
}
);
$data = $data->filter(
function (TransactionJournal $journal) {
if ($journal->amount != 0) {
return $journal;
}
} }
); );
$data->sortByDesc('queryAmount');
return $data; return $data;
} }
@@ -127,9 +131,14 @@ class ReportQuery implements ReportQueryInterface
/** /**
* This method works the same way as ReportQueryInterface::incomeInPeriod does, but instead of returning results
* will simply list the transaction journals only. This should allow any follow up counting to be accurate with
* regards to tags.
*
* This method returns all "income" journals in a certain period, which are both transfers from a shared account * This method returns all "income" journals in a certain period, which are both transfers from a shared account
* and "ordinary" deposits. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does * and "ordinary" deposits. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does
* not group and returns different fields. * not group and returns different fields.
* *
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
@@ -137,7 +146,7 @@ class ReportQuery implements ReportQueryInterface
* *
* @return Collection * @return Collection
*/ */
public function incomeInPeriod(Carbon $start, Carbon $end, $includeShared = false) public function incomeInPeriodCorrected(Carbon $start, Carbon $end, $includeShared = false)
{ {
$query = $this->queryJournalsWithTransactions($start, $end); $query = $this->queryJournalsWithTransactions($start, $end);
if ($includeShared === false) { if ($includeShared === false) {
@@ -163,35 +172,34 @@ class ReportQuery implements ReportQueryInterface
// any deposit is fine. // any deposit is fine.
$query->where('transaction_types.type', 'Deposit'); $query->where('transaction_types.type', 'Deposit');
} }
$query->groupBy('transaction_journals.id')->orderBy('transaction_journals.date'); $query->orderBy('transaction_journals.date');
// get everything, decrypt and return // get everything
$data = $query->get( $data = $query->get(
['transaction_journals.id', ['transaction_journals.*', 'transaction_types.type', 'ac_from.name as name', 'ac_from.id as account_id', 'ac_from.encrypted as account_encrypted']
'transaction_journals.description',
'transaction_journals.encrypted',
'transaction_types.type',
DB::Raw('SUM(`t_to`.`amount`) as `queryAmount`'),
'transaction_journals.date',
't_from.account_id as account_id',
'ac_from.name as name',
'ac_from.encrypted as account_encrypted'
]
); );
$data->each( $data->each(
function (Model $object) { function (TransactionJournal $journal) {
$object->name = intval($object->account_encrypted) == 1 ? Crypt::decrypt($object->name) : $object->name; if (intval($journal->account_encrypted) == 1) {
$journal->name = Crypt::decrypt($journal->name);
}
}
);
$data = $data->filter(
function (TransactionJournal $journal) {
if ($journal->amount != 0) {
return $journal;
}
} }
); );
$data->sortByDesc('queryAmount');
return $data; return $data;
} }
/** /**
* Covers tags
*
* @param Account $account * @param Account $account
* @param Budget $budget * @param Budget $budget
* @param Carbon $start * @param Carbon $start
@@ -199,7 +207,7 @@ class ReportQuery implements ReportQueryInterface
* *
* @return float * @return float
*/ */
public function spentInBudget(Account $account, Budget $budget, Carbon $start, Carbon $end) public function spentInBudgetCorrected(Account $account, Budget $budget, Carbon $start, Carbon $end)
{ {
return floatval( return floatval(
@@ -207,13 +215,12 @@ class ReportQuery implements ReportQueryInterface
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->transactionTypes(['Withdrawal']) ->transactionTypes(['Withdrawal'])
->where('transactions.amount', '<', 0)
->where('transactions.account_id', $account->id) ->where('transactions.account_id', $account->id)
->before($end) ->before($end)
->after($start) ->after($start)
->where('budget_transaction_journal.budget_id', $budget->id) ->where('budget_transaction_journal.budget_id', $budget->id)
->sum('transactions.amount') ->get(['transaction_journals.*'])->sum('amount')
); ) * -1;
} }
/** /**

View File

@@ -16,32 +16,8 @@ interface ReportQueryInterface
{ {
/** /**
* Get a users accounts combined with various meta-data related to the start and end date. * See ReportQueryInterface::incomeInPeriodCorrected
* *
* @param Carbon $start
* @param Carbon $end
* @param bool $includeShared
*
* @return Collection
*/
public function getAllAccounts(Carbon $start, Carbon $end, $includeShared = false);
/**
* This method returns all "income" journals in a certain period, which are both transfers from a shared account
* and "ordinary" deposits. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does
* not group and returns different fields.
*
* @param Carbon $start
* @param Carbon $end
* @param bool $includeShared
*
* @return Collection
*
*/
public function incomeInPeriod(Carbon $start, Carbon $end, $includeShared = false);
/**
* This method returns all "expense" journals in a certain period, which are both transfers to a shared account * This method returns all "expense" journals in a certain period, which are both transfers to a shared account
* and "ordinary" withdrawals. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does * and "ordinary" withdrawals. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does
* not group and returns different fields. * not group and returns different fields.
@@ -53,10 +29,35 @@ interface ReportQueryInterface
* @return Collection * @return Collection
* *
*/ */
public function expenseInPeriod(Carbon $start, Carbon $end, $includeShared = false); public function expenseInPeriodCorrected(Carbon $start, Carbon $end, $includeShared = false);
/** /**
* Get a users accounts combined with various meta-data related to the start and end date.
*
* @param Carbon $start
* @param Carbon $end
* @param bool $includeShared
*
* @return Collection
*/
public function getAllAccounts(Carbon $start, Carbon $end, $includeShared = false);
/**
* This method works the same way as ReportQueryInterface::incomeInPeriod does, but instead of returning results
* will simply list the transaction journals only. This should allow any follow up counting to be accurate with
* regards to tags.
*
* @param Carbon $start
* @param Carbon $end
* @param bool $includeShared
*
* @return Collection
*/
public function incomeInPeriodCorrected(Carbon $start, Carbon $end, $includeShared = false);
/**
* Covers tags as well.
*
* @param Account $account * @param Account $account
* @param Budget $budget * @param Budget $budget
* @param Carbon $start * @param Carbon $start
@@ -64,7 +65,7 @@ interface ReportQueryInterface
* *
* @return float * @return float
*/ */
public function spentInBudget(Account $account, Budget $budget, Carbon $start, Carbon $end); public function spentInBudgetCorrected(Account $account, Budget $budget, Carbon $start, Carbon $end);
/** /**
* @param Account $account * @param Account $account

View File

@@ -96,7 +96,7 @@ class AccountController extends Controller
{ {
$what = Config::get('firefly.shortNamesByFullName')[$account->accountType->type]; $what = Config::get('firefly.shortNamesByFullName')[$account->accountType->type];
$subTitle = 'Edit ' . strtolower(e($account->accountType->type)) . ' "' . e($account->name) . '"'; $subTitle = trans('firefly.edit_' . $what . '_account', ['name' => $account->name]);
$subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what); $subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what);
$openingBalance = $repository->openingBalanceTransaction($account); $openingBalance = $repository->openingBalanceTransaction($account);
@@ -170,7 +170,7 @@ class AccountController extends Controller
$subTitleIcon = Config::get('firefly.subTitlesByIdentifier.' . $account->accountType->type); $subTitleIcon = Config::get('firefly.subTitlesByIdentifier.' . $account->accountType->type);
$what = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type); $what = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type);
$journals = $repository->getJournals($account, $page); $journals = $repository->getJournals($account, $page);
$subTitle = 'Details for ' . strtolower(e($account->accountType->type)) . ' "' . e($account->name) . '"'; $subTitle = trans('firefly.details_for_' . $what, ['name' => $account->name]);
$journals->setPath('accounts/show/' . $account->id); $journals->setPath('accounts/show/' . $account->id);

View File

@@ -7,7 +7,6 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\Bill; use FireflyIII\Models\Bill;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use Input; use Input;
use Redirect; use Redirect;

View File

@@ -60,7 +60,7 @@ class BudgetController extends Controller
Session::put('budgets.create.url', URL::previous()); Session::put('budgets.create.url', URL::previous());
} }
Session::forget('budgets.create.fromStore'); Session::forget('budgets.create.fromStore');
$subTitle = 'Create a new budget'; $subTitle = trans('firefly.create_new_budget');
return view('budgets.create', compact('subTitle')); return view('budgets.create', compact('subTitle'));
} }
@@ -138,7 +138,7 @@ class BudgetController extends Controller
function (Budget $budget) use ($repository) { function (Budget $budget) use ($repository) {
$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->spentInPeriod($budget, $date, $end); $budget->spent = $repository->spentInPeriodCorrected($budget, $date, $end);
$budget->currentRep = $repository->getCurrentRepetition($budget, $date); $budget->currentRep = $repository->getCurrentRepetition($budget, $date);
} }
); );

View File

@@ -9,6 +9,8 @@ use FireflyIII\Models\LimitRepetition;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use Grumpydictator\Gchart\GChart; use Grumpydictator\Gchart\GChart;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Navigation;
use Preferences;
use Response; use Response;
use Session; use Session;
@@ -19,6 +21,39 @@ use Session;
*/ */
class BudgetController extends Controller class BudgetController extends Controller
{ {
/**
* @param GChart $chart
* @param BudgetRepositoryInterface $repository
* @param Budget $budget
*/
public function budget(GChart $chart, BudgetRepositoryInterface $repository, Budget $budget)
{
$chart->addColumn(trans('firefly.period'), 'date');
$chart->addColumn(trans('firefly.spent'), 'number');
$first = $repository->getFirstBudgetLimitDate($budget);
$range = $viewRange = Preferences::get('viewRange', '1M')->data;
$last = Session::get('end', new Carbon);
$final = clone $last;
$final->addYears(2);
$last = Navigation::endOfX($last, $range, $final);
while ($first < $last) {
$end = Navigation::addPeriod($first, $range, 0);
$spent = $repository->spentInPeriodCorrected($budget, $first, $end);
$chart->addRow($end, $spent);
$first = Navigation::addPeriod($first, $range, 0);
}
$chart->generate();
return Response::json($chart->getData());
}
/** /**
* Shows the amount left in a specific budget limit. * Shows the amount left in a specific budget limit.
* *
@@ -44,7 +79,7 @@ class BudgetController extends Controller
/* /*
* Sum of expenses on this day: * Sum of expenses on this day:
*/ */
$sum = $repository->expensesOnDay($budget, $start); $sum = $repository->expensesOnDayCorrected($budget, $start);
$amount += $sum; $amount += $sum;
$chart->addRow(clone $start, $amount); $chart->addRow(clone $start, $amount);
$start->addDay(); $start->addDay();
@@ -78,15 +113,15 @@ 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->spentInPeriod($budget, $start, $end, true); $expenses = $repository->spentInPeriodCorrected($budget, $start, $end, true);
$allEntries->push([$budget->name, 0, 0, $expenses]); $allEntries->push([$budget->name, 0, 0, $expenses]);
continue; continue;
} }
/** @var LimitRepetition $repetition */ /** @var LimitRepetition $repetition */
foreach ($repetitions as $repetition) { foreach ($repetitions as $repetition) {
$expenses = $repository->spentInPeriod($budget, $repetition->startdate, $repetition->enddate, true); $expenses = $repository->spentInPeriodCorrected($budget, $repetition->startdate, $repetition->enddate, true);
$left = $expenses < floatval($repetition->amount) ? floatval($repetition->amount) - $expenses : 0; $left = $expenses < floatval($repetition->amount) ? floatval($repetition->amount) - $expenses : 0;
$spent = $expenses > floatval($repetition->amount) ? 0 : $expenses; $spent = $expenses > floatval($repetition->amount) ? floatval($repetition->amount) : $expenses;
$overspent = $expenses > floatval($repetition->amount) ? $expenses - floatval($repetition->amount) : 0; $overspent = $expenses > floatval($repetition->amount) ? $expenses - floatval($repetition->amount) : 0;
$allEntries->push( $allEntries->push(
[$budget->name . ' (' . $repetition->startdate->formatLocalized($this->monthAndDayFormat) . ')', [$budget->name . ' (' . $repetition->startdate->formatLocalized($this->monthAndDayFormat) . ')',
@@ -145,7 +180,7 @@ class BudgetController extends Controller
// each budget, fill the row: // each budget, fill the row:
foreach ($budgets as $budget) { foreach ($budgets as $budget) {
$spent = $repository->spentInPeriod($budget, $start, $month, $shared); $spent = $repository->spentInPeriodCorrected($budget, $start, $month, $shared);
$row[] = $spent; $row[] = $spent;
} }
$chart->addRowArray($row); $chart->addRowArray($row);

View File

@@ -4,7 +4,6 @@ namespace FireflyIII\Http\Controllers\Chart;
use Carbon\Carbon; use Carbon\Carbon;
use Crypt;
use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Category; use FireflyIII\Models\Category;
use FireflyIII\Models\LimitRepetition; use FireflyIII\Models\LimitRepetition;
@@ -50,7 +49,7 @@ class CategoryController extends Controller
while ($start <= $end) { while ($start <= $end) {
$currentEnd = Navigation::endOfPeriod($start, $range); $currentEnd = Navigation::endOfPeriod($start, $range);
$spent = $repository->spentInPeriod($category, $start, $currentEnd); $spent = $repository->spentInPeriodCorrected($category, $start, $currentEnd);
$chart->addRow(clone $start, $spent); $chart->addRow(clone $start, $spent);
$start = Navigation::addPeriod($start, $range, 0); $start = Navigation::addPeriod($start, $range, 0);
@@ -78,13 +77,26 @@ class CategoryController extends Controller
$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());
$set = $repository->getCategoriesAndExpenses($start, $end); $set = $repository->getCategoriesAndExpensesCorrected($start, $end);
// sort by callback:
uasort(
$set,
function ($left, $right) {
if ($left['sum'] == $right['sum']) {
return 0;
}
return ($left['sum'] < $right['sum']) ? 1 : -1;
}
);
foreach ($set as $entry) { foreach ($set as $entry) {
$isEncrypted = intval($entry->encrypted) == 1 ? true : false; $sum = floatval($entry['sum']);
$name = strlen($entry->name) == 0 ? trans('firefly.noCategory') : $entry->name; if ($sum != 0) {
$name = $isEncrypted ? Crypt::decrypt($name) : $name; $chart->addRow($entry['name'], $sum);
$chart->addRow($name, floatval($entry->sum)); }
} }
$chart->generate(); $chart->generate();
@@ -109,7 +121,7 @@ class CategoryController extends Controller
$chart->addColumn(trans('firefly.spent'), 'number'); $chart->addColumn(trans('firefly.spent'), 'number');
while ($start <= $end) { while ($start <= $end) {
$spent = $repository->spentOnDaySum($category, $start); $spent = $repository->spentOnDaySumCorrected($category, $start);
$chart->addRow(clone $start, $spent); $chart->addRow(clone $start, $spent);
$start->addDay(); $start->addDay();
} }
@@ -153,7 +165,7 @@ class CategoryController extends Controller
// each budget, fill the row: // each budget, fill the row:
foreach ($categories as $category) { foreach ($categories as $category) {
$spent = $repository->spentInPeriod($category, $start, $month, $shared); $spent = $repository->spentInPeriodCorrected($category, $start, $month, $shared);
$row[] = $spent; $row[] = $spent;
} }
$chart->addRowArray($row); $chart->addRowArray($row);

View File

@@ -43,8 +43,8 @@ class ReportController extends Controller
$month = clone $start; $month = clone $start;
$month->endOfMonth(); $month->endOfMonth();
// total income and total expenses: // total income and total expenses:
$incomeSum = floatval($query->incomeInPeriod($start, $month, $shared)->sum('queryAmount')); $incomeSum = floatval($query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount'));
$expenseSum = floatval($query->expenseInPeriod($start, $month, $shared)->sum('queryAmount')) * -1; $expenseSum = floatval($query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount'));
$chart->addRow(clone $start, $incomeSum, $expenseSum); $chart->addRow(clone $start, $incomeSum, $expenseSum);
$start->addMonth(); $start->addMonth();
@@ -82,8 +82,8 @@ class ReportController extends Controller
$month = clone $start; $month = clone $start;
$month->endOfMonth(); $month->endOfMonth();
// total income and total expenses: // total income and total expenses:
$income += floatval($query->incomeInPeriod($start, $month, $shared)->sum('queryAmount')); $income += floatval($query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount'));
$expense += floatval($query->expenseInPeriod($start, $month, $shared)->sum('queryAmount')) * -1; $expense += floatval($query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount'));
$count++; $count++;
$start->addMonth(); $start->addMonth();
} }

View File

@@ -122,7 +122,12 @@ class JsonController extends Controller
{ {
$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());
$amount = $reportQuery->incomeInPeriod($start, $end, true)->sum('queryAmount'); $amount = $reportQuery->incomeInPeriodCorrected($start, $end, true)->sum('amount');
// $amount = 0;
// foreach($set as $entry) {
// //echo $entry->description.' ('.$entry->tags->count().'): ' . $entry->amount."\n";
// $amount += $entry->amount;
// }
return Response::json(['box' => 'in', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]); return Response::json(['box' => 'in', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]);
} }
@@ -136,7 +141,7 @@ class JsonController extends Controller
{ {
$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());
$amount = $reportQuery->expenseInPeriod($start, $end, true)->sum('queryAmount') * -1; $amount = $reportQuery->expenseInPeriodCorrected($start, $end, true)->sum('amount');
return Response::json(['box' => 'out', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]); return Response::json(['box' => 'out', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]);
} }

View File

@@ -133,7 +133,7 @@ class TagController extends Controller
* changes to an advancePayment. * changes to an advancePayment.
*/ */
if ($tag->tagMode == 'balancingAct') { if ($tag->tagMode == 'balancingAct' || $tag->tagMode == 'nothing') {
foreach ($tag->transactionjournals as $journal) { foreach ($tag->transactionjournals as $journal) {
if ($journal->transactionType->type == 'Transfer') { if ($journal->transactionType->type == 'Transfer') {
$allowToAdvancePayment = false; $allowToAdvancePayment = false;

View File

@@ -149,7 +149,7 @@ class TransactionController extends Controller
$preFilled['piggy_bank_id'] = $journal->piggyBankEvents()->orderBy('date', 'DESC')->first()->piggy_bank_id; $preFilled['piggy_bank_id'] = $journal->piggyBankEvents()->orderBy('date', 'DESC')->first()->piggy_bank_id;
} }
$preFilled['amount'] = $journal->amount; $preFilled['amount'] = $journal->actualAmount;
$preFilled['account_id'] = $journal->assetAccount->id; $preFilled['account_id'] = $journal->assetAccount->id;
$preFilled['expense_account'] = $transactions[0]->account->name; $preFilled['expense_account'] = $transactions[0]->account->name;
$preFilled['revenue_account'] = $transactions[1]->account->name; $preFilled['revenue_account'] = $transactions[1]->account->name;

View File

@@ -55,10 +55,10 @@ class Range
if (!Session::has('start') && !Session::has('end')) { if (!Session::has('start') && !Session::has('end')) {
/** @var \FireflyIII\Models\Preference $viewRange */ /** @var \FireflyIII\Models\Preference $viewRange */
$viewRange = Preferences::get('viewRange', '1M'); $viewRange = Preferences::get('viewRange', '1M')->data;
$start = new Carbon; $start = new Carbon;
$start = Navigation::updateStartDate($viewRange->data, $start); $start = Navigation::updateStartDate($viewRange, $start);
$end = Navigation::updateEndDate($viewRange->data, $start); $end = Navigation::updateEndDate($viewRange, $start);
Session::put('start', $start); Session::put('start', $start);
Session::put('end', $end); Session::put('end', $end);
@@ -73,9 +73,9 @@ class Range
Session::put('first', Carbon::now()->startOfYear()); Session::put('first', Carbon::now()->startOfYear());
} }
} }
$current = Carbon::now()->format('F Y'); $current = Carbon::now()->formatLocalized('%B %Y');
$next = Carbon::now()->endOfMonth()->addDay()->format('F Y'); $next = Carbon::now()->endOfMonth()->addDay()->formatLocalized('%B %Y');
$prev = Carbon::now()->startOfMonth()->subDay()->format('F Y'); $prev = Carbon::now()->startOfMonth()->subDay()->formatLocalized('%B %Y');
View::share('currentMonthName', $current); View::share('currentMonthName', $current);
View::share('previousMonthName', $prev); View::share('previousMonthName', $prev);
View::share('nextMonthName', $next); View::share('nextMonthName', $next);

View File

@@ -50,25 +50,10 @@ Breadcrumbs::register(
Breadcrumbs::register( Breadcrumbs::register(
'accounts.show', function (Generator $breadcrumbs, Account $account) { 'accounts.show', function (Generator $breadcrumbs, Account $account) {
switch ($account->accountType->type) {
default: $what = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type);
throw new FireflyException('Cannot handle account type "' . e($account->accountType->type) . '"');
break;
case 'Default account':
case 'Asset account':
$what = 'asset';
break;
case 'Cash account':
$what = 'cash';
break;
case 'Expense account':
case 'Beneficiary account':
$what = 'expense';
break;
case 'Revenue account':
$what = 'revenue';
break;
}
$breadcrumbs->parent('accounts.index', $what); $breadcrumbs->parent('accounts.index', $what);
$breadcrumbs->push(e($account->name), route('accounts.show', $account->id)); $breadcrumbs->push(e($account->name), route('accounts.show', $account->id));
} }
@@ -84,7 +69,9 @@ Breadcrumbs::register(
Breadcrumbs::register( Breadcrumbs::register(
'accounts.edit', function (Generator $breadcrumbs, Account $account) { 'accounts.edit', function (Generator $breadcrumbs, Account $account) {
$breadcrumbs->parent('accounts.show', $account); $breadcrumbs->parent('accounts.show', $account);
$breadcrumbs->push(trans('breadcrumbs.edit_account', ['name' => e($account->name)]), route('accounts.edit', $account->id)); $what = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type);
$breadcrumbs->push(trans('breadcrumbs.edit_'.$what.'_account', ['name' => e($account->name)]), route('accounts.edit', $account->id));
} }
); );

View File

@@ -276,7 +276,9 @@ 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/month/{year}/{month}/{shared?}', ['uses' => 'Chart\AccountController@all'])->where(['year' => '[0-9]{4}', 'month' => '[0-9]{1,2}', 'shared' => 'shared']); Route::get('/chart/account/month/{year}/{month}/{shared?}', ['uses' => 'Chart\AccountController@all'])->where(
['year' => '[0-9]{4}', 'month' => '[0-9]{1,2}', 'shared' => 'shared']
);
Route::get('/chart/account/{account}', ['uses' => 'Chart\AccountController@single']); Route::get('/chart/account/{account}', ['uses' => 'Chart\AccountController@single']);
@@ -288,6 +290,7 @@ Route::group(
Route::get('/chart/budget/frontpage', ['uses' => 'Chart\BudgetController@frontpage']); Route::get('/chart/budget/frontpage', ['uses' => 'Chart\BudgetController@frontpage']);
Route::get('/chart/budget/year/{year}/{shared?}', ['uses' => 'Chart\BudgetController@year'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']); Route::get('/chart/budget/year/{year}/{shared?}', ['uses' => 'Chart\BudgetController@year'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']);
Route::get('/chart/budget/{budget}/{limitrepetition}', ['uses' => 'Chart\BudgetController@budgetLimit']); Route::get('/chart/budget/{budget}/{limitrepetition}', ['uses' => 'Chart\BudgetController@budgetLimit']);
Route::get('/chart/budget/{budget}', ['uses' => 'Chart\BudgetController@budget']);
// categories: // categories:
Route::get('/chart/category/frontpage', ['uses' => 'Chart\CategoryController@frontpage']); Route::get('/chart/category/frontpage', ['uses' => 'Chart\CategoryController@frontpage']);

View File

@@ -96,18 +96,42 @@ class TransactionJournal extends Model
} }
// if journal is part of advancePayment AND journal is a withdrawal, // if journal is part of advancePayment AND journal is a withdrawal,
// then journal is being repaid by other journals, so the actual amount will lower: // then journal is being repaid by other journals, so the actual amount will lower:
/** @var Tag $tag */ /** @var Tag $advancePayment */
$tag = $this->tags()->where('tagMode', 'advancePayment')->first(); $advancePayment = $this->tags()->where('tagMode', 'advancePayment')->first();
if ($tag && $this->transactionType->type == 'Withdrawal') { if ($advancePayment && $this->transactionType->type == 'Withdrawal') {
// loop other deposits, remove from our amount. // loop other deposits, remove from our amount.
$others = $tag->transactionJournals()->transactionTypes(['Deposit'])->get(); $others = $advancePayment->transactionJournals()->transactionTypes(['Deposit'])->get();
foreach ($others as $other) { foreach ($others as $other) {
$amount -= $other->amount; $amount -= $other->actualAmount;
} }
return $amount; return $amount;
} }
// if this journal is part of an advancePayment AND the journal is a deposit,
// then the journal amount is correcting a withdrawal, and the amount is zero:
if ($advancePayment && $this->transactionType->type == 'Deposit') {
return 0;
}
// is balancing act?
$balancingAct = $this->tags()->where('tagMode', 'balancingAct')->first();
if ($balancingAct) {
// this is the transfer
// this is the expense:
if ($this->transactionType->type == 'Withdrawal') {
$transfer = $balancingAct->transactionJournals()->transactionTypes(['Transfer'])->first();
if ($transfer) {
$amount -= $transfer->actualAmount;
return $amount;
}
}
}
return $amount; return $amount;
} }

View File

@@ -49,9 +49,11 @@ class BudgetRepository implements BudgetRepositoryInterface
* *
* @return float * @return float
*/ */
public function expensesOnDay(Budget $budget, Carbon $date) public function expensesOnDayCorrected(Budget $budget, Carbon $date)
{ {
return floatval($budget->transactionjournals()->lessThan(0)->transactionTypes(['Withdrawal'])->onDate($date)->sum('amount')); $sum = floatval($budget->transactionjournals()->transactionTypes(['Withdrawal'])->onDate($date)->get(['transaction_journals.*'])->sum('amount'));
return $sum * -1;
} }
/** /**
@@ -99,6 +101,7 @@ class BudgetRepository implements BudgetRepositoryInterface
public function getBudgets() public function getBudgets()
{ {
$budgets = Auth::user()->budgets()->get(); $budgets = Auth::user()->budgets()->get();
return $budgets; return $budgets;
} }
@@ -262,11 +265,11 @@ class BudgetRepository implements BudgetRepositoryInterface
* *
* @return float * @return float
*/ */
public function spentInPeriod(Budget $budget, Carbon $start, Carbon $end, $shared = true) public function spentInPeriodCorrected(Budget $budget, Carbon $start, Carbon $end, $shared = true)
{ {
if ($shared === true) { if ($shared === true) {
// get everything: // get everything:
$sum = floatval($budget->transactionjournals()->before($end)->after($start)->lessThan(0)->sum('amount')) * -1; $sum = floatval($budget->transactionjournals()->before($end)->after($start)->lessThan(0)->get(['transaction_journals.*'])->sum('amount'));
} else { } else {
// 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 = $budget->transactionjournals() $sum = $budget->transactionjournals()
@@ -280,8 +283,9 @@ class BudgetRepository implements BudgetRepositoryInterface
} }
) )
->where('account_meta.data', '!=', '"sharedAsset"') ->where('account_meta.data', '!=', '"sharedAsset"')
->get(['transaction_journals.*'])
->sum('amount'); ->sum('amount');
$sum = floatval($sum) * -1; $sum = floatval($sum);
} }
return $sum; return $sum;
@@ -305,17 +309,7 @@ class BudgetRepository implements BudgetRepositoryInterface
return $newBudget; return $newBudget;
} }
/**
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
*
* @return float
*/
public function sumBudgetExpensesInPeriod(Budget $budget, $start, $end)
{
return floatval($budget->transactionjournals()->before($end)->after($start)->lessThan(0)->sum('amount')) * -1;
}
/** /**
* @param Budget $budget * @param Budget $budget

View File

@@ -27,12 +27,14 @@ interface BudgetRepositoryInterface
public function destroy(Budget $budget); public function destroy(Budget $budget);
/** /**
* Takes tags into account.
*
* @param Budget $budget * @param Budget $budget
* @param Carbon $date * @param Carbon $date
* *
* @return float * @return float
*/ */
public function expensesOnDay(Budget $budget, Carbon $date); public function expensesOnDayCorrected(Budget $budget, Carbon $date);
/** /**
* @return Collection * @return Collection
@@ -123,6 +125,9 @@ interface BudgetRepositoryInterface
public function getWithoutBudgetSum(Carbon $start, Carbon $end); public function getWithoutBudgetSum(Carbon $start, Carbon $end);
/** /**
*
* Same as ::spentInPeriod but corrects journals for their amount (tags).
*
* @param Budget $budget * @param Budget $budget
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
@@ -130,7 +135,7 @@ interface BudgetRepositoryInterface
* *
* @return float * @return float
*/ */
public function spentInPeriod(Budget $budget, Carbon $start, Carbon $end, $shared = true); public function spentInPeriodCorrected(Budget $budget, Carbon $start, Carbon $end, $shared = true);
/** /**
* @param array $data * @param array $data
@@ -139,15 +144,6 @@ interface BudgetRepositoryInterface
*/ */
public function store(array $data); public function store(array $data);
/**
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
*
* @return float
*/
public function sumBudgetExpensesInPeriod(Budget $budget, $start, $end);
/** /**
* @param Budget $budget * @param Budget $budget
* @param array $data * @param array $data

View File

@@ -4,6 +4,7 @@ namespace FireflyIII\Repositories\Category;
use Auth; use Auth;
use Carbon\Carbon; use Carbon\Carbon;
use Crypt;
use DB; use DB;
use FireflyIII\Models\Category; use FireflyIII\Models\Category;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
@@ -58,33 +59,44 @@ class CategoryRepository implements CategoryRepositoryInterface
} }
/** /**
*
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* *
* @return Collection * @return Collection
*/ */
public function getCategoriesAndExpenses($start, $end) public function getCategoriesAndExpensesCorrected($start, $end)
{ {
return TransactionJournal:: $set = Auth::user()->transactionjournals()
where('transaction_journals.user_id', Auth::user()->id)
->leftJoin(
'transactions',
function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('amount', '>', 0);
}
)
->leftJoin( ->leftJoin(
'category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id' 'category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'
) )
->leftJoin('categories', 'categories.id', '=', 'category_transaction_journal.category_id') ->leftJoin('categories', 'categories.id', '=', 'category_transaction_journal.category_id')
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->before($end) ->before($end)
->where('categories.user_id', Auth::user()->id) ->where('categories.user_id', Auth::user()->id)
->after($start) ->after($start)
->where('transaction_types.type', 'Withdrawal') ->transactionTypes(['Withdrawal'])
->groupBy('categories.id') ->groupBy('categories.id')
->orderBy('sum', 'DESC') ->get(['categories.id as category_id', 'categories.encrypted as category_encrypted', 'categories.name', 'transaction_journals.*']);
->get(['categories.id', 'categories.encrypted', 'categories.name', DB::Raw('SUM(`transactions`.`amount`) AS `sum`')]);
$result = [];
foreach ($set as $entry) {
$categoryId = intval($entry->category_id);
if (isset($result[$categoryId])) {
$result[$categoryId]['sum'] += floatval($entry->amount);
} else {
$isEncrypted = intval($entry->category_encrypted) == 1 ? true : false;
$name = strlen($entry->name) == 0 ? trans('firefly.noCategory') : $entry->name;
$name = $isEncrypted ? Crypt::decrypt($name) : $name;
$result[$categoryId] = [
'name' => $name,
'sum' => floatval($entry->amount),
];
}
}
return $result;
} }
/** /**
@@ -172,7 +184,7 @@ class CategoryRepository implements CategoryRepositoryInterface
* *
* @return float * @return float
*/ */
public function spentInPeriod(Category $category, Carbon $start, Carbon $end, $shared = false) public function spentInPeriodCorrected(Category $category, Carbon $start, Carbon $end, $shared = false)
{ {
if ($shared === true) { if ($shared === true) {
// shared is true. // shared is true.
@@ -180,8 +192,8 @@ class CategoryRepository implements CategoryRepositoryInterface
$sum = floatval( $sum = floatval(
$category->transactionjournals() $category->transactionjournals()
->transactionTypes(['Withdrawal']) ->transactionTypes(['Withdrawal'])
->before($end)->after($start)->lessThan(0)->sum('amount') ->before($end)->after($start)->get(['transaction_journals.*'])->sum('amount')
) * -1; );
} else { } else {
// do something else, SEE budgets. // do something else, SEE budgets.
@@ -198,22 +210,24 @@ class CategoryRepository implements CategoryRepositoryInterface
} }
) )
->where('account_meta.data', '!=', '"sharedAsset"') ->where('account_meta.data', '!=', '"sharedAsset"')
->sum('amount'); ->get(['transaction_journals.*'])->sum('amount');
$sum = floatval($sum) * -1; $sum = floatval($sum);
} }
return $sum; return $sum;
} }
/** /**
* Corrected for tags
*
* @param Category $category * @param Category $category
* @param Carbon $date * @param Carbon $date
* *
* @return float * @return float
*/ */
public function spentOnDaySum(Category $category, Carbon $date) public function spentOnDaySumCorrected(Category $category, Carbon $date)
{ {
return floatval($category->transactionjournals()->onDate($date)->lessThan(0)->sum('amount')) * -1; return floatval($category->transactionjournals()->onDate($date)->get(['transaction_journals.*'])->sum('amount'));
} }
/** /**

View File

@@ -33,12 +33,14 @@ interface CategoryRepositoryInterface
public function getCategories(); public function getCategories();
/** /**
* Corrected for tags.
*
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* *
* @return Collection * @return Collection
*/ */
public function getCategoriesAndExpenses($start, $end); public function getCategoriesAndExpensesCorrected($start, $end);
/** /**
* @param Category $category * @param Category $category
@@ -71,6 +73,8 @@ interface CategoryRepositoryInterface
public function getWithoutCategory(Carbon $start, Carbon $end); public function getWithoutCategory(Carbon $start, Carbon $end);
/** /**
* Corrected for tags.
*
* @param Category $category * @param Category $category
* @param \Carbon\Carbon $start * @param \Carbon\Carbon $start
* @param \Carbon\Carbon $end * @param \Carbon\Carbon $end
@@ -79,15 +83,18 @@ interface CategoryRepositoryInterface
* *
* @return float * @return float
*/ */
public function spentInPeriod(Category $category, Carbon $start, Carbon $end, $shared = false); public function spentInPeriodCorrected(Category $category, Carbon $start, Carbon $end, $shared = false);
/** /**
*
* Corrected for tags.
*
* @param Category $category * @param Category $category
* @param Carbon $date * @param Carbon $date
* *
* @return float * @return float
*/ */
public function spentOnDaySum(Category $category, Carbon $date); public function spentOnDaySumCorrected(Category $category, Carbon $date);
/** /**
* @param array $data * @param array $data

View File

@@ -9,7 +9,6 @@ use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\PiggyBankEvent; use FireflyIII\Models\PiggyBankEvent;
use FireflyIII\Models\PiggyBankRepetition; use FireflyIII\Models\PiggyBankRepetition;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Navigation;
/** /**
* Class PiggyBankRepository * Class PiggyBankRepository

View File

@@ -51,6 +51,7 @@ class ExpandedForm
if (isset($options['label'])) { if (isset($options['label'])) {
return $options['label']; return $options['label'];
} }
return trans('form.' . $name); return trans('form.' . $name);
} }

View File

@@ -39,6 +39,22 @@ class Budget extends Twig_Extension
} }
); );
$functions[] = new Twig_SimpleFunction(
'spentInRepetitionCorrected', function (LimitRepetition $repetition) {
$sum
= Auth::user()->transactionjournals()
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budget_transaction_journal.budget_id')
->leftJoin('limit_repetitions', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
->before($repetition->enddate)
->after($repetition->startdate)
->where('limit_repetitions.id', '=', $repetition->id)
->get(['transaction_journals.*'])->sum('amount');
return floatval($sum);
}
);
return $functions; return $functions;
} }

View File

@@ -85,6 +85,7 @@ class Journal extends Twig_Extension
// return tag formatted for a "balancing act", even if other // return tag formatted for a "balancing act", even if other
// tags are present. // tags are present.
$amount = App::make('amount')->formatJournal($journal, false); $amount = App::make('amount')->formatJournal($journal, false);
return '<a href="' . route('tags.show', $tag->id) . '" class="label label-success" title="' . $amount return '<a href="' . route('tags.show', $tag->id) . '" class="label label-success" title="' . $amount
. '"><i class="fa fa-fw fa-refresh"></i> ' . $tag->tag . '</a>'; . '"><i class="fa fa-fw fa-refresh"></i> ' . $tag->tag . '</a>';
} }
@@ -94,6 +95,7 @@ class Journal extends Twig_Extension
*/ */
if ($tag->tagMode == 'advancePayment' && $journal->transactionType->type == 'Deposit') { if ($tag->tagMode == 'advancePayment' && $journal->transactionType->type == 'Deposit') {
$amount = App::make('amount')->formatJournal($journal, false); $amount = App::make('amount')->formatJournal($journal, false);
return '<a href="' . route('tags.show', $tag->id) . '" class="label label-success" title="' . $amount return '<a href="' . route('tags.show', $tag->id) . '" class="label label-success" title="' . $amount
. '"><i class="fa fa-fw fa-sort-numeric-desc"></i> ' . $tag->tag . '</a>'; . '"><i class="fa fa-fw fa-sort-numeric-desc"></i> ' . $tag->tag . '</a>';
} }
@@ -103,6 +105,7 @@ class Journal extends Twig_Extension
*/ */
if ($tag->tagMode == 'advancePayment' && $journal->transactionType->type == 'Withdrawal') { if ($tag->tagMode == 'advancePayment' && $journal->transactionType->type == 'Withdrawal') {
$amount = App::make('amount')->formatJournal($journal); $amount = App::make('amount')->formatJournal($journal);
return '<a href="' . route('tags.show', $tag->id) . '">' . $amount . '</a>'; return '<a href="' . route('tags.show', $tag->id) . '">' . $amount . '</a>';
} }

View File

@@ -56,6 +56,7 @@ return [
'asset' => 'Asset accounts', 'asset' => 'Asset accounts',
'expense' => 'Expense accounts', 'expense' => 'Expense accounts',
'revenue' => 'Revenue accounts', 'revenue' => 'Revenue accounts',
'cash' => 'Cash accounts',
], ],
'subIconsByIdentifier' => 'subIconsByIdentifier' =>
[ [

View File

@@ -8,7 +8,7 @@ $(function () {
if (typeof budgetID !== 'undefined' && typeof repetitionID === 'undefined') { if (typeof budgetID !== 'undefined' && typeof repetitionID === 'undefined') {
googleColumnChart('chart/budget/' + budgetID + '/spending', 'budgetOverview'); googleColumnChart('chart/budget/' + budgetID, 'budgetOverview');
} }
if (typeof budgetID !== 'undefined' && typeof repetitionID !== 'undefined') { if (typeof budgetID !== 'undefined' && typeof repetitionID !== 'undefined') {
googleLineChart('chart/budget/' + budgetID + '/' + repetitionID, 'budgetOverview'); googleLineChart('chart/budget/' + budgetID + '/' + repetitionID, 'budgetOverview');
@@ -95,7 +95,9 @@ function updateTotal() {
} }
function updateIncome(e) { function updateIncome(e) {
$('#monthlyBudgetModal').empty().load('budgets/income').modal('show'); $('#monthlyBudgetModal').empty().load('budgets/income', function () {
$('#monthlyBudgetModal').modal('show');
});
return false; return false;
} }
@@ -112,7 +114,7 @@ function updateRanges() {
var value = parseInt(input.val()); var value = parseInt(input.val());
// calculate sum: // calculate sum:
sum += value sum += value;
// update small display: // update small display:
$('#budget-range-display-' + id).text('\u20AC ' + value.toFixed(2)); $('#budget-range-display-' + id).text('\u20AC ' + value.toFixed(2));

View File

@@ -6,7 +6,7 @@ $(function () {
ranges[currentMonthName] = [moment().startOf('month'), moment().endOf('month')]; ranges[currentMonthName] = [moment().startOf('month'), moment().endOf('month')];
ranges[previousMonthName] = [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]; ranges[previousMonthName] = [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')];
ranges[nextMonthName] = [moment().add(1, 'month').startOf('month'), moment().add(1, 'month').endOf('month')]; ranges[nextMonthName] = [moment().add(1, 'month').startOf('month'), moment().add(1, 'month').endOf('month')];
ranges['Everything'] = [firstDate, moment()]; ranges[everything] = [firstDate, moment()];
$('#daterange').daterangepicker( $('#daterange').daterangepicker(
{ {
@@ -15,10 +15,19 @@ $(function () {
//View::share('nextMonthName', $next); //View::share('nextMonthName', $next);
ranges: ranges ranges: ranges,
,
opens: 'left', opens: 'left',
locale: {
applyLabel: applyLabel,
cancelLabel: cancelLabel,
fromLabel: fromLabel,
toLabel: toLabel,
weekLabel: 'W',
customRangeLabel: customRangeLabel,
daysOfWeek: moment.weekdaysMin(),
monthNames: moment.monthsShort(),
firstDay: moment.localeData()._week.dow
},
format: 'DD-MM-YYYY', format: 'DD-MM-YYYY',
startDate: start, startDate: start,
endDate: end endDate: end

View File

@@ -2,70 +2,85 @@
return [ return [
'home' => 'Home', 'home' => 'Home',
// accounts
'asset_accounts' => 'Asset accounts', 'asset_accounts' => 'Asset accounts',
'expense_accounts' => 'Expense accounts', 'expense_accounts' => 'Expense accounts',
'revenue_accounts' => 'Revenue accounts', 'revenue_accounts' => 'Revenue accounts',
'cash_accounts' => 'Cash accounts',
'new_asset_account' => 'New asset accounts', 'new_asset_account' => 'New asset accounts',
'new_expense_account' => 'New expense account', 'new_expense_account' => 'New expense account',
'new_revenue_account' => 'New revenue account', 'new_revenue_account' => 'New revenue account',
'delete_account' => 'Delete account ":name"', 'delete_account' => 'Delete account ":name"',
'edit_account' => 'Edit account ":name"', 'edit_account' => 'Edit account ":name"',
'edit_asset_account' => 'Edit asset account ":name"',
'edit_expense_account' => 'Edit expense account ":name"',
'edit_revenue_account' => 'Edit revenue account ":name"',
// budgets
'budgets' => 'Budgets', 'budgets' => 'Budgets',
'newBudget' => 'Create a new budget', 'newBudget' => 'Create a new budget',
'delete_budget' => 'Delete budget ":name"', 'delete_budget' => 'Delete budget ":name"',
'edit_budget' => 'Edit budget ":name"', 'edit_budget' => 'Edit budget ":name"',
// categories
'categories' => 'Categories', 'categories' => 'Categories',
'newCategory' => 'Create a new categori', 'newCategory' => 'Create a new categori',
'delete_category' => 'Delete category ":name"', 'delete_category' => 'Delete category ":name"',
'edit_category' => 'Edit category ":name"', 'edit_category' => 'Edit category ":name"',
// currencies
'currencies' => 'Currencies', 'currencies' => 'Currencies',
'edit_currency' => 'Edit currencies ":name"', 'edit_currency' => 'Edit currencies ":name"',
'delete_currency' => 'Delete currencies ":name"', 'delete_currency' => 'Delete currencies ":name"',
// piggy banks
'piggyBanks' => 'Piggy banks', 'piggyBanks' => 'Piggy banks',
'newPiggyBank' => 'Create a new piggy bank', 'newPiggyBank' => 'Create a new piggy bank',
'edit_piggyBank' => 'Edit piggy bank ":name"', 'edit_piggyBank' => 'Edit piggy bank ":name"',
'delete_piggyBank' => 'Delete piggy bank ":name"', 'delete_piggyBank' => 'Delete piggy bank ":name"',
// top menu
'preferences' => 'Preferences', 'preferences' => 'Preferences',
'profile' => 'Profile', 'profile' => 'Profile',
'changePassword' => 'Change your password', 'changePassword' => 'Change your password',
// bills
'bills' => 'Bills', 'bills' => 'Bills',
'newBill' => 'New bill', 'newBill' => 'New bill',
'edit_bill' => 'Edit bill ":name"', 'edit_bill' => 'Edit bill ":name"',
'delete_bill' => 'Delete bill ":name"', 'delete_bill' => 'Delete bill ":name"',
// reminders
'reminders' => 'Reminders', 'reminders' => 'Reminders',
'reminder' => 'Reminder #:id', 'reminder' => 'Reminder #:id',
// reports
'reports' => 'Reports', 'reports' => 'Reports',
'monthly_report' => 'Montly report for :date', 'monthly_report' => 'Montly report for :date',
'monthly_report_shared' => 'Montly report for :date (including shared accounts)', 'monthly_report_shared' => 'Montly report for :date (including shared accounts)',
'yearly_report' => 'Yearly report for :date', 'yearly_report' => 'Yearly report for :date',
'yearly_report_shared' => 'Yearly report for :date (including shared accounts)', 'yearly_report_shared' => 'Yearly report for :date (including shared accounts)',
'budget_report' => 'Budget report for :date', 'budget_report' => 'Budget report for :date',
// search
'searchResult' => 'Search for ":query"', 'searchResult' => 'Search for ":query"',
// transaction lists.
'withdrawal_list' => 'Expenses', 'withdrawal_list' => 'Expenses',
'deposit_list' => 'Revenue, income and deposits', 'deposit_list' => 'Revenue, income and deposits',
'transfer_list' => 'Transfers', 'transfer_list' => 'Transfers',
'transfers_list' => 'Transfers', 'transfers_list' => 'Transfers',
// create transactions
'create_withdrawal' => 'Create new withdrawal', 'create_withdrawal' => 'Create new withdrawal',
'create_deposit' => 'Create new deposit', 'create_deposit' => 'Create new deposit',
'create_transfer' => 'Create new transfer', 'create_transfer' => 'Create new transfer',
// edit transactions
'edit_journal' => 'Edit transaction ":description"', 'edit_journal' => 'Edit transaction ":description"',
'delete_journal' => 'Delete transaction ":description"', 'delete_journal' => 'Delete transaction ":description"',
// tags
'tags' => 'Tags', 'tags' => 'Tags',
'createTag' => 'Create new tag', 'createTag' => 'Create new tag',
'edit_tag' => 'Edit tag ":tag"', 'edit_tag' => 'Edit tag ":tag"',

View File

@@ -1,6 +1,5 @@
<?php <?php
// general fields and things.
return [ return [
'test' => 'You have selected English.', 'test' => 'You have selected English.',
'close' => 'Close', 'close' => 'Close',
@@ -14,6 +13,46 @@ return [
'delete' => 'Delete', 'delete' => 'Delete',
'welcomeBack' => 'What\'s playing?', 'welcomeBack' => 'What\'s playing?',
'everything' => 'Everything',
'customRange' => 'Custom range',
'apply' => 'Apply',
'cancel' => 'Cancel',
'from' => 'From',
'to' => 'To',
'showEverything' => 'Show everything',
'create_new_budget' => 'Create a new budget',
'store_new_budget' => ' Store new budget',
'availableIn' => 'Available in :date',
'transactionsWithoutBudget' => 'Expenses without budget',
'transactionsWithoutBudgetDate' => 'Expenses without budget in :date',
'createBudget' => 'New budget',
'inactiveBudgets' => 'Inactive budgets',
'newCategory' => 'New category',
'withoutCategory' => 'Without a category',
'details_for_asset' => 'Details for asset account ":name"',
'details_for_expense' => 'Details for expense account ":name"',
'details_for_revenue' => 'Details for revenue account ":name"',
'details_for_cash' => 'Details for cash account ":name"',
'store_new_asset_account' => 'Store new asset account',
'store_new_expense_account' => 'Store new expense account',
'store_new_revenue_account' => 'Store new revenue account',
'edit_asset_account' => 'Edit asset account ":name"',
'edit_expense_account' => 'Edit expense account ":name"',
'edit_revenue_account' => 'Edit revenue account ":name"',
'update_asset_account' => 'Update asset account',
'update_expense_account' => 'Update expense account',
'update_revenue_account' => 'Update revenue account',
'make_new_asset_account' => 'New asset account',
'make_new_expense_account' => 'New expense account',
'make_new_revenue_account' => 'New revenue account',
// new user: // new user:
'welcome' => 'Welcome to Firefly!', 'welcome' => 'Welcome to Firefly!',
'createNewAsset' => 'Create a new asset account to get started. This will allow you to create transactions and start your financial management', 'createNewAsset' => 'Create a new asset account to get started. This will allow you to create transactions and start your financial management',
@@ -108,6 +147,7 @@ return [
'splitByAccount' => 'Split by account', 'splitByAccount' => 'Split by account',
'balancedByTransfersAndTags' => 'Balanced by transfers and tags', 'balancedByTransfersAndTags' => 'Balanced by transfers and tags',
'coveredWithTags' => 'Covered with tags',
'leftUnbalanced' => 'Left unbalanced', 'leftUnbalanced' => 'Left unbalanced',
'expectedBalance' => 'Expected balance', 'expectedBalance' => 'Expected balance',
'outsideOfBudgets' => 'Outside of budgets', 'outsideOfBudgets' => 'Outside of budgets',

View File

@@ -13,7 +13,7 @@ return [
'openingBalance' => 'Opening balance', 'openingBalance' => 'Opening balance',
'tagMode' => 'Tag mode', 'tagMode' => 'Tag mode',
'tagPosition' => 'Tag location', 'tagPosition' => 'Tag location',
'virtualBalance' => 'Vitual balance', 'virtualBalance' => 'Virtual balance',
'longitude_latitude' => 'Location', 'longitude_latitude' => 'Location',
'targetamount' => 'Target amount', 'targetamount' => 'Target amount',
'accountRole' => 'Account role', 'accountRole' => 'Account role',

View File

@@ -2,48 +2,59 @@
return [ return [
'home' => 'Home', 'home' => 'Home',
// accounts
'asset_accounts' => 'Betaalrekeningen', 'asset_accounts' => 'Betaalrekeningen',
'expense_accounts' => 'Crediteuren', 'expense_accounts' => 'Crediteuren',
'revenue_accounts' => 'Debiteuren', 'revenue_accounts' => 'Debiteuren',
'cash_accounts' => 'Contant geldrekeningen',
'new_asset_account' => 'Nieuwe betaalrekening', 'new_asset_account' => 'Nieuwe betaalrekening',
'new_expense_account' => 'Nieuwe crediteur', 'new_expense_account' => 'Nieuwe crediteur',
'new_revenue_account' => 'Nieuwe debiteur', 'new_revenue_account' => 'Nieuwe debiteur',
'delete_account' => 'Verwijder rekening ":name"', 'delete_account' => 'Verwijder rekening ":name"',
'edit_account' => 'Wijzig rekening ":name"', 'edit_account' => 'Wijzig rekening ":name"',
'edit_asset_account' => 'Wijzig betaalrekening ":name"',
'edit_expense_account' => 'Wijzig crediteur ":name"',
'edit_revenue_account' => 'Wijzig debiteur ":name"',
// budgets
'budgets' => 'Budgetten', 'budgets' => 'Budgetten',
'newBudget' => 'Maak een nieuw budget', 'newBudget' => 'Maak een nieuw budget',
'delete_budget' => 'Verwijder budget ":name"', 'delete_budget' => 'Verwijder budget ":name"',
'edit_budget' => 'Wijzig budget ":name"', 'edit_budget' => 'Wijzig budget ":name"',
// categories
'categories' => 'Categorieën', 'categories' => 'Categorieën',
'newCategory' => 'Maak een nieuw categorie', 'newCategory' => 'Maak een nieuw categorie',
'delete_category' => 'Verwijder categorie ":name"', 'delete_category' => 'Verwijder categorie ":name"',
'edit_category' => 'Wijzig categorie ":name"', 'edit_category' => 'Wijzig categorie ":name"',
// currencies
'currencies' => 'Munteenheden', 'currencies' => 'Munteenheden',
'edit_currency' => 'Wijzig munteenheid ":name"', 'edit_currency' => 'Wijzig munteenheid ":name"',
'delete_currency' => 'Verwijder munteenheid ":name"', 'delete_currency' => 'Verwijder munteenheid ":name"',
// piggy banks
'piggyBanks' => 'Spaarpotjes', 'piggyBanks' => 'Spaarpotjes',
'newPiggyBank' => 'Nieuw spaarpotje', 'newPiggyBank' => 'Nieuw spaarpotje',
'edit_piggyBank' => 'Wijzig spaarpotje ":name"', 'edit_piggyBank' => 'Wijzig spaarpotje ":name"',
'delete_piggyBank' => 'Verwijder spaarportje ":name"', 'delete_piggyBank' => 'Verwijder spaarportje ":name"',
// top menu
'preferences' => 'Voorkeuren', 'preferences' => 'Voorkeuren',
'profile' => 'Profiel', 'profile' => 'Profiel',
'changePassword' => 'Verander je wachtwoord', 'changePassword' => 'Verander je wachtwoord',
// bills
'bills' => 'Rekeningen', 'bills' => 'Rekeningen',
'newBill' => 'Nieuwe rekening', 'newBill' => 'Nieuwe rekening',
'edit_bill' => 'Wijzig rekening ":name"', 'edit_bill' => 'Wijzig rekening ":name"',
'delete_bill' => 'Verwijder rekening ":name"', 'delete_bill' => 'Verwijder rekening ":name"',
// reminders
'reminders' => 'Herinneringen', 'reminders' => 'Herinneringen',
'reminder' => 'Herinnering #:id', 'reminder' => 'Herinnering #:id',
// reports
'reports' => 'Overzichten', 'reports' => 'Overzichten',
'monthly_report' => 'Maandoverzicht :date', 'monthly_report' => 'Maandoverzicht :date',
'monthly_report_shared' => 'Maandoverzicht :date (inclusief gedeelde rekeningen)', 'monthly_report_shared' => 'Maandoverzicht :date (inclusief gedeelde rekeningen)',
@@ -51,20 +62,25 @@ return [
'yearly_report_shared' => 'Jaaroverzicht :date (inclusief gedeelde rekeningen)', 'yearly_report_shared' => 'Jaaroverzicht :date (inclusief gedeelde rekeningen)',
'budget_report' => 'Budgetoverzicht :date', 'budget_report' => 'Budgetoverzicht :date',
// search
'searchResult' => 'Zoeken naar ":query"', 'searchResult' => 'Zoeken naar ":query"',
// transaction lists.
'withdrawal_list' => 'Uitgaven', 'withdrawal_list' => 'Uitgaven',
'deposit_list' => 'Inkomsten', 'deposit_list' => 'Inkomsten',
'transfer_list' => 'Overschrijvingen', 'transfer_list' => 'Overschrijvingen',
'transfers_list' => 'Overschrijvingen', 'transfers_list' => 'Overschrijvingen',
// create transactions
'create_withdrawal' => 'Sla nieuwe uitgave op', 'create_withdrawal' => 'Sla nieuwe uitgave op',
'create_deposit' => 'Sla nieuwe inkomsten op', 'create_deposit' => 'Sla nieuwe inkomsten op',
'create_transfer' => 'Sla nieuwe overschrijving op', 'create_transfer' => 'Sla nieuwe overschrijving op',
// edit transactions
'edit_journal' => 'Wijzig transactie ":description"', 'edit_journal' => 'Wijzig transactie ":description"',
'delete_journal' => 'Verwijder transactie ":description"', 'delete_journal' => 'Verwijder transactie ":description"',
// tags
'tags' => 'Tags', 'tags' => 'Tags',
'createTag' => 'Maak nieuwe tag', 'createTag' => 'Maak nieuwe tag',
'edit_tag' => 'Wijzig tag ":tag"', 'edit_tag' => 'Wijzig tag ":tag"',

View File

@@ -1,6 +1,5 @@
<?php <?php
// general fields and things.
return [ return [
'test' => 'Nederlands geselecteerd!', 'test' => 'Nederlands geselecteerd!',
'close' => 'Sluiten', 'close' => 'Sluiten',
@@ -14,6 +13,46 @@ return [
'delete' => 'Verwijder', 'delete' => 'Verwijder',
'welcomeBack' => 'Hoe staat het er voor?', 'welcomeBack' => 'Hoe staat het er voor?',
'everything' => 'Alles',
'customRange' => 'Zelf bereik kiezen',
'apply' => 'Go',
'cancel' => 'Annuleren',
'from' => 'Van',
'to' => 'Tot',
'showEverything' => 'Laat alles zien',
'create_new_budget' => 'Maak een nieuw budget',
'store_new_budget' => 'Sla nieuw budget op',
'availableIn' => 'Beschikbaar in :date',
'transactionsWithoutBudget' => 'Uitgaven zonder budget',
'transactionsWithoutBudgetDate' => 'Uitgaven zonder budget in :date',
'createBudget' => 'Maak nieuw budget',
'inactiveBudgets' => 'Inactieve budgetten',
'newCategory' => 'Nieuwe categorie',
'withoutCategory' => 'Zonder categorie',
'details_for_asset' => 'Overzicht voor betaalrekening ":name"',
'details_for_expense' => 'Overzicht voor crediteur ":name"',
'details_for_revenue' => 'Overzicht voor debiteur ":name"',
'details_for_cash' => 'Overzicht voor contant geldrekening ":name"',
'store_new_asset_account' => 'Sla nieuwe betaalrekening op',
'store_new_expense_account' => 'Sla nieuwe crediteur op',
'store_new_revenue_account' => 'Sla nieuwe debiteur op',
'edit_asset_account' => 'Wijzig betaalrekening ":name"',
'edit_expense_account' => 'Wijzig crediteur ":name"',
'edit_revenue_account' => 'Wijzig debiteur ":name"',
'update_asset_account' => 'Wijzig betaalrekening',
'update_expense_account' => 'Wijzig crediteur',
'update_revenue_account' => 'Wijzig debiteur',
'make_new_asset_account' => 'Nieuwe betaalrekening',
'make_new_expense_account' => 'Nieuwe crediteur',
'make_new_revenue_account' => 'Nieuwe debiteur',
// new user: // new user:
'welcome' => 'Welkom bij Firefly!', 'welcome' => 'Welkom bij Firefly!',
'createNewAsset' => 'Maak om te beginnen een nieuwe betaalrekening. Dit is je start van je financiële beheer.', 'createNewAsset' => 'Maak om te beginnen een nieuwe betaalrekening. Dit is je start van je financiële beheer.',
@@ -157,7 +196,8 @@ return [
// some extra help: // some extra help:
'accountExtraHelp_asset' => '', 'accountExtraHelp_asset' => '',
'accountExtraHelp_expense' => 'Een crediteur is een persoon of een bedrijf waar je geld aan moet betalen. Je staat bij ze in het krijt. Een verwarrende' . 'accountExtraHelp_expense' =>
'Een crediteur is een persoon of een bedrijf waar je geld aan moet betalen. Je staat bij ze in het krijt. Een verwarrende' .
' term misschien, maar zo werkt het nou eenmaal. De supermarkt, je huurbaas of de bank zijn crediteuren. Jouw ' . ' term misschien, maar zo werkt het nou eenmaal. De supermarkt, je huurbaas of de bank zijn crediteuren. Jouw ' .
'geld (krediet) gaat naar hen toe. De term komt uit de wereld van de boekhouding. De uitgaves die je hier ziet zijn ' . 'geld (krediet) gaat naar hen toe. De term komt uit de wereld van de boekhouding. De uitgaves die je hier ziet zijn ' .
'positief, want je kijkt uit hun perspectief. Zodra jij afrekent in een winkel, komt het geld er bij hen bij (positief).', 'positief, want je kijkt uit hun perspectief. Zodra jij afrekent in een winkel, komt het geld er bij hen bij (positief).',

View File

@@ -50,7 +50,7 @@
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12"> <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<p> <p>
<button type="submit" class="btn btn-lg btn-success"> <button type="submit" class="btn btn-lg btn-success">
<i class="fa fa-plus-circle"></i> Store new {{ what }} account <i class="fa fa-plus-circle"></i> {{ ('store_new_' ~ what ~ '_account')|_ }}
</button> </button>
</p> </p>
</div> </div>

View File

@@ -62,7 +62,7 @@
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12"> <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<p> <p>
<button type="submit" class="btn btn-lg btn-success"> <button type="submit" class="btn btn-lg btn-success">
Update account {{ ('update_' ~ what ~ '_account')|_ }}
</button> </button>
</p> </p>
</div> </div>

View File

@@ -22,7 +22,7 @@
<span class="caret"></span> <span class="caret"></span>
</button> </button>
<ul class="dropdown-menu pull-right" role="menu"> <ul class="dropdown-menu pull-right" role="menu">
<li><a href="{{route('accounts.create', what)}}"><i class="fa fa-plus fa-fw"></i> New {{ what }} account</a></li> <li><a href="{{route('accounts.create', what)}}"><i class="fa fa-plus fa-fw"></i> {{ ('make_new_' ~ what ~ '_account')|_ }}</a></li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@@ -31,7 +31,7 @@
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12"> <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<p> <p>
<button type="submit" class="btn btn-lg btn-success"> <button type="submit" class="btn btn-lg btn-success">
<i class="fa fa-plus-circle"></i> Store new budget <i class="fa fa-plus-circle"></i> {{ 'store_new_budget'|_ }}
</button> </button>
</p> </p>
</div> </div>

View File

@@ -1,12 +1,6 @@
{% extends "./layout/default.twig" %} {% extends "./layout/default.twig" %}
{% block content %} {% block content %}
{{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, budget) }} {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, budget) }}
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12">
<p class="lead">Use budgets to organize and limit your expenses.</p>
</div>
</div>
{{ Form.model(budget, {'class' : 'form-horizontal','id' : 'update','url' : route('budgets.update',budget.id) } ) }} {{ Form.model(budget, {'class' : 'form-horizontal','id' : 'update','url' : route('budgets.update',budget.id) } ) }}
<input type="hidden" name="id" value="{{budget.id}}" /> <input type="hidden" name="id" value="{{budget.id}}" />
<div class="row"> <div class="row">

View File

@@ -1,13 +1,12 @@
<form style="display: inline;" id="income" action="{{route('budgets.postIncome')}}" method="POST">
<input type="hidden" name="_token" value="{{ csrf_token() }}"
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">{{ 'close'|_ }}</span></button> <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">{{ 'close'|_ }}</span></button>
<h4 class="modal-title" id="myModalLabel">Update (expected) available amount for {{Session.get('start').format('F Y')}}</h4> <h4 class="modal-title" id="myModalLabel">Update (expected) available amount for {{Session.get('start').format('F Y')}}</h4>
</div> </div>
<form style="display: inline;" id="income" action="{{route('budgets.postIncome')}}" method="POST">
<div class="modal-body"> <div class="modal-body">
<input type="hidden" name="_token" value="{{ csrf_token() }}"
<div class="input-group"> <div class="input-group">
<div class="input-group-addon">{{ getCurrencySymbol() }}</div> <div class="input-group-addon">{{ getCurrencySymbol() }}</div>
<input step="any" class="form-control" id="amount" value="{{ amount.data }}" autocomplete="off" name="amount" type="number"> <input step="any" class="form-control" id="amount" value="{{ amount.data }}" autocomplete="off" name="amount" type="number">
@@ -17,6 +16,6 @@
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'close'|_ }}</button> <button type="button" class="btn btn-default" data-dismiss="modal">{{ 'close'|_ }}</button>
<button type="submit" class="btn btn-primary">Update</button> <button type="submit" class="btn btn-primary">Update</button>
</div> </div>
</div>
</div>
</form> </form>
</div>
</div>

View File

@@ -14,7 +14,7 @@
<small>{{ 'budgeted'|_ }}: <span id="budgetedAmount" data-value="300"></span></small> <small>{{ 'budgeted'|_ }}: <span id="budgetedAmount" data-value="300"></span></small>
</div> </div>
<div class="col-lg-6 col-md-4 col-sm-3" style="text-align:right;"> <div class="col-lg-6 col-md-4 col-sm-3" style="text-align:right;">
<small>Available in {{ Session.get('start').formatLocalized(monthFormat) }}: <small>{{ trans('firefly.availableIn',{date : Session.get('start').formatLocalized(monthFormat) }) }}:
<a href="#" class="updateIncome"><span id="totalAmount" data-value="{{ amount }}">{{ amount|formatAmount }}</span></a></small> <a href="#" class="updateIncome"><span id="totalAmount" data-value="{{ amount }}">{{ amount|formatAmount }}</span></a></small>
</div> </div>
</div> </div>
@@ -60,12 +60,13 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<i class="fa fa-fw fa-tags"></i> <i class="fa fa-fw fa-tags"></i>
Transactions without a budget {{ 'transactionsWithoutBudget'|_ }}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<p> <p>
<a href="{{ route('budgets.noBudget') }}">Transactions without a budget in <a href="{{ route('budgets.noBudget') }}">
{{ Session.get('start').format('F Y') }}.</a> {{ trans('firefly.transactionsWithoutBudgetDate', {date: Session.get('start').formatLocalized(monthFormat)}) }}
</a>
</p> </p>
</div> </div>
</div> </div>
@@ -144,7 +145,7 @@
</p> </p>
<p> <p>
<span id="spent-{{ budget.id }}" data-value="{{ budget.spent }}">Spent: {{ budget.spent|formatAmount }}</span> <span id="spent-{{ budget.id }}" data-value="{{ budget.spent }}">{{ 'spent'|_ }}: {{ budget.spent|formatAmount }}</span>
</p> </p>
</div> </div>
</div> </div>
@@ -154,10 +155,10 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<i class="fa fa-fw fa-plus-circle"></i> <i class="fa fa-fw fa-plus-circle"></i>
Create budget {{ 'createBudget'|_ }}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<a href="{{ route('budgets.create') }}" class="btn btn-success"><i class="fa fa-fw fa-plus"></i> Create new budget</a> <a href="{{ route('budgets.create') }}" class="btn btn-success"><i class="fa fa-fw fa-plus"></i> {{ 'createBudget'|_ }}</a>
</div> </div>
</div> </div>
</div> </div>
@@ -166,7 +167,7 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<i class="fa fa-fw fa-minus-circle"></i> <i class="fa fa-fw fa-minus-circle"></i>
Inactive budgets {{ 'inactiveBudgets'|_ }}
</div> </div>
<div class="panel-body"> <div class="panel-body">
{% for index,budget in inactive %} {% for index,budget in inactive %}
@@ -184,6 +185,8 @@
<!-- DIALOG --> <!-- DIALOG -->
<div class="modal fade" id="monthlyBudgetModal"> <div class="modal fade" id="monthlyBudgetModal">
</div><!-- /.modal --> </div><!-- /.modal -->
{% endblock %} {% endblock %}

View File

@@ -29,36 +29,36 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
Transactions {{ 'transactions'|_ }}
</div> </div>
{% include 'list/journals.twig' %} {% include 'list/journals.twig' %}
</div> </div>
</div> </div>
<div class="col-lg-3 col-md-3 col-sm-5"> <div class="col-lg-3 col-md-3 col-sm-5">
{% if limits|length == 1 %} {% if limits|length == 1 %}
<p class="small text-center"><a href="{{ route('budgets.show',budget.id) }}">Show everything</a></p> <p class="small text-center"><a href="{{ route('budgets.show',budget.id) }}">{{ 'showEverything'|_ }}</a></p>
{% endif %} {% endif %}
{% for limit in limits %} {% for limit in limits %}
{% for rep in limit.limitRepetitions %} {% for rep in limit.limitRepetitions %}
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<a href="{{route('budgets.show',[budget.id,rep.id])}}">{{rep.startdate.format('F Y')}}</a> <a href="{{route('budgets.show',[budget.id,rep.id])}}">{{rep.startdate.formatLocalized(monthFormat)}}</a>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<div class="row"> <div class="row">
<div class="col-lg-6 col-md-6 col-sm-6"> <div class="col-lg-6 col-md-6 col-sm-6">
Amount: {{ rep.amount|formatAmount }} {{ 'amount'|_ }}: {{ rep.amount|formatAmount }}
</div> </div>
<div class="col-lg-6 col-md-6 col-sm-6"> <div class="col-lg-6 col-md-6 col-sm-6">
Spent: {{ spentInRepetition(rep)|formatAmount }} {{ 'spent'|_ }}: {{ spentInRepetitionCorrected(rep)|formatAmount }}
</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">
{% set overspent = spentInRepetition(rep) > rep.amount %} {% set overspent = spentInRepetitionCorrected(rep) > rep.amount %}
{% if overspent %} {% if overspent %}
{% set spent = spentInRepetition(rep) %} {% set spent = spentInRepetitionCorrected(rep) %}
{% set pct = (spent != 0 ? (rep.amount / spent)*100 : 0) %} {% set pct = (spent != 0 ? (rep.amount / spent)*100 : 0) %}
<div class="progress progress-striped"> <div class="progress progress-striped">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{pct|round}}" aria-valuemin="0" aria-valuemax="100" style="width: {{pct|round}}%;"></div> <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{pct|round}}" aria-valuemin="0" aria-valuemax="100" style="width: {{pct|round}}%;"></div>
@@ -66,7 +66,7 @@
</div> </div>
{% else %} {% else %}
{% set amount = rep.amount %} {% set amount = rep.amount %}
{% set pct = (amount != 0 ? (spentInRepetition(rep) / amount)*100 : 0) %} {% set pct = (amount != 0 ? (spentInRepetitionCorrected(rep) / amount)*100 : 0) %}
<div class="progress progress-striped"> <div class="progress progress-striped">
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="{{pct|round}}" aria-valuemin="0" aria-valuemax="100" style="width: {{pct|round}}%;"></div> <div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="{{pct|round}}" aria-valuemin="0" aria-valuemax="100" style="width: {{pct|round}}%;"></div>
</div> </div>
@@ -79,7 +79,7 @@
{% endfor %} {% endfor %}
{% if limits|length == 1 %} {% if limits|length == 1 %}
<p class="small text-center"><a href="{{route('budgets.show',budget.id)}}">Show everything</a></p> <p class="small text-center"><a href="{{route('budgets.show',budget.id)}}">{{ 'showEverything'|_ }}</a></p>
{% endif %} {% endif %}
</div> </div>

View File

@@ -5,7 +5,7 @@
<div class="col-lg-12 col-md-12 col-sm-12"> <div class="col-lg-12 col-md-12 col-sm-12">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<i class="fa {{ mainTitleIcon }}"></i> Categories <i class="fa {{ mainTitleIcon }}"></i> {{ 'categories'|_ }}
<!-- ACTIONS MENU --> <!-- ACTIONS MENU -->
<div class="pull-right"> <div class="pull-right">
@@ -15,7 +15,7 @@
<span class="caret"></span> <span class="caret"></span>
</button> </button>
<ul class="dropdown-menu pull-right" role="menu"> <ul class="dropdown-menu pull-right" role="menu">
<li><a href="{{ route('categories.create') }}"><i class="fa fa-plus fa-fw"></i> New category</a></li> <li><a href="{{ route('categories.create') }}"><i class="fa fa-plus fa-fw"></i> {{ 'newCategory'|_ }}</a></li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@@ -128,13 +128,22 @@
<script type="text/javascript"> <script type="text/javascript">
var start = "{{Session.get('start').format('d-m-Y')}}"; var start = "{{Session.get('start').format('d-m-Y')}}";
var end = "{{Session.get('end').format('d-m-Y')}}"; var end = "{{Session.get('end').format('d-m-Y')}}";
var titleString = "{{Session.get('start').format('j M Y')}} - {{Session.get('end').format('j M Y')}}"; var titleString = "{{Session.get('start').formatLocalized(monthAndDayFormat)}} - {{Session.get('end').formatLocalized(monthAndDayFormat)}}";
var dateRangeURL = "{{route('daterange')}}"; var dateRangeURL = "{{route('daterange')}}";
var token = "{{csrf_token()}}"; var token = "{{csrf_token()}}";
var firstDate = moment("{{Session.get('first').format('Y-m-d')}}"); var firstDate = moment("{{Session.get('first').format('Y-m-d')}}");
var currentMonthName = "{{ currentMonthName }}"; var currentMonthName = "{{ currentMonthName }}";
var previousMonthName = "{{ previousMonthName }}"; var previousMonthName = "{{ previousMonthName }}";
var language = "{{ language }}"; var language = "{{ language }}";
// translations:
var everything = '{{ 'everything'|_ }}';
var customRangeLabel = '{{ 'customRange'|_ }}';
var applyLabel = '{{ 'apply'|_ }}';
var cancelLabel = '{{ 'cancel'|_ }}';
var fromLabel = '{{ 'from'|_ }}';
var toLabel = '{{ 'to'|_ }}';
var nextMonthName = "{{ nextMonthName }}"; var nextMonthName = "{{ nextMonthName }}";
var currencyCode = '{{getCurrencyCode() }}'; var currencyCode = '{{getCurrencyCode() }}';
$('#daterange span').text(titleString); $('#daterange span').text(titleString);

View File

@@ -9,7 +9,7 @@
<tbody> <tbody>
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td><a href="{{ route('categories.noCategory') }}"><em>Without a category</em></a></td> <td><a href="{{ route('categories.noCategory') }}"><em>{{ 'withoutCategory'|_ }}</em></a></td>
<td>&nbsp;</td> <td>&nbsp;</td>
</tr> </tr>
{% for category in categories %} {% for category in categories %}

View File

@@ -3,27 +3,7 @@
<a class="list-group-item" title="{{journal.date.format('jS M Y')}}" href="{{route('transactions.show',journal.id)}}"> <a class="list-group-item" title="{{journal.date.format('jS M Y')}}" href="{{route('transactions.show',journal.id)}}">
{% if not journal.type %} {{ journal|typeIcon }}
{% if journal.transactiontype.type == 'Withdrawal' %}
<i class="fa fa-long-arrow-left fa-fw" title="{{ trans('list.withdrawal') }}"></i>
{% endif %}
{% if journal.transactiontype.type == 'Deposit' %}
<i class="fa fa-long-arrow-right fa-fw" title="{{ trans('list.deposit') }}"></i>
{% endif %}
{% if journal.transactiontype.type == 'Transfer' %}
<i class="fa fa-fw fa-exchange" title="{{ trans('list.transfer') }}"></i>
{% endif %}
{% else %}
{% if journal.type == 'Withdrawal' %}
<i class="fa fa-long-arrow-left fa-fw" title="{{ trans('list.withdrawal') }}"></i>
{% endif %}
{% if journal.type == 'Deposit' %}
<i class="fa fa-long-arrow-right fa-fw" title="{{ trans('list.deposit') }}"></i>
{% endif %}
{% if journal.type == 'Transfer' %}
<i class="fa fa-fw fa-exchange" title="{{ trans('list.transfer') }}"></i>
{% endif %}
{% endif %}
{{ journal.description }} {{ journal.description }}

View File

@@ -16,7 +16,7 @@
<br /><small>{{ expense.count }} {{ 'transactions'|_|lower }}</small> <br /><small>{{ expense.count }} {{ 'transactions'|_|lower }}</small>
{% endif %} {% endif %}
</td> </td>
<td><span class="text-danger">{{ (expense.amount*-1)|formatAmountPlain }}</span></td> <td><span class="text-danger">{{ (expense.amount)|formatAmountPlain }}</span></td>
</tr> </tr>
{% endfor %} {% endfor %}
{% if expenses.getExpenses|length > expenseTopLength %} {% if expenses.getExpenses|length > expenseTopLength %}
@@ -28,7 +28,7 @@
{% endif %} {% endif %}
<tr> <tr>
<td><em>{{ 'sum'|_ }}</em></td> <td><em>{{ 'sum'|_ }}</em></td>
<td><span class="text-danger">{{ (expenses.getTotal * -1)|formatAmountPlain }}</span></td> <td><span class="text-danger">{{ (expenses.getTotal)|formatAmountPlain }}</span></td>
</tr> </tr>
</table> </table>
</div> </div>

View File

@@ -1,4 +1,3 @@
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@@ -6,13 +5,12 @@
<h4 class="modal-title" id="myModalLabel">Add money to {{ piggyBank.name }}</h4> <h4 class="modal-title" id="myModalLabel">Add money to {{ piggyBank.name }}</h4>
</div> </div>
<form style="display: inline;" id="add" action="{{ route('piggy-banks.add', piggyBank.id) }}" method="POST"> <form style="display: inline;" id="add" action="{{ route('piggy-banks.add', piggyBank.id) }}" method="POST">
<div class="modal-body"> <div class="modal-body">
<p> <p>
The maximum amount you can add is {{ maxAmount|formatAmount }}. The maximum amount you can add is {{ maxAmount|formatAmount }}.
</p> </p>
<div class="input-group"> <div class="input-group">
<div class="input-group-addon">{{ getCurrencySymbol() }}</div> <div class="input-group-addon">{{ getCurrencySymbol()|raw }}</div>
<input type="hidden" name="_token" value="{{ csrf_token() }}" /> <input type="hidden" name="_token" value="{{ csrf_token() }}" />
<input step="any" class="form-control" id="amount" autocomplete="off" name="amount" max="{{ maxAmount|round(2) }}" type="number" /> <input step="any" class="form-control" id="amount" autocomplete="off" name="amount" max="{{ maxAmount|round(2) }}" type="number" />
</div> </div>

View File

@@ -12,7 +12,7 @@
The maximum amount you can remove is {{ currentRelevantRepAmount(piggyBank)|formatAmount }} The maximum amount you can remove is {{ currentRelevantRepAmount(piggyBank)|formatAmount }}
</p> </p>
<div class="input-group"> <div class="input-group">
<div class="input-group-addon">{{ getCurrencySymbol() }}</div> <div class="input-group-addon">{{ getCurrencySymbol()|raw }}</div>
<input step="any" class="form-control" id="amount" autocomplete="off" name="amount" max="{{ currentRelevantRepAmount(piggyBank)|round(2) }}" type="number"> <input step="any" class="form-control" id="amount" autocomplete="off" name="amount" max="{{ currentRelevantRepAmount(piggyBank)|round(2) }}" type="number">
</div> </div>
</div> </div>

View File

@@ -113,7 +113,7 @@ class BudgetControllerTest extends TestCase
$repository->shouldReceive('getActiveBudgets')->once()->andReturn($collection); $repository->shouldReceive('getActiveBudgets')->once()->andReturn($collection);
$repository->shouldReceive('getInactiveBudgets')->once()->andReturn($collection); $repository->shouldReceive('getInactiveBudgets')->once()->andReturn($collection);
$repository->shouldReceive('cleanupBudgets')->once(); $repository->shouldReceive('cleanupBudgets')->once();
$repository->shouldReceive('spentInPeriod')->once(); $repository->shouldReceive('spentInPeriodCorrected')->once();
$repository->shouldReceive('getCurrentRepetition')->once(); $repository->shouldReceive('getCurrentRepetition')->once();
Amount::shouldReceive('getCurrencySymbol')->andReturn('x'); Amount::shouldReceive('getCurrencySymbol')->andReturn('x');
Amount::shouldReceive('format')->andReturn('x'); Amount::shouldReceive('format')->andReturn('x');

View File

@@ -98,7 +98,7 @@ class JsonControllerTest extends TestCase
$this->be($user); $this->be($user);
$repository = $this->mock('FireflyIII\Helpers\Report\ReportQueryInterface'); $repository = $this->mock('FireflyIII\Helpers\Report\ReportQueryInterface');
$repository->shouldReceive('incomeInPeriod')->andReturn(new Collection); $repository->shouldReceive('incomeInPeriodCorrected')->andReturn(new Collection);
Amount::shouldReceive('format')->andReturn('xx'); Amount::shouldReceive('format')->andReturn('xx');
Amount::shouldReceive('getCurrencyCode')->andReturn('X'); Amount::shouldReceive('getCurrencyCode')->andReturn('X');
@@ -112,7 +112,7 @@ class JsonControllerTest extends TestCase
$this->be($user); $this->be($user);
$repository = $this->mock('FireflyIII\Helpers\Report\ReportQueryInterface'); $repository = $this->mock('FireflyIII\Helpers\Report\ReportQueryInterface');
$repository->shouldReceive('expenseInPeriod')->andReturn(new Collection); $repository->shouldReceive('expenseInPeriodCorrected')->andReturn(new Collection);
Amount::shouldReceive('format')->andReturn('xx'); Amount::shouldReceive('format')->andReturn('xx');
Amount::shouldReceive('getCurrencyCode')->andReturn('X'); Amount::shouldReceive('getCurrencyCode')->andReturn('X');

View File

@@ -275,6 +275,65 @@ class TransactionControllerTest extends TestCase
} }
/**
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testStoreTransfer()
{
// account types:
FactoryMuffin::create('FireflyIII\Models\AccountType');
FactoryMuffin::create('FireflyIII\Models\AccountType');
$asset = FactoryMuffin::create('FireflyIII\Models\AccountType');
$account = FactoryMuffin::create('FireflyIII\Models\Account');
$account2 = FactoryMuffin::create('FireflyIII\Models\Account');
$currency = FactoryMuffin::create('FireflyIII\Models\TransactionCurrency');
$piggy = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
FactoryMuffin::create('FireflyIII\Models\TransactionType');
FactoryMuffin::create('FireflyIII\Models\TransactionType');
$journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal');
$this->be($account->user);
$account2->user_id = $account->user_id;
$account->account_type_id = $asset->id;
$account2->account_type_id = $asset->id;
$piggy->account_id = $account->id;
$account->save();
$account2->save();
$piggy->save();
$data = [
'reminder_id' => '',
'what' => 'transfer',
'description' => 'Bla bla bla',
'account_from_id' => $account->id,
'account_to_id' => $account2->id,
'amount' => '100',
'amount_currency_id' => $currency->id,
'date' => '2015-05-05',
'budget_id' => '0',
'create_another' => '1',
'category' => '',
'tags' => '',
'piggy_bank_id' => $piggy->id,
'_token' => 'replaceMe',
];
// mock!
$repository = $this->mock('FireflyIII\Repositories\Journal\JournalRepositoryInterface');
// fake!
$repository->shouldReceive('store')->andReturn($journal);
$repository->shouldReceive('deactivateReminder')->andReturnNull();
$this->call('POST', '/transactions/store/withdrawal', $data);
//$this->assertSessionHas('errors','bla');
$this->assertResponseStatus(302);
$this->assertSessionHas('success');
}
/** /**
* @SuppressWarnings(PHPMD.ExcessiveMethodLength) * @SuppressWarnings(PHPMD.ExcessiveMethodLength)

View File

@@ -1,5 +1,10 @@
<?php <?php
use Carbon\Carbon;
use FireflyIII\Models\AccountMeta;
use Illuminate\Support\Collection;
use League\FactoryMuffin\Facade as FactoryMuffin;
/** /**
* Class ChartAccountControllerTest * Class ChartAccountControllerTest
*/ */
@@ -25,16 +30,93 @@ class ChartAccountControllerTest extends TestCase
public function testAll() public function testAll()
{ {
$this->markTestIncomplete(); $user = FactoryMuffin::create('FireflyIII\User');
FactoryMuffin::create('FireflyIII\Models\AccountType');
FactoryMuffin::create('FireflyIII\Models\AccountType');
$asset = FactoryMuffin::create('FireflyIII\Models\AccountType');
$one = FactoryMuffin::create('FireflyIII\Models\Account');
$two = FactoryMuffin::create('FireflyIII\Models\Account');
$one->account_type_id = $asset->id;
$two->account_type_id = $asset->id;
$one->save();
$two->save();
$accounts = new Collection([$one, $two]);
$date = new Carbon;
$this->be($user);
// make one shared:
AccountMeta::create(
[
'account_id' => $one->id,
'name' => 'accountRole',
'data' => 'sharedAsset'
]
);
// mock!
$repository = $this->mock('FireflyIII\Repositories\Account\AccountRepositoryInterface');
// fake!
$repository->shouldReceive('getAccounts')->once()->andReturn($accounts);
$this->call('GET', '/chart/account/month/' . $date->format('Y/m'));
$this->assertResponseOk();
}
public function testAllShared()
{
$user = FactoryMuffin::create('FireflyIII\User');
$account = FactoryMuffin::create('FireflyIII\Models\Account');
$accounts = new Collection([$account]);
$date = new Carbon;
$this->be($user);
// make it shared:
AccountMeta::create(
[
'account_id' => $account->id,
'name' => 'accountRole',
'data' => 'sharedAsset'
]
);
// mock!
$repository = $this->mock('FireflyIII\Repositories\Account\AccountRepositoryInterface');
// fake!
$repository->shouldReceive('getAccounts')->once()->andReturn($accounts);
$this->call('GET', '/chart/account/month/' . $date->format('Y/m') . '/shared');
$this->assertResponseOk();
} }
public function testFrontpage() public function testFrontpage()
{ {
$this->markTestIncomplete(); $accounts = new Collection([FactoryMuffin::create('FireflyIII\Models\Account')]);
$user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
// mock!
$repository = $this->mock('FireflyIII\Repositories\Account\AccountRepositoryInterface');
// fake!
$repository->shouldReceive('getFrontpageAccounts')->andReturn($accounts);
$this->call('GET', '/chart/account/frontpage');
$this->assertResponseOk();
} }
public function testSingle() public function testSingle()
{ {
$this->markTestIncomplete(); $account = FactoryMuffin::create('FireflyIII\Models\Account');
$this->be($account->user);
$this->call('GET', '/chart/account/' . $account->id);
$this->assertResponseOk();
} }
} }

View File

@@ -1,5 +1,9 @@
<?php <?php
use Carbon\Carbon;
use Illuminate\Support\Collection;
use League\FactoryMuffin\Facade as FactoryMuffin;
/** /**
* Class ChartBillControllerTest * Class ChartBillControllerTest
*/ */
@@ -20,17 +24,62 @@ class ChartBillControllerTest extends TestCase
*/ */
public function tearDown() public function tearDown()
{ {
parent::tearDown(); $user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
} }
public function testFrontpage() public function testFrontpage()
{ {
$this->markTestIncomplete(); $user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
// set!
$bills = new Collection([FactoryMuffin::create('FireflyIII\Models\Bill'), FactoryMuffin::create('FireflyIII\Models\Bill')]);
$journals = new Collection(
[FactoryMuffin::create('FireflyIII\Models\TransactionJournal'), FactoryMuffin::create('FireflyIII\Models\TransactionJournal')]
);
$creditCards = new Collection([FactoryMuffin::create('FireflyIII\Models\Account'), FactoryMuffin::create('FireflyIII\Models\Account')]);
$ranges = [['start' => new Carbon, 'end' => new Carbon]];
// mock!
$repository = $this->mock('FireflyIII\Repositories\Bill\BillRepositoryInterface');
$accounts = $this->mock('FireflyIII\Repositories\Account\AccountRepositoryInterface');
// fake!
$repository->shouldReceive('getActiveBills')->andReturn($bills);
$repository->shouldReceive('getRanges')->andReturn($ranges);
$repository->shouldReceive('getJournalsInRange')->andReturn(new Collection, $journals);
$accounts->shouldReceive('getCreditCards')->andReturn($creditCards);
$accounts->shouldReceive('getTransfersInRange')->andReturn(new Collection);
$repository->shouldReceive('createFakeBill')->andReturn($bills->first());
Steam::shouldReceive('balance')->andReturn(-10,0);
$this->call('GET', '/chart/bill/frontpage');
$this->assertResponseOk();
} }
public function testSingle() public function testSingle()
{ {
$this->markTestIncomplete(); $bill = FactoryMuffin::create('FireflyIII\Models\Bill');
$this->be($bill->user);
// set
$journals = new Collection([FactoryMuffin::create('FireflyIII\Models\TransactionJournal')]);
// mock!
$repository = $this->mock('FireflyIII\Repositories\Bill\BillRepositoryInterface');
$repository->shouldReceive('getJournals')->andReturn($journals);
// fake!
$this->call('GET', '/chart/bill/' . $bill->id);
$this->assertResponseOk();
} }

View File

@@ -1,4 +1,8 @@
<?php <?php
use Carbon\Carbon;
use Illuminate\Support\Collection;
use League\FactoryMuffin\Facade as FactoryMuffin;
/** /**
* Class ChartBudgetControllerTest * Class ChartBudgetControllerTest
@@ -25,17 +29,120 @@ class ChartBudgetControllerTest extends TestCase
public function testBudget() public function testBudget()
{ {
$this->markTestIncomplete(); $budget = FactoryMuffin::create('FireflyIII\Models\Budget');
$this->be($budget->user);
$this->call('GET', '/chart/budget/' . $budget->id);
$this->assertResponseOk();
}
public function testBudgetLimit()
{
$user = FactoryMuffin::create('FireflyIII\User');
$budget = FactoryMuffin::create('FireflyIII\Models\Budget');
/** @var \FireflyIII\Models\BudgetLimit $limit */
$limit = FactoryMuffin::create('FireflyIII\Models\BudgetLimit');
/** @var \FireflyIII\Models\LimitRepetition $repetition */
$repetition = FactoryMuffin::create('FireflyIII\Models\LimitRepetition');
$start = Carbon::now()->startOfMonth();
$end = Carbon::now()->endOfMonth();
$budget->user_id = $user->id;
$limit->budget_id = $budget->id;
$limit->startdate = $start;
$repetition->budget_limit_id = $limit->id;
$repetition->startdate = $start;
$repetition->enddate = $end;
$budget->save();
$limit->save();
$repetition->save();
$this->be($user);
$this->call('GET', '/chart/budget/' . $budget->id . '/' . $repetition->id);
$this->assertResponseOk();
} }
public function testFrontpage() public function testFrontpage()
{ {
$this->markTestIncomplete(); $user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
$start = Carbon::now()->startOfMonth();
$end = Carbon::now()->endOfMonth();
$budgets = new Collection;
$limits = [];
$repetitions = [];
for ($i = 0; $i < 5; $i++) {
/** @var \FireflyIII\Models\Budget $budget */
$budget = FactoryMuffin::create('FireflyIII\Models\Budget');
$budgets->push($budget);
/** @var \FireflyIII\Models\BudgetLimit $limit */
$limit = FactoryMuffin::create('FireflyIII\Models\BudgetLimit');
$limit->budget_id = $budget->id;
$limit->startdate = $start;
$limit->save();
$set = new Collection([$limit]);
$limits[] = $set;
/** @var \FireflyIII\Models\LimitRepetition $repetition */
$repetition = FactoryMuffin::create('FireflyIII\Models\LimitRepetition');
$repetition->budget_limit_id = $limit->id;
$repetition->startdate = $start;
$repetition->enddate = $end;
$repetition->save();
$set = new Collection([$repetition]);
$repetitions[] = $set;
}
// mock!
$repository = $this->mock('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
// fake!
$repository->shouldReceive('getBudgets')->andReturn($budgets);
$repository->shouldReceive('getBudgetLimitRepetitions')->andReturn($repetitions[0], $repetitions[1], new Collection);
$repository->shouldReceive('spentInPeriodCorrected')->andReturn(10);
$repository->shouldReceive('getWithoutBudgetSum')->andReturn(10);
$this->call('GET', '/chart/budget/frontpage');
$this->assertResponseOk();
} }
public function testYear() public function testYear()
{ {
$this->markTestIncomplete(); $user = FactoryMuffin::create('FireflyIII\User');
$budget = FactoryMuffin::create('FireflyIII\Models\Budget');
$collection = new Collection([$budget]);
$this->be($user);
// mock!
$repository = $this->mock('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
// fake!
$repository->shouldReceive('getBudgets')->andReturn($collection);
$repository->shouldReceive('spentInPeriodCorrected')->andReturn(0);
$this->call('GET', '/chart/budget/year/2015');
$this->assertResponseOk();
}
public function testYearShared()
{
$user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
$this->call('GET', '/chart/budget/year/2015/shared');
$this->assertResponseOk();
} }
} }

View File

@@ -1,5 +1,8 @@
<?php <?php
use Illuminate\Support\Collection;
use League\FactoryMuffin\Facade as FactoryMuffin;
/** /**
* Class ChartCategoryControllerTest * Class ChartCategoryControllerTest
*/ */
@@ -25,22 +28,83 @@ class ChartCategoryControllerTest extends TestCase
public function testAll() public function testAll()
{ {
$this->markTestIncomplete();
$category = FactoryMuffin::create('FireflyIII\Models\Category');
$this->be($category->user);
$this->call('GET', '/chart/category/'.$category->id.'/all');
$this->assertResponseOk();
} }
public function testFrontpage() public function testFrontpage()
{ {
$this->markTestIncomplete(); $user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
// make data:
$set = [
['name' => 'Something', 'sum' => 100],
['name' => 'Something Else', 'sum' => 200],
['name' => 'Something Else Entirely', 'sum' => 200]
];
// mock!
$repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
// fake!
$repository->shouldReceive('getCategoriesAndExpensesCorrected')->andReturn($set);
//getCategoriesAndExpensesCorrected
$this->call('GET', '/chart/category/frontpage');
$this->assertResponseOk();
} }
public function testMonth() public function testMonth()
{ {
$this->markTestIncomplete(); $category = FactoryMuffin::create('FireflyIII\Models\Category');
$this->be($category->user);
$this->call('GET', '/chart/category/'.$category->id.'/month');
$this->assertResponseOk();
} }
public function testYear() public function testYear()
{ {
$this->markTestIncomplete(); $user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
$categories = new Collection([FactoryMuffin::create('FireflyIII\Models\Category')]);
// mock!
$repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
// fake!
$repository->shouldReceive('getCategories')->andReturn($categories);
$repository->shouldReceive('spentInPeriodCorrected')->andReturn(0);
$this->call('GET', '/chart/category/year/2015');
$this->assertResponseOk();
}
public function testYearShared()
{
$user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
$categories = new Collection([FactoryMuffin::create('FireflyIII\Models\Category')]);
// mock!
$repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
// fake!
$repository->shouldReceive('getCategories')->andReturn($categories);
$repository->shouldReceive('spentInPeriodCorrected')->andReturn(0);
$this->call('GET', '/chart/category/year/2015/shared');
$this->assertResponseOk();
} }
} }

View File

@@ -1,5 +1,7 @@
<?php <?php
use League\FactoryMuffin\Facade as FactoryMuffin;
/** /**
* Class ChartPiggyBankControllerTest * Class ChartPiggyBankControllerTest
*/ */
@@ -25,6 +27,24 @@ class ChartPiggyBankControllerTest extends TestCase
public function testHistory() public function testHistory()
{ {
$this->markTestIncomplete(); $piggy = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
$this->be($piggy->account->user);
// data:
$obj = new stdClass;
$obj->sum = 100;
$obj->date = '2015-01-01';
$set = [
$obj
];
// mock!
$repository = $this->mock('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface');
// fake!
$repository->shouldReceive('getEventSummarySet')->andReturn($set);
$this->call('GET', '/chart/piggyBank/' . $piggy->id);
$this->assertResponseOk();
} }
} }

View File

@@ -1,5 +1,7 @@
<?php <?php
use League\FactoryMuffin\Facade as FactoryMuffin;
/** /**
* Class ChartReportControllerTest * Class ChartReportControllerTest
*/ */
@@ -25,11 +27,39 @@ class ChartReportControllerTest extends TestCase
public function testYearInOut() public function testYearInOut()
{ {
$this->markTestIncomplete(); $user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
$this->call('GET', '/chart/report/in-out/2015');
$this->assertResponseOk();
}
public function testYearInOutShared()
{
$user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
$this->call('GET', '/chart/report/in-out/2015/shared');
$this->assertResponseOk();
} }
public function testYearInOutSummarized() public function testYearInOutSummarized()
{ {
$this->markTestIncomplete(); $user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
$this->call('GET', '/chart/report/in-out-sum/2015');
$this->assertResponseOk();
}
public function testYearInOutSummarizedShared()
{
$user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
$this->call('GET', '/chart/report/in-out-sum/2015/shared');
$this->assertResponseOk();
} }
} }

View File

@@ -87,6 +87,27 @@ class ReminderHelperTest extends TestCase
$this->assertEquals(0, $result->metadata->leftToSave); $this->assertEquals(0, $result->metadata->leftToSave);
} }
/**
*
*/
public function testCreateReminders()
{
$account = FactoryMuffin::create('FireflyIII\Models\Account');
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
$piggyBank->account_id = $account->id;
$piggyBank->startdate = new Carbon('2015-01-01');
$piggyBank->targetdate = new Carbon('2015-12-31');
$piggyBank->reminder = 'monthly';
$piggyBank->remind_me = true;
$piggyBank->save();
$this->be($account->user);
$this->object->createReminders($piggyBank, new Carbon('2015-05-05'));
$this->assertCount(1, $piggyBank->reminders()->get());
}
public function testGetReminderRangesNull() public function testGetReminderRangesNull()
{ {
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank'); $piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');

View File

@@ -1,10 +1,12 @@
<?php <?php
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Helpers\Collection\Account as AccountCollection;
use FireflyIII\Helpers\Report\ReportHelper; use FireflyIII\Helpers\Report\ReportHelper;
use FireflyIII\Models\AccountMeta; use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\PiggyBankRepetition; use FireflyIII\Models\PiggyBankRepetition;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use Illuminate\Support\Collection;
use League\FactoryMuffin\Facade as FactoryMuffin; use League\FactoryMuffin\Facade as FactoryMuffin;
/** /**
@@ -38,6 +40,307 @@ class ReportHelperTest extends TestCase
parent::tearDown(); parent::tearDown();
} }
/**
* @covers FireflyIII\Helpers\Report\ReportHelper::getAccountReport
* @covers FireflyIII\Helpers\Report\ReportQuery::getAllAccounts
*/
public function testGetAccountReport()
{
FactoryMuffin::create('FireflyIII\Models\AccountType');
FactoryMuffin::create('FireflyIII\Models\AccountType');
$asset = FactoryMuffin::create('FireflyIII\Models\AccountType');
$user = FactoryMuffin::create('FireflyIII\User');
for ($i = 0; $i < 5; $i++) {
$account = FactoryMuffin::create('FireflyIII\Models\Account');
$account->user_id = $user->id;
$account->account_type_id = $asset->id;
$account->save();
}
$this->be($user);
/** @var AccountCollection $object */
$object = $this->object->getAccountReport(Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth(), false);
$this->assertCount(5, $object->getAccounts());
$this->assertEquals(0, $object->getDifference());
$this->assertEquals(0, $object->getEnd());
$this->assertEquals(0, $object->getStart());
}
/**
* @covers FireflyIII\Helpers\Report\ReportHelper::getBalanceReport
* @covers FireflyIII\Helpers\Report\ReportQuery::getAllAccounts
* @covers FireflyIII\Helpers\Report\ReportQuery::spentInBudgetCorrected
*/
public function testGetBalanceReport()
{
// factory!
FactoryMuffin::create('FireflyIII\Models\AccountType');
FactoryMuffin::create('FireflyIII\Models\AccountType');
$asset = FactoryMuffin::create('FireflyIII\Models\AccountType');
$user = FactoryMuffin::create('FireflyIII\User');
$rep = FactoryMuffin::create('FireflyIII\Models\LimitRepetition');
for ($i = 0; $i < 5; $i++) {
$account = FactoryMuffin::create('FireflyIII\Models\Account');
$account->user_id = $user->id;
$account->account_type_id = $asset->id;
$account->save();
}
$set = new Collection;
for ($i = 0; $i < 5; $i++) {
$set->push(FactoryMuffin::create('FireflyIII\Models\Budget'));
}
$this->be($user);
// mock!
$budgetRepos = $this->mock('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$tagRepos = $this->mock('FireflyIII\Repositories\Tag\TagRepositoryInterface');
// fake!
$budgetRepos->shouldReceive('getBudgets')->andReturn($set);
$budgetRepos->shouldReceive('getCurrentRepetition')->andReturn($rep);
$tagRepos->shouldReceive('coveredByBalancingActs')->andReturn(0);
// test!
$object = $this->object->getBalanceReport(Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth(), false);
$this->assertCount(8, $object->getBalanceLines());
$this->assertCount(5, $object->getBalanceHeader()->getAccounts());
}
/**
* @covers FireflyIII\Helpers\Report\ReportHelper::getBillReport
*/
public function testGetBillReport()
{
// factory!
$set = new Collection;
$journals = new Collection;
$left = FactoryMuffin::create('FireflyIII\Models\Account');
$right = FactoryMuffin::create('FireflyIII\Models\Account');
for ($i = 0; $i < 5; $i++) {
$set->push(FactoryMuffin::create('FireflyIII\Models\Bill'));
}
for ($i = 0; $i < 5; $i++) {
$journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal');
Transaction::create(
[
'account_id' => $left->id,
'transaction_journal_id' => $journal->id,
'amount' => rand(-100, 100)
]
);
Transaction::create(
[
'account_id' => $right->id,
'transaction_journal_id' => $journal->id,
'amount' => rand(-100, 100)
]
);
$journals->push($journal);
}
// mock!
$repository = $this->mock('FireflyIII\Repositories\Bill\BillRepositoryInterface');
// fake!
$repository->shouldReceive('getBills')->andReturn($set);
$repository->shouldReceive('getJournalsInRange')->withAnyArgs()->andReturn(new Collection, $journals);
// test!
$object = $this->object->getBillReport(Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth(), false);
$this->assertCount(5, $object->getBills());
}
/**
* @covers FireflyIII\Helpers\Report\ReportHelper::getBudgetReport
*/
public function testGetBudgetReport()
{
// factory!
$user = FactoryMuffin::create('FireflyIII\User');
$set = new Collection;
$rep1 = new Collection;
$rep2 = new Collection;
for ($i = 0; $i < 5; $i++) {
$set->push(FactoryMuffin::create('FireflyIII\Models\Budget'));
}
for ($i = 0; $i < 5; $i++) {
$rep1->push(FactoryMuffin::create('FireflyIII\Models\LimitRepetition'));
}
$this->be($user);
// mock!
$repository = $this->mock('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
// fake!
$repository->shouldReceive('getBudgets')->andReturn($set);
$repository->shouldReceive('getBudgetLimitRepetitions')->andReturn($rep1, $rep2);
$repository->shouldReceive('spentInPeriodCorrected')->andReturn(rand(0, 100));
$repository->shouldReceive('getWithoutBudgetSum')->andReturn(rand(0, 100));
// test!
$object = $this->object->getBudgetReport(Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth(), false);
$this->assertCount(10, $object->getBudgetLines());
}
/**
* @covers FireflyIII\Helpers\Report\ReportHelper::getCategoryReport
*/
public function testGetCategoryReport()
{
// factory!
$user = FactoryMuffin::create('FireflyIII\User');
$set = new Collection;
for ($i = 0; $i < 5; $i++) {
$set->push(FactoryMuffin::create('FireflyIII\Models\Category'));
}
$this->be($user);
// mock!
$repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
// fake!
$repository->shouldReceive('getCategories')->andReturn($set);
$repository->shouldReceive('spentInPeriodCorrected')->andReturn(rand(0, 100));
// test!
$object = $this->object->getCategoryReport(Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth(), false);
$this->assertCount(5, $object->getCategories());
}
/**
* @covers FireflyIII\Helpers\Report\ReportHelper::getExpenseReport
* @covers FireflyIII\Helpers\Report\ReportQuery::expenseInPeriodCorrected
*/
public function testGetExpenseReport()
{
// factory!
$user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
$type = FactoryMuffin::create('FireflyIII\Models\TransactionType');
// create five journals in this month for the report:
$date = Carbon::now()->startOfMonth()->addDay();
$asset = FactoryMuffin::create('FireflyIII\Models\AccountType');
$left = FactoryMuffin::create('FireflyIII\Models\Account');
$right = FactoryMuffin::create('FireflyIII\Models\Account');
$left->account_type_id = $asset->id;
$right->account_type_id = $asset->id;
$right->save();
$left->save();
// save meta for account:
AccountMeta::create([
'account_id' => $left->id,
'name' => 'accountRole',
'data' => 'defaultAsset'
]);
AccountMeta::create([
'account_id' => $right->id,
'name' => 'accountRole',
'data' => 'defaultAsset'
]);
for ($i = 0; $i < 5; $i++) {
$journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal');
$journal->date = $date;
$journal->transaction_type_id = $type->id;
$journal->user_id = $user->id;
$journal->save();
Transaction::create(
[
'account_id' => $left->id,
'transaction_journal_id' => $journal->id,
'amount' => 100
]
);
Transaction::create(
[
'account_id' => $right->id,
'transaction_journal_id' => $journal->id,
'amount' => -100
]
);
}
// test!
$object = $this->object->getExpenseReport(Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth(), true);
$this->assertCount(1, $object->getExpenses());
}
/**
* @covers FireflyIII\Helpers\Report\ReportHelper::getIncomeReport
* @covers FireflyIII\Helpers\Report\ReportQuery::incomeInPeriodCorrected
*/
public function testGetIncomeReport()
{
// factory!
$user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
FactoryMuffin::create('FireflyIII\Models\TransactionType');
$type = FactoryMuffin::create('FireflyIII\Models\TransactionType');
// create five journals in this month for the report:
$date = Carbon::now()->startOfMonth()->addDay();
$left = FactoryMuffin::create('FireflyIII\Models\Account');
$right = FactoryMuffin::create('FireflyIII\Models\Account');
$asset = FactoryMuffin::create('FireflyIII\Models\AccountType');
$left->account_type_id = $asset->id;
$right->account_type_id = $asset->id;
// save meta for account:
AccountMeta::create([
'account_id' => $left->id,
'name' => 'accountRole',
'data' => 'defaultAsset'
]);
AccountMeta::create([
'account_id' => $right->id,
'name' => 'accountRole',
'data' => 'defaultAsset'
]);
$right->save();
$left->save();
for ($i = 0; $i < 5; $i++) {
$journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal');
$journal->date = $date;
$journal->transaction_type_id = $type->id;
$journal->user_id = $user->id;
$journal->save();
Transaction::create(
[
'account_id' => $left->id,
'transaction_journal_id' => $journal->id,
'amount' => 100
]
);
Transaction::create(
[
'account_id' => $right->id,
'transaction_journal_id' => $journal->id,
'amount' => -100
]
);
}
// test!
$object = $this->object->getIncomeReport(Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth(), true);
$this->assertCount(1, $object->getIncomes());
}
/**
* @covers FireflyIII\Helpers\Report\ReportHelper::listOfMonths
*/
public function testListOfMonths() public function testListOfMonths()
{ {
// start of year up until now // start of year up until now

View File

@@ -70,13 +70,13 @@ class BudgetRepositoryTest extends TestCase
} }
/** /**
* @covers FireflyIII\Repositories\Budget\BudgetRepository::expensesOnDay * @covers FireflyIII\Repositories\Budget\BudgetRepository::expensesOnDayCorrected
*/ */
public function testExpensesOnDay() public function testExpensesOnDayCorrected()
{ {
$budget = FactoryMuffin::create('FireflyIII\Models\Budget'); $budget = FactoryMuffin::create('FireflyIII\Models\Budget');
$result = $this->object->expensesOnDay($budget, new Carbon); $result = $this->object->expensesOnDayCorrected($budget, new Carbon);
$this->assertEquals(0, $result); $this->assertEquals(0, $result);
} }
@@ -289,13 +289,13 @@ class BudgetRepositoryTest extends TestCase
} }
/** /**
* @covers FireflyIII\Repositories\Budget\BudgetRepository::spentInPeriod * @covers FireflyIII\Repositories\Budget\BudgetRepository::spentInPeriodCorrected
*/ */
public function testSpentInPeriod() public function testSpentInPeriodCorrected()
{ {
$budget = FactoryMuffin::create('FireflyIII\Models\Budget'); $budget = FactoryMuffin::create('FireflyIII\Models\Budget');
$amount = $this->object->spentInPeriod($budget, new Carbon, new Carbon); $amount = $this->object->spentInPeriodCorrected($budget, new Carbon, new Carbon);
$this->assertEquals(0, $amount); $this->assertEquals(0, $amount);
} }
@@ -316,16 +316,6 @@ class BudgetRepositoryTest extends TestCase
$this->assertEquals($result->name, $data['name']); $this->assertEquals($result->name, $data['name']);
} }
/**
* @covers FireflyIII\Repositories\Budget\BudgetRepository::sumBudgetExpensesInPeriod
*/
public function testSumBudgetExpensesInPeriod()
{
$budget = FactoryMuffin::create('FireflyIII\Models\Budget');
$result = $this->object->sumBudgetExpensesInPeriod($budget, new Carbon, new Carbon);
$this->assertEquals(0, $result);
}
/** /**
* @covers FireflyIII\Repositories\Budget\BudgetRepository::update * @covers FireflyIII\Repositories\Budget\BudgetRepository::update
*/ */

View File

@@ -79,9 +79,9 @@ class CategoryRepositoryTest extends TestCase
} }
/** /**
* @covers FireflyIII\Repositories\Category\CategoryRepository::getCategoriesAndExpenses * @covers FireflyIII\Repositories\Category\CategoryRepository::getCategoriesAndExpensesCorrected
*/ */
public function testGetCategoriesAndExpenses() public function testGetCategoriesAndExpensesCorrected()
{ {
$user = FactoryMuffin::create('FireflyIII\User'); $user = FactoryMuffin::create('FireflyIII\User');
$type = FactoryMuffin::create('FireflyIII\Models\TransactionType'); $type = FactoryMuffin::create('FireflyIII\Models\TransactionType');
@@ -100,9 +100,11 @@ class CategoryRepositoryTest extends TestCase
} }
$this->be($user); $this->be($user);
$set = $this->object->getCategoriesAndExpenses(new Carbon('2015-02-01'), new Carbon('2015-02-28')); $set = $this->object->getCategoriesAndExpensesCorrected(new Carbon('2015-02-01'), new Carbon('2015-02-28'));
$this->assertCount(5, $set); $this->assertCount(5, $set);
$this->assertEquals(0, $set->first()->sum); reset($set);
$this->assertEquals(0, current($set)['sum']);
} }
/** /**
@@ -189,12 +191,12 @@ class CategoryRepositoryTest extends TestCase
} }
/** /**
* @covers FireflyIII\Repositories\Category\CategoryRepository::spentInPeriod * @covers FireflyIII\Repositories\Category\CategoryRepository::spentInPeriodCorrected
*/ */
public function testSpentInPeriodSum() public function testSpentInPeriodSumCorrected()
{ {
$category = FactoryMuffin::create('FireflyIII\Models\Category'); $category = FactoryMuffin::create('FireflyIII\Models\Category');
$sum = $this->object->spentInPeriod($category, new Carbon, new Carbon); $sum = $this->object->spentInPeriodCorrected($category, new Carbon, new Carbon);
$this->assertEquals(0, $sum); $this->assertEquals(0, $sum);
@@ -202,12 +204,12 @@ class CategoryRepositoryTest extends TestCase
} }
/** /**
* @covers FireflyIII\Repositories\Category\CategoryRepository::spentOnDaySum * @covers FireflyIII\Repositories\Category\CategoryRepository::spentOnDaySumCorrected
*/ */
public function testSpentOnDaySum() public function testSpentOnDaySumCorrected()
{ {
$category = FactoryMuffin::create('FireflyIII\Models\Category'); $category = FactoryMuffin::create('FireflyIII\Models\Category');
$sum = $this->object->spentOnDaySum($category, new Carbon); $sum = $this->object->spentOnDaySumCorrected($category, new Carbon);
$this->assertEquals(0, $sum); $this->assertEquals(0, $sum);
} }