From 4f4576e4586039868e76d028cd932c9a56aae39f Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 10 Oct 2025 16:41:46 +0200 Subject: [PATCH] Add option to select date, fix #11042 --- .../Controllers/Rule/SelectController.php | 68 +++++++++++-------- .../RuleGroup/ExecutionController.php | 11 +++ .../rules/rule-group/select-transactions.twig | 2 + .../views/rules/rule/select-transactions.twig | 2 + 4 files changed, 54 insertions(+), 29 deletions(-) diff --git a/app/Http/Controllers/Rule/SelectController.php b/app/Http/Controllers/Rule/SelectController.php index 1084a9f2c8..c16572851b 100644 --- a/app/Http/Controllers/Rule/SelectController.php +++ b/app/Http/Controllers/Rule/SelectController.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Controllers\Rule; +use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Requests\SelectTransactionsRequest; @@ -56,7 +57,7 @@ class SelectController extends Controller $this->middleware( static function ($request, $next) { - app('view')->share('title', (string) trans('firefly.rules')); + app('view')->share('title', (string)trans('firefly.rules')); app('view')->share('mainTitleIcon', 'fa-random'); return $next($request); @@ -71,20 +72,29 @@ class SelectController extends Controller { // Get parameters specified by the user /** @var User $user */ - $user = auth()->user(); - $accounts = implode(',', $request->get('accounts')); - + $user = auth()->user(); + $accounts = implode(',', $request->get('accounts')); // create new rule engine: $newRuleEngine = app(RuleEngineInterface::class); $newRuleEngine->setUser($user); + // add date operators. + if (null !== $request->get('start')) { + $startDate = new Carbon($request->get('start')); + $newRuleEngine->addOperator(['type' => 'date_after', 'value' => $startDate->format('Y-m-d')]); + } + if (null !== $request->get('end')) { + $endDate = new Carbon($request->get('end')); + $newRuleEngine->addOperator(['type' => 'date_before', 'value' => $endDate->format('Y-m-d')]); + } + // add extra operators: $newRuleEngine->addOperator(['type' => 'account_id', 'value' => $accounts]); // set rules: $newRuleEngine->setRules(new Collection()->push($rule)); $newRuleEngine->fire(); - $resultCount = $newRuleEngine->getResults(); + $resultCount = $newRuleEngine->getResults(); session()->flash('success', trans_choice('firefly.applied_rule_selection', $resultCount, ['title' => $rule->title])); @@ -94,7 +104,7 @@ class SelectController extends Controller /** * View to select transactions by a rule. */ - public function selectTransactions(Rule $rule): Factory|RedirectResponse|View + public function selectTransactions(Rule $rule): Factory | RedirectResponse | View { if (false === $rule->active) { session()->flash('warning', trans('firefly.cannot_fire_inactive_rules')); @@ -102,7 +112,7 @@ class SelectController extends Controller return redirect(route('rules.index')); } // does the user have shared accounts? - $subTitle = (string) trans('firefly.apply_rule_selection', ['title' => $rule->title]); + $subTitle = (string)trans('firefly.apply_rule_selection', ['title' => $rule->title]); return view('rules.rule.select-transactions', compact('rule', 'subTitle')); } @@ -116,25 +126,25 @@ class SelectController extends Controller public function testTriggers(TestRuleFormRequest $request): JsonResponse { // build fake rule - $rule = new Rule(); + $rule = new Rule(); /** @var \Illuminate\Database\Eloquent\Collection $triggers */ - $triggers = new Collection(); - $rule->strict = '1' === $request->get('strict'); + $triggers = new Collection(); + $rule->strict = '1' === $request->get('strict'); // build trigger array from response - $textTriggers = $this->getValidTriggerList($request); + $textTriggers = $this->getValidTriggerList($request); // warn if nothing. if (0 === count($textTriggers)) { - return response()->json(['html' => '', 'warning' => (string) trans('firefly.warning_no_valid_triggers')]); + return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]); } foreach ($textTriggers as $textTrigger) { - $needsContext = config(sprintf('search.operators.%s.needs_context', $textTrigger['type'])) ?? true; - $trigger = new RuleTrigger(); - $trigger->trigger_type = $textTrigger['type']; - $trigger->trigger_value = $textTrigger['value']; + $needsContext = config(sprintf('search.operators.%s.needs_context', $textTrigger['type'])) ?? true; + $trigger = new RuleTrigger(); + $trigger->trigger_type = $textTrigger['type']; + $trigger->trigger_value = $textTrigger['value']; if (false === $needsContext) { $trigger->trigger_value = 'true'; } @@ -149,22 +159,22 @@ class SelectController extends Controller // create new rule engine: /** @var RuleEngineInterface $newRuleEngine */ - $newRuleEngine = app(RuleEngineInterface::class); + $newRuleEngine = app(RuleEngineInterface::class); // set rules: $newRuleEngine->setRules(new Collection()->push($rule)); $newRuleEngine->setRefreshTriggers(false); - $collection = $newRuleEngine->find(); - $collection = $collection->slice(0, 20); + $collection = $newRuleEngine->find(); + $collection = $collection->slice(0, 20); // Warn the user if only a subset of transactions is returned - $warning = ''; + $warning = ''; if (0 === count($collection)) { - $warning = (string) trans('firefly.warning_no_matching_transactions'); + $warning = (string)trans('firefly.warning_no_matching_transactions'); } // Return json response - $view = 'ERROR, see logs.'; + $view = 'ERROR, see logs.'; try { $view = view('list.journals-array-tiny', ['groups' => $collection])->render(); @@ -187,26 +197,26 @@ class SelectController extends Controller */ public function testTriggersByRule(Rule $rule): JsonResponse { - $triggers = $rule->ruleTriggers; + $triggers = $rule->ruleTriggers; if (0 === count($triggers)) { - return response()->json(['html' => '', 'warning' => (string) trans('firefly.warning_no_valid_triggers')]); + return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]); } // create new rule engine: $newRuleEngine = app(RuleEngineInterface::class); // set rules: $newRuleEngine->setRules(new Collection()->push($rule)); - $collection = $newRuleEngine->find(); - $collection = $collection->slice(0, 20); + $collection = $newRuleEngine->find(); + $collection = $collection->slice(0, 20); - $warning = ''; + $warning = ''; if (0 === count($collection)) { - $warning = (string) trans('firefly.warning_no_matching_transactions'); + $warning = (string)trans('firefly.warning_no_matching_transactions'); } // Return json response - $view = 'ERROR, see logs.'; + $view = 'ERROR, see logs.'; try { $view = view('list.journals-array-tiny', ['groups' => $collection])->render(); diff --git a/app/Http/Controllers/RuleGroup/ExecutionController.php b/app/Http/Controllers/RuleGroup/ExecutionController.php index a0191cba3f..14ee17209a 100644 --- a/app/Http/Controllers/RuleGroup/ExecutionController.php +++ b/app/Http/Controllers/RuleGroup/ExecutionController.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Controllers\RuleGroup; +use Carbon\Carbon; use Exception; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Requests\SelectTransactionsRequest; @@ -73,6 +74,16 @@ class ExecutionController extends Controller $newRuleEngine = app(RuleEngineInterface::class); $newRuleEngine->setUser($user); + // add date operators. + if (null !== $request->get('start')) { + $startDate = new Carbon($request->get('start')); + $newRuleEngine->addOperator(['type' => 'date_after', 'value' => $startDate->format('Y-m-d')]); + } + if (null !== $request->get('end')) { + $endDate = new Carbon($request->get('end')); + $newRuleEngine->addOperator(['type' => 'date_before', 'value' => $endDate->format('Y-m-d')]); + } + // add extra operators: $newRuleEngine->addOperator(['type' => 'account_id', 'value' => $accounts]); diff --git a/resources/views/rules/rule-group/select-transactions.twig b/resources/views/rules/rule-group/select-transactions.twig index 81abe48208..4988fc45ed 100644 --- a/resources/views/rules/rule-group/select-transactions.twig +++ b/resources/views/rules/rule-group/select-transactions.twig @@ -24,6 +24,8 @@

+ {{ ExpandedForm.date('start') }} + {{ ExpandedForm.date('end') }} {{ AccountForm.assetAccountCheckList('accounts', {'select_all': true,'class': 'account-checkbox', 'label': trans('firefly.include_transactions_from_accounts') }) }}
diff --git a/resources/views/rules/rule/select-transactions.twig b/resources/views/rules/rule/select-transactions.twig index a6575e53f9..1338ce3c39 100644 --- a/resources/views/rules/rule/select-transactions.twig +++ b/resources/views/rules/rule/select-transactions.twig @@ -23,6 +23,8 @@

+ {{ ExpandedForm.date('start') }} + {{ ExpandedForm.date('end') }} {{ AccountForm.assetAccountCheckList('accounts', {'select_all': true, 'class': 'account-checkbox', 'label': trans('firefly.include_transactions_from_accounts') }) }}