diff --git a/app/Handlers/Events/FireRulesForStore.php b/app/Handlers/Events/FireRulesForStore.php index daa0a2993f..1fa8554217 100644 --- a/app/Handlers/Events/FireRulesForStore.php +++ b/app/Handlers/Events/FireRulesForStore.php @@ -49,7 +49,7 @@ class FireRulesForStore // get all the user's rule groups, with the rules, order by 'order'. /** @var User $user */ $user = Auth::user(); - $groups = $user->ruleGroups()->orderBy('order', 'ASC')->get(); + $groups = $user->ruleGroups()->where('rule_groups.active', 1)->orderBy('order', 'ASC')->get(); // /** @var RuleGroup $group */ foreach ($groups as $group) { @@ -58,16 +58,17 @@ class FireRulesForStore ->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id') ->where('rule_triggers.trigger_type', 'user_action') ->where('rule_triggers.trigger_value', 'store-journal') + ->where('rules.active', 1) ->get(['rules.*']); /** @var Rule $rule */ foreach ($rules as $rule) { - Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title. ')'); + Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title . ')'); $processor = new Processor($rule, $event->journal); // get some return out of this? $processor->handle(); - if($rule->stop_processing) { + if ($rule->stop_processing) { break; } diff --git a/app/Http/Controllers/RuleController.php b/app/Http/Controllers/RuleController.php index a5fef2265a..fe70fd6937 100644 --- a/app/Http/Controllers/RuleController.php +++ b/app/Http/Controllers/RuleController.php @@ -217,8 +217,8 @@ class RuleController extends Controller $actionCount = 0; // collection of those triggers/actions. - $triggers = []; - $actions = []; + $oldTriggers = []; + $oldActions = []; // has old input? if (Input::old()) { @@ -284,14 +284,15 @@ class RuleController extends Controller 'count' => $count, ] )->render(); + $newIndex++; } - $newIndex++; + } // get current actions $newIndex = 0; /** - * @var int $index + * @var int $index * @var RuleAction $entry */ foreach ($rule->ruleActions as $index => $entry) { @@ -314,7 +315,7 @@ class RuleController extends Controller } // get rule trigger for update / store-journal: - $primaryTrigger = $rule->ruleTriggers()->where('trigger_type','user_action')->first()->trigger_value; + $primaryTrigger = $rule->ruleTriggers()->where('trigger_type', 'user_action')->first()->trigger_value; $subTitle = trans('firefly.edit_rule', ['title' => $rule->title]); @@ -327,10 +328,49 @@ class RuleController extends Controller Session::flash('gaEventCategory', 'rules'); Session::flash('gaEventAction', 'edit-rule'); - return view('rules.rule.edit', compact('rule', 'subTitle','primaryTrigger', + return view('rules.rule.edit', compact('rule', 'subTitle', 'primaryTrigger', 'oldTriggers', 'oldActions', 'triggerCount', 'actionCount')); } + /** + * @param RuleRepositoryInterface $repository + * @param RuleFormRequest $request + * @param Rule $rule + * @return $this|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector + */ + public function updateRule(RuleRepositoryInterface $repository, RuleFormRequest $request, Rule $rule) + { + + // process the rule itself: + $data = [ + 'title' => $request->get('title'), + 'active' => intval($request->get('active')) == 1, + 'trigger' => $request->get('trigger'), + 'description' => $request->get('description'), + 'rule-triggers' => $request->get('rule-trigger'), + 'rule-trigger-values' => $request->get('rule-trigger-value'), + 'rule-trigger-stop' => $request->get('rule-trigger-stop'), + 'rule-actions' => $request->get('rule-action'), + 'rule-action-values' => $request->get('rule-action-value'), + 'rule-action-stop' => $request->get('rule-action-stop'), + 'stop_processing' => intval($request->get('stop_processing')) == 1, + ]; + $repository->updateRule($rule, $data); + + Session::flash('success', trans('firefly.updated_rule', ['title' => $rule->title])); + Preferences::mark(); + + if (intval(Input::get('return_to_edit')) === 1) { + // set value so edit routine will not overwrite URL: + Session::put('rules.rule.edit.fromUpdate', true); + + return redirect(route('rules.rule.edit', [$rule->id]))->withInput(['return_to_edit' => 1]); + } + + // redirect to previous URL. + return redirect(Session::get('rules.rule.edit.url')); + } + /** * @param RuleGroup $ruleGroup diff --git a/app/Http/Requests/RuleFormRequest.php b/app/Http/Requests/RuleFormRequest.php index be60f0e06a..d5e7423b36 100644 --- a/app/Http/Requests/RuleFormRequest.php +++ b/app/Http/Requests/RuleFormRequest.php @@ -62,7 +62,6 @@ class RuleFormRequest extends Request for ($i = 0; $i < 10; $i++) { $rules['rule-action-value.' . $i] = 'required_if:rule-action.' . $i . ',' . $contextActions . '|ruleActionValue'; } - return $rules; } } diff --git a/app/Repositories/Rule/RuleRepository.php b/app/Repositories/Rule/RuleRepository.php index 2c5cc8cc5d..09659c2c30 100644 --- a/app/Repositories/Rule/RuleRepository.php +++ b/app/Repositories/Rule/RuleRepository.php @@ -409,4 +409,47 @@ class RuleRepository implements RuleRepositoryInterface return $ruleAction; } + + /** + * @param Rule $rule + * @param array $data + * @return Rule + */ + public function updateRule(Rule $rule, array $data) + { + // update rule: + $rule->active = $data['active']; + $rule->stop_processing = $data['stop_processing']; + $rule->title = $data['title']; + $rule->description = $data['description']; + $rule->save(); + + // delete triggers: + $rule->ruleTriggers()->delete(); + + // delete actions: + $rule->ruleActions()->delete(); + + // recreate triggers: + $order = 1; + $stopProcessing = false; + $this->storeTrigger($rule, 'user_action', $data['trigger'], $stopProcessing, $order); + foreach ($data['rule-triggers'] as $index => $trigger) { + $value = $data['rule-trigger-values'][$index]; + $stopProcessing = isset($data['rule-trigger-stop'][$index]) ? true : false; + $this->storeTrigger($rule, $trigger, $value, $stopProcessing, $order); + $order++; + } + + // recreate actions: + $order = 1; + foreach ($data['rule-actions'] as $index => $action) { + $value = $data['rule-action-values'][$index]; + $stopProcessing = isset($data['rule-action-stop'][$index]) ? true : false; + $this->storeAction($rule, $action, $value, $stopProcessing, $order); + } + + + return $rule; + } } \ No newline at end of file diff --git a/app/Repositories/Rule/RuleRepositoryInterface.php b/app/Repositories/Rule/RuleRepositoryInterface.php index 7980a473e1..cab6741a28 100644 --- a/app/Repositories/Rule/RuleRepositoryInterface.php +++ b/app/Repositories/Rule/RuleRepositoryInterface.php @@ -60,14 +60,14 @@ interface RuleRepositoryInterface public function destroyRule(Rule $rule); /** - * @param Rule $rule + * @param Rule $rule * @param array $ids * @return bool */ public function reorderRuleTriggers(Rule $rule, array $ids); /** - * @param Rule $rule + * @param Rule $rule * @param array $ids * @return bool */ @@ -89,6 +89,13 @@ interface RuleRepositoryInterface */ public function moveRuleUp(Rule $rule); + /** + * @param Rule $rule + * @param array $data + * @return Rule + */ + public function updateRule(Rule $rule, array $data); + /** * @param Rule $rule * @return bool @@ -128,22 +135,22 @@ interface RuleRepositoryInterface /** - * @param Rule $rule + * @param Rule $rule * @param string $action * @param string $value - * @param bool $stopProcessing - * @param int $order + * @param bool $stopProcessing + * @param int $order * * @return RuleTrigger */ public function storeTrigger(Rule $rule, $action, $value, $stopProcessing, $order); /** - * @param Rule $rule + * @param Rule $rule * @param string $action * @param string $value - * @param bool $stopProcessing - * @param int $order + * @param bool $stopProcessing + * @param int $order * * @return RuleAction */ diff --git a/app/Validation/FireflyValidator.php b/app/Validation/FireflyValidator.php index 72fe505804..6ca1067c65 100644 --- a/app/Validation/FireflyValidator.php +++ b/app/Validation/FireflyValidator.php @@ -10,10 +10,12 @@ use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; use FireflyIII\Models\Budget; use FireflyIII\Models\PiggyBank; +use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\User; use Illuminate\Contracts\Encryption\DecryptException; use Illuminate\Validation\Validator; +use Log; use Symfony\Component\Translation\TranslatorInterface; /** @@ -45,22 +47,29 @@ class FireflyValidator extends Validator */ public function validateRuleTriggerValue($attribute, $value, $parameters) { + // get the index from a string like "rule-trigger-value.2". + $parts = explode('.', $attribute); + $index = $parts[count($parts) - 1]; + // loop all rule-triggers. // check if rule-value matches the thing. if (is_array($this->data['rule-trigger'])) { - foreach ($this->data['rule-trigger'] as $index => $name) { - $value = isset($this->data['rule-trigger-value'][$index]) ? $this->data['rule-trigger-value'][$index] : false; - switch ($name) { - default: - return true; - case 'amount_less': - return is_numeric($value); - break; - case 'transaction_type': - echo 'Implement me!'; - exit; - break; - } + $name = isset($this->data['rule-trigger'][$index]) ? $this->data['rule-trigger'][$index] : 'invalid'; + $value = isset($this->data['rule-trigger-value'][$index]) ? $this->data['rule-trigger-value'][$index] : false; + switch ($name) { + default: + return true; + case 'amount_less': + return is_numeric($value); + break; + case 'transaction_type': + $count = TransactionType::where('type', $value)->count(); + + return $count === 1; + break; + case 'invalid': + return false; + break; } } } @@ -74,27 +83,35 @@ class FireflyValidator extends Validator */ public function validateRuleActionValue($attribute, $value, $parameters) { + // get the index from a string like "rule-action-value.2". + $parts = explode('.', $attribute); + $index = $parts[count($parts) - 1]; // loop all rule-actions. // check if rule-action-value matches the thing. - if (is_array($this->data['rule-action'])) { - foreach ($this->data['rule-action'] as $index => $name) { - $value = isset($this->data['rule-action-value'][$index]) ? $this->data['rule-action-value'][$index] : false; - switch ($name) { - default: - return true; - case 'set_budget': - /** @var BudgetRepositoryInterface $repository */ - $repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface'); - $budgets = $repository->getBudgets(); - // count budgets, should have at least one - $count = $budgets->filter( - function (Budget $budget) use ($value) { - return $budget->name == $value; - } - )->count(); - return ($count === 1); - } + if (is_array($this->data['rule-action'])) { + $name = isset($this->data['rule-action'][$index]) ? $this->data['rule-action'][$index] : 'invalid'; + $value = isset($this->data['rule-action-value'][$index]) ? $this->data['rule-action-value'][$index] : false; + switch ($name) { + default: + Log::debug(' (' . $attribute . ') (index:' . $index . ') Name is "' . $name . '" so no action is taken.'); + + return true; + case 'set_budget': + /** @var BudgetRepositoryInterface $repository */ + $repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface'); + $budgets = $repository->getBudgets(); + // count budgets, should have at least one + $count = $budgets->filter( + function (Budget $budget) use ($value) { + return $budget->name == $value; + } + )->count(); + + return ($count === 1); + case 'invalid': + return false; + } } diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index b38a75ce3e..d354d410c7 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -62,9 +62,11 @@ return [ 'save_rules_by_moving' => 'Save these rule(s) by moving them to another rule group:', 'make_new_rule' => 'Make new rule in rule group ":title"', 'rule_help_stop_processing' => 'When you check this box, later rules in this group will not be executed.', + 'rule_help_active' => 'Inactive rules will never fire.', 'stored_new_rule' => 'Stored new rule with title ":title"', 'deleted_rule' => 'Deleted rule with title ":title"', 'store_new_rule' => 'Store new rule', + 'updated_rule' => 'Updated rule with title ":title"', 'trigger' => 'Trigger', 'trigger_value' => 'Trigger on value', diff --git a/resources/views/rules/rule/edit.twig b/resources/views/rules/rule/edit.twig index b9a715408f..e14ac079d5 100644 --- a/resources/views/rules/rule/edit.twig +++ b/resources/views/rules/rule/edit.twig @@ -6,6 +6,7 @@ {% block content %} {{ Form.model(rule, {'class' : 'form-horizontal','id' : 'store','url' : route('rules.rule.update', rule.id)}) }} +