This commit is contained in:
James Cole 2021-02-03 10:41:41 +01:00
parent 2ad7336605
commit 3b2dd93316
3 changed files with 93 additions and 4 deletions

View File

@ -100,6 +100,7 @@ class OperatorQuerySearch implements SearchInterface
private Collection $modifiers; // obsolete
private Collection $operators;
private string $originalQuery;
private Carbon $date;
/**
* OperatorQuerySearch constructor.
@ -115,6 +116,7 @@ class OperatorQuerySearch implements SearchInterface
$this->words = [];
$this->limit = 25;
$this->originalQuery = '';
$this->date = today(config('app.timezone'));
$this->validOperators = array_keys(config('firefly.search.operators'));
$this->startTime = microtime(true);
$this->accountRepository = app(AccountRepositoryInterface::class);
@ -144,6 +146,14 @@ class OperatorQuerySearch implements SearchInterface
return $this->operators;
}
/**
* @param Carbon $date
*/
public function setDate(Carbon $date): void
{
$this->date = $date;
}
/**
* @inheritDoc
* @codeCoverageIgnore
@ -255,7 +265,7 @@ class OperatorQuerySearch implements SearchInterface
throw new FireflyException(sprintf('Firefly III search cant handle "%s"-nodes', $class));
case Subquery::class:
// loop all notes in subquery:
foreach($searchNode->getNodes() as $subNode) {
foreach ($searchNode->getNodes() as $subNode) {
$this->handleSearchNode($subNode); // lets hope its not too recursive!
}
break;
@ -831,7 +841,7 @@ class OperatorQuerySearch implements SearchInterface
{
$parser = new ParseDateString;
if ($parser->isDateRange($value)) {
return $parser->parseRange($value, today(config('app.timezone')));
return $parser->parseRange($value, $this->date);
}
$date = $parser->parseDate($value);

View File

@ -22,6 +22,7 @@ declare(strict_types=1);
namespace FireflyIII\Support\Search;
use Carbon\Carbon;
use FireflyIII\User;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
@ -80,4 +81,9 @@ interface SearchInterface
* @param User $user
*/
public function setUser(User $user);
/**
* @param Carbon $date
*/
public function setDate(Carbon $date): void;
}

View File

@ -43,11 +43,13 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Engine;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Models\RuleTrigger;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Search\SearchInterface;
use FireflyIII\TransactionRules\Factory\ActionFactory;
use FireflyIII\User;
@ -274,8 +276,9 @@ class SearchRuleEngine implements RuleEngineInterface
Log::debug(sprintf('SearchRuleEngine:: done processing strict rule #%d', $rule->id));
$result = $collection->count() > 0;
if(true === $result) {
if (true === $result) {
Log::debug(sprintf('SearchRuleEngine:: rule #%d was triggered (on %d transaction(s)).', $rule->id, $collection->count()));
return true;
}
Log::debug(sprintf('SearchRuleEngine:: rule #%d was not triggered (on %d transaction(s)).', $rule->id, $collection->count()));
@ -332,15 +335,21 @@ class SearchRuleEngine implements RuleEngineInterface
Log::debug(sprintf('SearchRuleEngine:: add local added operator: %s:"%s"', $operator['type'], $operator['value']));
$searchArray[$operator['type']][] = sprintf('"%s"', $operator['value']);
}
$date = today(config('app.timezone'));
if ($this->hasSpecificJournalTrigger($searchArray)) {
$date = $this->setDateFromJournalTrigger($searchArray);
}
// build and run the search engine.
$searchEngine = app(SearchInterface::class);
$searchEngine->setUser($this->user);
$searchEngine->setPage(1);
$searchEngine->setLimit(31337);
$searchEngine->setDate($date);
foreach ($searchArray as $type => $searches) {
foreach($searches as $value) {
foreach ($searches as $value) {
$searchEngine->parseQuery(sprintf('%s:%s', $type, $value));
}
}
@ -422,6 +431,38 @@ class SearchRuleEngine implements RuleEngineInterface
return $unique;
}
/**
* Search in the triggers of this particular search and if it contains
* one search operator for "journal_id" it means the date ranges
* in the search may need to be updated.
*
* @param array $array
*
* @return bool
*/
private function hasSpecificJournalTrigger(array $array): bool
{
Log::debug('Now in hasSpecificJournalTrigger.');
$journalTrigger = false;
$dateTrigger = false;
foreach ($array as $triggerName => $values) {
if ('journal_id' === $triggerName) {
if (is_array($values) && 1 === count($values)) {
Log::debug('Found a journal_id trigger with 1 journal, true.');
$journalTrigger = true;
}
}
if (in_array($triggerName, ['date_is', 'date', 'on', 'date_before', 'before', 'date_after', 'after'], true)) {
Log::debug('Found a date related trigger, set to true.');
$dateTrigger = true;
}
}
$result = $journalTrigger && $dateTrigger;
Log::debug(sprintf('Result of hasSpecificJournalTrigger is %s.', var_export($result, true)));
return $result;
}
/**
* @param RuleGroup $group
*
@ -447,4 +488,36 @@ class SearchRuleEngine implements RuleEngineInterface
return $all;
}
/**
* @param array $array
*
* @return Carbon
*/
private function setDateFromJournalTrigger(array $array): Carbon
{
Log::debug('Now in setDateFromJournalTrigger()');
$journalId = 0;
foreach ($array as $triggerName => $values) {
if ('journal_id' === $triggerName) {
if (is_array($values) && 1 === count($values)) {
$journalId = (int)trim(($values[0] ?? '"0"'), '"'); // follows format "123".
Log::debug(sprintf('Found journal ID #%d', $journalId));
}
}
}
if (0 !== $journalId) {
$repository = app(JournalRepositoryInterface::class);
$journal = $repository->findNull($journalId);
if (null !== $journal) {
$date = $journal->date;
Log::debug(sprintf('Found journal #%d with date %s.', $journal->id, $journal->date->format('Y-m-d')));
return $date;
}
}
Log::debug('Found no journal, return default date.');
return today(config('app.timezone'));
}
}