diff --git a/app/Helpers/Report/BudgetReportHelper.php b/app/Helpers/Report/BudgetReportHelper.php index 9c250e8560..4f370f89bb 100644 --- a/app/Helpers/Report/BudgetReportHelper.php +++ b/app/Helpers/Report/BudgetReportHelper.php @@ -15,13 +15,17 @@ namespace FireflyIII\Helpers\Report; use Carbon\Carbon; +use DB; use FireflyIII\Helpers\Collection\Budget as BudgetCollection; use FireflyIII\Helpers\Collection\BudgetLine; use FireflyIII\Models\Budget; use FireflyIII\Models\LimitRepetition; +use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Support\CacheProperties; +use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Collection; +use stdClass; /** * Class BudgetReportHelper @@ -97,6 +101,66 @@ class BudgetReportHelper implements BudgetReportHelperInterface return $return; } + /** + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts + * + * @return array + */ + public function getBudgetMultiYear(Carbon $start, Carbon $end, Collection $accounts): array + { + $accountIds = $accounts->pluck('id')->toArray(); + $query = TransactionJournal + ::leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') + ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') + ->leftJoin( + 'transactions', function (JoinClause $join) { + $join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '<', 0); + } + ) + ->whereNull('transaction_journals.deleted_at') + ->whereNull('transactions.deleted_at') + ->where('transaction_types.type', 'Withdrawal') + ->where('transaction_journals.user_id', auth()->user()->id); + + if (count($accountIds) > 0) { + $query->whereIn('transactions.account_id', $accountIds); + } + $query->groupBy(['budget_transaction_journal.budget_id', 'the_year']); + $queryResult = $query->get( + [ + 'budget_transaction_journal.budget_id', + DB::raw('DATE_FORMAT(transaction_journals.date,"%Y") AS the_year'), + DB::raw('SUM(transactions.amount) as sum_of_period'), + ] + ); + + $data = []; + $budgets = $this->repository->getBudgets(); + $years = $this->listOfYears($start, $end); + + // do budget "zero" + $emptyBudget = new Budget; + $emptyBudget->id = 0; + $emptyBudget->name = strval(trans('firefly.no_budget')); + $budgets->push($emptyBudget); + + + // get all budgets and years. + foreach ($budgets as $budget) { + $data[$budget->id] = [ + 'name' => $budget->name, + 'entries' => $this->filterAmounts($queryResult, $budget->id, $years), + 'sum' => '0', + ]; + } + // filter out empty ones and fill sum: + $data = $this->getBudgetMultiYearMeta($data); + + return $data; + } + /** * @param Carbon $start * @param Carbon $end @@ -183,30 +247,21 @@ class BudgetReportHelper implements BudgetReportHelperInterface } /** - * Take the array as returned by CategoryRepositoryInterface::spentPerDay and CategoryRepositoryInterface::earnedByDay - * and sum up everything in the array in the given range. - * * @param Carbon $start * @param Carbon $end - * @param array $array * - * @return string + * @return array */ - protected function getSumOfRange(Carbon $start, Carbon $end, array $array) + public function listOfYears(Carbon $start, Carbon $end): array { - $sum = '0'; - $currentStart = clone $start; // to not mess with the original one - $currentEnd = clone $end; // to not mess with the original one - - while ($currentStart <= $currentEnd) { - $date = $currentStart->format('Y-m-d'); - if (isset($array[$date])) { - $sum = bcadd($sum, $array[$date]); - } - $currentStart->addDay(); + $begin = clone $start; + $years = []; + while ($begin < $end) { + $years[] = $begin->year; + $begin->addYear(); } - return $sum; + return $years; } /** @@ -247,6 +302,59 @@ class BudgetReportHelper implements BudgetReportHelperInterface return $headers; } + /** + * @param Collection $set + * @param int $budgetId + * @param array $years + * + * @return array + */ + private function filterAmounts(Collection $set, int $budgetId, array $years):array + { + $arr = []; + foreach ($years as $year) { + /** @var stdClass $object */ + $result = $set->filter( + function (TransactionJournal $object) use ($budgetId, $year) { + return intval($object->the_year) === $year && $budgetId === intval($object->budget_id); + } + ); + $amount = '0'; + if (!is_null($result->first())) { + $amount = $result->first()->sum_of_period; + } + + $arr[$year] = $amount; + } + + return $arr; + } + + /** + * @param array $data + * + * @return array + */ + private function getBudgetMultiYearMeta(array $data): array + { + /** + * @var int $budgetId + * @var array $set + */ + foreach ($data as $budgetId => $set) { + $sum = '0'; + foreach ($set['entries'] as $amount) { + $sum = bcadd($amount, $sum); + } + $data[$budgetId]['sum'] = $sum; + if (bccomp('0', $sum) === 0) { + unset($data[$budgetId]); + } + } + + return $data; + } + /** * @param Carbon $current * @param Carbon $end diff --git a/app/Helpers/Report/BudgetReportHelperInterface.php b/app/Helpers/Report/BudgetReportHelperInterface.php index 3660447c99..89c785b0a8 100644 --- a/app/Helpers/Report/BudgetReportHelperInterface.php +++ b/app/Helpers/Report/BudgetReportHelperInterface.php @@ -34,6 +34,15 @@ interface BudgetReportHelperInterface */ public function budgetYearOverview(Carbon $start, Carbon $end, Collection $accounts): Collection; + /** + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts + * + * @return array + */ + public function getBudgetMultiYear(Carbon $start, Carbon $end, Collection $accounts): array; + /** * @param Carbon $start * @param Carbon $end @@ -52,4 +61,12 @@ interface BudgetReportHelperInterface */ public function getBudgetsWithExpenses(Carbon $start, Carbon $end, Collection $accounts): Collection; + /** + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function listOfYears(Carbon $start, Carbon $end): array; + } diff --git a/app/Helpers/Report/ReportHelper.php b/app/Helpers/Report/ReportHelper.php index ce0ab0cfaf..b95ac24315 100644 --- a/app/Helpers/Report/ReportHelper.php +++ b/app/Helpers/Report/ReportHelper.php @@ -113,66 +113,6 @@ class ReportHelper implements ReportHelperInterface return $collection; } - /** - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts - * - * @return array - */ - public function getBudgetMultiYear(Carbon $start, Carbon $end, Collection $accounts): array - { - $accountIds = $accounts->pluck('id')->toArray(); - $query = TransactionJournal - ::leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') - ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') - ->leftJoin( - 'transactions', function (JoinClause $join) { - $join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '<', 0); - } - ) - ->whereNull('transaction_journals.deleted_at') - ->whereNull('transactions.deleted_at') - ->where('transaction_types.type', 'Withdrawal') - ->where('transaction_journals.user_id', auth()->user()->id); - - if (count($accountIds) > 0) { - $query->whereIn('transactions.account_id', $accountIds); - } - $query->groupBy(['budget_transaction_journal.budget_id', 'the_year']); - $queryResult = $query->get( - [ - 'budget_transaction_journal.budget_id', - DB::raw('DATE_FORMAT(transaction_journals.date,"%Y") AS the_year'), - DB::raw('SUM(transactions.amount) as sum_of_period'), - ] - ); - - $data = []; - $budgets = $this->budgetRepository->getBudgets(); - $years = $this->listOfYears($start, $end); - - // do budget "zero" - $emptyBudget = new Budget; - $emptyBudget->id = 0; - $emptyBudget->name = strval(trans('firefly.no_budget')); - $budgets->push($emptyBudget); - - - // get all budgets and years. - foreach ($budgets as $budget) { - $data[$budget->id] = [ - 'name' => $budget->name, - 'entries' => $this->filterAmounts($queryResult, $budget->id, $years), - 'sum' => '0', - ]; - } - // filter out empty ones and fill sum: - $data = $this->getBudgetMultiYearMeta($data); - - return $data; - } - /** * @param Carbon $start * @param Carbon $end @@ -293,24 +233,6 @@ class ReportHelper implements ReportHelperInterface return $months; } - /** - * @param Carbon $start - * @param Carbon $end - * - * @return array - */ - public function listOfYears(Carbon $start, Carbon $end): array - { - $begin = clone $start; - $years = []; - while ($begin < $end) { - $years[] = $begin->year; - $begin->addYear(); - } - - return $years; - } - /** * Returns an array of tags and their comparitive size with amounts bla bla. * @@ -385,85 +307,4 @@ class ReportHelper implements ReportHelperInterface return $collection; } - /** - * @param array $data - * - * @return array - */ - protected function getBudgetMultiYearMeta(array $data): array - { - /** - * @var int $budgetId - * @var array $set - */ - foreach ($data as $budgetId => $set) { - $sum = '0'; - foreach ($set['entries'] as $amount) { - $sum = bcadd($amount, $sum); - } - $data[$budgetId]['sum'] = $sum; - if (bccomp('0', $sum) === 0) { - unset($data[$budgetId]); - } - } - - return $data; - } - - /** - * Take the array as returned by CategoryRepositoryInterface::spentPerDay and CategoryRepositoryInterface::earnedByDay - * and sum up everything in the array in the given range. - * - * @param Carbon $start - * @param Carbon $end - * @param array $array - * - * @return string - */ - protected function getSumOfRange(Carbon $start, Carbon $end, array $array) - { - $sum = '0'; - $currentStart = clone $start; // to not mess with the original one - $currentEnd = clone $end; // to not mess with the original one - - while ($currentStart <= $currentEnd) { - $date = $currentStart->format('Y-m-d'); - if (isset($array[$date])) { - $sum = bcadd($sum, $array[$date]); - } - $currentStart->addDay(); - } - - return $sum; - } - - /** - * @param Collection $set - * @param int $budgetId - * @param array $years - * - * @return array - */ - private function filterAmounts(Collection $set, int $budgetId, array $years):array - { - $arr = []; - foreach ($years as $year) { - /** @var stdClass $object */ - $result = $set->filter( - function (TransactionJournal $object) use ($budgetId, $year) { - return intval($object->the_year) === $year && $budgetId === intval($object->budget_id); - } - ); - $amount = '0'; - if (!is_null($result->first())) { - $amount = $result->first()->sum_of_period; - } - - $arr[$year] = $amount; - } - - return $arr; - } - - } diff --git a/app/Helpers/Report/ReportHelperInterface.php b/app/Helpers/Report/ReportHelperInterface.php index 6dec1b9c0e..34ffcc9e7b 100644 --- a/app/Helpers/Report/ReportHelperInterface.php +++ b/app/Helpers/Report/ReportHelperInterface.php @@ -28,16 +28,6 @@ use Illuminate\Support\Collection; interface ReportHelperInterface { - /** - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts - * - * @return array - */ - public function getBudgetMultiYear(Carbon $start, Carbon $end, Collection $accounts): array; - - /** * This method generates a full report for the given period on all * the users bills and their payments. @@ -90,14 +80,6 @@ interface ReportHelperInterface */ public function listOfMonths(Carbon $date): array; - /** - * @param Carbon $start - * @param Carbon $end - * - * @return array - */ - public function listOfYears(Carbon $start, Carbon $end): array; - /** * Returns an array of tags and their comparitive size with amounts bla bla. * diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 58917455dc..727ef34f7a 100755 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -61,31 +61,4 @@ class Controller extends BaseController } - /** - * Take the array as returned by CategoryRepositoryInterface::spentPerDay and CategoryRepositoryInterface::earnedByDay - * and sum up everything in the array in the given range. - * - * @param Carbon $start - * @param Carbon $end - * @param array $array - * - * @return string - */ - protected function getSumOfRange(Carbon $start, Carbon $end, array $array) - { - $sum = '0'; - $currentStart = clone $start; // to not mess with the original one - $currentEnd = clone $end; // to not mess with the original one - - while ($currentStart <= $currentEnd) { - $date = $currentStart->format('Y-m-d'); - if (isset($array[$date])) { - $sum = bcadd($sum, $array[$date]); - } - $currentStart->addDay(); - } - - return $sum; - } - } diff --git a/app/Http/Controllers/Report/BudgetController.php b/app/Http/Controllers/Report/BudgetController.php index 1d139c23ca..b18f1b8d43 100644 --- a/app/Http/Controllers/Report/BudgetController.php +++ b/app/Http/Controllers/Report/BudgetController.php @@ -28,6 +28,33 @@ use Illuminate\Support\Collection; class BudgetController extends Controller { + /** + * @param BudgetReportHelperInterface $helper + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts + */ + public function budgetMultiYear(BudgetReportHelperInterface $helper, Carbon $start, Carbon $end, Collection $accounts) + { + $cache = new CacheProperties; + $cache->addProperty($start); + $cache->addProperty($end); + $cache->addProperty('budget-mult-year-report'); + $cache->addProperty($accounts->pluck('id')->toArray()); + if ($cache->has()) { + return $cache->get(); + } + + + $years = $helper->listOfYears($start, $end); + $budgetMultiYear = $helper->getBudgetMultiYear($start, $end, $accounts); + + $result = view('reports.partials.budget-multi-year', compact('budgetMultiYear', 'years'))->render(); + $cache->store($result); + + return $result; + } + /** * @param BudgetReportHelperInterface $helper * @param Carbon $start diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index 7878830f15..6ac94f0883 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -244,8 +244,7 @@ class ReportController extends Controller { // need all budgets // need all years. - $years = $this->helper->listOfYears($start, $end); - $budgetMultiYear = $this->helper->getBudgetMultiYear($start, $end, $accounts); + // and some id's, joined: @@ -259,8 +258,7 @@ class ReportController extends Controller return view( 'reports.default.multi-year', compact( - 'accounts', 'start', 'end', 'accountIds', 'reportType', - 'years', 'budgetMultiYear' + 'accounts', 'start', 'end', 'accountIds', 'reportType' ) ); } diff --git a/app/Support/Twig/Transaction.php b/app/Support/Twig/Transaction.php index ef8c97da73..a5b98f34d1 100644 --- a/app/Support/Twig/Transaction.php +++ b/app/Support/Twig/Transaction.php @@ -294,7 +294,7 @@ class Transaction extends Twig_Extension switch ($transaction->transaction_type_type) { case TransactionType::WITHDRAWAL: - $txt = sprintf('' . trans('firefly.withdrawal')); + $txt = sprintf('', trans('firefly.withdrawal')); break; case TransactionType::DEPOSIT: $txt = sprintf('', trans('firefly.deposit')); diff --git a/public/js/ff/reports/default/all.js b/public/js/ff/reports/default/all.js index a76d6be0ec..5d47620714 100644 --- a/public/js/ff/reports/default/all.js +++ b/public/js/ff/reports/default/all.js @@ -128,4 +128,33 @@ function respondInfoButton(data) { $('#defaultModal').empty().html(data.html); $('#defaultModal').modal('show'); +} + +function loadAjaxPartial(holder, uri) { + "use strict"; + console.log('Going to grab URI ' + uri); + $.get(uri).done(function (data) { + displayAjaxPartial(data, holder); + }).fail(function () { + failAjaxPartial(uri, holder); + }); +} + +function displayAjaxPartial(data, holder) { + "use strict"; + console.log('Display stuff in ' + holder); + var obj = $('#' + holder); + obj.removeClass('loading').html(data); + + // call some often needed recalculations and what-not: + + // find a sortable table and make it sortable: + $.bootstrapSortable(true); +} + +function failAjaxPartial(uri, holder) { + "use strict"; + console.log('Failed to load' + uri); + $('#' + holder).removeClass('loading').addClass('general-chart-error'); + } \ No newline at end of file diff --git a/public/js/ff/reports/default/multi-year.js b/public/js/ff/reports/default/multi-year.js index 04b9ab3ddb..9274a86ac1 100644 --- a/public/js/ff/reports/default/multi-year.js +++ b/public/js/ff/reports/default/multi-year.js @@ -1,13 +1,13 @@ -/* globals google, startDate ,reportURL, endDate , reportType ,accountIds , picker:true, minDate, year, month, columnChart, lineChart, stackedColumnChart */ +/* globals budgetMultiUrl, accountIds */ $(function () { "use strict"; drawChart(); + loadAjaxPartial('budgetMultiYear', budgetMultiUrl); }); - function drawChart() { "use strict"; diff --git a/resources/views/admin/domains/index.twig b/resources/views/admin/domains/index.twig index 2da0fe9ad2..ad854f3c52 100644 --- a/resources/views/admin/domains/index.twig +++ b/resources/views/admin/domains/index.twig @@ -12,7 +12,7 @@
{% if domains|length > 0 %} - +
@@ -59,7 +59,7 @@ {{ 'all_domains_is_filtered'|_ }}

