Implement first version of the new rule engine.

This commit is contained in:
James Cole
2020-08-22 16:55:54 +02:00
parent 14df37712c
commit 216a0a186c
12 changed files with 825 additions and 586 deletions

View File

@@ -33,12 +33,14 @@ use FireflyIII\Models\Rule;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
use FireflyIII\TransactionRules\Engine\RuleEngine;
use FireflyIII\TransactionRules\Engine\RuleEngineInterface;
use FireflyIII\TransactionRules\TransactionMatcher;
use FireflyIII\Transformers\RuleTransformer;
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
@@ -215,8 +217,8 @@ class RuleController extends Controller
* @param RuleTestRequest $request
* @param Rule $rule
*
* @throws FireflyException
* @return JsonResponse
* @throws FireflyException
*/
public function testRule(RuleTestRequest $request, Rule $rule): JsonResponse
{
@@ -265,28 +267,27 @@ class RuleController extends Controller
// Get parameters specified by the user
$parameters = $request->getTriggerParameters();
/** @var RuleEngine $ruleEngine */
$ruleEngine = app(RuleEngine::class);
$ruleEngine->setUser(auth()->user());
/** @var RuleEngineInterface $ruleEngine */
$ruleEngine = app(RuleEngineInterface::class);
$ruleEngine->setRules(new Collection([$rule]));
$rules = [$rule->id];
$ruleEngine->setRulesToApply($rules);
$ruleEngine->setTriggerMode(RuleEngine::TRIGGER_STORE);
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($parameters['accounts']);
$collector->setRange($parameters['start_date'], $parameters['end_date']);
$journals = $collector->getExtractedJournals();
/** @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.');
// overrule the rule(s) if necessary.
if (array_key_exists('start', $parameters) && null !== $parameters['start'] ) {
// add a range:
$ruleEngine->addOperator(['type' => 'date_after', 'value' => $parameters['start']->format('Y-m-d')]);
}
if (array_key_exists('end', $parameters) && null !== $parameters['end']) {
// add a range:
$ruleEngine->addOperator(['type' => 'date_before', 'value' => $parameters['end']->format('Y-m-d')]);
}
if (array_key_exists('accounts', $parameters) && '' !== $parameters['accounts']) {
$ruleEngine->addOperator(['type' => 'account_id', 'value' => $parameters['accounts']]);
}
// file the rule(s)
$ruleEngine->fire();
return response()->json([], 204);
}

View File

@@ -28,11 +28,8 @@ namespace FireflyIII\Api\V1\Requests;
use Carbon\Carbon;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Collection;
use Log;
/**
* Class RuleTriggerRequest
@@ -40,6 +37,7 @@ use Log;
class RuleTriggerRequest extends FormRequest
{
use ConvertsDataTypes;
/**
* Authorize logged in users.
*
@@ -57,9 +55,9 @@ class RuleTriggerRequest extends FormRequest
public function getTriggerParameters(): array
{
return [
'start_date' => $this->getDate('start_date'),
'end_date' => $this->getDate('end_date'),
'accounts' => $this->getAccounts(),
'start' => $this->getDate('start'),
'end' => $this->getDate('end'),
'accounts' => $this->getAccounts(),
];
}
@@ -69,33 +67,17 @@ class RuleTriggerRequest extends FormRequest
public function rules(): array
{
return [
'start_date' => 'required|date',
'end_date' => 'required|date|after:start_date',
'start' => 'date',
'end' => 'date|after:start',
];
}
/**
* @return Collection
* @return string
*/
private function getAccounts(): Collection
private function getAccounts(): string
{
$accountList = '' === (string) $this->query('accounts') ? [] : explode(',', $this->query('accounts'));
$accounts = new Collection;
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app(AccountRepositoryInterface::class);
foreach ($accountList as $accountId) {
Log::debug(sprintf('Searching for asset account with id "%s"', $accountId));
$account = $accountRepository->findNull((int) $accountId);
if ($this->validAccount($account)) {
/** @noinspection NullPointerExceptionInspection */
Log::debug(sprintf('Found account #%d ("%s") and its an asset account', $account->id, $account->name));
$accounts->push($account);
}
}
return $accounts;
return (string) $this->query('accounts');
}
/**
@@ -111,14 +93,4 @@ class RuleTriggerRequest extends FormRequest
return $result;
}
/**
* @param Account|null $account
*
* @return bool
*/
private function validAccount(?Account $account): bool
{
return null !== $account && AccountType::ASSET === $account->accountType->type;
}
}