mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-30 10:33:30 +00:00
Build code for tag report.
This commit is contained in:
@@ -131,6 +131,16 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $tags
|
||||
*
|
||||
* @return ReportGeneratorInterface
|
||||
*/
|
||||
public function setTags(Collection $tags): ReportGeneratorInterface
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $collection
|
||||
* @param int $sortFlag
|
||||
|
@@ -141,6 +141,16 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $tags
|
||||
*
|
||||
* @return ReportGeneratorInterface
|
||||
*/
|
||||
public function setTags(Collection $tags): ReportGeneratorInterface
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $collection
|
||||
* @param int $sortFlag
|
||||
|
@@ -64,4 +64,11 @@ interface ReportGeneratorInterface
|
||||
*/
|
||||
public function setStartDate(Carbon $date): ReportGeneratorInterface;
|
||||
|
||||
/**
|
||||
* @param Collection $tags
|
||||
*
|
||||
* @return ReportGeneratorInterface
|
||||
*/
|
||||
public function setTags(Collection $tags): ReportGeneratorInterface;
|
||||
|
||||
}
|
||||
|
@@ -106,4 +106,14 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $tags
|
||||
*
|
||||
* @return ReportGeneratorInterface
|
||||
*/
|
||||
public function setTags(Collection $tags): ReportGeneratorInterface
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@@ -103,4 +103,14 @@ class MultiYearReportGenerator implements ReportGeneratorInterface
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $tags
|
||||
*
|
||||
* @return ReportGeneratorInterface
|
||||
*/
|
||||
public function setTags(Collection $tags): ReportGeneratorInterface
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@@ -103,4 +103,14 @@ class YearReportGenerator implements ReportGeneratorInterface
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $tags
|
||||
*
|
||||
* @return ReportGeneratorInterface
|
||||
*/
|
||||
public function setTags(Collection $tags): ReportGeneratorInterface
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@@ -19,9 +19,11 @@ use FireflyIII\Generator\Report\ReportGeneratorFactory;
|
||||
use FireflyIII\Helpers\Report\ReportHelperInterface;
|
||||
use FireflyIII\Http\Requests\ReportFormRequest;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
@@ -96,6 +98,42 @@ class ReportController extends Controller
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Collection $tags
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function tagReport(Collection $accounts, Collection $tags, 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_tag',
|
||||
[
|
||||
'start' => $start->formatLocalized($this->monthFormat),
|
||||
'end' => $end->formatLocalized($this->monthFormat),
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
$generator = ReportGeneratorFactory::reportGenerator('Tag', $start, $end);
|
||||
$generator->setAccounts($accounts);
|
||||
$generator->setTags($tags);
|
||||
$result = $generator->generate();
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Collection $budgets
|
||||
@@ -238,6 +276,9 @@ class ReportController extends Controller
|
||||
case 'budget':
|
||||
$result = $this->budgetReportOptions();
|
||||
break;
|
||||
case 'tag':
|
||||
$result = $this->tagReportOptions();
|
||||
break;
|
||||
}
|
||||
|
||||
return Response::json(['html' => $result]);
|
||||
@@ -258,6 +299,7 @@ class ReportController extends Controller
|
||||
$accounts = join(',', $request->getAccountList()->pluck('id')->toArray());
|
||||
$categories = join(',', $request->getCategoryList()->pluck('id')->toArray());
|
||||
$budgets = join(',', $request->getBudgetList()->pluck('id')->toArray());
|
||||
$tags = join(',', $request->getTagList()->pluck('tag')->toArray());
|
||||
|
||||
if ($request->getAccountList()->count() === 0) {
|
||||
Session::flash('error', trans('firefly.select_more_than_one_account'));
|
||||
@@ -277,6 +319,12 @@ class ReportController extends Controller
|
||||
return redirect(route('reports.index'));
|
||||
}
|
||||
|
||||
if ($request->getTagList()->count() === 0 && $reportType === 'tag') {
|
||||
Session::flash('error', trans('firefly.select_more_than_one_tag'));
|
||||
|
||||
return redirect(route('reports.index'));
|
||||
}
|
||||
|
||||
if ($end < $start) {
|
||||
return view('error')->with('message', trans('firefly.end_after_start_date'));
|
||||
}
|
||||
@@ -301,6 +349,9 @@ class ReportController extends Controller
|
||||
case 'budget':
|
||||
$uri = route('reports.report.budget', [$accounts, $budgets, $start, $end]);
|
||||
break;
|
||||
case 'tag':
|
||||
$uri = route('reports.report.tag', [$accounts, $tags, $start, $end]);
|
||||
break;
|
||||
}
|
||||
|
||||
return redirect($uri);
|
||||
@@ -341,4 +392,22 @@ class ReportController extends Controller
|
||||
{
|
||||
return view('reports.options.no-options')->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function tagReportOptions(): string
|
||||
{
|
||||
/** @var TagRepositoryInterface $repository */
|
||||
$repository = app(TagRepositoryInterface::class);
|
||||
$tags = $repository->get()->sortBy(
|
||||
function (Tag $tag) {
|
||||
return $tag->tag;
|
||||
}
|
||||
);
|
||||
$result = view('reports.options.tag', compact('tags'))->render();
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@@ -141,13 +142,34 @@ class ReportFormRequest extends Request
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getTagList(): Collection
|
||||
{
|
||||
/** @var TagRepositoryInterface $repository */
|
||||
$repository = app(TagRepositoryInterface::class);
|
||||
$set = $this->get('tag');
|
||||
$collection = new Collection;
|
||||
if (is_array($set)) {
|
||||
foreach ($set as $tagTag) {
|
||||
$tag = $repository->findByTag($tagTag);
|
||||
if (!is_null($tag->id)) {
|
||||
$collection->push($tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'report_type' => 'in:audit,default,category,budget',
|
||||
'report_type' => 'in:audit,default,category,budget,tag',
|
||||
];
|
||||
}
|
||||
|
||||
|
52
app/Support/Binder/TagList.php
Normal file
52
app/Support/Binder/TagList.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* TagList.php
|
||||
* Copyright (c) 2017 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\Support\Binder;
|
||||
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Class TagList
|
||||
*
|
||||
* @package FireflyIII\Support\Binder
|
||||
*/
|
||||
class TagList implements BinderInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $route
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function routeBinder($value, $route): Collection
|
||||
{
|
||||
if (auth()->check()) {
|
||||
$tags = explode(',', $value);
|
||||
/** @var TagRepositoryInterface $repository */
|
||||
$repository = app(TagRepositoryInterface::class);
|
||||
$allTags = $repository->get();
|
||||
$set = $allTags->filter(
|
||||
function (Tag $tag) use ($tags) {
|
||||
return in_array($tag->tag, $tags);
|
||||
}
|
||||
);
|
||||
|
||||
if ($set->count() > 0) {
|
||||
return $set;
|
||||
}
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
}
|
@@ -153,6 +153,7 @@ return [
|
||||
'budgetList' => 'FireflyIII\Support\Binder\BudgetList',
|
||||
'journalList' => 'FireflyIII\Support\Binder\JournalList',
|
||||
'categoryList' => 'FireflyIII\Support\Binder\CategoryList',
|
||||
'tagList' => 'FireflyIII\Support\Binder\TagList',
|
||||
'start_date' => 'FireflyIII\Support\Binder\Date',
|
||||
'end_date' => 'FireflyIII\Support\Binder\Date',
|
||||
],
|
||||
|
@@ -98,8 +98,8 @@ function setOptionalFromCookies() {
|
||||
arr.forEach(function (val) {
|
||||
$('#inputCategories').find('option[value="' + val + '"]').prop('selected', true);
|
||||
});
|
||||
$('#inputCategories').multiselect(defaultMultiSelect);
|
||||
}
|
||||
$('#inputCategories').multiselect(defaultMultiSelect);
|
||||
|
||||
// and budgets!
|
||||
if ((readCookie('report-budgets') !== null)) {
|
||||
@@ -107,8 +107,17 @@ function setOptionalFromCookies() {
|
||||
arr.forEach(function (val) {
|
||||
$('#inputBudgets').find('option[value="' + val + '"]').prop('selected', true);
|
||||
});
|
||||
$('#inputBudgets').multiselect(defaultMultiSelect);
|
||||
}
|
||||
$('#inputBudgets').multiselect(defaultMultiSelect);
|
||||
|
||||
// and tags!
|
||||
if ((readCookie('report-tags') !== null)) {
|
||||
arr = readCookie('report-tags').split(',');
|
||||
arr.forEach(function (val) {
|
||||
$('#inputBudgets').find('option[value="' + val + '"]').prop('selected', true);
|
||||
});
|
||||
}
|
||||
$('#inputTags').multiselect(defaultMultiSelect);
|
||||
}
|
||||
|
||||
function catchSubmit() {
|
||||
@@ -117,45 +126,20 @@ function catchSubmit() {
|
||||
var picker = $('#inputDateRange').data('daterangepicker');
|
||||
|
||||
// all account ids:
|
||||
var count = 0;
|
||||
var accounts = [];
|
||||
$.each($('.account-checkbox'), function (i, v) {
|
||||
var c = $(v);
|
||||
if (c.prop('checked')) {
|
||||
accounts.push(c.val());
|
||||
count++;
|
||||
}
|
||||
});
|
||||
|
||||
// all category ids:
|
||||
var categories = [];
|
||||
$.each($('.category-checkbox'), function (i, v) {
|
||||
var c = $(v);
|
||||
if (c.prop('checked')) {
|
||||
categories.push(c.val());
|
||||
}
|
||||
});
|
||||
|
||||
// all budget ids:
|
||||
var budgets = [];
|
||||
$.each($('.budget-checkbox'), function (i, v) {
|
||||
var c = $(v);
|
||||
if (c.prop('checked')) {
|
||||
budgets.push(c.val());
|
||||
}
|
||||
});
|
||||
|
||||
var accounts = $('#inputAccounts').val();
|
||||
var categories = $('#inputCategories').val();
|
||||
var budgets = $('#inputBudgets').val();
|
||||
var tags = $('#inputTags').val();
|
||||
|
||||
// remember all
|
||||
if (count > 0) {
|
||||
// set cookie to remember choices.
|
||||
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-tags', tags, 365);
|
||||
createCookie('report-start', moment(picker.startDate).format("YYYYMMDD"), 365);
|
||||
createCookie('report-end', moment(picker.endDate).format("YYYYMMDD"), 365);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -554,6 +554,7 @@ return [
|
||||
'select_more_than_one_account' => 'Please select more than one account',
|
||||
'select_more_than_one_category' => 'Please select more than one category',
|
||||
'select_more_than_one_budget' => 'Please select more than one budget',
|
||||
'select_more_than_one_tag' => 'Please select more than one tag',
|
||||
'from_to' => 'From :start to :end',
|
||||
|
||||
// categories:
|
||||
@@ -711,6 +712,7 @@ return [
|
||||
'report_type_audit' => 'Transaction history overview (audit)',
|
||||
'report_type_category' => 'Category report',
|
||||
'report_type_budget' => 'Budget report',
|
||||
'report_type_tag' => 'Tag 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',
|
||||
@@ -729,8 +731,9 @@ return [
|
||||
'report_has_no_extra_options' => 'This report has no extra options',
|
||||
'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.',
|
||||
'select_category' => 'Select category(ies)',
|
||||
'select_budget' => 'Select budget(s).',
|
||||
'select_tag' => 'Select tag(s).',
|
||||
'income_per_category' => 'Income per category',
|
||||
'expense_per_category' => 'Expense per category',
|
||||
'expense_per_budget' => 'Expense per budget',
|
||||
|
@@ -28,6 +28,7 @@
|
||||
<option label="{{ 'report_type_audit'|_ }}" value="audit">{{ 'report_type_audit'|_ }}</option>
|
||||
<option label="{{ 'report_type_budget'|_ }}" value="budget">{{ 'report_type_budget'|_ }}</option>
|
||||
<option label="{{ 'report_type_category'|_ }}" value="category">{{ 'report_type_category'|_ }}</option>
|
||||
<option label="{{ 'report_type_tag'|_ }}" value="tag">{{ 'report_type_tag'|_ }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,8 +1,10 @@
|
||||
<p>
|
||||
{{ 'select_budget'|_ }}
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<label for="inputBudgets" class="col-sm-3 control-label">{{ 'select_budget'|_ }}</label>
|
||||
<div class="col-sm-9">
|
||||
<select id="inputBudgets" name="budget[]" multiple="multiple" class="form-control">
|
||||
{% for budget in budgets %}
|
||||
<option value="{{ budget.id }}" label="{{ budget.name }}">{{ budget.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
@@ -1,8 +1,11 @@
|
||||
<p>
|
||||
{{ 'select_category'|_ }}
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<label for="inputCategories" class="col-sm-3 control-label">{{ 'select_category'|_ }}</label>
|
||||
<div class="col-sm-9">
|
||||
<select id="inputCategories" name="category[]" multiple="multiple" class="form-control">
|
||||
{% for category in categories %}
|
||||
<option value="{{ category.id }}" label="{{ category.name }}">{{ category.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
10
resources/views/reports/options/tag.twig
Normal file
10
resources/views/reports/options/tag.twig
Normal file
@@ -0,0 +1,10 @@
|
||||
<div class="form-group">
|
||||
<label for="inputTags" class="col-sm-3 control-label">{{ 'select_tag'|_ }}</label>
|
||||
<div class="col-sm-9">
|
||||
<select id="inputTags" name="tag[]" multiple="multiple" class="form-control">
|
||||
{% for tag in tags %}
|
||||
<option value="{{ tag.tag }}" label="{{ tag.tag }}">{{ tag.tag }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
@@ -478,6 +478,7 @@ Route::group(
|
||||
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::get('tag/{accountList}/{tagList}/{start_date}/{end_date}', ['uses' => 'ReportController@tagReport', 'as' => 'report.tag']);
|
||||
|
||||
Route::post('', ['uses' => 'ReportController@postIndex', 'as' => 'index.post']);
|
||||
}
|
||||
|
Reference in New Issue
Block a user