-
 
+
@@ -118,3 +118,9 @@ {% endblock %} +{% block styles %} + +{% endblock %} +{% block scripts %} + +{% endblock %} diff --git a/resources/views/admin/users/index.twig b/resources/views/admin/users/index.twig index 9b47a66dd8..60708d175c 100644 --- a/resources/views/admin/users/index.twig +++ b/resources/views/admin/users/index.twig @@ -11,7 +11,7 @@

{{ 'all_users'|_ }}

-
 
+
@@ -29,15 +29,15 @@ {% for user in users %} - - - + - @@ -47,28 +47,28 @@ - - - -
 
+
#{{ user.id }} + #{{ user.id }} {{ user.email }} + {{ user.created_at.formatLocalized(monthAndDayFormat) }} {{ user.created_at.format('H:i') }} {{ Preferences.getForUser(user,"confirmation_ip_address").data }} + {% if user.isAdmin %} {% else %} {% endif %} + {% if user.has2FA %} {% else %} {% endif %} + {% if user.activated %} {% else %} {% endif %} + {% if user.blocked == 1 %} {% else %} @@ -95,3 +95,9 @@ {% endblock %} +{% block styles %} + +{% endblock %} +{% block scripts %} + +{% endblock %} diff --git a/resources/views/reports/default/multi-year.twig b/resources/views/reports/default/multi-year.twig index 0754163e1e..d4a059577a 100644 --- a/resources/views/reports/default/multi-year.twig +++ b/resources/views/reports/default/multi-year.twig @@ -91,40 +91,8 @@

