mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-18 18:40:12 +00:00
Expand search
This commit is contained in:
@@ -32,33 +32,20 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
|||||||
*/
|
*/
|
||||||
trait CollectorProperties
|
trait CollectorProperties
|
||||||
{
|
{
|
||||||
/** @var array The standard fields to select. */
|
private array $fields;
|
||||||
private $fields;
|
private bool $hasAccountInfo;
|
||||||
/** @var bool Will be set to true if query result contains account information. (see function withAccountInformation). */
|
private bool $hasBillInformation;
|
||||||
private $hasAccountInfo;
|
private bool $hasBudgetInformation;
|
||||||
/** @var bool Will be true if query result includes bill information. */
|
private bool $hasCatInformation;
|
||||||
private $hasBillInformation;
|
private bool $hasJoinedAttTables;
|
||||||
/** @var bool Will be true if query result contains budget info. */
|
|
||||||
private $hasBudgetInformation;
|
|
||||||
/** @var bool Will be true if query result contains category info. */
|
|
||||||
private $hasCatInformation;
|
|
||||||
/** @var bool Will be true for attachments */
|
|
||||||
private $hasJoinedAttTables;
|
|
||||||
private bool $hasJoinedMetaTables;
|
private bool $hasJoinedMetaTables;
|
||||||
/** @var bool Will be true of the query has the tag info tables joined. */
|
private bool $hasJoinedTagTables;
|
||||||
private $hasJoinedTagTables;
|
private bool $hasNotesInformation;
|
||||||
/** @var bool */
|
private array $integerFields;
|
||||||
private $hasNotesInformation;
|
private ?int $limit;
|
||||||
/** @var array */
|
private ?int $page;
|
||||||
private $integerFields;
|
private HasMany $query;
|
||||||
/** @var int The maximum number of results. */
|
private int $total;
|
||||||
private $limit;
|
private ?User $user;
|
||||||
/** @var int The page to return. */
|
private array $postFilters;
|
||||||
private $page;
|
|
||||||
/** @var HasMany The query object. */
|
|
||||||
private $query;
|
|
||||||
/** @var int Total number of results. */
|
|
||||||
private $total;
|
|
||||||
/** @var User The user object. */
|
|
||||||
private $user;
|
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,7 @@ use FireflyIII\Models\Tag;
|
|||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Query\JoinClause;
|
use Illuminate\Database\Query\JoinClause;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trait MetaCollection
|
* Trait MetaCollection
|
||||||
@@ -295,6 +296,35 @@ trait MetaCollection
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Without tags
|
||||||
|
*
|
||||||
|
* @param Collection $tags
|
||||||
|
*
|
||||||
|
* @return GroupCollectorInterface
|
||||||
|
*/
|
||||||
|
public function setWithoutSpecificTags(Collection $tags): GroupCollectorInterface
|
||||||
|
{
|
||||||
|
$this->withTagInformation();
|
||||||
|
|
||||||
|
// this method adds a "postFilter" to the collector.
|
||||||
|
$list = $tags->pluck('tag')->toArray();
|
||||||
|
$filter = function (int $index, array $object) use ($list): bool {
|
||||||
|
foreach($object['transactions'] as $transaction) {
|
||||||
|
foreach($transaction['tags'] as $tag) {
|
||||||
|
if(in_array($tag['name'], $list)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
$this->postFilters[] = $filter;
|
||||||
|
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return GroupCollectorInterface
|
* @return GroupCollectorInterface
|
||||||
*/
|
*/
|
||||||
@@ -307,7 +337,7 @@ trait MetaCollection
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Limit results to transactions without a bill..
|
* Limit results to transactions without a bill.
|
||||||
*
|
*
|
||||||
* @return GroupCollectorInterface
|
* @return GroupCollectorInterface
|
||||||
*/
|
*/
|
||||||
|
@@ -55,6 +55,11 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
$this->postFilters = [];
|
||||||
|
$this->user = null;
|
||||||
|
$this->limit = null;
|
||||||
|
$this->page = null;
|
||||||
|
|
||||||
$this->hasAccountInfo = false;
|
$this->hasAccountInfo = false;
|
||||||
$this->hasCatInformation = false;
|
$this->hasCatInformation = false;
|
||||||
$this->hasBudgetInformation = false;
|
$this->hasBudgetInformation = false;
|
||||||
@@ -241,6 +246,11 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
|
|
||||||
// now to parse this into an array.
|
// now to parse this into an array.
|
||||||
$collection = $this->parseArray($result);
|
$collection = $this->parseArray($result);
|
||||||
|
|
||||||
|
// filter the array using all available post filters:
|
||||||
|
$collection = $this->postFilterCollection($collection);
|
||||||
|
|
||||||
|
// count it and continue:
|
||||||
$this->total = $collection->count();
|
$this->total = $collection->count();
|
||||||
|
|
||||||
// now filter the array according to the page and the limit (if necessary)
|
// now filter the array according to the page and the limit (if necessary)
|
||||||
@@ -730,7 +740,7 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
|
|
||||||
// also merge attachments:
|
// also merge attachments:
|
||||||
if (array_key_exists('attachment_id', $result)) {
|
if (array_key_exists('attachment_id', $result)) {
|
||||||
$uploaded = 1 === (int)$result['attachment_uploaded'];
|
$uploaded = 1 === (int) $result['attachment_uploaded'];
|
||||||
$attachmentId = (int) $augumentedJournal['attachment_id'];
|
$attachmentId = (int) $augumentedJournal['attachment_id'];
|
||||||
if (0 !== $attachmentId && $uploaded) {
|
if (0 !== $attachmentId && $uploaded) {
|
||||||
$result['attachments'][$attachmentId] = [
|
$result['attachments'][$attachmentId] = [
|
||||||
@@ -738,6 +748,8 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// unset various fields:
|
||||||
|
unset($result['tag_id'], $result['tag_name'], $result['tag_date'], $result['tag_description'], $result['tag_latitude'], $result['tag_longitude'], $result['tag_zoom_level']);
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
@@ -789,4 +801,27 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
|
|
||||||
return $groups;
|
return $groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $collection
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
private function postFilterCollection(Collection $collection): Collection
|
||||||
|
{
|
||||||
|
Log::debug('Now in postFilterCollection()');
|
||||||
|
$newCollection = new Collection;
|
||||||
|
foreach ($collection as $i => $item) {
|
||||||
|
Log::debug(sprintf('Now working on item #%d/%d', $i + 1, $collection->count()));
|
||||||
|
foreach ($this->postFilters as $func) {
|
||||||
|
if (false === $func($i, $item)) {
|
||||||
|
// skip other filters, continue to next item.
|
||||||
|
Log::debug('Filter returns false, jump to next item.');
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
Log::debug('Filter returns true');
|
||||||
|
}
|
||||||
|
$newCollection->push($item);
|
||||||
|
}
|
||||||
|
return $newCollection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -419,6 +419,15 @@ interface GroupCollectorInterface
|
|||||||
*/
|
*/
|
||||||
public function setTags(Collection $tags): GroupCollectorInterface;
|
public function setTags(Collection $tags): GroupCollectorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only when does not have these tags
|
||||||
|
*
|
||||||
|
* @param Collection $tags
|
||||||
|
*
|
||||||
|
* @return GroupCollectorInterface
|
||||||
|
*/
|
||||||
|
public function setWithoutSpecificTags(Collection $tags): GroupCollectorInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Limit the search to one specific transaction group.
|
* Limit the search to one specific transaction group.
|
||||||
*
|
*
|
||||||
|
@@ -782,4 +782,35 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
|
|
||||||
return $service->update($bill, $data);
|
return $service->update($bill, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function billEndsWith(string $query, int $limit): Collection
|
||||||
|
{
|
||||||
|
$search = $this->user->bills();
|
||||||
|
if ('' !== $query) {
|
||||||
|
$search->where('name', 'LIKE', sprintf('%%%s', $query));
|
||||||
|
}
|
||||||
|
$search->orderBy('name', 'ASC')
|
||||||
|
->where('active', true);
|
||||||
|
|
||||||
|
return $search->take($limit)->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function billStartsWith(string $query, int $limit): Collection
|
||||||
|
{
|
||||||
|
$search = $this->user->bills();
|
||||||
|
if ('' !== $query) {
|
||||||
|
$search->where('name', 'LIKE', sprintf('%s%%', $query));
|
||||||
|
}
|
||||||
|
$search->orderBy('name', 'ASC')
|
||||||
|
->where('active', true);
|
||||||
|
|
||||||
|
return $search->take($limit)->get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,6 +40,22 @@ interface BillRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function correctOrder(): void;
|
public function correctOrder(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
* @param int $limit
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function billEndsWith(string $query, int $limit): Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
* @param int $limit
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function billStartsWith(string $query, int $limit): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Bill $bill
|
* @param Bill $bill
|
||||||
*
|
*
|
||||||
|
@@ -564,4 +564,34 @@ class BudgetRepository implements BudgetRepositoryInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function budgetEndsWith(string $query, int $limit): Collection
|
||||||
|
{
|
||||||
|
$search = $this->user->budgets();
|
||||||
|
if ('' !== $query) {
|
||||||
|
$search->where('name', 'LIKE', sprintf('%%%s', $query));
|
||||||
|
}
|
||||||
|
$search->orderBy('order', 'ASC')
|
||||||
|
->orderBy('name', 'ASC')->where('active', true);
|
||||||
|
|
||||||
|
return $search->take($limit)->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function budgetStartsWith(string $query, int $limit): Collection
|
||||||
|
{
|
||||||
|
$search = $this->user->budgets();
|
||||||
|
if ('' !== $query) {
|
||||||
|
$search->where('name', 'LIKE', sprintf('%s%%', $query));
|
||||||
|
}
|
||||||
|
$search->orderBy('order', 'ASC')
|
||||||
|
->orderBy('name', 'ASC')->where('active', true);
|
||||||
|
|
||||||
|
return $search->take($limit)->get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -174,4 +174,21 @@ interface BudgetRepositoryInterface
|
|||||||
* @return Budget
|
* @return Budget
|
||||||
*/
|
*/
|
||||||
public function update(Budget $budget, array $data): Budget;
|
public function update(Budget $budget, array $data): Budget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
* @param int $limit
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function budgetEndsWith(string $query, int $limit): Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
* @param int $limit
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function budgetStartsWith(string $query, int $limit): Collection;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -420,4 +420,30 @@ class CategoryRepository implements CategoryRepositoryInterface
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function categoryEndsWith(string $query, int $limit): Collection
|
||||||
|
{
|
||||||
|
$search = $this->user->categories();
|
||||||
|
if ('' !== $query) {
|
||||||
|
$search->where('name', 'LIKE', sprintf('%%%s', $query));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $search->take($limit)->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function categoryStartsWith(string $query, int $limit): Collection
|
||||||
|
{
|
||||||
|
$search = $this->user->categories();
|
||||||
|
if ('' !== $query) {
|
||||||
|
$search->where('name', 'LIKE', sprintf('%s%%', $query));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $search->take($limit)->get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -134,6 +134,22 @@ interface CategoryRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function searchCategory(string $query, int $limit): Collection;
|
public function searchCategory(string $query, int $limit): Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
* @param int $limit
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function categoryEndsWith(string $query, int $limit): Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
* @param int $limit
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function categoryStartsWith(string $query, int $limit): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param User $user
|
* @param User $user
|
||||||
*/
|
*/
|
||||||
|
@@ -186,7 +186,7 @@ class RuleRepository implements RuleRepositoryInterface
|
|||||||
if ('user_action' === $trigger->trigger_type) {
|
if ('user_action' === $trigger->trigger_type) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$needsContext = config(sprintf('firefly.search.operators.%s.needs_context', $trigger->trigger_type)) ?? true;
|
$needsContext = config(sprintf('search.operators.%s.needs_context', $trigger->trigger_type)) ?? true;
|
||||||
if (false === $needsContext) {
|
if (false === $needsContext) {
|
||||||
$params[] = sprintf('%s:true', OperatorQuerySearch::getRootOperator($trigger->trigger_type));
|
$params[] = sprintf('%s:true', OperatorQuerySearch::getRootOperator($trigger->trigger_type));
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ class EitherConfigKey
|
|||||||
// triggers and actions:
|
// triggers and actions:
|
||||||
'firefly.rule-actions',
|
'firefly.rule-actions',
|
||||||
'firefly.context-rule-actions',
|
'firefly.context-rule-actions',
|
||||||
'firefly.search.operators'
|
'search.operators'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -156,7 +156,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
$parser = new QueryParser();
|
$parser = new QueryParser();
|
||||||
try {
|
try {
|
||||||
$query1 = $parser->parse($query);
|
$query1 = $parser->parse($query);
|
||||||
} catch (TypeError | LogicException $e) {
|
} catch (TypeError|LogicException $e) {
|
||||||
Log::error($e->getMessage());
|
Log::error($e->getMessage());
|
||||||
Log::error(sprintf('Could not parse search: "%s".', $query));
|
Log::error(sprintf('Could not parse search: "%s".', $query));
|
||||||
throw new FireflyException('Invalid search value. See the logs.', 0, $e);
|
throw new FireflyException('Invalid search value. See the logs.', 0, $e);
|
||||||
@@ -233,7 +233,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
$this->collector->setUser($user);
|
$this->collector->setUser($user);
|
||||||
$this->collector->withAccountInformation()->withCategoryInformation()->withBudgetInformation();
|
$this->collector->withAccountInformation()->withCategoryInformation()->withBudgetInformation();
|
||||||
|
|
||||||
$this->setLimit((int)app('preferences')->getForUser($user, 'listPageSize', 50)->data);
|
$this->setLimit((int) app('preferences')->getForUser($user, 'listPageSize', 50)->data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +265,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
case Emoticon::class:
|
case Emoticon::class:
|
||||||
case Emoji::class:
|
case Emoji::class:
|
||||||
case Mention::class:
|
case Mention::class:
|
||||||
$allWords = (string)$searchNode->getValue();
|
$allWords = (string) $searchNode->getValue();
|
||||||
Log::debug(sprintf('Add words "%s" to search string, because Node class is "%s"', $allWords, $class));
|
Log::debug(sprintf('Add words "%s" to search string, because Node class is "%s"', $allWords, $class));
|
||||||
$this->words[] = $allWords;
|
$this->words[] = $allWords;
|
||||||
break;
|
break;
|
||||||
@@ -276,11 +276,11 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
$operator = strtolower($searchNode->getValue());
|
$operator = strtolower($searchNode->getValue());
|
||||||
$value = $searchNode->getNode()->getValue();
|
$value = $searchNode->getNode()->getValue();
|
||||||
// must be valid operator:
|
// must be valid operator:
|
||||||
if (in_array($operator, $this->validOperators, true) && $this->updateCollector($operator, (string)$value)) {
|
if (in_array($operator, $this->validOperators, true) && $this->updateCollector($operator, (string) $value)) {
|
||||||
$this->operators->push(
|
$this->operators->push(
|
||||||
[
|
[
|
||||||
'type' => self::getRootOperator($operator),
|
'type' => self::getRootOperator($operator),
|
||||||
'value' => (string)$value,
|
'value' => (string) $value,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
Log::debug(sprintf('Added operator type "%s"', $operator));
|
Log::debug(sprintf('Added operator type "%s"', $operator));
|
||||||
@@ -289,7 +289,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
Log::debug(sprintf('Added INVALID operator type "%s"', $operator));
|
Log::debug(sprintf('Added INVALID operator type "%s"', $operator));
|
||||||
$this->invalidOperators[] = [
|
$this->invalidOperators[] = [
|
||||||
'type' => $operator,
|
'type' => $operator,
|
||||||
'value' => (string)$value,
|
'value' => (string) $value,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -322,6 +322,30 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
//
|
//
|
||||||
// all account related searches:
|
// all account related searches:
|
||||||
//
|
//
|
||||||
|
case 'account_is':
|
||||||
|
$this->searchAccount($value, 3, 4);
|
||||||
|
break;
|
||||||
|
case 'account_contains':
|
||||||
|
$this->searchAccount($value, 3, 3);
|
||||||
|
break;
|
||||||
|
case 'account_ends':
|
||||||
|
$this->searchAccount($value, 3, 2);
|
||||||
|
break;
|
||||||
|
case 'account_starts':
|
||||||
|
$this->searchAccount($value, 3, 1);
|
||||||
|
break;
|
||||||
|
case 'account_nr_is':
|
||||||
|
$this->searchAccountNr($value, 3, 4);
|
||||||
|
break;
|
||||||
|
case 'account_nr_contains':
|
||||||
|
$this->searchAccountNr($value, 3, 3);
|
||||||
|
break;
|
||||||
|
case 'account_nr_ends':
|
||||||
|
$this->searchAccountNr($value, 3, 2);
|
||||||
|
break;
|
||||||
|
case 'account_nr_starts':
|
||||||
|
$this->searchAccountNr($value, 3, 1);
|
||||||
|
break;
|
||||||
case 'source_account_starts':
|
case 'source_account_starts':
|
||||||
$this->searchAccount($value, 1, 1);
|
$this->searchAccount($value, 1, 1);
|
||||||
break;
|
break;
|
||||||
@@ -347,7 +371,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
$this->searchAccount($value, 1, 3);
|
$this->searchAccount($value, 1, 3);
|
||||||
break;
|
break;
|
||||||
case 'source_account_id':
|
case 'source_account_id':
|
||||||
$account = $this->accountRepository->find((int)$value);
|
$account = $this->accountRepository->find((int) $value);
|
||||||
if (null !== $account) {
|
if (null !== $account) {
|
||||||
$this->collector->setSourceAccounts(new Collection([$account]));
|
$this->collector->setSourceAccounts(new Collection([$account]));
|
||||||
}
|
}
|
||||||
@@ -389,7 +413,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
$this->searchAccount($value, 2, 3);
|
$this->searchAccount($value, 2, 3);
|
||||||
break;
|
break;
|
||||||
case 'destination_account_id':
|
case 'destination_account_id':
|
||||||
$account = $this->accountRepository->find((int)$value);
|
$account = $this->accountRepository->find((int) $value);
|
||||||
if (null !== $account) {
|
if (null !== $account) {
|
||||||
$this->collector->setDestinationAccounts(new Collection([$account]));
|
$this->collector->setDestinationAccounts(new Collection([$account]));
|
||||||
}
|
}
|
||||||
@@ -401,7 +425,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
$parts = explode(',', $value);
|
$parts = explode(',', $value);
|
||||||
$collection = new Collection;
|
$collection = new Collection;
|
||||||
foreach ($parts as $accountId) {
|
foreach ($parts as $accountId) {
|
||||||
$account = $this->accountRepository->find((int)$accountId);
|
$account = $this->accountRepository->find((int) $accountId);
|
||||||
if (null !== $account) {
|
if (null !== $account) {
|
||||||
$collection->push($account);
|
$collection->push($account);
|
||||||
}
|
}
|
||||||
@@ -481,6 +505,32 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
$this->collector->withCategory();
|
$this->collector->withCategory();
|
||||||
break;
|
break;
|
||||||
case 'category_is':
|
case 'category_is':
|
||||||
|
$category = $this->categoryRepository->findByName($value);
|
||||||
|
if (null !== $category) {
|
||||||
|
$this->collector->setCategory($category);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$this->collector->findNothing();
|
||||||
|
break;
|
||||||
|
case 'category_ends':
|
||||||
|
$result = $this->categoryRepository->categoryEndsWith($value, 1337);
|
||||||
|
if ($result->count() > 0) {
|
||||||
|
$this->collector->setCategories($result);
|
||||||
|
}
|
||||||
|
if (0 === $result->count()) {
|
||||||
|
$this->collector->findNothing();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'category_starts':
|
||||||
|
$result = $this->categoryRepository->categoryStartsWith($value, 1337);
|
||||||
|
if ($result->count() > 0) {
|
||||||
|
$this->collector->setCategories($result);
|
||||||
|
}
|
||||||
|
if (0 === $result->count()) {
|
||||||
|
$this->collector->findNothing();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'category_contains':
|
||||||
$result = $this->categoryRepository->searchCategory($value, 1337);
|
$result = $this->categoryRepository->searchCategory($value, 1337);
|
||||||
if ($result->count() > 0) {
|
if ($result->count() > 0) {
|
||||||
$this->collector->setCategories($result);
|
$this->collector->setCategories($result);
|
||||||
@@ -498,7 +548,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
case 'has_any_budget':
|
case 'has_any_budget':
|
||||||
$this->collector->withBudget();
|
$this->collector->withBudget();
|
||||||
break;
|
break;
|
||||||
case 'budget_is':
|
case 'budget_contains':
|
||||||
$result = $this->budgetRepository->searchBudget($value, 1337);
|
$result = $this->budgetRepository->searchBudget($value, 1337);
|
||||||
if ($result->count() > 0) {
|
if ($result->count() > 0) {
|
||||||
$this->collector->setBudgets($result);
|
$this->collector->setBudgets($result);
|
||||||
@@ -507,6 +557,32 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
$this->collector->findNothing();
|
$this->collector->findNothing();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'budget_is':
|
||||||
|
$budget = $this->budgetRepository->findByName($value);
|
||||||
|
if (null !== $budget) {
|
||||||
|
$this->collector->setBudget($budget);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$this->collector->findNothing();
|
||||||
|
break;
|
||||||
|
case 'budget_ends':
|
||||||
|
$result = $this->budgetRepository->budgetEndsWith($value, 1337);
|
||||||
|
if ($result->count() > 0) {
|
||||||
|
$this->collector->setBudgets($result);
|
||||||
|
}
|
||||||
|
if (0 === $result->count()) {
|
||||||
|
$this->collector->findNothing();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'budget_starts':
|
||||||
|
$result = $this->budgetRepository->budgetStartsWith($value, 1337);
|
||||||
|
if ($result->count() > 0) {
|
||||||
|
$this->collector->setBudgets($result);
|
||||||
|
}
|
||||||
|
if (0 === $result->count()) {
|
||||||
|
$this->collector->findNothing();
|
||||||
|
}
|
||||||
|
break;
|
||||||
//
|
//
|
||||||
// bill
|
// bill
|
||||||
//
|
//
|
||||||
@@ -516,8 +592,33 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
case 'has_any_bill':
|
case 'has_any_bill':
|
||||||
$this->collector->withBill();
|
$this->collector->withBill();
|
||||||
break;
|
break;
|
||||||
case 'bill_is':
|
case 'bill_contains':
|
||||||
$result = $this->billRepository->searchBill($value, 1337);
|
$result = $this->billRepository->searchBill($value, 1337);
|
||||||
|
if ($result->count() > 0) {
|
||||||
|
$this->collector->setBills($result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$this->collector->findNothing();
|
||||||
|
break;
|
||||||
|
case 'bill_is':
|
||||||
|
$bill = $this->billRepository->findByName($value);
|
||||||
|
if (null !== $bill) {
|
||||||
|
$this->collector->setBill($bill);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$this->collector->findNothing();
|
||||||
|
break;
|
||||||
|
case 'bill_ends':
|
||||||
|
$result = $this->billRepository->billEndsWith($value, 1337);
|
||||||
|
if ($result->count() > 0) {
|
||||||
|
$this->collector->setBills($result);
|
||||||
|
}
|
||||||
|
if (0 === $result->count()) {
|
||||||
|
$this->collector->findNothing();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'bill_starts':
|
||||||
|
$result = $this->billRepository->billStartsWith($value, 1337);
|
||||||
if ($result->count() > 0) {
|
if ($result->count() > 0) {
|
||||||
$this->collector->setBills($result);
|
$this->collector->setBills($result);
|
||||||
}
|
}
|
||||||
@@ -545,19 +646,25 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
$this->collector->findNothing();
|
$this->collector->findNothing();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'tag_is_not':
|
||||||
|
$result = $this->tagRepository->searchTag($value);
|
||||||
|
if ($result->count() > 0) {
|
||||||
|
$this->collector->setWithoutSpecificTags($result);
|
||||||
|
}
|
||||||
|
break;
|
||||||
//
|
//
|
||||||
// notes
|
// notes
|
||||||
//
|
//
|
||||||
case 'notes_contain':
|
case 'notes_contains':
|
||||||
$this->collector->notesContain($value);
|
$this->collector->notesContain($value);
|
||||||
break;
|
break;
|
||||||
case 'notes_start':
|
case 'notes_starts':
|
||||||
$this->collector->notesStartWith($value);
|
$this->collector->notesStartWith($value);
|
||||||
break;
|
break;
|
||||||
case 'notes_end':
|
case 'notes_ends':
|
||||||
$this->collector->notesEndWith($value);
|
$this->collector->notesEndWith($value);
|
||||||
break;
|
break;
|
||||||
case 'notes_are':
|
case 'notes_is':
|
||||||
$this->collector->notesExactly($value);
|
$this->collector->notesExactly($value);
|
||||||
break;
|
break;
|
||||||
case 'no_notes':
|
case 'no_notes':
|
||||||
@@ -569,10 +676,10 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
//
|
//
|
||||||
// amount
|
// amount
|
||||||
//
|
//
|
||||||
case 'amount_exactly':
|
case 'amount_is':
|
||||||
|
|
||||||
// strip comma's, make dots.
|
// strip comma's, make dots.
|
||||||
$value = str_replace(',', '.', (string)$value);
|
$value = str_replace(',', '.', (string) $value);
|
||||||
|
|
||||||
$amount = app('steam')->positive($value);
|
$amount = app('steam')->positive($value);
|
||||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
|
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
|
||||||
@@ -580,7 +687,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
break;
|
break;
|
||||||
case 'amount_less':
|
case 'amount_less':
|
||||||
// strip comma's, make dots.
|
// strip comma's, make dots.
|
||||||
$value = str_replace(',', '.', (string)$value);
|
$value = str_replace(',', '.', (string) $value);
|
||||||
|
|
||||||
$amount = app('steam')->positive($value);
|
$amount = app('steam')->positive($value);
|
||||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
|
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
|
||||||
@@ -589,7 +696,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
case 'amount_more':
|
case 'amount_more':
|
||||||
Log::debug(sprintf('Now handling operator "%s"', $operator));
|
Log::debug(sprintf('Now handling operator "%s"', $operator));
|
||||||
// strip comma's, make dots.
|
// strip comma's, make dots.
|
||||||
$value = str_replace(',', '.', (string)$value);
|
$value = str_replace(',', '.', (string) $value);
|
||||||
$amount = app('steam')->positive($value);
|
$amount = app('steam')->positive($value);
|
||||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
|
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
|
||||||
$this->collector->amountMore($amount);
|
$this->collector->amountMore($amount);
|
||||||
@@ -657,7 +764,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
*/
|
*/
|
||||||
public static function getRootOperator(string $operator): string
|
public static function getRootOperator(string $operator): string
|
||||||
{
|
{
|
||||||
$config = config(sprintf('firefly.search.operators.%s', $operator));
|
$config = config(sprintf('search.operators.%s', $operator));
|
||||||
if (null === $config) {
|
if (null === $config) {
|
||||||
throw new FireflyException(sprintf('No configuration for search operator "%s"', $operator));
|
throw new FireflyException(sprintf('No configuration for search operator "%s"', $operator));
|
||||||
}
|
}
|
||||||
@@ -672,7 +779,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* searchDirection: 1 = source (default), 2 = destination
|
* searchDirection: 1 = source (default), 2 = destination, 3 = both
|
||||||
* stringPosition: 1 = start (default), 2 = end, 3 = contains, 4 = is
|
* stringPosition: 1 = start (default), 2 = end, 3 = contains, 4 = is
|
||||||
*
|
*
|
||||||
* @param string $value
|
* @param string $value
|
||||||
@@ -693,6 +800,11 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE];
|
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE];
|
||||||
$collectorMethod = 'setDestinationAccounts';
|
$collectorMethod = 'setDestinationAccounts';
|
||||||
}
|
}
|
||||||
|
// either account could be:
|
||||||
|
if (3 === $searchDirection) {
|
||||||
|
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE, AccountType::REVENUE];
|
||||||
|
$collectorMethod = 'setAccounts';
|
||||||
|
}
|
||||||
// string position (default): starts with:
|
// string position (default): starts with:
|
||||||
$stringMethod = 'str_starts_with';
|
$stringMethod = 'str_starts_with';
|
||||||
|
|
||||||
@@ -733,7 +845,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* searchDirection: 1 = source (default), 2 = destination
|
* searchDirection: 1 = source (default), 2 = destination, 3 = both
|
||||||
* stringPosition: 1 = start (default), 2 = end, 3 = contains, 4 = is
|
* stringPosition: 1 = start (default), 2 = end, 3 = contains, 4 = is
|
||||||
*
|
*
|
||||||
* @param string $value
|
* @param string $value
|
||||||
@@ -754,6 +866,13 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE];
|
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE];
|
||||||
$collectorMethod = 'setDestinationAccounts';
|
$collectorMethod = 'setDestinationAccounts';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// either account could be:
|
||||||
|
if (3 === $searchDirection) {
|
||||||
|
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE, AccountType::REVENUE];
|
||||||
|
$collectorMethod = 'setAccounts';
|
||||||
|
}
|
||||||
|
|
||||||
// string position (default): starts with:
|
// string position (default): starts with:
|
||||||
$stringMethod = 'str_starts_with';
|
$stringMethod = 'str_starts_with';
|
||||||
|
|
||||||
@@ -782,7 +901,7 @@ class OperatorQuerySearch implements SearchInterface
|
|||||||
$filtered = $accounts->filter(
|
$filtered = $accounts->filter(
|
||||||
function (Account $account) use ($value, $stringMethod) {
|
function (Account $account) use ($value, $stringMethod) {
|
||||||
// either IBAN or account number!
|
// either IBAN or account number!
|
||||||
$ibanMatch = $stringMethod(strtolower((string)$account->iban), strtolower((string)$value));
|
$ibanMatch = $stringMethod(strtolower((string) $account->iban), strtolower((string) $value));
|
||||||
$accountNrMatch = false;
|
$accountNrMatch = false;
|
||||||
/** @var AccountMeta $meta */
|
/** @var AccountMeta $meta */
|
||||||
foreach ($account->accountMeta as $meta) {
|
foreach ($account->accountMeta as $meta) {
|
||||||
|
@@ -186,7 +186,7 @@ class SearchRuleEngine implements RuleEngineInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if needs no context, value is different:
|
// if needs no context, value is different:
|
||||||
$needsContext = config(sprintf('firefly.search.operators.%s.needs_context', $ruleTrigger->trigger_type)) ?? true;
|
$needsContext = config(sprintf('search.operators.%s.needs_context', $ruleTrigger->trigger_type)) ?? true;
|
||||||
if (false === $needsContext) {
|
if (false === $needsContext) {
|
||||||
Log::debug(sprintf('SearchRuleEngine:: add a rule trigger: %s:true', $ruleTrigger->trigger_type));
|
Log::debug(sprintf('SearchRuleEngine:: add a rule trigger: %s:true', $ruleTrigger->trigger_type));
|
||||||
$searchArray[$ruleTrigger->trigger_type][] = 'true';
|
$searchArray[$ruleTrigger->trigger_type][] = 'true';
|
||||||
@@ -310,7 +310,7 @@ class SearchRuleEngine implements RuleEngineInterface
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$searchArray = [];
|
$searchArray = [];
|
||||||
$needsContext = config(sprintf('firefly.search.operators.%s.needs_context', $ruleTrigger->trigger_type)) ?? true;
|
$needsContext = config(sprintf('search.operators.%s.needs_context', $ruleTrigger->trigger_type)) ?? true;
|
||||||
if (false === $needsContext) {
|
if (false === $needsContext) {
|
||||||
Log::debug(sprintf('SearchRuleEngine:: non strict, will search for: %s:true', $ruleTrigger->trigger_type));
|
Log::debug(sprintf('SearchRuleEngine:: non strict, will search for: %s:true', $ruleTrigger->trigger_type));
|
||||||
$searchArray[$ruleTrigger->trigger_type] = 'true';
|
$searchArray[$ruleTrigger->trigger_type] = 'true';
|
||||||
|
20
composer.lock
generated
20
composer.lock
generated
@@ -5131,16 +5131,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "spatie/ignition",
|
"name": "spatie/ignition",
|
||||||
"version": "1.2.4",
|
"version": "1.2.5",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/spatie/ignition.git",
|
"url": "https://github.com/spatie/ignition.git",
|
||||||
"reference": "ec58c125c15eecaa20180f01ef9667d41a568ba8"
|
"reference": "982f69f3c2e525cef62fa23ada047d745e4bcda9"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/spatie/ignition/zipball/ec58c125c15eecaa20180f01ef9667d41a568ba8",
|
"url": "https://api.github.com/repos/spatie/ignition/zipball/982f69f3c2e525cef62fa23ada047d745e4bcda9",
|
||||||
"reference": "ec58c125c15eecaa20180f01ef9667d41a568ba8",
|
"reference": "982f69f3c2e525cef62fa23ada047d745e4bcda9",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -5197,20 +5197,20 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-03-11T13:28:02+00:00"
|
"time": "2022-03-19T14:07:30+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "spatie/laravel-ignition",
|
"name": "spatie/laravel-ignition",
|
||||||
"version": "1.0.10",
|
"version": "1.1.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/spatie/laravel-ignition.git",
|
"url": "https://github.com/spatie/laravel-ignition.git",
|
||||||
"reference": "71df77cad94aae4db904aaef1cc2f06950daed76"
|
"reference": "5b8c360d1f6bcba339a6d593efa02816c06d17c3"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/71df77cad94aae4db904aaef1cc2f06950daed76",
|
"url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/5b8c360d1f6bcba339a6d593efa02816c06d17c3",
|
||||||
"reference": "71df77cad94aae4db904aaef1cc2f06950daed76",
|
"reference": "5b8c360d1f6bcba339a6d593efa02816c06d17c3",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -5284,7 +5284,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-03-17T11:01:36+00:00"
|
"time": "2022-03-19T17:03:56+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
|
@@ -31,6 +31,7 @@ return [
|
|||||||
'from_account_ends' => ['alias' => true, 'alias_for' => 'source_account_ends', 'needs_context' => true,],
|
'from_account_ends' => ['alias' => true, 'alias_for' => 'source_account_ends', 'needs_context' => true,],
|
||||||
'source_account_starts' => ['alias' => false, 'needs_context' => true,],
|
'source_account_starts' => ['alias' => false, 'needs_context' => true,],
|
||||||
'from_account_starts' => ['alias' => true, 'alias_for' => 'source_account_starts', 'needs_context' => true,],
|
'from_account_starts' => ['alias' => true, 'alias_for' => 'source_account_starts', 'needs_context' => true,],
|
||||||
|
|
||||||
'source_account_nr_is' => ['alias' => false, 'needs_context' => true,],
|
'source_account_nr_is' => ['alias' => false, 'needs_context' => true,],
|
||||||
'from_account_nr_is' => ['alias' => true, 'alias_for' => 'source_account_nr_is', 'needs_context' => true,],
|
'from_account_nr_is' => ['alias' => true, 'alias_for' => 'source_account_nr_is', 'needs_context' => true,],
|
||||||
'source_account_nr_contains' => ['alias' => false, 'needs_context' => true,],
|
'source_account_nr_contains' => ['alias' => false, 'needs_context' => true,],
|
||||||
@@ -39,6 +40,7 @@ return [
|
|||||||
'from_account_nr_ends' => ['alias' => true, 'alias_for' => 'source_account_nr_ends', 'needs_context' => true,],
|
'from_account_nr_ends' => ['alias' => true, 'alias_for' => 'source_account_nr_ends', 'needs_context' => true,],
|
||||||
'source_account_nr_starts' => ['alias' => false, 'needs_context' => true,],
|
'source_account_nr_starts' => ['alias' => false, 'needs_context' => true,],
|
||||||
'from_account_nr_starts' => ['alias' => true, 'alias_for' => 'source_account_nr_starts', 'needs_context' => true,],
|
'from_account_nr_starts' => ['alias' => true, 'alias_for' => 'source_account_nr_starts', 'needs_context' => true,],
|
||||||
|
|
||||||
'destination_account_is' => ['alias' => false, 'needs_context' => true,],
|
'destination_account_is' => ['alias' => false, 'needs_context' => true,],
|
||||||
'to_account_is' => ['alias' => true, 'alias_for' => 'destination_account_is', 'needs_context' => true,],
|
'to_account_is' => ['alias' => true, 'alias_for' => 'destination_account_is', 'needs_context' => true,],
|
||||||
'destination_account_contains' => ['alias' => false, 'needs_context' => true,],
|
'destination_account_contains' => ['alias' => false, 'needs_context' => true,],
|
||||||
@@ -49,6 +51,7 @@ return [
|
|||||||
'to_account_ends' => ['alias' => true, 'alias_for' => 'destination_account_ends', 'needs_context' => true,],
|
'to_account_ends' => ['alias' => true, 'alias_for' => 'destination_account_ends', 'needs_context' => true,],
|
||||||
'destination_account_starts' => ['alias' => false, 'needs_context' => true,],
|
'destination_account_starts' => ['alias' => false, 'needs_context' => true,],
|
||||||
'to_account_starts' => ['alias' => true, 'alias_for' => 'destination_account_starts', 'needs_context' => true,],
|
'to_account_starts' => ['alias' => true, 'alias_for' => 'destination_account_starts', 'needs_context' => true,],
|
||||||
|
|
||||||
'destination_account_nr_is' => ['alias' => false, 'needs_context' => true,],
|
'destination_account_nr_is' => ['alias' => false, 'needs_context' => true,],
|
||||||
'to_account_nr_is' => ['alias' => true, 'alias_for' => 'destination_account_nr_is', 'needs_context' => true,],
|
'to_account_nr_is' => ['alias' => true, 'alias_for' => 'destination_account_nr_is', 'needs_context' => true,],
|
||||||
'destination_account_nr_contains' => ['alias' => false, 'needs_context' => true,],
|
'destination_account_nr_contains' => ['alias' => false, 'needs_context' => true,],
|
||||||
@@ -57,14 +60,17 @@ return [
|
|||||||
'to_account_nr_ends' => ['alias' => true, 'alias_for' => 'destination_account_nr_ends', 'needs_context' => true,],
|
'to_account_nr_ends' => ['alias' => true, 'alias_for' => 'destination_account_nr_ends', 'needs_context' => true,],
|
||||||
'destination_account_nr_starts' => ['alias' => false, 'needs_context' => true,],
|
'destination_account_nr_starts' => ['alias' => false, 'needs_context' => true,],
|
||||||
'to_account_nr_starts' => ['alias' => true, 'alias_for' => 'destination_account_nr_starts', 'needs_context' => true,],
|
'to_account_nr_starts' => ['alias' => true, 'alias_for' => 'destination_account_nr_starts', 'needs_context' => true,],
|
||||||
|
|
||||||
'account_is' => ['alias' => false, 'needs_context' => true,],
|
'account_is' => ['alias' => false, 'needs_context' => true,],
|
||||||
'account_contains' => ['alias' => false, 'needs_context' => true,],
|
'account_contains' => ['alias' => false, 'needs_context' => true,],
|
||||||
'account_ends' => ['alias' => false, 'needs_context' => true,],
|
'account_ends' => ['alias' => false, 'needs_context' => true,],
|
||||||
'account_starts' => ['alias' => false, 'needs_context' => true,],
|
'account_starts' => ['alias' => false, 'needs_context' => true,],
|
||||||
|
|
||||||
'account_nr_is' => ['alias' => false, 'needs_context' => true,],
|
'account_nr_is' => ['alias' => false, 'needs_context' => true,],
|
||||||
'account_nr_contains' => ['alias' => false, 'needs_context' => true,],
|
'account_nr_contains' => ['alias' => false, 'needs_context' => true,],
|
||||||
'account_nr_ends' => ['alias' => false, 'needs_context' => true,],
|
'account_nr_ends' => ['alias' => false, 'needs_context' => true,],
|
||||||
'account_nr_starts' => ['alias' => false, 'needs_context' => true,],
|
'account_nr_starts' => ['alias' => false, 'needs_context' => true,],
|
||||||
|
|
||||||
'category_is' => ['alias' => false, 'needs_context' => true,],
|
'category_is' => ['alias' => false, 'needs_context' => true,],
|
||||||
'category_contains' => ['alias' => false, 'needs_context' => true,],
|
'category_contains' => ['alias' => false, 'needs_context' => true,],
|
||||||
'category' => ['alias' => true, 'alias_for' => 'category_contains', 'needs_context' => true,],
|
'category' => ['alias' => true, 'alias_for' => 'category_contains', 'needs_context' => true,],
|
||||||
@@ -80,6 +86,7 @@ return [
|
|||||||
'bill' => ['alias' => true, 'alias_for' => 'bill_contains', 'needs_context' => true,],
|
'bill' => ['alias' => true, 'alias_for' => 'bill_contains', 'needs_context' => true,],
|
||||||
'bill_ends' => ['alias' => false, 'needs_context' => true,],
|
'bill_ends' => ['alias' => false, 'needs_context' => true,],
|
||||||
'bill_starts' => ['alias' => false, 'needs_context' => true,],
|
'bill_starts' => ['alias' => false, 'needs_context' => true,],
|
||||||
|
// TODO here we are
|
||||||
'external_id_is' => ['alias' => false, 'needs_context' => true,],
|
'external_id_is' => ['alias' => false, 'needs_context' => true,],
|
||||||
'external_id_contains' => ['alias' => false, 'needs_context' => true,],
|
'external_id_contains' => ['alias' => false, 'needs_context' => true,],
|
||||||
'external_id' => ['alias' => true, 'alias_for' => 'external_id_contains', 'needs_context' => true,],
|
'external_id' => ['alias' => true, 'alias_for' => 'external_id_contains', 'needs_context' => true,],
|
||||||
|
@@ -282,16 +282,17 @@ return [
|
|||||||
'search_found_more_transactions' => 'Firefly III found more than :count transactions in :time seconds.',
|
'search_found_more_transactions' => 'Firefly III found more than :count transactions in :time seconds.',
|
||||||
'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: <span class="text-info">:query</span>',
|
'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: <span class="text-info">:query</span>',
|
||||||
'invalid_operators_list' => 'These search parameters are not valid and have been ignored.',
|
'invalid_operators_list' => 'These search parameters are not valid and have been ignored.',
|
||||||
|
|
||||||
|
// old
|
||||||
|
|
||||||
'search_modifier_date_is' => 'Transaction date is ":value"',
|
'search_modifier_date_is' => 'Transaction date is ":value"',
|
||||||
'search_modifier_id' => 'Transaction ID is ":value"',
|
'search_modifier_id' => 'Transaction ID is ":value"',
|
||||||
'search_modifier_date_before' => 'Transaction date is before or on ":value"',
|
'search_modifier_date_before' => 'Transaction date is before or on ":value"',
|
||||||
'search_modifier_date_after' => 'Transaction date is after or on ":value"',
|
'search_modifier_date_after' => 'Transaction date is after or on ":value"',
|
||||||
'search_modifier_created_on' => 'Transaction was created on ":value"',
|
'search_modifier_external_id_is' => 'External ID is ":value"',
|
||||||
'search_modifier_updated_on' => 'Transaction was last updated on ":value"',
|
|
||||||
'search_modifier_external_id' => 'External ID is ":value"',
|
|
||||||
'search_modifier_no_external_url' => 'The transaction has no external URL',
|
'search_modifier_no_external_url' => 'The transaction has no external URL',
|
||||||
'search_modifier_any_external_url' => 'The transaction must have a (any) external URL',
|
'search_modifier_any_external_url' => 'The transaction must have a (any) external URL',
|
||||||
'search_modifier_internal_reference' => 'Internal reference is ":value"',
|
'search_modifier_internal_reference_is' => 'Internal reference is ":value"',
|
||||||
'search_modifier_description_starts' => 'Description is ":value"',
|
'search_modifier_description_starts' => 'Description is ":value"',
|
||||||
'search_modifier_description_ends' => 'Description ends with ":value"',
|
'search_modifier_description_ends' => 'Description ends with ":value"',
|
||||||
'search_modifier_description_contains' => 'Description contains ":value"',
|
'search_modifier_description_contains' => 'Description contains ":value"',
|
||||||
@@ -307,13 +308,13 @@ return [
|
|||||||
'search_modifier_has_any_bill' => 'The transaction must have a (any) bill',
|
'search_modifier_has_any_bill' => 'The transaction must have a (any) bill',
|
||||||
'search_modifier_has_no_tag' => 'The transaction must have no tags',
|
'search_modifier_has_no_tag' => 'The transaction must have no tags',
|
||||||
'search_modifier_has_any_tag' => 'The transaction must have a (any) tag',
|
'search_modifier_has_any_tag' => 'The transaction must have a (any) tag',
|
||||||
'search_modifier_notes_contain' => 'The transaction notes contain ":value"',
|
'search_modifier_notes_contains' => 'The transaction notes contain ":value"',
|
||||||
'search_modifier_notes_start' => 'The transaction notes start with ":value"',
|
'search_modifier_notes_starts' => 'The transaction notes start with ":value"',
|
||||||
'search_modifier_notes_end' => 'The transaction notes end with ":value"',
|
'search_modifier_notes_ends' => 'The transaction notes end with ":value"',
|
||||||
'search_modifier_notes_are' => 'The transaction notes are exactly ":value"',
|
'search_modifier_notes_is' => 'The transaction notes are exactly ":value"',
|
||||||
'search_modifier_no_notes' => 'The transaction has no notes',
|
'search_modifier_no_notes' => 'The transaction has no notes',
|
||||||
'search_modifier_any_notes' => 'The transaction must have notes',
|
'search_modifier_any_notes' => 'The transaction must have notes',
|
||||||
'search_modifier_amount_exactly' => 'Amount is exactly :value',
|
'search_modifier_amount_is' => 'Amount is exactly :value',
|
||||||
'search_modifier_amount_less' => 'Amount is less than or equal to :value',
|
'search_modifier_amount_less' => 'Amount is less than or equal to :value',
|
||||||
'search_modifier_amount_more' => 'Amount is more than or equal to :value',
|
'search_modifier_amount_more' => 'Amount is more than or equal to :value',
|
||||||
'search_modifier_source_account_is' => 'Source account name is exactly ":value"',
|
'search_modifier_source_account_is' => 'Source account name is exactly ":value"',
|
||||||
@@ -342,15 +343,130 @@ return [
|
|||||||
'search_modifier_bill_is' => 'Bill is ":value"',
|
'search_modifier_bill_is' => 'Bill is ":value"',
|
||||||
'search_modifier_transaction_type' => 'Transaction type is ":value"',
|
'search_modifier_transaction_type' => 'Transaction type is ":value"',
|
||||||
'search_modifier_tag_is' => 'Tag is ":value"',
|
'search_modifier_tag_is' => 'Tag is ":value"',
|
||||||
'search_modifier_date_is_year' => 'Transaction is in year ":value"',
|
'search_modifier_date_on_year' => 'Transaction is in year ":value"',
|
||||||
'search_modifier_date_is_month' => 'Transaction is in month ":value"',
|
'search_modifier_date_on_month' => 'Transaction is in month ":value"',
|
||||||
'search_modifier_date_is_day' => 'Transaction is on day of month ":value"',
|
'search_modifier_date_on_day' => 'Transaction is on day of month ":value"',
|
||||||
'search_modifier_date_before_year' => 'Transaction is before or in year ":value"',
|
'search_modifier_date_before_year' => 'Transaction is before or in year ":value"',
|
||||||
'search_modifier_date_before_month' => 'Transaction is before or in month ":value"',
|
'search_modifier_date_before_month' => 'Transaction is before or in month ":value"',
|
||||||
'search_modifier_date_before_day' => 'Transaction is before or on day of month ":value"',
|
'search_modifier_date_before_day' => 'Transaction is before or on day of month ":value"',
|
||||||
'search_modifier_date_after_year' => 'Transaction is in or after year ":value"',
|
'search_modifier_date_after_year' => 'Transaction is in or after year ":value"',
|
||||||
'search_modifier_date_after_month' => 'Transaction is in or after month ":value"',
|
'search_modifier_date_after_month' => 'Transaction is in or after month ":value"',
|
||||||
'search_modifier_date_after_day' => 'Transaction is after or on day of month ":value"',
|
'search_modifier_date_after_day' => 'Transaction is after or on day of month ":value"',
|
||||||
|
|
||||||
|
|
||||||
|
// new
|
||||||
|
'search_modifier_tag_is_not' => 'No tag is ":value"',
|
||||||
|
|
||||||
|
'search_modifier_account_is' => 'Either account is ":value"',
|
||||||
|
'search_modifier_account_contains' => 'Either account contains ":value"',
|
||||||
|
'search_modifier_account_ends' => 'Either account ends with ":value"',
|
||||||
|
'search_modifier_account_starts' => 'Either account starts with ":value"',
|
||||||
|
'search_modifier_account_nr_is' => 'Either account number / IBAN is ":value"',
|
||||||
|
'search_modifier_account_nr_contains' => 'Either account number / IBAN contains ":value"',
|
||||||
|
'search_modifier_account_nr_ends' => 'Either account number / IBAN ends with ":value"',
|
||||||
|
'search_modifier_account_nr_starts' => 'Either account number / IBAN starts with ":value"',
|
||||||
|
'search_modifier_category_contains' => 'Category contains ":value"',
|
||||||
|
'search_modifier_category_ends' => 'Category ends with ":value"',
|
||||||
|
'search_modifier_category_starts' => 'Category starts with ":value"',
|
||||||
|
'search_modifier_budget_contains' => 'Budget contains ":value"',
|
||||||
|
'search_modifier_budget_ends' => 'Budget ends with ":value"',
|
||||||
|
'search_modifier_budget_starts' => 'Budget starts with ":value"',
|
||||||
|
'search_modifier_bill_contains' => 'Bill contains ":value"',
|
||||||
|
'search_modifier_bill_ends' => 'Bill ends with ":value"',
|
||||||
|
'search_modifier_bill_starts' => 'Bill starts with ":value"',
|
||||||
|
'search_modifier_external_id_contains' => 'External ID contains ":value"',
|
||||||
|
'search_modifier_external_id_ends' => 'External ID ends with ":value"',
|
||||||
|
'search_modifier_external_id_starts' => 'External ID starts with ":value"',
|
||||||
|
'search_modifier_internal_reference_contains' => 'Internal reference contains ":value"',
|
||||||
|
'search_modifier_internal_reference_ends' => 'Internal reference ends with ":value"',
|
||||||
|
'search_modifier_internal_reference_starts' => 'Internal reference starts with ":value"',
|
||||||
|
'search_modifier_external_url_is' => 'External URL is ":value"',
|
||||||
|
'search_modifier_external_url_contains' => 'External URL contains ":value"',
|
||||||
|
'search_modifier_external_url_ends' => 'External URL ends with ":value"',
|
||||||
|
'search_modifier_external_url_starts' => 'External URL starts with ":value"',
|
||||||
|
'search_modifier_has_no_attachments' => 'Transaction has no attachments',
|
||||||
|
'search_modifier_account_is_cash' => 'Either account is a cash account.',
|
||||||
|
'search_modifier_journal_id' => 'The journal ID is ":value"',
|
||||||
|
'search_modifier_recurrence_id' => 'The recurring transaction ID is ":value"',
|
||||||
|
'search_modifier_foreign_amount_is' => 'The foreign amount is ":value"',
|
||||||
|
'search_modifier_foreign_amount_less' => 'The foreign amount is less than ":value"',
|
||||||
|
'search_modifier_foreign_amount_more' => 'The foreign amount is more than ":value"',
|
||||||
|
|
||||||
|
// date fields
|
||||||
|
'search_modifier_interest_date_on_year' => 'Transaction interest date is in year ":value"',
|
||||||
|
'search_modifier_interest_date_on_month' => 'Transaction interest date is in month ":value"',
|
||||||
|
'search_modifier_interest_date_on_day' => 'Transaction interest date is on day of month ":value"',
|
||||||
|
'search_modifier_interest_date_before_year' => 'Transaction interest date is before or in year ":value"',
|
||||||
|
'search_modifier_interest_date_before_month' => 'Transaction interest date is before or in month ":value"',
|
||||||
|
'search_modifier_interest_date_before_day' => 'Transaction interest date is before or on day of month ":value"',
|
||||||
|
'search_modifier_interest_date_after_year' => 'Transaction interest date is after or in year ":value"',
|
||||||
|
'search_modifier_interest_date_after_month' => 'Transaction interest date is after or in month ":value"',
|
||||||
|
'search_modifier_interest_date_after_day' => 'Transaction interest date is after or on day of month ":value"',
|
||||||
|
'search_modifier_book_date_on_year' => 'Transaction book date is in year ":value"',
|
||||||
|
'search_modifier_book_date_on_month' => 'Transaction book date is in month ":value"',
|
||||||
|
'search_modifier_book_date_on_day' => 'Transaction book date is on day of month ":value"',
|
||||||
|
'search_modifier_book_date_before_year' => 'Transaction book date is before or in year ":value"',
|
||||||
|
'search_modifier_book_date_before_month' => 'Transaction book date is before or in month ":value"',
|
||||||
|
'search_modifier_book_date_before_day' => 'Transaction book date is before or on day of month ":value"',
|
||||||
|
'search_modifier_book_date_after_year' => 'Transaction book date is after or in year ":value"',
|
||||||
|
'search_modifier_book_date_after_month' => 'Transaction book date is after or in month ":value"',
|
||||||
|
'search_modifier_book_date_after_day' => 'Transaction book date is after or on day of month ":value"',
|
||||||
|
'search_modifier_process_date_on_year' => 'Transaction process date is in year ":value"',
|
||||||
|
'search_modifier_process_date_on_month' => 'Transaction process date is in month ":value"',
|
||||||
|
'search_modifier_process_date_on_day' => 'Transaction process date is on day of month ":value"',
|
||||||
|
'search_modifier_process_date_before_year' => 'Transaction process date is before or in year ":value"',
|
||||||
|
'search_modifier_process_date_before_month' => 'Transaction process date is before or in month ":value"',
|
||||||
|
'search_modifier_process_date_before_day' => 'Transaction process date is before or on day of month ":value"',
|
||||||
|
'search_modifier_process_date_after_year' => 'Transaction process date is after or in year ":value"',
|
||||||
|
'search_modifier_process_date_after_month' => 'Transaction process date is after or in month ":value"',
|
||||||
|
'search_modifier_process_date_after_day' => 'Transaction process date is after or on day of month ":value"',
|
||||||
|
'search_modifier_due_date_on_year' => 'Transaction due date is in year ":value"',
|
||||||
|
'search_modifier_due_date_on_month' => 'Transaction due date is in month ":value"',
|
||||||
|
'search_modifier_due_date_on_day' => 'Transaction due date is on day of month ":value"',
|
||||||
|
'search_modifier_due_date_before_year' => 'Transaction due date is before or in year ":value"',
|
||||||
|
'search_modifier_due_date_before_month' => 'Transaction due date is before or in month ":value"',
|
||||||
|
'search_modifier_due_date_before_day' => 'Transaction due date is before or on day of month ":value"',
|
||||||
|
'search_modifier_due_date_after_year' => 'Transaction due date is after or in year ":value"',
|
||||||
|
'search_modifier_due_date_after_month' => 'Transaction due date is after or in month ":value"',
|
||||||
|
'search_modifier_due_date_after_day' => 'Transaction due date is after or on day of month ":value"',
|
||||||
|
'search_modifier_payment_date_on_year' => 'Transaction payment date is in year ":value"',
|
||||||
|
'search_modifier_payment_date_on_month' => 'Transaction payment date is in month ":value"',
|
||||||
|
'search_modifier_payment_date_on_day' => 'Transaction payment date is on day of month ":value"',
|
||||||
|
'search_modifier_payment_date_before_year' => 'Transaction payment date is before or in year ":value"',
|
||||||
|
'search_modifier_payment_date_before_month' => 'Transaction payment date is before or in month ":value"',
|
||||||
|
'search_modifier_payment_date_before_day' => 'Transaction payment date is before or on day of month ":value"',
|
||||||
|
'search_modifier_payment_date_after_year' => 'Transaction payment date is after or in year ":value"',
|
||||||
|
'search_modifier_payment_date_after_month' => 'Transaction payment date is after or in month ":value"',
|
||||||
|
'search_modifier_payment_date_after_day' => 'Transaction payment date is after or on day of month ":value"',
|
||||||
|
'search_modifier_invoice_date_on_year' => 'Transaction invoice date is in year ":value"',
|
||||||
|
'search_modifier_invoice_date_on_month' => 'Transaction invoice date is in month ":value"',
|
||||||
|
'search_modifier_invoice_date_on_day' => 'Transaction invoice date is on day of month ":value"',
|
||||||
|
'search_modifier_invoice_date_before_year' => 'Transaction invoice date is before or in year ":value"',
|
||||||
|
'search_modifier_invoice_date_before_month' => 'Transaction invoice date is before or in month ":value"',
|
||||||
|
'search_modifier_invoice_date_before_day' => 'Transaction invoice date is before or on day of month ":value"',
|
||||||
|
'search_modifier_invoice_date_after_year' => 'Transaction invoice date is after or in year ":value"',
|
||||||
|
'search_modifier_invoice_date_after_month' => 'Transaction invoice date is after or in month ":value"',
|
||||||
|
'search_modifier_invoice_date_after_day' => 'Transaction invoice date is after or on day of month ":value"',
|
||||||
|
'search_modifier_updated_at_on_year' => 'Transaction was last updated in year ":value"',
|
||||||
|
'search_modifier_updated_at_on_month' => 'Transaction was last updated in month ":value"',
|
||||||
|
'search_modifier_updated_at_on_day' => 'Transaction was last updated on day of month ":value"',
|
||||||
|
'search_modifier_updated_at_before_year' => 'Transaction was last updated in or before year ":value"',
|
||||||
|
'search_modifier_updated_at_before_month' => 'Transaction was last updated in or before month ":value"',
|
||||||
|
'search_modifier_updated_at_before_day' => 'Transaction was last updated on or before day of month ":value"',
|
||||||
|
'search_modifier_updated_at_after_year' => 'Transaction was last updated in or after year ":value"',
|
||||||
|
'search_modifier_updated_at_after_month' => 'Transaction was last updated in or after month ":value"',
|
||||||
|
'search_modifier_updated_at_after_day' => 'Transaction was last updated on or after day of month ":value"',
|
||||||
|
'search_modifier_created_at_on_year' => 'Transaction was created in year ":value"',
|
||||||
|
'search_modifier_created_at_on_month' => 'Transaction was created in month ":value"',
|
||||||
|
'search_modifier_created_at_on_day' => 'Transaction was created on day of month ":value"',
|
||||||
|
'search_modifier_created_at_before_year' => 'Transaction was created in or before year ":value"',
|
||||||
|
'search_modifier_created_at_before_month' => 'Transaction was created in or before month ":value"',
|
||||||
|
'search_modifier_created_at_before_day' => 'Transaction was created on or before day of month ":value"',
|
||||||
|
'search_modifier_created_at_after_year' => 'Transaction was created in or after year ":value"',
|
||||||
|
'search_modifier_created_at_after_month' => 'Transaction was created in or after month ":value"',
|
||||||
|
'search_modifier_created_at_after_day' => 'Transaction was created on or after day of month ":value"',
|
||||||
|
|
||||||
|
|
||||||
'update_rule_from_query' => 'Update rule ":rule" from search query',
|
'update_rule_from_query' => 'Update rule ":rule" from search query',
|
||||||
'create_rule_from_query' => 'Create new rule from search query',
|
'create_rule_from_query' => 'Create new rule from search query',
|
||||||
'rule_from_search_words' => 'The rule engine has a hard time handling ":string". The suggested rule that fits your search query may give different results. Please verify the rule triggers carefully.',
|
'rule_from_search_words' => 'The rule engine has a hard time handling ":string". The suggested rule that fits your search query may give different results. Please verify the rule triggers carefully.',
|
||||||
|
Reference in New Issue
Block a user