firefly-iii/app/controllers/GoogleChartController.php

551 lines
17 KiB
PHP
Raw Normal View History

2014-10-28 10:15:16 -05:00
<?php
2014-10-29 04:30:52 -05:00
use Carbon\Carbon;
2014-12-13 02:36:30 -06:00
use Grumpydictator\Gchart\GChart as GChart;
2014-10-28 10:15:16 -05:00
/**
* Class GoogleChartController
*/
2014-10-29 04:30:52 -05:00
class GoogleChartController extends BaseController
{
2014-10-28 10:15:16 -05:00
2014-12-13 02:36:30 -06:00
/** @var GChart */
protected $_chart;
/**
* @param GChart $chart
*/
public function __construct(GChart $chart)
{
$this->_chart = $chart;
}
2014-11-12 15:36:02 -06:00
/**
* @param Account $account
2014-12-06 10:45:29 -06:00
* @param string $view
*
* @return \Illuminate\Http\JsonResponse
2014-11-12 15:36:02 -06:00
*/
2014-11-28 00:40:04 -06:00
public function accountBalanceChart(Account $account, $view = 'session')
2014-11-12 15:36:02 -06:00
{
2014-12-13 02:36:30 -06:00
$this->_chart->addColumn('Day of month', 'date');
$this->_chart->addColumn('Balance for ' . $account->name, 'number');
2014-11-28 00:40:04 -06:00
2014-12-19 14:18:42 -06:00
// TODO this can be combined in some method, it's coming up quite often, is it?
$start = Session::get('start', Carbon::now()->startOfMonth());
2014-12-13 02:36:30 -06:00
$end = Session::get('end');
$count = $account->transactions()->count();
2014-11-12 15:36:02 -06:00
2014-12-13 02:36:30 -06:00
if ($view == 'all' && $count > 0) {
$first = $account->transactions()->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->orderBy(
'date', 'ASC'
)->first(['transaction_journals.date']);
$last = $account->transactions()->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->orderBy(
'date', 'DESC'
)->first(['transaction_journals.date']);
$start = new Carbon($first->date);
$end = new Carbon($last->date);
2014-11-28 00:40:04 -06:00
}
2014-12-19 14:18:42 -06:00
// todo until this part.
2014-11-28 00:40:04 -06:00
2014-11-12 15:36:02 -06:00
$current = clone $start;
while ($end >= $current) {
2014-12-13 02:36:30 -06:00
$this->_chart->addRow(clone $current, $current > Carbon::now() ? null : Steam::balance($account, $current));
2014-11-12 15:36:02 -06:00
$current->addDay();
}
2014-12-13 02:36:30 -06:00
$this->_chart->generate();
2014-11-12 15:36:02 -06:00
2014-12-13 02:36:30 -06:00
return Response::json($this->_chart->getData());
2014-11-12 15:36:02 -06:00
}
2014-10-29 04:30:52 -05:00
/**
* This method renders the b
*/
public function allAccountsBalanceChart()
{
2014-12-14 13:40:02 -06:00
$this->_chart->addColumn('Day of the month', 'date');
2014-10-29 04:30:52 -05:00
/** @var \FireflyIII\Shared\Preferences\Preferences $preferences */
$preferences = App::make('FireflyIII\Shared\Preferences\Preferences');
$pref = $preferences->get('frontpageAccounts', []);
2014-10-29 04:30:52 -05:00
2014-12-13 15:54:52 -06:00
/** @var \FireflyIII\Database\Account\Account $acct */
$acct = App::make('FireflyIII\Database\Account\Account');
if (count($pref->data) > 0) {
$accounts = $acct->getByIds($pref->data);
} else {
$accounts = $acct->getAssetAccounts();
}
2014-10-29 04:30:52 -05:00
/** @var Account $account */
foreach ($accounts as $account) {
2014-12-14 13:40:02 -06:00
$this->_chart->addColumn('Balance for ' . $account->name, 'number');
2014-10-29 04:30:52 -05:00
}
$start = Session::get('start', Carbon::now()->startOfMonth());
2014-10-29 04:30:52 -05:00
$end = Session::get('end');
$current = clone $start;
while ($end >= $current) {
$row = [clone $current];
foreach ($accounts as $account) {
$row[] = Steam::balance($account, $current);
2014-10-29 04:30:52 -05:00
}
2014-12-14 13:40:02 -06:00
$this->_chart->addRowArray($row);
2014-10-29 04:30:52 -05:00
$current->addDay();
}
2014-12-14 13:40:02 -06:00
$this->_chart->generate();
2014-11-12 15:36:02 -06:00
2014-12-14 13:40:02 -06:00
return Response::json($this->_chart->getData());
2014-10-29 04:30:52 -05:00
}
2014-11-02 11:46:01 -06:00
/**
* @return \Illuminate\Http\JsonResponse
*/
2014-11-12 15:36:02 -06:00
public function allBudgetsHomeChart()
2014-11-02 11:46:01 -06:00
{
2014-12-13 14:59:02 -06:00
$this->_chart->addColumn('Budget', 'string');
$this->_chart->addColumn('Budgeted', 'number');
$this->_chart->addColumn('Spent', 'number');
2014-11-02 11:46:01 -06:00
2014-12-13 15:54:52 -06:00
/** @var \FireflyIII\Database\Budget\Budget $bdt */
$bdt = App::make('FireflyIII\Database\Budget\Budget');
2014-11-12 15:36:02 -06:00
$budgets = $bdt->get();
2014-11-02 11:46:01 -06:00
2014-11-12 15:36:02 -06:00
/** @var Budget $budget */
foreach ($budgets as $budget) {
/** @var \LimitRepetition $repetition */
$repetition = $bdt->repetitionOnStartingOnDate($budget, Session::get('start', Carbon::now()->startOfMonth()));
2014-11-12 15:36:02 -06:00
if (is_null($repetition)) {
// use the session start and end for our search query
$searchStart = Session::get('start', Carbon::now()->startOfMonth());
2014-11-12 15:36:02 -06:00
$searchEnd = Session::get('end');
2014-12-19 14:18:42 -06:00
$limit = 0; // the limit is zero:
2014-11-12 15:36:02 -06:00
} else {
// use the limit's start and end for our search query
$searchStart = $repetition->startdate;
$searchEnd = $repetition->enddate;
2014-12-19 14:18:42 -06:00
$limit = floatval($repetition->amount); // the limit is the repetitions limit:
2014-11-12 15:36:02 -06:00
}
$expenses = floatval($budget->transactionjournals()->before($searchEnd)->after($searchStart)->lessThan(0)->sum('amount')) * -1;
if ($expenses > 0) {
2014-12-13 14:59:02 -06:00
$this->_chart->addRow($budget->name, $limit, $expenses);
2014-11-12 15:36:02 -06:00
}
2014-11-02 11:46:01 -06:00
}
$noBudgetSet = $bdt->transactionsWithoutBudgetInDateRange(Session::get('start', Carbon::now()->startOfMonth()), Session::get('end'));
2014-11-12 15:36:02 -06:00
$sum = $noBudgetSet->sum('amount') * -1;
2014-12-13 14:59:02 -06:00
$this->_chart->addRow('No budget', 0, $sum);
$this->_chart->generate();
2014-11-02 11:46:01 -06:00
2014-12-13 14:59:02 -06:00
return Response::json($this->_chart->getData());
2014-11-02 11:46:01 -06:00
}
2014-11-04 13:37:00 -06:00
2014-11-02 11:46:01 -06:00
/**
* @return \Illuminate\Http\JsonResponse
*/
2014-11-12 15:36:02 -06:00
public function allCategoriesHomeChart()
2014-11-02 11:46:01 -06:00
{
2014-11-12 15:36:02 -06:00
$data = [];
2014-11-02 11:46:01 -06:00
/** @var \Grumpydictator\Gchart\GChart $chart */
$chart = App::make('gchart');
2014-11-12 15:36:02 -06:00
$chart->addColumn('Category', 'string');
$chart->addColumn('Spent', 'number');
2014-11-02 11:46:01 -06:00
2014-12-13 15:54:52 -06:00
/** @var \FireflyIII\Database\TransactionJournal\TransactionJournal $tj */
$tj = App::make('FireflyIII\Database\TransactionJournal\TransactionJournal');
2014-11-02 11:46:01 -06:00
2014-11-12 15:36:02 -06:00
/*
* Get the journals:
*/
$journals = $tj->getInDateRange(Session::get('start', Carbon::now()->startOfMonth()), Session::get('end'));
2014-11-02 11:46:01 -06:00
2014-11-12 15:36:02 -06:00
/** @var \TransactionJournal $journal */
foreach ($journals as $journal) {
if ($journal->transactionType->type == 'Withdrawal') {
$amount = $journal->getAmount();
$category = $journal->categories()->first();
if (!is_null($category)) {
if (isset($data[$category->name])) {
$data[$category->name] += $amount;
} else {
$data[$category->name] = $amount;
}
}
}
}
arsort($data);
foreach ($data as $key => $entry) {
$chart->addRow($key, $entry);
2014-11-02 11:46:01 -06:00
}
$chart->generate();
2014-11-12 15:36:02 -06:00
2014-11-02 11:46:01 -06:00
return Response::json($chart->getData());
}
2014-12-06 10:53:25 -06:00
/**
* @param Budget $budget
* @param LimitRepetition $repetition
*
* @return \Illuminate\Http\JsonResponse
*/
2014-11-15 04:36:27 -06:00
public function budgetLimitSpending(\Budget $budget, \LimitRepetition $repetition)
{
$start = clone $repetition->startdate;
$end = $repetition->enddate;
/** @var \Grumpydictator\Gchart\GChart $chart */
$chart = App::make('gchart');
$chart->addColumn('Day', 'date');
$chart->addColumn('Left', 'number');
$amount = $repetition->amount;
while ($start <= $end) {
/*
* Sum of expenses on this day:
*/
$sum = floatval($budget->transactionjournals()->lessThan(0)->transactionTypes(['Withdrawal'])->onDate($start)->sum('amount'));
$amount += $sum;
$chart->addRow(clone $start, $amount);
$start->addDay();
}
$chart->generate();
return Response::json($chart->getData());
}
2014-12-17 14:32:27 -06:00
/**
* @param Budget $component
* @param $year
*
* @return \Illuminate\Http\JsonResponse
*/
public function budgetsAndSpending(Budget $component, $year)
{
try {
$start = new Carbon('01-01-' . $year);
} catch (Exception $e) {
App::abort(500);
}
/** @var \FireflyIII\Database\Budget\Budget $repos */
$repos = App::make('FireflyIII\Database\Budget\Budget');
/** @var \Grumpydictator\Gchart\GChart $chart */
$chart = App::make('gchart');
$chart->addColumn('Month', 'date');
$chart->addColumn('Budgeted', 'number');
$chart->addColumn('Spent', 'number');
$end = clone $start;
$end->endOfYear();
while ($start <= $end) {
$spent = $repos->spentInMonth($component, $start);
$repetition = $repos->repetitionOnStartingOnDate($component, $start);
if ($repetition) {
$budgeted = floatval($repetition->amount);
} else {
$budgeted = null;
}
$chart->addRow(clone $start, $budgeted, $spent);
$start->addMonth();
}
$chart->generate();
return Response::json($chart->getData());
}
2014-10-29 04:30:52 -05:00
/**
2014-12-17 14:32:27 -06:00
* @param Category $component
2014-11-12 15:36:02 -06:00
* @param $year
*
2014-10-29 04:30:52 -05:00
* @return \Illuminate\Http\JsonResponse
*/
2014-12-17 14:32:27 -06:00
public function categoriesAndSpending(Category $component, $year)
2014-10-29 04:30:52 -05:00
{
2014-11-12 15:36:02 -06:00
try {
$start = new Carbon('01-01-' . $year);
} catch (Exception $e) {
App::abort(500);
}
2014-12-17 14:32:27 -06:00
/** @var \FireflyIII\Database\Category\Category $repos */
$repos = App::make('FireflyIII\Database\Category\Category');
2014-10-29 04:30:52 -05:00
/** @var \Grumpydictator\Gchart\GChart $chart */
$chart = App::make('gchart');
2014-11-12 15:36:02 -06:00
$chart->addColumn('Month', 'date');
$chart->addColumn('Budgeted', 'number');
2014-10-29 04:30:52 -05:00
$chart->addColumn('Spent', 'number');
2014-11-12 15:36:02 -06:00
$end = clone $start;
$end->endOfYear();
while ($start <= $end) {
2014-10-29 04:30:52 -05:00
2014-12-17 14:32:27 -06:00
$spent = $repos->spentInMonth($component, $start);
$budgeted = null;
2014-11-12 15:36:02 -06:00
$chart->addRow(clone $start, $budgeted, $spent);
$start->addMonth();
2014-10-29 04:30:52 -05:00
}
$chart->generate();
2014-11-12 15:36:02 -06:00
2014-10-29 04:30:52 -05:00
return Response::json($chart->getData());
2014-11-12 15:36:02 -06:00
2014-10-29 04:30:52 -05:00
}
2014-12-06 10:53:25 -06:00
/**
* @param Piggybank $piggybank
*
* @return \Illuminate\Http\JsonResponse
*/
2014-11-16 13:03:53 -06:00
public function piggyBankHistory(\Piggybank $piggybank)
{
/** @var \Grumpydictator\Gchart\GChart $chart */
$chart = App::make('gchart');
$chart->addColumn('Date', 'date');
$chart->addColumn('Balance', 'number');
2014-12-14 14:27:13 -06:00
$set = \DB::table('piggy_bank_events')->where('piggybank_id', $piggybank->id)->groupBy('date')->get(['date', DB::Raw('SUM(`amount`) AS `sum`')]);
2014-11-16 13:03:53 -06:00
2014-11-17 00:33:18 -06:00
foreach ($set as $entry) {
2014-11-16 13:03:53 -06:00
$chart->addRow(new Carbon($entry->date), floatval($entry->sum));
}
$chart->generate();
return Response::json($chart->getData());
}
2014-11-15 04:36:27 -06:00
/**
* @param RecurringTransaction $recurring
2014-12-06 10:53:25 -06:00
*
* @return \Illuminate\Http\JsonResponse
2014-11-15 04:36:27 -06:00
*/
public function recurringOverview(RecurringTransaction $recurring)
{
2014-11-14 04:43:08 -06:00
/** @var \Grumpydictator\Gchart\GChart $chart */
$chart = App::make('gchart');
2014-11-15 04:36:27 -06:00
$chart->addColumn('Date', 'date');
$chart->addColumn('Max amount', 'number');
$chart->addColumn('Min amount', 'number');
$chart->addColumn('Current entry', 'number');
// get first transaction or today for start:
$first = $recurring->transactionjournals()->orderBy('date', 'ASC')->first();
if ($first) {
$start = $first->date;
} else {
$start = new Carbon;
2014-11-14 04:43:08 -06:00
}
2014-11-15 04:36:27 -06:00
$end = new Carbon;
while ($start <= $end) {
$result = $recurring->transactionjournals()->before($end)->after($start)->first();
2014-11-16 13:03:53 -06:00
if ($result) {
2014-11-15 04:36:27 -06:00
$amount = $result->getAmount();
} else {
$amount = 0;
}
unset($result);
$chart->addRow(clone $start, $recurring->amount_max, $recurring->amount_min, $amount);
2014-11-21 04:12:22 -06:00
$start = DateKit::addPeriod($start, $recurring->repeat_freq, 0);
2014-11-15 04:36:27 -06:00
}
2014-11-14 04:43:08 -06:00
$chart->generate();
2014-11-15 04:36:27 -06:00
2014-11-14 04:43:08 -06:00
return Response::json($chart->getData());
}
2014-10-30 12:06:29 -05:00
/**
* @return \Illuminate\Http\JsonResponse
* @throws \FireflyIII\Exception\FireflyException
2014-10-30 12:06:29 -05:00
*/
2014-10-29 04:30:52 -05:00
public function recurringTransactionsOverview()
{
/*
* Set of paid transaction journals.
* Set of unpaid recurring transactions.
*/
2014-11-12 15:36:02 -06:00
$paid = ['items' => [], 'amount' => 0];
$unpaid = ['items' => [], 'amount' => 0];
2014-10-29 04:30:52 -05:00
/** @var \Grumpydictator\Gchart\GChart $chart */
$chart = App::make('gchart');
$chart->addColumn('Name', 'string');
$chart->addColumn('Amount', 'number');
2014-12-13 15:54:52 -06:00
/** @var \FireflyIII\Database\RecurringTransaction\RecurringTransaction $rcr */
$rcr = App::make('FireflyIII\Database\RecurringTransaction\RecurringTransaction');
2014-10-29 04:30:52 -05:00
2014-12-15 00:24:01 -06:00
$recurring = $rcr->getActive();
2014-10-29 04:30:52 -05:00
/** @var \RecurringTransaction $entry */
foreach ($recurring as $entry) {
/*
* Start another loop starting at the $date.
*/
$start = clone $entry->date;
$end = Carbon::now();
/*
* The jump we make depends on the $repeat_freq
*/
$current = clone $start;
while ($current <= $end) {
/*
* Get end of period for $current:
*/
$currentEnd = DateKit::endOfPeriod($current, $entry->repeat_freq);
2014-10-29 04:30:52 -05:00
/*
* In the current session range?
*/
if (\Session::get('end') >= $current and $currentEnd >= \Session::get('start', Carbon::now()->startOfMonth())) {
2014-10-29 04:30:52 -05:00
/*
* Lets see if we've already spent money on this recurring transaction (it hath recurred).
*/
/** @var TransactionJournal $set */
$journal = $rcr->getJournalForRecurringInRange($entry, $current, $currentEnd);
if (is_null($journal)) {
$unpaid['items'][] = $entry->name;
$unpaid['amount'] += (($entry->amount_max + $entry->amount_min) / 2);
} else {
2014-11-02 14:24:50 -06:00
$amount = $journal->getAmount();
2014-10-29 04:30:52 -05:00
$paid['items'][] = $journal->description;
$paid['amount'] += $amount;
}
}
/*
* Add some time for the next loop!
*/
$current = DateKit::addPeriod($current, $entry->repeat_freq, intval($entry->skip));
2014-10-29 04:30:52 -05:00
}
}
/** @var \RecurringTransaction $entry */
$chart->addRow('Unpaid: ' . join(', ', $unpaid['items']), $unpaid['amount']);
$chart->addRow('Paid: ' . join(', ', $paid['items']), $paid['amount']);
$chart->generate();
2014-11-15 04:36:27 -06:00
2014-10-30 12:06:29 -05:00
return Response::json($chart->getData());
2014-11-12 15:36:02 -06:00
2014-10-30 12:06:29 -05:00
}
/**
2014-11-12 15:36:02 -06:00
* @param $year
2014-10-30 12:06:29 -05:00
*
* @return \Illuminate\Http\JsonResponse
*/
2014-11-12 15:36:02 -06:00
public function yearInExp($year)
2014-10-30 12:06:29 -05:00
{
2014-11-12 15:36:02 -06:00
try {
$start = new Carbon('01-01-' . $year);
} catch (Exception $e) {
App::abort(500);
}
2014-10-30 12:06:29 -05:00
/** @var \Grumpydictator\Gchart\GChart $chart */
$chart = App::make('gchart');
2014-11-12 15:36:02 -06:00
$chart->addColumn('Month', 'date');
$chart->addColumn('Income', 'number');
$chart->addColumn('Expenses', 'number');
2014-10-30 12:06:29 -05:00
2014-12-14 13:40:02 -06:00
/** @var \FireflyIII\Database\TransactionJournal\TransactionJournal $repository */
$repository = App::make('FireflyIII\Database\TransactionJournal\TransactionJournal');
2014-10-30 12:06:29 -05:00
2014-11-12 15:36:02 -06:00
$end = clone $start;
$end->endOfYear();
while ($start < $end) {
2014-10-30 12:06:29 -05:00
2014-11-12 15:36:02 -06:00
// total income:
2014-12-14 13:40:02 -06:00
$income = $repository->getSumOfIncomesByMonth($start);
$expense = $repository->getSumOfExpensesByMonth($start);
2014-10-30 12:06:29 -05:00
2014-11-12 15:36:02 -06:00
$chart->addRow(clone $start, $income, $expense);
$start->addMonth();
2014-10-30 12:06:29 -05:00
}
$chart->generate();
2014-11-12 15:36:02 -06:00
2014-10-30 12:06:29 -05:00
return Response::json($chart->getData());
}
/**
2014-11-12 15:36:02 -06:00
* @param $year
2014-10-30 12:06:29 -05:00
*
* @return \Illuminate\Http\JsonResponse
*/
2014-11-12 15:36:02 -06:00
public function yearInExpSum($year)
2014-10-30 12:06:29 -05:00
{
2014-11-12 15:36:02 -06:00
try {
$start = new Carbon('01-01-' . $year);
} catch (Exception $e) {
App::abort(500);
}
2014-10-30 12:06:29 -05:00
/** @var \Grumpydictator\Gchart\GChart $chart */
$chart = App::make('gchart');
2014-11-12 15:36:02 -06:00
$chart->addColumn('Summary', 'string');
$chart->addColumn('Income', 'number');
$chart->addColumn('Expenses', 'number');
2014-10-30 12:06:29 -05:00
2014-12-14 13:40:02 -06:00
/** @var \FireflyIII\Database\TransactionJournal\TransactionJournal $repository */
$repository = App::make('FireflyIII\Database\TransactionJournal\TransactionJournal');
2014-10-30 12:06:29 -05:00
2014-11-12 15:36:02 -06:00
$end = clone $start;
$end->endOfYear();
$income = 0;
$expense = 0;
$count = 0;
while ($start < $end) {
2014-10-30 12:06:29 -05:00
2014-11-12 15:36:02 -06:00
// total income:
2014-12-14 13:40:02 -06:00
$income += $repository->getSumOfIncomesByMonth($start);
$expense += $repository->getSumOfExpensesByMonth($start);
2014-11-12 15:36:02 -06:00
$count++;
2014-10-30 12:06:29 -05:00
2014-11-12 15:36:02 -06:00
$start->addMonth();
2014-10-30 12:06:29 -05:00
}
2014-11-12 15:36:02 -06:00
$chart->addRow('Sum', $income, $expense);
$count = $count > 0 ? $count : 1;
$chart->addRow('Average', ($income / $count), ($expense / $count));
2014-10-30 12:06:29 -05:00
$chart->generate();
2014-11-12 15:36:02 -06:00
2014-10-30 12:06:29 -05:00
return Response::json($chart->getData());
}
2014-10-28 10:15:16 -05:00
}