From edb5b2ed5e4015f542f355b9679b806cbc4e559a Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 8 Dec 2016 21:50:20 +0100 Subject: [PATCH] Initial code for new budget report #426 --- .../Report/Audit/MonthReportGenerator.php | 10 +++ .../Report/Category/MonthReportGenerator.php | 11 +++- .../Report/ReportGeneratorInterface.php | 7 ++ .../Report/Standard/MonthReportGenerator.php | 10 +++ .../Standard/MultiYearReportGenerator.php | 10 +++ .../Report/Standard/YearReportGenerator.php | 10 +++ app/Http/Controllers/ReportController.php | 64 +++++++++++++++++++ app/Http/Requests/ReportFormRequest.php | 24 ++++++- public/js/ff/reports/index.js | 23 ++++++- resources/lang/en_US/firefly.php | 2 + resources/views/reports/index.twig | 1 + resources/views/reports/options/budget.twig | 8 +++ routes/web.php | 1 + 13 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 resources/views/reports/options/budget.twig diff --git a/app/Generator/Report/Audit/MonthReportGenerator.php b/app/Generator/Report/Audit/MonthReportGenerator.php index 7caff56bb4..f5ab29a5bb 100644 --- a/app/Generator/Report/Audit/MonthReportGenerator.php +++ b/app/Generator/Report/Audit/MonthReportGenerator.php @@ -110,6 +110,16 @@ class MonthReportGenerator implements ReportGeneratorInterface return $this; } + /** + * @param Collection $budgets + * + * @return ReportGeneratorInterface + */ + public function setBudgets(Collection $budgets): ReportGeneratorInterface + { + return $this; + } + /** * @param Collection $categories * diff --git a/app/Generator/Report/Category/MonthReportGenerator.php b/app/Generator/Report/Category/MonthReportGenerator.php index a72eb65f68..cbac1ee2d9 100644 --- a/app/Generator/Report/Category/MonthReportGenerator.php +++ b/app/Generator/Report/Category/MonthReportGenerator.php @@ -15,7 +15,6 @@ namespace FireflyIII\Generator\Report\Category; use Carbon\Carbon; -use Crypt; use FireflyIII\Generator\Report\ReportGeneratorInterface; use FireflyIII\Helpers\Collector\JournalCollector; use FireflyIII\Models\Transaction; @@ -95,6 +94,16 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface return $this; } + /** + * @param Collection $budgets + * + * @return ReportGeneratorInterface + */ + public function setBudgets(Collection $budgets): ReportGeneratorInterface + { + return $this; + } + /** * @param Collection $categories * diff --git a/app/Generator/Report/ReportGeneratorInterface.php b/app/Generator/Report/ReportGeneratorInterface.php index e14ed4fb91..ad46c0646a 100644 --- a/app/Generator/Report/ReportGeneratorInterface.php +++ b/app/Generator/Report/ReportGeneratorInterface.php @@ -36,6 +36,13 @@ interface ReportGeneratorInterface */ public function setAccounts(Collection $accounts): ReportGeneratorInterface; + /** + * @param Collection $budgets + * + * @return ReportGeneratorInterface + */ + public function setBudgets(Collection $budgets): ReportGeneratorInterface; + /** * @param Collection $categories * diff --git a/app/Generator/Report/Standard/MonthReportGenerator.php b/app/Generator/Report/Standard/MonthReportGenerator.php index bcffeedff2..5905e12815 100644 --- a/app/Generator/Report/Standard/MonthReportGenerator.php +++ b/app/Generator/Report/Standard/MonthReportGenerator.php @@ -63,6 +63,16 @@ class MonthReportGenerator implements ReportGeneratorInterface return $this; } + /** + * @param Collection $budgets + * + * @return ReportGeneratorInterface + */ + public function setBudgets(Collection $budgets): ReportGeneratorInterface + { + return $this; + } + /** * @param Collection $categories * diff --git a/app/Generator/Report/Standard/MultiYearReportGenerator.php b/app/Generator/Report/Standard/MultiYearReportGenerator.php index 64f74f1295..3437283426 100644 --- a/app/Generator/Report/Standard/MultiYearReportGenerator.php +++ b/app/Generator/Report/Standard/MultiYearReportGenerator.php @@ -60,6 +60,16 @@ class MultiYearReportGenerator implements ReportGeneratorInterface return $this; } + /** + * @param Collection $budgets + * + * @return ReportGeneratorInterface + */ + public function setBudgets(Collection $budgets): ReportGeneratorInterface + { + return $this; + } + /** * @param Collection $categories * diff --git a/app/Generator/Report/Standard/YearReportGenerator.php b/app/Generator/Report/Standard/YearReportGenerator.php index 7536b4027f..545084909f 100644 --- a/app/Generator/Report/Standard/YearReportGenerator.php +++ b/app/Generator/Report/Standard/YearReportGenerator.php @@ -60,6 +60,16 @@ class YearReportGenerator implements ReportGeneratorInterface return $this; } + /** + * @param Collection $budgets + * + * @return ReportGeneratorInterface + */ + public function setBudgets(Collection $budgets): ReportGeneratorInterface + { + return $this; + } + /** * @param Collection $categories * diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index 655c3b2a22..19468b77b1 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -20,6 +20,7 @@ use FireflyIII\Helpers\Report\ReportHelperInterface; use FireflyIII\Http\Requests\ReportFormRequest; use FireflyIII\Models\AccountType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use Illuminate\Http\RedirectResponse; use Illuminate\Support\Collection; @@ -95,6 +96,42 @@ class ReportController extends Controller } + /** + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end + * + * @return string + */ + public function budgetReport(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end) + { + if ($end < $start) { + return view('error')->with('message', trans('firefly.end_after_start_date')); + } + if ($start < session('first')) { + $start = session('first'); + } + + View::share( + 'subTitle', trans( + 'firefly.report_budget', + [ + 'start' => $start->formatLocalized($this->monthFormat), + 'end' => $end->formatLocalized($this->monthFormat), + ] + ) + ); + + $generator = ReportGeneratorFactory::reportGenerator('Budget', $start, $end); + $generator->setAccounts($accounts); + $generator->setBudgets($budgets); + $result = $generator->generate(); + + return $result; + + } + /** * @param Collection $accounts * @param Collection $categories @@ -198,6 +235,9 @@ class ReportController extends Controller case 'category': $result = $this->categoryReportOptions(); break; + case 'budget': + $result = $this->budgetReportOptions(); + break; } return Response::json(['html' => $result]); @@ -217,6 +257,7 @@ class ReportController extends Controller $end = $request->getEndDate()->format('Ymd'); $accounts = join(',', $request->getAccountList()->pluck('id')->toArray()); $categories = join(',', $request->getCategoryList()->pluck('id')->toArray()); + $budgets = join(',', $request->getBudgetList()->pluck('id')->toArray()); if ($request->getAccountList()->count() === 0) { Session::flash('error', trans('firefly.select_more_than_one_account')); @@ -230,6 +271,12 @@ class ReportController extends Controller return redirect(route('reports.index')); } + if ($request->getBudgetList()->count() === 0 && $reportType === 'budget') { + Session::flash('error', trans('firefly.select_more_than_one_budget')); + + return redirect(route('reports.index')); + } + if ($end < $start) { return view('error')->with('message', trans('firefly.end_after_start_date')); } @@ -251,11 +298,28 @@ class ReportController extends Controller case 'audit': $uri = route('reports.report.audit', [$accounts, $start, $end]); break; + case 'budget': + $uri = route('reports.report.budget', [$accounts, $budgets, $start, $end]); + break; } return redirect($uri); } + /** + * @return string + */ + private function budgetReportOptions(): string + { + /** @var BudgetRepositoryInterface $repository */ + $repository = app(BudgetRepositoryInterface::class); + $budgets = $repository->getBudgets(); + $result = view('reports.options.budget', compact('budgets'))->render(); + + return $result; + + } + /** * @return string */ diff --git a/app/Http/Requests/ReportFormRequest.php b/app/Http/Requests/ReportFormRequest.php index 7d97a37b76..fbb153bcb9 100644 --- a/app/Http/Requests/ReportFormRequest.php +++ b/app/Http/Requests/ReportFormRequest.php @@ -17,6 +17,7 @@ use Carbon\Carbon; use Exception; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use Illuminate\Support\Collection; @@ -79,6 +80,27 @@ class ReportFormRequest extends Request return $collection; } + /** + * @return Collection + */ + public function getBudgetList(): Collection + { + /** @var BudgetRepositoryInterface $repository */ + $repository = app(BudgetRepositoryInterface::class); + $set = $this->get('budget'); + $collection = new Collection; + if (is_array($set)) { + foreach ($set as $budgetId) { + $budget = $repository->find(intval($budgetId)); + if (!is_null($budget->id)) { + $collection->push($budget); + } + } + } + + return $collection; + } + /** * @return Carbon * @throws FireflyException @@ -125,7 +147,7 @@ class ReportFormRequest extends Request public function rules(): array { return [ - 'report_type' => 'in:audit,default,category', + 'report_type' => 'in:audit,default,category,budget', ]; } diff --git a/public/js/ff/reports/index.js b/public/js/ff/reports/index.js index bd949eeac6..9de3f79b50 100644 --- a/public/js/ff/reports/index.js +++ b/public/js/ff/reports/index.js @@ -65,12 +65,22 @@ function getReportOptions() { } function setOptionalFromCookies() { + var arr; + // categories if ((readCookie('report-categories') !== null)) { - var arr = readCookie('report-categories').split(','); + arr = readCookie('report-categories').split(','); arr.forEach(function (val) { $('input[class="category-checkbox"][type="checkbox"][value="' + val + '"]').prop('checked', true); }); } + + // and budgets! + if ((readCookie('report-budgets') !== null)) { + arr = readCookie('report-budgets').split(','); + arr.forEach(function (val) { + $('input[class="budget-checkbox"][type="checkbox"][value="' + val + '"]').prop('checked', true); + }); + } } function catchSubmit() { @@ -90,7 +100,6 @@ function catchSubmit() { }); // all category ids: - //category-checkbox var categories = []; $.each($('.category-checkbox'), function (i, v) { var c = $(v); @@ -99,6 +108,15 @@ function catchSubmit() { } }); + // all budget ids: + var budgets = []; + $.each($('.budget-checkbox'), function (i, v) { + var c = $(v); + if (c.prop('checked')) { + budgets.push(c.val()); + } + }); + // remember all if (count > 0) { @@ -106,6 +124,7 @@ function catchSubmit() { createCookie('report-type', $('select[name="report_type"]').val(), 365); createCookie('report-accounts', accounts, 365); createCookie('report-categories', categories, 365); + createCookie('report-budgets', budgets, 365); createCookie('report-start', moment(picker.startDate).format("YYYYMMDD"), 365); createCookie('report-end', moment(picker.endDate).format("YYYYMMDD"), 365); } diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 11d55a5cac..7372a2876a 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -679,6 +679,7 @@ return [ 'report_type_default' => 'Default financial report', 'report_type_audit' => 'Transaction history overview (audit)', 'report_type_category' => 'Category report', + 'report_type_budget' => 'Budget report', 'report_type_meta-history' => 'Categories, budgets and bills overview', 'more_info_help' => 'More information about these types of reports can be found in the help pages. Press the (?) icon in the top right corner.', 'report_included_accounts' => 'Included accounts', @@ -698,6 +699,7 @@ return [ 'reports_submit' => 'View report', 'end_after_start_date' => 'End date of report must be after start date.', 'select_category' => 'Select one or more categories.', + 'select_budget' => 'Select one or more budgets.', 'income_per_category' => 'Income per category', 'expense_per_category' => 'Expense per category', 'income_per_account' => 'Income per account', diff --git a/resources/views/reports/index.twig b/resources/views/reports/index.twig index c889d0eee2..70d8fd86db 100644 --- a/resources/views/reports/index.twig +++ b/resources/views/reports/index.twig @@ -26,6 +26,7 @@ diff --git a/resources/views/reports/options/budget.twig b/resources/views/reports/options/budget.twig new file mode 100644 index 0000000000..b2e0e7862e --- /dev/null +++ b/resources/views/reports/options/budget.twig @@ -0,0 +1,8 @@ +

+ {{ 'select_budget'|_ }} +

+{% for budget in budgets %} + +{% endfor %} diff --git a/routes/web.php b/routes/web.php index 3d9221d2a7..04cacdad0c 100755 --- a/routes/web.php +++ b/routes/web.php @@ -456,6 +456,7 @@ Route::group( Route::get('default/{accountList}/{start_date}/{end_date}', ['uses' => 'ReportController@defaultReport', 'as' => 'report.default']); Route::get('audit/{accountList}/{start_date}/{end_date}', ['uses' => 'ReportController@auditReport', 'as' => 'report.audit']); Route::get('category/{accountList}/{categoryList}/{start_date}/{end_date}', ['uses' => 'ReportController@categoryReport', 'as' => 'report.category']); + Route::get('budget/{accountList}/{budgetList}/{start_date}/{end_date}', ['uses' => 'ReportController@budgetReport', 'as' => 'report.budget']); Route::post('', ['uses' => 'ReportController@postIndex', 'as' => 'index.post']); }