Switch to new rule engine on command line.

This commit is contained in:
James Cole 2020-08-23 16:37:08 +02:00
parent ce34e097a2
commit 41f2339c8c
No known key found for this signature in database
GPG Key ID: B5669F9493CDE38D
2 changed files with 30 additions and 59 deletions

View File

@ -27,7 +27,6 @@ namespace FireflyIII\Console\Commands\Tools;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Console\Commands\VerifiesAccessToken; use FireflyIII\Console\Commands\VerifiesAccessToken;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
use FireflyIII\Models\Rule; use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleGroup; use FireflyIII\Models\RuleGroup;
@ -35,7 +34,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\Rule\RuleRepositoryInterface; use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use FireflyIII\TransactionRules\Engine\RuleEngine; use FireflyIII\TransactionRules\Engine\RuleEngineInterface;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Log; use Log;
@ -58,7 +57,7 @@ class ApplyRules extends Command
* *
* @var string * @var string
*/ */
protected $signature protected $signature
= 'firefly-iii:apply-rules = 'firefly-iii:apply-rules
{--user=1 : The user ID.} {--user=1 : The user ID.}
{--token= : The user\'s access token.} {--token= : The user\'s access token.}
@ -68,45 +67,33 @@ class ApplyRules extends Command
{--all_rules : If set, will overrule both settings and simply apply ALL of your rules.} {--all_rules : If set, will overrule both settings and simply apply ALL of your rules.}
{--start_date= : The date of the earliest transaction to be included (inclusive). If omitted, will be your very first transaction ever. Format: YYYY-MM-DD} {--start_date= : The date of the earliest transaction to be included (inclusive). If omitted, will be your very first transaction ever. Format: YYYY-MM-DD}
{--end_date= : The date of the latest transaction to be included (inclusive). If omitted, will be your latest transaction ever. Format: YYYY-MM-DD}'; {--end_date= : The date of the latest transaction to be included (inclusive). If omitted, will be your latest transaction ever. Format: YYYY-MM-DD}';
/** @var array */ private array $acceptedAccounts;
private $acceptedAccounts; private Collection $accounts;
/** @var Collection */ private bool $allRules;
private $accounts; private Carbon $endDate;
/** @var bool */ private Collection $groups;
private $allRules; private RuleGroupRepositoryInterface $ruleGroupRepository;
/** @var Carbon */ private array $ruleGroupSelection;
private $endDate; private RuleRepositoryInterface $ruleRepository;
/** @var Collection */ private array $ruleSelection;
private $groups; private Carbon $startDate;
/** @var RuleGroupRepositoryInterface */
private $ruleGroupRepository;
/** @var array */
private $ruleGroupSelection;
/** @var RuleRepositoryInterface */
private $ruleRepository;
/** @var array */
private $ruleSelection;
/** @var Carbon */
private $startDate;
/** /**
* Execute the console command. * Execute the console command.
* *
* @throws FireflyException
* @return int * @return int
* @throws FireflyException
*/ */
public function handle(): int public function handle(): int
{ {
$start = microtime(true); $start = microtime(true);
$this->stupidLaravel(); $this->stupidLaravel();
// @codeCoverageIgnoreStart
if (!$this->verifyAccessToken()) { if (!$this->verifyAccessToken()) {
$this->error('Invalid access token.'); $this->error('Invalid access token.');
return 1; return 1;
} }
// @codeCoverageIgnoreEnd
// set user: // set user:
$this->ruleRepository->setUser($this->getUser()); $this->ruleRepository->setUser($this->getUser());
@ -125,7 +112,7 @@ class ApplyRules extends Command
// loop all groups and rules and indicate if they're included: // loop all groups and rules and indicate if they're included:
$rulesToApply = $this->getRulesToApply(); $rulesToApply = $this->getRulesToApply();
$count = count($rulesToApply); $count = $rulesToApply->count();
if (0 === $count) { if (0 === $count) {
$this->error('No rules or rule groups have been included.'); $this->error('No rules or rule groups have been included.');
$this->warn('Make a selection using:'); $this->warn('Make a selection using:');
@ -137,37 +124,20 @@ class ApplyRules extends Command
return 1; return 1;
} }
/** @var GroupCollectorInterface $collector */ // create new rule engine:
$collector = app(GroupCollectorInterface::class); /** @var RuleEngineInterface $ruleEngine */
$collector->setUser($this->getUser()); $ruleEngine = app(RuleEngineInterface::class);
$collector->setAccounts($this->accounts); $ruleEngine->setRules($rulesToApply);
$collector->setRange($this->startDate, $this->endDate); $ruleEngine->setUser($this->getUser());
$journals = $collector->getExtractedJournals();
// start running rules. // start running rules.
$this->line(sprintf('Will apply %d rule(s) to %d transaction(s).', $count, count($journals))); $this->line(sprintf('Will apply %d rule(s) to your transaction(s).', $count));
// start looping. // file the rule(s)
/** @var RuleEngine $ruleEngine */ $ruleEngine->fire();
$ruleEngine = app(RuleEngine::class);
$ruleEngine->setUser($this->getUser());
$ruleEngine->setRulesToApply($rulesToApply);
app('telemetry')->feature('system.command.executed', $this->signature); app('telemetry')->feature('system.command.executed', $this->signature);
// for this call, the rule engine only includes "store" rules:
$ruleEngine->setTriggerMode(RuleEngine::TRIGGER_STORE);
$bar = $this->output->createProgressBar(count($journals));
Log::debug(sprintf('Now looping %d transactions.', count($journals)));
/** @var array $journal */
foreach ($journals as $journal) {
Log::debug('Start of new journal.');
$ruleEngine->processJournalArray($journal);
Log::debug('Done with all rules for this group + done with journal.');
/** @noinspection DisconnectedForeachInstructionInspection */
$bar->advance();
}
$this->line(''); $this->line('');
$end = round(microtime(true) - $start, 2); $end = round(microtime(true) - $start, 2);
$this->line(sprintf('Done in %s seconds!', $end)); $this->line(sprintf('Done in %s seconds!', $end));
@ -176,11 +146,11 @@ class ApplyRules extends Command
} }
/** /**
* @return array * @return Collection
*/ */
private function getRulesToApply(): array private function getRulesToApply(): Collection
{ {
$rulesToApply = []; $rulesToApply = new Collection;
/** @var RuleGroup $group */ /** @var RuleGroup $group */
foreach ($this->groups as $group) { foreach ($this->groups as $group) {
$rules = $this->ruleGroupRepository->getActiveStoreRules($group); $rules = $this->ruleGroupRepository->getActiveStoreRules($group);
@ -190,7 +160,7 @@ class ApplyRules extends Command
$test = $this->includeRule($rule, $group); $test = $this->includeRule($rule, $group);
if (true === $test) { if (true === $test) {
Log::debug(sprintf('Will include rule #%d "%s"', $rule->id, $rule->title)); Log::debug(sprintf('Will include rule #%d "%s"', $rule->id, $rule->title));
$rulesToApply[] = $rule->id; $rulesToApply->push($rule);
} }
} }
} }
@ -238,8 +208,8 @@ class ApplyRules extends Command
} }
/** /**
* @throws FireflyException
* @return bool * @return bool
* @throws FireflyException
*/ */
private function verifyInput(): bool private function verifyInput(): bool
{ {
@ -261,8 +231,8 @@ class ApplyRules extends Command
} }
/** /**
* @throws FireflyException
* @return bool * @return bool
* @throws FireflyException
*/ */
private function verifyInputAccounts(): bool private function verifyInputAccounts(): bool
{ {

View File

@ -42,7 +42,8 @@ class SearchRuleEngine implements RuleEngineInterface
public function __construct() public function __construct()
{ {
$this->rules = new Collection; $this->rules = new Collection;
$this->operators = [];
} }
/** /**