Code cleanup

This commit is contained in:
James Cole
2019-08-17 10:47:29 +02:00
parent 23479790fe
commit c2296c3ad5
95 changed files with 463 additions and 507 deletions

View File

@@ -22,6 +22,7 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
use Exception;
use FireflyIII\Models\Note;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
@@ -47,7 +48,7 @@ class ClearNotes implements ActionInterface
* @param TransactionJournal $journal
*
* @return bool
* @throws \Exception
* @throws Exception
*/
public function act(TransactionJournal $journal): bool
{

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\AccountFactory;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
@@ -57,7 +58,7 @@ class ConvertToDeposit implements ActionInterface
* @param TransactionJournal $journal
*
* @return bool
* @throws \FireflyIII\Exceptions\FireflyException
* @throws FireflyException
*/
public function act(TransactionJournal $journal): bool
{
@@ -121,7 +122,7 @@ class ConvertToDeposit implements ActionInterface
* @param TransactionJournal $journal
*
* @return bool
* @throws \FireflyIII\Exceptions\FireflyException
* @throws FireflyException
*/
private function convertTransfer(TransactionJournal $journal): bool
{
@@ -163,7 +164,7 @@ class ConvertToDeposit implements ActionInterface
* @param TransactionJournal $journal
*
* @return bool
* @throws \FireflyIII\Exceptions\FireflyException
* @throws FireflyException
*/
private function convertWithdrawal(TransactionJournal $journal): bool
{

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\AccountFactory;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
@@ -58,7 +59,7 @@ class ConvertToWithdrawal implements ActionInterface
* @param TransactionJournal $journal
*
* @return bool
* @throws \FireflyIII\Exceptions\FireflyException
* @throws FireflyException
*/
public function act(TransactionJournal $journal): bool
{
@@ -122,7 +123,7 @@ class ConvertToWithdrawal implements ActionInterface
* @param TransactionJournal $journal
*
* @return bool
* @throws \FireflyIII\Exceptions\FireflyException
* @throws FireflyException
*/
private function convertDeposit(TransactionJournal $journal): bool
{
@@ -175,7 +176,7 @@ class ConvertToWithdrawal implements ActionInterface
* @param TransactionJournal $journal
*
* @return bool
* @throws \FireflyIII\Exceptions\FireflyException
* @throws FireflyException
*/
private function convertTransfer(TransactionJournal $journal): bool
{

View File

@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Tag;
use FireflyIII\Models\TransactionJournal;
use Log;
@@ -47,6 +46,7 @@ class RemoveTag implements ActionInterface
/**
* Remove tag X
*
* @param TransactionJournal $journal
*
* @return bool
@@ -55,7 +55,7 @@ class RemoveTag implements ActionInterface
{
// if tag does not exist, no need to continue:
$name = $this->action->action_value;
$tag = $journal->user->tags()->where('tag', $name)->first();
$tag = $journal->user->tags()->where('tag', $name)->first();
if (null !== $tag) {
Log::debug(sprintf('RuleAction RemoveTag removed tag #%d ("%s") from journal #%d.', $tag->id, $tag->tag, $journal->id));

View File

@@ -47,13 +47,14 @@ class SetBudget implements ActionInterface
/**
* Set budget.
*
* @param TransactionJournal $journal
*
* @return bool
*/
public function act(TransactionJournal $journal): bool
{
$search = $this->action->action_value;
$search = $this->action->action_value;
$budget = $journal->user->budgets()->where('name', $search)->first();
if (null === $budget) {

View File

@@ -24,7 +24,6 @@ namespace FireflyIII\TransactionRules\Actions;
use FireflyIII\Factory\CategoryFactory;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use Log;

View File

@@ -133,9 +133,9 @@ class SetDestinationAccount implements ActionInterface
if (null === $account) {
$data = [
'name' => $this->action->action_value,
'account_type' => 'expense',
'account_type' => 'expense',
'account_type_id' => null,
'virtual_balance' => 0,
'virtual_balance' => 0,
'active' => true,
'iban' => null,
];

View File

@@ -137,9 +137,9 @@ class SetSourceAccount implements ActionInterface
// create new revenue account with this name:
$data = [
'name' => $this->action->action_value,
'account_type' => 'revenue',
'account_type' => 'revenue',
'account_type_id' => null,
'virtual_balance' => 0,
'virtual_balance' => 0,
'active' => true,
'iban' => null,
];

View File

@@ -45,19 +45,18 @@ class RuleEngine
public const TRIGGER_STORE = 1;
/** @var int */
public const TRIGGER_UPDATE = 2;
/** @var bool */
private $allRules;
/** @var RuleGroupRepository */
private $ruleGroupRepository;
/** @var Collection */
private $ruleGroups;
/** @var array */
private $rulesToApply;
/** @var bool */
private $allRules;
/** @var User */
private $user;
/** @var RuleGroupRepository */
private $ruleGroupRepository;
/** @var int */
private $triggerMode;
/** @var User */
private $user;
/**
* RuleEngine constructor.
@@ -72,94 +71,6 @@ class RuleEngine
$this->triggerMode = self::TRIGGER_STORE;
}
/**
* @param int $triggerMode
*/
public function setTriggerMode(int $triggerMode): void
{
$this->triggerMode = $triggerMode;
}
/**
* @param bool $allRules
*/
public function setAllRules(bool $allRules): void
{
Log::debug('RuleEngine will apply ALL rules.');
$this->allRules = $allRules;
}
/**
* @param array $rulesToApply
*/
public function setRulesToApply(array $rulesToApply): void
{
Log::debug('RuleEngine will try rules', $rulesToApply);
$this->rulesToApply = $rulesToApply;
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
$this->ruleGroupRepository->setUser($user);
$this->ruleGroups = $this->ruleGroupRepository->getActiveGroups();
}
/**
* @param TransactionJournal $transactionJournal
*/
public function processTransactionJournal(TransactionJournal $transactionJournal): void
{
Log::debug(sprintf('Will process transaction journal #%d ("%s")', $transactionJournal->id, $transactionJournal->description));
/** @var RuleGroup $group */
foreach ($this->ruleGroups as $group) {
Log::debug(sprintf('Now at rule group #%d', $group->id));
$groupTriggered = false;
/** @var Rule $rule */
foreach ($group->rules as $rule) {
Log::debug(sprintf('Now at rule #%d from rule group #%d', $rule->id, $group->id));
$ruleTriggered = false;
// if in rule selection, or group in selection or all rules, it's included.
if ($this->includeRule($rule)) {
Log::debug(sprintf('Rule #%d is included.', $rule->id));
/** @var Processor $processor */
$processor = app(Processor::class);
$ruleTriggered = false;
try {
$processor->make($rule, true);
$ruleTriggered = $processor->handleTransactionJournal($transactionJournal);
} catch (FireflyException $e) {
Log::error($e->getMessage());
}
if ($ruleTriggered) {
Log::debug('The rule was triggered, so the group is as well!');
$groupTriggered = true;
}
}
if (!$this->includeRule($rule)) {
Log::debug(sprintf('Rule #%d is not included.', $rule->id));
}
// if the rule is triggered and stop processing is true, cancel the entire group.
if ($ruleTriggered && $rule->stop_processing) {
Log::info(sprintf('Break out group #%d because rule #%d was triggered.', $group->id, $rule->id));
break;
}
}
// if group is triggered and stop processing is true, cancel the whole thing.
if ($groupTriggered && $group->stop_processing) {
Log::info(sprintf('Break out ALL because group #%d was triggered.', $group->id));
break;
}
}
Log::debug('Done processing this transaction journal.');
}
/**
* @param array $journal
*/
@@ -212,8 +123,96 @@ class RuleEngine
Log::debug('Done processing this transaction journal.');
}
/**
* @param TransactionJournal $transactionJournal
*/
public function processTransactionJournal(TransactionJournal $transactionJournal): void
{
Log::debug(sprintf('Will process transaction journal #%d ("%s")', $transactionJournal->id, $transactionJournal->description));
/** @var RuleGroup $group */
foreach ($this->ruleGroups as $group) {
Log::debug(sprintf('Now at rule group #%d', $group->id));
$groupTriggered = false;
/** @var Rule $rule */
foreach ($group->rules as $rule) {
Log::debug(sprintf('Now at rule #%d from rule group #%d', $rule->id, $group->id));
$ruleTriggered = false;
// if in rule selection, or group in selection or all rules, it's included.
if ($this->includeRule($rule)) {
Log::debug(sprintf('Rule #%d is included.', $rule->id));
/** @var Processor $processor */
$processor = app(Processor::class);
$ruleTriggered = false;
try {
$processor->make($rule, true);
$ruleTriggered = $processor->handleTransactionJournal($transactionJournal);
} catch (FireflyException $e) {
Log::error($e->getMessage());
}
if ($ruleTriggered) {
Log::debug('The rule was triggered, so the group is as well!');
$groupTriggered = true;
}
}
if (!$this->includeRule($rule)) {
Log::debug(sprintf('Rule #%d is not included.', $rule->id));
}
// if the rule is triggered and stop processing is true, cancel the entire group.
if ($ruleTriggered && $rule->stop_processing) {
Log::info(sprintf('Break out group #%d because rule #%d was triggered.', $group->id, $rule->id));
break;
}
}
// if group is triggered and stop processing is true, cancel the whole thing.
if ($groupTriggered && $group->stop_processing) {
Log::info(sprintf('Break out ALL because group #%d was triggered.', $group->id));
break;
}
}
Log::debug('Done processing this transaction journal.');
}
/**
* @param bool $allRules
*/
public function setAllRules(bool $allRules): void
{
Log::debug('RuleEngine will apply ALL rules.');
$this->allRules = $allRules;
}
/**
* @param array $rulesToApply
*/
public function setRulesToApply(array $rulesToApply): void
{
Log::debug('RuleEngine will try rules', $rulesToApply);
$this->rulesToApply = $rulesToApply;
}
/**
* @param int $triggerMode
*/
public function setTriggerMode(int $triggerMode): void
{
$this->triggerMode = $triggerMode;
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
$this->ruleGroupRepository->setUser($user);
$this->ruleGroups = $this->ruleGroupRepository->getActiveGroups();
}
/**
* @param Rule $rule
*
* @return bool
*/
private function includeRule(Rule $rule): bool
@@ -224,8 +223,8 @@ class RuleEngine
return false;
}
$validTrigger = ('store-journal' === $trigger->trigger_value && self::TRIGGER_STORE === $this->triggerMode) ||
('update-journal' === $trigger->trigger_value && self::TRIGGER_UPDATE === $this->triggerMode);
$validTrigger = ('store-journal' === $trigger->trigger_value && self::TRIGGER_STORE === $this->triggerMode)
|| ('update-journal' === $trigger->trigger_value && self::TRIGGER_UPDATE === $this->triggerMode);
return $validTrigger && ($this->allRules || in_array($rule->id, $this->rulesToApply, true));
}

View File

@@ -78,11 +78,11 @@ class TriggerFactory
* @param string $triggerValue
* @param bool $stopProcessing
*
* @see TriggerFactory::getTrigger
*
* @return AbstractTrigger
*
* @throws FireflyException
* @see TriggerFactory::getTrigger
*
*/
public static function makeTriggerFromStrings(string $triggerType, string $triggerValue, bool $stopProcessing): AbstractTrigger
{

View File

@@ -22,6 +22,7 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\RuleTrigger;
@@ -62,16 +63,71 @@ class Processor
$this->actions = new Collection;
}
/**
* Return found triggers
*
* @return int
*/
public function getFoundTriggers(): int
{
return $this->foundTriggers;
}
/**
* Set found triggers
*
* @param int $foundTriggers
*/
public function setFoundTriggers(int $foundTriggers): void
{
$this->foundTriggers = $foundTriggers;
}
/**
* Returns the rule
*
* @return \FireflyIII\Models\Rule
* @return Rule
*/
public function getRule(): Rule
{
return $this->rule;
}
/**
* This method will scan the given transaction journal and check if it matches the triggers found in the Processor
* If so, it will also attempt to run the given actions on the journal. It returns a bool indicating if the transaction journal
* matches all of the triggers (regardless of whether the Processor could act on it).
*
* @param array $journal
*
* @return bool
* @throws FireflyException
*/
public function handleJournalArray(array $journal): bool
{
Log::debug(sprintf('handleJournalArray for journal #%d (group #%d)', $journal['transaction_journal_id'], $journal['transaction_group_id']));
// grab the actual journal.
$this->journal = TransactionJournal::find($journal['transaction_journal_id']);
// get all triggers:
$triggered = $this->triggered();
if ($triggered) {
Log::debug('Rule is triggered, go to actions.');
if ($this->actions->count() > 0) {
Log::debug('Has more than zero actions.');
$this->actions();
}
if (0 === $this->actions->count()) {
Log::info('Rule has no actions!');
}
return true;
}
return false;
}
/**
* This method will scan the given transaction journal and check if it matches the triggers found in the Processor
* If so, it will also attempt to run the given actions on the journal. It returns a bool indicating if the transaction journal
@@ -80,7 +136,7 @@ class Processor
* @param Transaction $transaction
*
* @return bool
* @throws \FireflyIII\Exceptions\FireflyException
* @throws FireflyException
*/
public function handleTransaction(Transaction $transaction): bool
{
@@ -107,6 +163,140 @@ class Processor
return false;
}
/**
* This method will scan the given transaction journal and check if it matches the triggers found in the Processor
* If so, it will also attempt to run the given actions on the journal. It returns a bool indicating if the transaction journal
* matches all of the triggers (regardless of whether the Processor could act on it).
*
* @param TransactionJournal $journal
*
* @return bool
* @throws FireflyException
*/
public function handleTransactionJournal(TransactionJournal $journal): bool
{
Log::debug(sprintf('handleTransactionJournal for journal %d', $journal->id));
$this->journal = $journal;
// get all triggers:
$triggered = $this->triggered();
if ($triggered) {
if ($this->actions->count() > 0) {
$this->actions();
}
return true;
}
return false;
}
/**
* @return bool
*/
public function isStrict(): bool
{
return $this->strict;
}
/**
* @param bool $strict
*/
public function setStrict(bool $strict): void
{
$this->strict = $strict;
}
/**
* This method will make a Processor that will process each transaction journal using the triggers
* and actions found in the given Rule.
*
* @param Rule $rule
* @param bool $includeActions
*
* @throws FireflyException
*/
public function make(Rule $rule, bool $includeActions = null): void
{
$includeActions = $includeActions ?? true;
Log::debug(sprintf('Making new rule from Rule %d', $rule->id));
Log::debug(sprintf('Rule is strict: %s', var_export($rule->strict, true)));
$this->rule = $rule;
$this->strict = $rule->strict;
$triggerSet = $rule->ruleTriggers()->orderBy('order', 'ASC')->get();
/** @var RuleTrigger $trigger */
foreach ($triggerSet as $trigger) {
Log::debug(sprintf('Push trigger %d', $trigger->id));
$this->triggers->push(TriggerFactory::getTrigger($trigger));
}
if (true === $includeActions) {
$this->actions = $rule->ruleActions()->orderBy('order', 'ASC')->get();
}
}
/**
* This method will make a Processor that will process each transaction journal using the given
* trigger (singular!). It can only report if the transaction journal was hit by the given trigger
* and will not be able to act on it using actions.
*
* @param string $triggerName
* @param string $triggerValue
*
* @throws FireflyException
*/
public function makeFromString(string $triggerName, string $triggerValue): void
{
Log::debug(sprintf('Processor::makeFromString("%s", "%s")', $triggerName, $triggerValue));
$trigger = TriggerFactory::makeTriggerFromStrings($triggerName, $triggerValue, false);
$this->triggers->push($trigger);
}
/**
* This method will make a Processor that will process each transaction journal using the given
* triggers. It can only report if the transaction journal was hit by the given triggers
* and will not be able to act on it using actions.
*
* The given triggers must be in the following format:
*
* [type => xx, value => yy, stop_processing => bool], [type => xx, value => yy, stop_processing => bool],
*
* @param array $triggers
*
* @throws FireflyException
*/
public function makeFromStringArray(array $triggers): void
{
foreach ($triggers as $entry) {
$entry['value'] = $entry['value'] ?? '';
$trigger = TriggerFactory::makeTriggerFromStrings($entry['type'], $entry['value'], $entry['stop_processing']);
$this->triggers->push($trigger);
}
}
/**
* Run the actions
*
* @return void
* @throws FireflyException
*/
private function actions(): void
{
/**
* @var int
* @var RuleAction $action
*/
foreach ($this->actions as $action) {
/** @var ActionInterface $actionClass */
$actionClass = ActionFactory::getAction($action);
Log::debug(sprintf('Fire action %s on journal #%d', get_class($actionClass), $this->journal->id));
$actionClass->act($this->journal);
if ($action->stop_processing) {
Log::debug('Stop processing now and break.');
break;
}
}
}
/**
* Method to check whether the current transaction would be triggered
* by the given list of triggers.
@@ -147,193 +337,4 @@ class Processor
return $result;
}
/**
* Return found triggers
*
* @return int
*/
public function getFoundTriggers(): int
{
return $this->foundTriggers;
}
/**
* Set found triggers
*
* @param int $foundTriggers
*/
public function setFoundTriggers(int $foundTriggers): void
{
$this->foundTriggers = $foundTriggers;
}
/**
* Run the actions
*
* @return void
* @throws \FireflyIII\Exceptions\FireflyException
*/
private function actions(): void
{
/**
* @var int
* @var RuleAction $action
*/
foreach ($this->actions as $action) {
/** @var ActionInterface $actionClass */
$actionClass = ActionFactory::getAction($action);
Log::debug(sprintf('Fire action %s on journal #%d', get_class($actionClass), $this->journal->id));
$actionClass->act($this->journal);
if ($action->stop_processing) {
Log::debug('Stop processing now and break.');
break;
}
}
}
/**
* This method will scan the given transaction journal and check if it matches the triggers found in the Processor
* If so, it will also attempt to run the given actions on the journal. It returns a bool indicating if the transaction journal
* matches all of the triggers (regardless of whether the Processor could act on it).
*
* @param array $journal
*
* @return bool
* @throws \FireflyIII\Exceptions\FireflyException
*/
public function handleJournalArray(array $journal): bool
{
Log::debug(sprintf('handleJournalArray for journal #%d (group #%d)', $journal['transaction_journal_id'], $journal['transaction_group_id']));
// grab the actual journal.
$this->journal = TransactionJournal::find($journal['transaction_journal_id']);
// get all triggers:
$triggered = $this->triggered();
if ($triggered) {
Log::debug('Rule is triggered, go to actions.');
if ($this->actions->count() > 0) {
Log::debug('Has more than zero actions.');
$this->actions();
}
if (0 === $this->actions->count()) {
Log::info('Rule has no actions!');
}
return true;
}
return false;
}
/**
* This method will scan the given transaction journal and check if it matches the triggers found in the Processor
* If so, it will also attempt to run the given actions on the journal. It returns a bool indicating if the transaction journal
* matches all of the triggers (regardless of whether the Processor could act on it).
*
* @param TransactionJournal $journal
*
* @return bool
* @throws \FireflyIII\Exceptions\FireflyException
*/
public function handleTransactionJournal(TransactionJournal $journal): bool
{
Log::debug(sprintf('handleTransactionJournal for journal %d', $journal->id));
$this->journal = $journal;
// get all triggers:
$triggered = $this->triggered();
if ($triggered) {
if ($this->actions->count() > 0) {
$this->actions();
}
return true;
}
return false;
}
/**
* @return bool
*/
public function isStrict(): bool
{
return $this->strict;
}
/**
* @param bool $strict
*/
public function setStrict(bool $strict): void
{
$this->strict = $strict;
}
/**
* This method will make a Processor that will process each transaction journal using the triggers
* and actions found in the given Rule.
*
* @param Rule $rule
* @param bool $includeActions
*
* @throws \FireflyIII\Exceptions\FireflyException
*/
public function make(Rule $rule, bool $includeActions = null): void
{
$includeActions = $includeActions ?? true;
Log::debug(sprintf('Making new rule from Rule %d', $rule->id));
Log::debug(sprintf('Rule is strict: %s', var_export($rule->strict, true)));
$this->rule = $rule;
$this->strict = $rule->strict;
$triggerSet = $rule->ruleTriggers()->orderBy('order', 'ASC')->get();
/** @var RuleTrigger $trigger */
foreach ($triggerSet as $trigger) {
Log::debug(sprintf('Push trigger %d', $trigger->id));
$this->triggers->push(TriggerFactory::getTrigger($trigger));
}
if (true === $includeActions) {
$this->actions = $rule->ruleActions()->orderBy('order', 'ASC')->get();
}
}
/**
* This method will make a Processor that will process each transaction journal using the given
* trigger (singular!). It can only report if the transaction journal was hit by the given trigger
* and will not be able to act on it using actions.
*
* @param string $triggerName
* @param string $triggerValue
*
* @throws \FireflyIII\Exceptions\FireflyException
*/
public function makeFromString(string $triggerName, string $triggerValue): void
{
Log::debug(sprintf('Processor::makeFromString("%s", "%s")', $triggerName, $triggerValue));
$trigger = TriggerFactory::makeTriggerFromStrings($triggerName, $triggerValue, false);
$this->triggers->push($trigger);
}
/**
* This method will make a Processor that will process each transaction journal using the given
* triggers. It can only report if the transaction journal was hit by the given triggers
* and will not be able to act on it using actions.
*
* The given triggers must be in the following format:
*
* [type => xx, value => yy, stop_processing => bool], [type => xx, value => yy, stop_processing => bool],
*
* @param array $triggers
*
* @throws \FireflyIII\Exceptions\FireflyException
*/
public function makeFromStringArray(array $triggers): void
{
foreach ($triggers as $entry) {
$entry['value'] = $entry['value'] ?? '';
$trigger = TriggerFactory::makeTriggerFromStrings($entry['type'], $entry['value'], $entry['stop_processing']);
$this->triggers->push($trigger);
}
}
}

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleTrigger;
@@ -78,7 +79,7 @@ class TransactionMatcher
* triggers onto each transaction journal until enough matches are found ($limit).
*
* @return array
* @throws \FireflyIII\Exceptions\FireflyException
* @throws FireflyException
*/
public function findTransactionsByRule(): array
{
@@ -108,7 +109,7 @@ class TransactionMatcher
* triggers onto each transaction journal until enough matches are found ($limit).
*
* @return array
* @throws \FireflyIII\Exceptions\FireflyException
* @throws FireflyException
*/
public function findTransactionsByTriggers(): array
{