{{ 'budgets'|_ }}

-
- - - - - {% for year in years %} - - {% endfor %} - - - - - {% for id, info in budgetMultiYear %} - - - {% for amount in info.entries %} - - {% endfor %} - - - {% endfor %} - -
{{ 'budget'|_ }}{{ year }}{{ 'sum'|_ }}
- {% if id == 0 %} - {{ info.name }} +
- {% else %} - {{ info.name }} - {% endif %} -
- {{ amount|formatAmount }} - - {{ info.sum|formatAmount }} -
@@ -152,6 +120,7 @@ var accountReportUrl = '{{ route('reports.data.accountReport', [start.format('Ymd'), end.format('Ymd'), accountIds]) }}'; var inOutReportUrl = '{{ route('reports.data.inOutReport', [start.format('Ymd'), end.format('Ymd'), accountIds]) }}'; + var budgetMultiUrl = '{{ route('reports.data.budgetMultiYear', [start.format('Ymd'), end.format('Ymd'), accountIds]) }}'; diff --git a/resources/views/reports/partials/budget-multi-year.twig b/resources/views/reports/partials/budget-multi-year.twig new file mode 100644 index 0000000000..7fc30ea9f3 --- /dev/null +++ b/resources/views/reports/partials/budget-multi-year.twig @@ -0,0 +1,33 @@ + + + + + {% for year in years %} + + {% endfor %} + + + + + {% for id, info in budgetMultiYear %} + + + {% for amount in info.entries %} + + {% endfor %} + + + {% endfor %} + +
{{ 'budget'|_ }}{{ year }}{{ 'sum'|_ }}
+ {% if id == 0 %} + {{ info.name }} + + {% else %} + {{ info.name }} + {% endif %} + + {{ amount|formatAmount }} + + {{ info.sum|formatAmount }} +
\ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 7a5072cf29..d7a6f64b5d 100755 --- a/routes/web.php +++ b/routes/web.php @@ -345,6 +345,12 @@ Route::group( ['uses' => 'Report\BudgetController@budgetYearOverview', 'as' => 'reports.data.budgetYearOverview'] ); + // budget multi year overview + Route::get( + '/reports/data/budget-multi-year/{start_date}/{end_date}/{accountList}', + ['uses' => 'Report\BudgetController@budgetMultiYear', 'as' => 'reports.data.budgetMultiYear'] + ); + /** * Rules Controller