firefly-iii/app/Http/Controllers/ReportController.php

451 lines
15 KiB
PHP
Raw Normal View History

2015-02-23 13:25:48 -06:00
<?php namespace FireflyIII\Http\Controllers;
2015-05-16 06:06:38 -05:00
use App;
2015-02-23 13:25:48 -06:00
use Carbon\Carbon;
use FireflyIII\Helpers\Report\ReportHelperInterface;
use FireflyIII\Helpers\Report\ReportQueryInterface;
use FireflyIII\Models\Account;
2015-05-16 06:06:38 -05:00
use FireflyIII\Models\Budget;
use FireflyIII\Models\LimitRepetition;
2015-03-29 05:25:46 -05:00
use FireflyIII\Models\Preference;
use FireflyIII\Models\TransactionJournal;
2015-05-15 13:43:50 -05:00
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
2015-05-16 06:06:38 -05:00
use Illuminate\Support\Collection;
use Session;
2015-02-23 13:25:48 -06:00
use View;
2015-02-23 13:25:48 -06:00
/**
* Class ReportController
*
* @package FireflyIII\Http\Controllers
*/
class ReportController extends Controller
{
2015-03-29 05:25:46 -05:00
/** @var ReportHelperInterface */
protected $helper;
/** @var ReportQueryInterface */
protected $query;
2015-02-23 13:25:48 -06:00
/**
2015-03-29 05:25:46 -05:00
* @param ReportHelperInterface $helper
* @param ReportQueryInterface $query
2015-02-23 13:25:48 -06:00
*/
2015-03-29 05:25:46 -05:00
public function __construct(ReportHelperInterface $helper, ReportQueryInterface $query)
2015-02-23 13:25:48 -06:00
{
2015-05-15 15:00:00 -05:00
parent::__construct();
2015-03-29 05:25:46 -05:00
$this->query = $query;
$this->helper = $helper;
2015-05-15 14:01:24 -05:00
View::share('title', trans('firefly.reports'));
2015-02-23 13:25:48 -06:00
View::share('mainTitleIcon', 'fa-line-chart');
}
/**
* @return View
2015-05-03 05:58:55 -05:00
* @internal param ReportHelperInterface $helper
*
2015-02-23 13:25:48 -06:00
*/
2015-05-15 13:43:50 -05:00
public function index(AccountRepositoryInterface $repository)
2015-02-23 13:25:48 -06:00
{
2015-05-16 06:06:38 -05:00
$start = Session::get('first');
$months = $this->helper->listOfMonths($start);
2015-02-23 13:25:48 -06:00
2015-05-15 13:43:50 -05:00
// does the user have shared accounts?
$accounts = $repository->getAccounts(['Default account', 'Asset account']);
$hasShared = false;
/** @var Account $account */
foreach ($accounts as $account) {
if ($account->getMeta('accountRole') == 'sharedAsset') {
$hasShared = true;
}
}
2015-05-16 06:06:38 -05:00
return view('reports.index', compact('months', 'hasShared'));
2015-02-23 13:25:48 -06:00
}
/**
* @param Account $account
* @param string $year
* @param string $month
*
* @return \Illuminate\View\View
*/
2015-03-29 05:25:46 -05:00
public function modalBalancedTransfers(Account $account, $year = '2014', $month = '1')
{
$start = new Carbon($year . '-' . $month . '-01');
$end = clone $start;
$end->endOfMonth();
2015-03-29 05:25:46 -05:00
$journals = $this->query->balancedTransactionsList($account, $start, $end);
return view('reports.modal-journal-list', compact('journals'));
}
/**
2015-05-03 05:58:55 -05:00
* @param Account $account
* @param string $year
* @param string $month
*
* @return View
2015-05-03 05:58:55 -05:00
* @internal param ReportQueryInterface $query
*
*/
2015-03-29 05:25:46 -05:00
public function modalLeftUnbalanced(Account $account, $year = '2014', $month = '1')
{
$start = new Carbon($year . '-' . $month . '-01');
$end = clone $start;
$end->endOfMonth();
2015-03-29 05:25:46 -05:00
$set = $this->query->getTransactionsWithoutBudget($account, $start, $end);
$journals = $set->filter(
function (TransactionJournal $journal) {
$count = $journal->transactiongroups()->where('relation', 'balance')->count();
if ($count == 0) {
return $journal;
}
2015-05-03 05:58:55 -05:00
return null;
}
);
return view('reports.modal-journal-list', compact('journals'));
}
/**
* @param Account $account
* @param string $year
* @param string $month
*
* @return \Illuminate\View\View
*/
2015-03-29 05:25:46 -05:00
public function modalNoBudget(Account $account, $year = '2014', $month = '1')
{
$start = new Carbon($year . '-' . $month . '-01');
$end = clone $start;
$end->endOfMonth();
2015-03-29 05:25:46 -05:00
$journals = $this->query->getTransactionsWithoutBudget($account, $start, $end);
return view('reports.modal-journal-list', compact('journals'));
}
2015-02-23 13:25:48 -06:00
/**
* @param string $year
* @param string $month
*
* @return \Illuminate\View\View
*/
2015-05-15 13:38:39 -05:00
public function month($year = '2014', $month = '1', $shared = false)
2015-02-23 13:25:48 -06:00
{
2015-05-16 06:06:38 -05:00
$start = new Carbon($year . '-' . $month . '-01');
$subTitle = trans('firefly.reportForMonth', ['date' => $start->formatLocalized($this->monthFormat)]);
$subTitleIcon = 'fa-calendar';
$end = clone $start;
2015-05-16 00:28:58 -05:00
$totalExpense = 0;
$totalIncome = 0;
2015-05-16 01:05:04 -05:00
$incomeTopLength = 8;
$expenseTopLength = 8;
2015-05-15 13:38:39 -05:00
if ($shared == 'shared') {
2015-05-15 15:00:00 -05:00
$shared = true;
2015-05-16 06:06:38 -05:00
$subTitle = trans('firefly.reportForMonthShared', ['date' => $start->formatLocalized($this->monthFormat)]);
2015-05-15 13:38:39 -05:00
}
2015-05-15 14:01:24 -05:00
2015-05-16 06:06:38 -05:00
$end->endOfMonth();
2015-05-15 15:00:00 -05:00
2015-05-16 06:06:38 -05:00
// all accounts:
$accounts = $this->helper->getAccountReport($start, $end, $shared);
2015-05-15 15:00:00 -05:00
/**
* ALL INCOMES.
* Grouped, sorted and summarized.
*/
2015-05-16 06:06:38 -05:00
$set = $this->query->incomeInPeriod($start, $end, $shared);
2015-05-15 15:00:00 -05:00
// group, sort and sum:
$incomes = [];
foreach ($set as $entry) {
$id = $entry->account_id;
$totalIncome += floatval($entry->queryAmount);
if (isset($incomes[$id])) {
$incomes[$id]['amount'] += floatval($entry->queryAmount);
$incomes[$id]['count']++;
} else {
$incomes[$id] = [
'amount' => floatval($entry->queryAmount),
'name' => $entry->name,
'count' => 1,
2015-05-16 00:28:58 -05:00
'id' => $id,
2015-05-15 15:00:00 -05:00
];
}
}
2015-05-16 00:28:58 -05:00
// sort with callback:
uasort(
$incomes, function ($a, $b) {
if ($a['amount'] == $b['amount']) {
return 0;
}
return ($a['amount'] < $b['amount']) ? 1 : -1;
}
);
2015-05-15 15:00:00 -05:00
unset($set, $id);
/**
* GET ALL EXPENSES
* Summarized.
*/
2015-05-16 06:06:38 -05:00
$set = $this->query->expenseInPeriod($start, $end, $shared);
2015-05-16 01:05:04 -05:00
// group, sort and sum:
$expenses = [];
foreach ($set as $entry) {
$id = $entry->account_id;
$totalExpense += floatval($entry->queryAmount);
if (isset($expenses[$id])) {
$expenses[$id]['amount'] += floatval($entry->queryAmount);
$expenses[$id]['count']++;
} else {
$expenses[$id] = [
'amount' => floatval($entry->queryAmount),
'name' => $entry->name,
'count' => 1,
'id' => $id,
];
}
2015-05-15 15:00:00 -05:00
}
2015-05-16 01:05:04 -05:00
// sort with callback:
uasort(
$expenses, function ($a, $b) {
if ($a['amount'] == $b['amount']) {
return 0;
}
return ($a['amount'] < $b['amount']) ? -1 : 1;
}
);
unset($set, $id);
2015-02-23 13:25:48 -06:00
2015-05-16 06:06:38 -05:00
/**
* DO BUDGETS.
*/
/** @var \FireflyIII\Repositories\Budget\BudgetRepositoryInterface $repository */
$repository = App::make('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$set = $repository->getBudgets();
$budgets = new Collection;
$budgetSums = ['budgeted' => 0, 'spent' => 0, 'left' => 0, 'overspent' => 0];
/** @var Budget $budget */
foreach ($set as $budget) {
$repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end);
if ($repetitions->count() == 0) {
$exp = $repository->spentInPeriod($budget, $start, $end, $shared);
$budgets->push([$budget, null, 0, 0, $exp]);
$budgetSums['overspent'] += $exp;
continue;
}
/** @var LimitRepetition $repetition */
foreach ($repetitions as $repetition) {
$exp = $repository->spentInPeriod($budget, $repetition->startdate, $repetition->enddate, $shared);
$left = $exp < floatval($repetition->amount) ? floatval($repetition->amount) - $exp : 0;
$spent = $exp > floatval($repetition->amount) ? 0 : $exp;
$overspent = $exp > floatval($repetition->amount) ? $exp - floatval($repetition->amount) : 0;
$budgetSums['budgeted'] += floatval($repetition->amount);
$budgetSums['spent'] += $spent;
$budgetSums['left'] += $left;
$budgetSums['overspent'] += $overspent;
$budgets->push([$budget, $repetition, $left, $spent, $overspent]);
}
}
$noBudgetExpenses = $repository->getWithoutBudgetSum($start, $end);
$budgets->push([null, null, 0, 0, $noBudgetExpenses]);
$budgetSums['overspent'] += $noBudgetExpenses;
unset($noBudgetExpenses, $repository, $set, $repetition, $repetitions, $exp);
/**
* GET CATEGORIES:
*/
/** @var \FireflyIII\Repositories\Category\CategoryRepositoryInterface $repository */
$repository = App::make('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
$set = $repository->getCategories();
$categories = [];
$categorySum = 0;
foreach ($set as $category) {
$spent = $repository->spentInPeriod($category, $start, $end, $shared);
$categories[] = [$category, $spent];
$categorySum += $spent;
}
// no category:
// sort with callback:
uasort(
$categories, function ($a, $b) {
if ($a[1] == $b[1]) {
return 0;
}
return ($a[1] < $b[1]) ? 1 : -1;
}
);
unset($set, $repository, $spent);
return view(
'reports.month',
compact(
'start', 'shared',
'subTitle', 'subTitleIcon',
'accounts', 'accountsSums',
'incomes', 'totalIncome', 'incomeTopLength',
'expenses', 'totalExpense', 'expenseTopLength',
'budgets', 'budgetSums',
'categories', 'categorySum'
)
);
// get all income and expenses. it's OK.
// $income = $this->query->incomeInPeriod($start, $end, $shared);
// $expensesSet = $this->query->journalsByExpenseAccount($start, $end, $shared);
//
// /**
// * INCLUDE ORIGINAL BUDGET REPORT HERE:
// */
// // should show shared reports?
// /** @var Preference $pref */
// $accountAmounts = []; // array with sums of spent amounts on each account.
// $accounts = $this->query->getAllAccounts($start, $end, $shared); // all accounts and some data.
//
// foreach ($accounts as $account) {
//
// $budgets = $this->query->getBudgetSummary($account, $start, $end);// get budget summary for this account:
// $balancedAmount = $this->query->balancedTransactionsSum($account, $start, $end);
// $accountAmounts[$account->id] = $balancedAmount;
// // balance out the transactions (see transaction groups & tags) ^^
//
// // array with budget information for each account:
// $array = [];
// // should always hide account
// $hide = true;
// // loop all budgets
// /** @var \FireflyIII\Models\Budget $budget */
// foreach ($budgets as $budget) {
// $id = intval($budget->id);
// $data = $budget->toArray();
// $array[$id] = $data;
//
// // no longer hide account if any budget has money in it.
// if (floatval($data['queryAmount']) != 0) {
// $hide = false;
// }
// $accountAmounts[$account->id] += $data['queryAmount'];
// }
// $account->hide = $hide;
// $account->budgetInformation = $array;
// $account->balancedAmount = $balancedAmount;
//
// }
// /**
// * END ORIGINAL BUDGET REPORT
// */
//
// /**
// * Start getBudgetsForMonth DONE
// */
// $budgets = $this->helper->getBudgetsForMonth($date, $shared);
//
// /**
// * End getBudgetsForMonth DONE
// */
// /**
// * Start getCategoriesForMonth DONE
// */
// // all categories.
// $result = $this->query->journalsByCategory($start, $end);
// $categories = Steam::makeArray($result);
//
//
// // all transfers
// if ($shared === false) {
// $result = $this->query->sharedExpensesByCategory($start, $end);
// $transfers = Steam::makeArray($result);
// $merged = Steam::mergeArrays($categories, $transfers);
// } else {
// $merged = $categories;
// }
//
//
// // sort.
// $sorted = Steam::sortNegativeArray($merged);
//
// // limit to $limit:
// $categories = Steam::limitArray($sorted, 10);
//
// /**
// * End getCategoriesForMonth DONE
// */
//
//
// // clean up and sort expenses:
// $expenses = Steam::makeArray($expensesSet);
// $expenses = Steam::sortArray($expenses);
// $expenses = Steam::limitArray($expenses, 10);
//
//
// return view(
// 'reports.month',
// compact(
// 'income', 'expenses', 'budgets', 'accounts', 'categories', 'shared',
// 'date', 'subTitle', 'displaySum', 'subTitleIcon'
// )
// );
}
/**
* @param $year
*
* @return $this
*/
public function year($year, $shared = false)
{
$start = new Carbon('01-01-' . $year);
$end = clone $start;
$subTitle = trans('firefly.reportForYear', ['year' => $year]);
$subTitleIcon = 'fa-bar-chart';
$incomeTopLength = 8;
$expenseTopLength = 8;
if ($shared == 'shared') {
$shared = true;
$subTitle = trans('firefly.reportForYearShared', ['year' => $year]);
}
$end->endOfYear();
$accounts = $this->helper->getAccountReport($start, $end, $shared);
$incomes = $this->helper->getIncomeReport($start, $end, $shared);
$expenses = $this->helper->getExpenseReport($start, $end, $shared);
2015-02-24 15:53:38 -06:00
return view(
2015-05-15 15:00:00 -05:00
'reports.year',
compact(
2015-05-16 06:06:38 -05:00
'start', // the date for this report.
2015-05-15 15:00:00 -05:00
'shared', // is a shared report?
'accounts', // all accounts
'incomes', 'expenses', // expenses and incomes.
2015-05-16 00:28:58 -05:00
'subTitle', 'subTitleIcon', // subtitle and subtitle icon.
'incomeTopLength', // length of income top X
'expenseTopLength' // length of expense top X.
2015-05-15 15:00:00 -05:00
)
2015-02-23 13:25:48 -06:00
);
}
}