Optimised another chart.

This commit is contained in:
James Cole 2015-12-31 08:26:04 +01:00
parent cc810a5b6f
commit aac5c2b13c
3 changed files with 148 additions and 16 deletions

View File

@ -5,6 +5,7 @@ namespace FireflyIII\Helpers\Report;
use Auth;
use Carbon\Carbon;
use Crypt;
use DB;
use FireflyIII\Models\Account;
use FireflyIII\Models\Budget;
use FireflyIII\Models\TransactionJournal;
@ -101,6 +102,7 @@ class ReportQuery implements ReportQueryInterface
return $query;
}
/**
* 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
@ -231,4 +233,95 @@ class ReportQuery implements ReportQueryInterface
return $data;
}
/**
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
* grouped by month like so: "2015-01" => '123.45'
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function spentPerMonth(Collection $accounts, Carbon $start, Carbon $end)
{
$ids = $accounts->pluck('id')->toArray();
$query = Auth::user()->transactionjournals()
->leftJoin(
'transactions AS t_from', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_from.transaction_journal_id')->where('t_from.amount', '<', 0);
}
)
->leftJoin(
'transactions AS t_to', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_to.transaction_journal_id')->where('t_to.amount', '>', 0);
}
)
->whereIn('t_from.account_id', $ids)
->whereNotIn('t_to.account_id', $ids)
->after($start)
->before($end)
->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
->groupBy('dateFormatted')
->get(
[
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`,"%Y-%m") AS `dateFormatted`'),
DB::Raw('SUM(`t_from`.`amount`) AS `sum`')
]
);
$array = [];
foreach ($query as $result) {
$array[$result->dateFormatted] = $result->sum;
}
return $array;
}
/**
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
* grouped by month like so: "2015-01" => '123.45'
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function earnedPerMonth(Collection $accounts, Carbon $start, Carbon $end)
{
$ids = $accounts->pluck('id')->toArray();
$query = Auth::user()->transactionjournals()
->leftJoin(
'transactions AS t_from', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_from.transaction_journal_id')->where('t_from.amount', '<', 0);
}
)
->leftJoin(
'transactions AS t_to', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_to.transaction_journal_id')->where('t_to.amount', '>', 0);
}
)
->whereIn('t_to.account_id', $ids)
->whereNotIn('t_from.account_id', $ids)
->after($start)
->before($end)
->transactionTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
->groupBy('dateFormatted')
->get(
[
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`,"%Y-%m") AS `dateFormatted`'),
DB::Raw('SUM(`t_from`.`amount`) AS `sum`')
]
);
$array = [];
foreach ($query as $result) {
$array[$result->dateFormatted] = $result->sum;
}
return $array;
}
}

View File

@ -65,5 +65,29 @@ interface ReportQueryInterface
*/
public function spentNoBudget(Account $account, Carbon $start, Carbon $end);
/**
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
* grouped by month like so: "2015-01" => '123.45'
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function spentPerMonth(Collection $accounts, Carbon $start, Carbon $end);
/**
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
* grouped by month like so: "2015-01" => '123.45'
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function earnedPerMonth(Collection $accounts, Carbon $start, Carbon $end);
}

View File

@ -55,20 +55,18 @@ class ReportController extends Controller
return Response::json($cache->get()); // @codeCoverageIgnore
}
// spent per month, and earned per month. For a specific set of accounts
// grouped by month
$spentArray = $query->spentPerMonth($accounts, $start, $end);
$earnedArray = $query->earnedPerMonth($accounts, $start, $end);
// per year?
// per year? put all months together.
if ($start->diffInMonths($end) > 12) {
$entries = new Collection;
while ($start < $end) {
$startOfYear = clone $start;
$startOfYear->startOfYear();
$endOfYear = clone $startOfYear;
$endOfYear->endOfYear();
// total income and total expenses:
$incomeSum = $query->incomeInPeriod($startOfYear, $endOfYear, $accounts)->sum('amount_positive');
$expenseSum = $query->expenseInPeriod($startOfYear, $endOfYear, $accounts)->sum('amount_positive');
$incomeSum = $this->pluckFromArray($start->year, $earnedArray);
$expenseSum = $this->pluckFromArray($start->year, $spentArray);
$entries->push([clone $start, $incomeSum, $expenseSum]);
$start->addYear();
@ -77,16 +75,14 @@ class ReportController extends Controller
$data = $this->generator->multiYearInOut($entries);
$cache->store($data);
} else {
// per month:
// per month? simply use each month.
$entries = new Collection;
while ($start < $end) {
$month = clone $start;
$month->endOfMonth();
// total income and total expenses:
$incomeSum = $query->incomeInPeriod($start, $month, $accounts)->sum('amount_positive');
$expenseSum = $query->expenseInPeriod($start, $month, $accounts)->sum('amount_positive');
$date = $start->format('Y-m');
$incomeSum = isset($earnedArray[$date]) ? $earnedArray[$date] : 0;
$expenseSum = isset($spentArray[$date]) ? $spentArray[$date] : 0;
$entries->push([clone $start, $incomeSum, $expenseSum]);
$start->addMonth();
@ -96,7 +92,6 @@ class ReportController extends Controller
$cache->store($data);
}
return Response::json($data);
}
@ -174,4 +169,24 @@ class ReportController extends Controller
return Response::json($data);
}
/**
* @param int $year
* @param array $set
*
* @return string
*/
protected function pluckFromArray($year, array $set)
{
bcscale(2);
$sum = '0';
foreach ($set as $date => $amount) {
if (substr($date, 0, 4) == $year) {
$sum = bcadd($sum, $amount);
}
}
return $sum;
}
}