First code for #426

This commit is contained in:
James Cole
2016-12-09 07:07:53 +01:00
parent c73866f47c
commit 1fd028dfb8
6 changed files with 648 additions and 2 deletions

View File

@@ -25,7 +25,7 @@ use Steam;
/**
* Class MonthReportGenerator
*
* @package FireflyIII\Generator\Report\Standard
* @package FireflyIII\Generator\Report\Audit
*/
class MonthReportGenerator implements ReportGeneratorInterface
{

View File

@@ -0,0 +1,329 @@
<?php
/**
* MonthReportGenerator.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Report\Budget;
use Carbon\Carbon;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use FireflyIII\Helpers\Collector\JournalCollector;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionType;
use Illuminate\Support\Collection;
use Log;
/**
* Class MonthReportGenerator
*
* @package FireflyIII\Generator\Report\Budget
*/
class MonthReportGenerator implements ReportGeneratorInterface
{
/** @var Collection */
private $accounts;
/** @var Collection */
private $budgets;
/** @var Carbon */
private $end;
/** @var Collection */
private $expenses;
/** @var Collection */
private $income;
/** @var Carbon */
private $start;
/**
* MonthReportGenerator constructor.
*/
public function __construct()
{
$this->income = new Collection;
$this->expenses = new Collection;
}
/**
* @return string
*/
public function generate(): string
{
$accountIds = join(',', $this->accounts->pluck('id')->toArray());
$categoryIds = join(',', $this->budgets->pluck('id')->toArray());
$reportType = 'budget';
// $expenses = $this->getExpenses();
// $income = $this->getIncome();
// $accountSummary = $this->getObjectSummary($this->summarizeByAccount($expenses), $this->summarizeByAccount($income));
// $categorySummary = $this->getObjectSummary($this->summarizeByCategory($expenses), $this->summarizeByCategory($income));
// $averageExpenses = $this->getAverages($expenses, SORT_ASC);
// $averageIncome = $this->getAverages($income, SORT_DESC);
// $topExpenses = $this->getTopExpenses();
// $topIncome = $this->getTopIncome();
// render!
return view(
'reports.budget.month',
compact(
'accountIds', 'categoryIds', 'topIncome', 'reportType', 'accountSummary', 'categorySummary', 'averageExpenses', 'averageIncome', 'topExpenses'
)
)
->with('start', $this->start)->with('end', $this->end)
->with('budgets', $this->budgets)
->with('accounts', $this->accounts)
->render();
}
/**
* @param Collection $accounts
*
* @return ReportGeneratorInterface
*/
public function setAccounts(Collection $accounts): ReportGeneratorInterface
{
$this->accounts = $accounts;
return $this;
}
/**
* @param Collection $budgets
*
* @return ReportGeneratorInterface
*/
public function setBudgets(Collection $budgets): ReportGeneratorInterface
{
$this->budgets = $budgets;
return $this;
}
/**
* @param Collection $categories
*
* @return ReportGeneratorInterface
*/
public function setCategories(Collection $categories): ReportGeneratorInterface
{
$this->categories = $categories;
return $this;
}
/**
* @param Carbon $date
*
* @return ReportGeneratorInterface
*/
public function setEndDate(Carbon $date): ReportGeneratorInterface
{
$this->end = $date;
return $this;
}
/**
* @param Carbon $date
*
* @return ReportGeneratorInterface
*/
public function setStartDate(Carbon $date): ReportGeneratorInterface
{
$this->start = $date;
return $this;
}
/**
* @param Collection $collection
* @param int $sortFlag
*
* @return array
*/
private function getAverages(Collection $collection, int $sortFlag): array
{
$result = [];
/** @var Transaction $transaction */
foreach ($collection as $transaction) {
// opposing name and ID:
$opposingId = $transaction->opposing_account_id;
// is not set?
if (!isset($result[$opposingId])) {
$name = $transaction->opposing_account_name;
$result[$opposingId] = [
'name' => $name,
'count' => 1,
'id' => $opposingId,
'average' => $transaction->transaction_amount,
'sum' => $transaction->transaction_amount,
];
continue;
}
$result[$opposingId]['count']++;
$result[$opposingId]['sum'] = bcadd($result[$opposingId]['sum'], $transaction->transaction_amount);
$result[$opposingId]['average'] = bcdiv($result[$opposingId]['sum'], strval($result[$opposingId]['count']));
}
// sort result by average:
$average = [];
foreach ($result as $key => $row) {
$average[$key] = floatval($row['average']);
}
array_multisort($average, $sortFlag, $result);
return $result;
}
/**
* @return Collection
*/
private function getExpenses(): Collection
{
if ($this->expenses->count() > 0) {
Log::debug('Return previous set of expenses.');
return $this->expenses;
}
$collector = new JournalCollector(auth()->user());
$collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
->setCategories($this->categories)->withOpposingAccount()->disableFilter();
$accountIds = $this->accounts->pluck('id')->toArray();
$transactions = $collector->getJournals();
$transactions = self::filterExpenses($transactions, $accountIds);
$this->expenses = $transactions;
return $transactions;
}
/**
* @return Collection
*/
private function getIncome(): Collection
{
if ($this->income->count() > 0) {
return $this->income;
}
$collector = new JournalCollector(auth()->user());
$collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
->setCategories($this->categories)->withOpposingAccount();
$accountIds = $this->accounts->pluck('id')->toArray();
$transactions = $collector->getJournals();
$transactions = self::filterIncome($transactions, $accountIds);
$this->income = $transactions;
return $transactions;
}
/**
* @param array $spent
* @param array $earned
*
* @return array
*/
private function getObjectSummary(array $spent, array $earned): array
{
$return = [];
/**
* @var int $accountId
* @var string $entry
*/
foreach ($spent as $objectId => $entry) {
if (!isset($return[$objectId])) {
$return[$objectId] = ['spent' => 0, 'earned' => 0];
}
$return[$objectId]['spent'] = $entry;
}
unset($entry);
/**
* @var int $accountId
* @var string $entry
*/
foreach ($earned as $objectId => $entry) {
if (!isset($return[$objectId])) {
$return[$objectId] = ['spent' => 0, 'earned' => 0];
}
$return[$objectId]['earned'] = $entry;
}
return $return;
}
/**
* @return Collection
*/
private function getTopExpenses(): Collection
{
$transactions = $this->getExpenses()->sortBy('transaction_amount');
return $transactions;
}
/**
* @return Collection
*/
private function getTopIncome(): Collection
{
$transactions = $this->getIncome()->sortByDesc('transaction_amount');
return $transactions;
}
/**
* @param Collection $collection
*
* @return array
*/
private function summarizeByAccount(Collection $collection): array
{
$result = [];
/** @var Transaction $transaction */
foreach ($collection as $transaction) {
$accountId = $transaction->account_id;
$result[$accountId] = $result[$accountId] ?? '0';
$result[$accountId] = bcadd($transaction->transaction_amount, $result[$accountId]);
}
return $result;
}
/**
* @param Collection $collection
*
* @return array
*/
private function summarizeByCategory(Collection $collection): array
{
$result = [];
/** @var Transaction $transaction */
foreach ($collection as $transaction) {
$jrnlCatId = intval($transaction->transaction_journal_category_id);
$transCatId = intval($transaction->transaction_category_id);
$categoryId = max($jrnlCatId, $transCatId);
$result[$categoryId] = $result[$categoryId] ?? '0';
$result[$categoryId] = bcadd($transaction->transaction_amount, $result[$categoryId]);
}
return $result;
}
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* MultiYearReportGenerator.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Report\Budget;
/**
* Class MultiYearReportGenerator
*
* @package FireflyIII\Generator\Report\Budget
*/
class MultiYearReportGenerator extends MonthReportGenerator
{
/**
* Doesn't do anything different.
*/
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* YearReportGenerator.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Report\Budget;
/**
* Class YearReportGenerator
*
* @package FireflyIII\Generator\Report\Budget
*/
class YearReportGenerator extends MonthReportGenerator
{
/**
* Doesn't do anything different.
*/
}