mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Expand search and add operators.
This commit is contained in:
parent
6eaed9829b
commit
9b7285ea84
@ -62,6 +62,32 @@ trait AttachmentCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNameDoesNotContain(string $name): GroupCollectorInterface
|
||||
{
|
||||
$this->hasAttachments();
|
||||
$this->withAttachmentInformation();
|
||||
$filter = function (int $index, array $object) use ($name): bool {
|
||||
/** @var array $transaction */
|
||||
foreach ($object['transactions'] as $transaction) {
|
||||
/** @var array $attachment */
|
||||
foreach ($transaction['attachments'] as $attachment) {
|
||||
$result = !str_contains(strtolower($attachment['filename']), strtolower($name)) && !str_contains(strtolower($attachment['title']), strtolower($name));
|
||||
if (true === $result) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
$this->postFilters[] = $filter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has attachments
|
||||
*
|
||||
@ -135,6 +161,32 @@ trait AttachmentCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNameDoesNotEnd(string $name): GroupCollectorInterface
|
||||
{
|
||||
$this->hasAttachments();
|
||||
$this->withAttachmentInformation();
|
||||
$filter = function (int $index, array $object) use ($name): bool {
|
||||
/** @var array $transaction */
|
||||
foreach ($object['transactions'] as $transaction) {
|
||||
/** @var array $attachment */
|
||||
foreach ($transaction['attachments'] as $attachment) {
|
||||
$result = !str_ends_with(strtolower($attachment['filename']), strtolower($name)) && !str_ends_with(strtolower($attachment['title']), strtolower($name));
|
||||
if (true === $result) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
$this->postFilters[] = $filter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GroupCollectorInterface
|
||||
@ -161,6 +213,32 @@ trait AttachmentCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNameIsNot(string $name): GroupCollectorInterface
|
||||
{
|
||||
$this->hasAttachments();
|
||||
$this->withAttachmentInformation();
|
||||
$filter = function (int $index, array $object) use ($name): bool {
|
||||
/** @var array $transaction */
|
||||
foreach ($object['transactions'] as $transaction) {
|
||||
/** @var array $attachment */
|
||||
foreach ($transaction['attachments'] as $attachment) {
|
||||
$result = $attachment['filename'] !== $name && $attachment['title'] !== $name;
|
||||
if (true === $result) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
$this->postFilters[] = $filter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GroupCollectorInterface
|
||||
@ -187,6 +265,32 @@ trait AttachmentCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNameDoesNotStart(string $name): GroupCollectorInterface
|
||||
{
|
||||
$this->hasAttachments();
|
||||
$this->withAttachmentInformation();
|
||||
$filter = function (int $index, array $object) use ($name): bool {
|
||||
/** @var array $transaction */
|
||||
foreach ($object['transactions'] as $transaction) {
|
||||
/** @var array $attachment */
|
||||
foreach ($transaction['attachments'] as $attachment) {
|
||||
$result = !str_starts_with(strtolower($attachment['filename']), strtolower($name)) && !str_starts_with(strtolower($attachment['title']), strtolower($name));
|
||||
if (true === $result) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
$this->postFilters[] = $filter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
@ -213,6 +317,32 @@ trait AttachmentCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNotesAreNot(string $value): GroupCollectorInterface
|
||||
{
|
||||
$this->hasAttachments();
|
||||
$this->withAttachmentInformation();
|
||||
$filter = function (int $index, array $object) use ($value): bool {
|
||||
/** @var array $transaction */
|
||||
foreach ($object['transactions'] as $transaction) {
|
||||
/** @var array $attachment */
|
||||
foreach ($transaction['attachments'] as $attachment) {
|
||||
/** @var Attachment $object */
|
||||
$object = auth()->user()->attachments()->find($attachment['id']);
|
||||
$notes = (string) $object->notes()?->first()?->text;
|
||||
return $notes !== '' && $notes !== $value;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
$this->postFilters[] = $filter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
@ -239,6 +369,32 @@ trait AttachmentCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNotesDoNotContain(string $value): GroupCollectorInterface
|
||||
{
|
||||
$this->hasAttachments();
|
||||
$this->withAttachmentInformation();
|
||||
$filter = function (int $index, array $object) use ($value): bool {
|
||||
/** @var array $transaction */
|
||||
foreach ($object['transactions'] as $transaction) {
|
||||
/** @var array $attachment */
|
||||
foreach ($transaction['attachments'] as $attachment) {
|
||||
/** @var Attachment $object */
|
||||
$object = auth()->user()->attachments()->find($attachment['id']);
|
||||
$notes = (string) $object->notes()?->first()?->text;
|
||||
return $notes !== '' && !str_contains(strtolower($notes), strtolower($value));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
$this->postFilters[] = $filter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
@ -265,6 +421,32 @@ trait AttachmentCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNotesDoNotEnd(string $value): GroupCollectorInterface
|
||||
{
|
||||
$this->hasAttachments();
|
||||
$this->withAttachmentInformation();
|
||||
$filter = function (int $index, array $object) use ($value): bool {
|
||||
/** @var array $transaction */
|
||||
foreach ($object['transactions'] as $transaction) {
|
||||
/** @var array $attachment */
|
||||
foreach ($transaction['attachments'] as $attachment) {
|
||||
/** @var Attachment $object */
|
||||
$object = auth()->user()->attachments()->find($attachment['id']);
|
||||
$notes = (string) $object->notes()?->first()?->text;
|
||||
return $notes !== '' && !str_ends_with(strtolower($notes), strtolower($value));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
$this->postFilters[] = $filter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
@ -291,6 +473,32 @@ trait AttachmentCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNotesDoNotStart(string $value): GroupCollectorInterface
|
||||
{
|
||||
$this->hasAttachments();
|
||||
$this->withAttachmentInformation();
|
||||
$filter = function (int $index, array $object) use ($value): bool {
|
||||
/** @var array $transaction */
|
||||
foreach ($object['transactions'] as $transaction) {
|
||||
/** @var array $attachment */
|
||||
foreach ($transaction['attachments'] as $attachment) {
|
||||
/** @var Attachment $object */
|
||||
$object = auth()->user()->attachments()->find($attachment['id']);
|
||||
$notes = (string) $object->notes()?->first()?->text;
|
||||
return $notes !== '' && !str_starts_with(strtolower($notes), strtolower($value));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
$this->postFilters[] = $filter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has attachments
|
||||
*
|
||||
|
@ -135,6 +135,18 @@ trait MetaCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function externalIdDoesNotContain(string $externalId): GroupCollectorInterface
|
||||
{
|
||||
$this->joinMetaDataTables();
|
||||
$this->query->where('journal_meta.name', '=', 'external_id');
|
||||
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s%%', $externalId));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Join table to get tag information.
|
||||
*/
|
||||
@ -160,6 +172,18 @@ trait MetaCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function externalIdDoesNotEnd(string $externalId): GroupCollectorInterface
|
||||
{
|
||||
$this->joinMetaDataTables();
|
||||
$this->query->where('journal_meta.name', '=', 'external_id');
|
||||
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s"', $externalId));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@ -172,6 +196,18 @@ trait MetaCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function externalIdDoesNotStart(string $externalId): GroupCollectorInterface
|
||||
{
|
||||
$this->joinMetaDataTables();
|
||||
$this->query->where('journal_meta.name', '=', 'external_id');
|
||||
$this->query->where('journal_meta.data', 'LIKE', sprintf('"%s%%', $externalId));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
@ -187,6 +223,23 @@ trait MetaCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalUrlDoesNotContain(string $url): GroupCollectorInterface
|
||||
{
|
||||
$this->joinMetaDataTables();
|
||||
$url = json_encode($url);
|
||||
$url = str_replace('\\', '\\\\', trim($url, '"'));
|
||||
$this->query->where('journal_meta.name', '=', 'external_url');
|
||||
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s%%', $url));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
@ -202,6 +255,23 @@ trait MetaCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalUrlDoesNotEnd(string $url): GroupCollectorInterface
|
||||
{
|
||||
$this->joinMetaDataTables();
|
||||
$url = json_encode($url);
|
||||
$url = str_replace('\\', '\\\\', ltrim($url, '"'));
|
||||
$this->query->where('journal_meta.name', '=', 'external_url');
|
||||
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s', $url));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
@ -219,6 +289,23 @@ trait MetaCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalUrlDoesNotStart(string $url): GroupCollectorInterface
|
||||
{
|
||||
$this->joinMetaDataTables();
|
||||
$url = json_encode($url);
|
||||
$url = str_replace('\\', '\\\\', rtrim($url, '"'));
|
||||
//var_dump($url);
|
||||
|
||||
$this->query->where('journal_meta.name', '=', 'external_url');
|
||||
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%s%%', $url));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Where has no tags.
|
||||
*
|
||||
@ -275,6 +362,18 @@ trait MetaCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function internalReferenceDoesNotContain(string $externalId): GroupCollectorInterface
|
||||
{
|
||||
$this->joinMetaDataTables();
|
||||
$this->query->where('journal_meta.name', '=', 'internal_reference');
|
||||
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s%%', $externalId));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@ -287,6 +386,18 @@ trait MetaCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function internalReferenceDoesNotEnd(string $externalId): GroupCollectorInterface
|
||||
{
|
||||
$this->joinMetaDataTables();
|
||||
$this->query->where('journal_meta.name', '=', 'internal_reference');
|
||||
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s"', $externalId));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@ -299,6 +410,18 @@ trait MetaCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function internalReferenceDoesNotStart(string $externalId): GroupCollectorInterface
|
||||
{
|
||||
$this->joinMetaDataTables();
|
||||
$this->query->where('journal_meta.name', '=', 'internal_reference');
|
||||
$this->query->where('journal_meta.data', 'LIKE', sprintf('"%s%%', $externalId));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
@ -605,6 +728,19 @@ trait MetaCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function excludeExternalId(string $externalId): GroupCollectorInterface
|
||||
{
|
||||
$this->joinMetaDataTables();
|
||||
$this->query->where('journal_meta.name', '=', 'external_id');
|
||||
$this->query->where('journal_meta.data', '!=', sprintf('%s', json_encode($externalId)));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@ -617,6 +753,18 @@ trait MetaCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function excludeExternalUrl(string $url): GroupCollectorInterface
|
||||
{
|
||||
$this->joinMetaDataTables();
|
||||
$this->query->where('journal_meta.name', '=', 'external_url');
|
||||
$this->query->where('journal_meta.data', '!=', json_encode($url));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@ -630,6 +778,19 @@ trait MetaCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function excludeInternalReference(string $internalReference): GroupCollectorInterface
|
||||
{
|
||||
$this->joinMetaDataTables();
|
||||
|
||||
$this->query->where('journal_meta.name', '=', 'internal_reference');
|
||||
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s%%', $internalReference));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@ -642,6 +803,18 @@ trait MetaCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function excludeRecurrenceId(string $recurringId): GroupCollectorInterface
|
||||
{
|
||||
$this->joinMetaDataTables();
|
||||
$this->query->where('journal_meta.name', '=', 'recurrence_id');
|
||||
$this->query->where('journal_meta.data', '!=', sprintf('%s', json_encode($recurringId)));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit results to a specific tag.
|
||||
*
|
||||
|
@ -79,18 +79,42 @@ interface GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNameContains(string $name): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNameDoesNotContain(string $name): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNameEnds(string $name): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNameDoesNotEnd(string $name): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNameIs(string $name): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNameIsNot(string $name): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNameDoesNotStart(string $name): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GroupCollectorInterface
|
||||
@ -103,12 +127,24 @@ interface GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNotesAre(string $value): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNotesAreNot(string $value): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNotesContains(string $value): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNotesDoNotContain(string $value): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
@ -121,6 +157,18 @@ interface GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNotesStarts(string $value): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNotesDoNotEnd(string $value): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function attachmentNotesDoNotStart(string $value): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $day
|
||||
* @return GroupCollectorInterface
|
||||
@ -358,36 +406,76 @@ interface GroupCollectorInterface
|
||||
*/
|
||||
public function externalIdContains(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $externalId
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalIdDoesNotContain(string $externalId): GroupCollectorInterface;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $externalId
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalIdEnds(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $externalId
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalIdDoesNotEnd(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $externalId
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalIdStarts(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $externalId
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalIdDoesNotStart(string $externalId): GroupCollectorInterface;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalUrlContains(string $url): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalUrlDoesNotContain(string $url): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalUrlEnds(string $url): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalUrlDoesNotEnd(string $url): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalUrlStarts(string $url): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function externalUrlDoesNotStart(string $url): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* Ensure the search will find nothing at all, zero results.
|
||||
*
|
||||
@ -477,18 +565,36 @@ interface GroupCollectorInterface
|
||||
*/
|
||||
public function internalReferenceContains(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $externalId
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function internalReferenceDoesNotContain(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $externalId
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function internalReferenceEnds(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $externalId
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function internalReferenceDoesNotEnd(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $externalId
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function internalReferenceStarts(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $externalId
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function internalReferenceDoesNotStart(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* Only journals that are reconciled.
|
||||
*
|
||||
@ -876,12 +982,27 @@ interface GroupCollectorInterface
|
||||
*/
|
||||
public function setExternalId(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* Look for specific external ID's.
|
||||
*
|
||||
* @param string $externalId
|
||||
*
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function excludeExternalId(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function setExternalUrl(string $url): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function excludeExternalUrl(string $url): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* Limit results to a specific foreign currency.
|
||||
*
|
||||
@ -909,6 +1030,17 @@ interface GroupCollectorInterface
|
||||
*/
|
||||
public function setInternalReference(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* Look for specific external ID's.
|
||||
*
|
||||
* @param string $externalId
|
||||
*
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function excludeInternalReference(string $externalId): GroupCollectorInterface;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Limit the result to a set of specific transaction journals.
|
||||
*
|
||||
@ -1015,6 +1147,13 @@ interface GroupCollectorInterface
|
||||
*/
|
||||
public function setRecurrenceId(string $recurringId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* @param string $recurringId
|
||||
*
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function excludeRecurrenceId(string $recurringId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* Search for words in descriptions.
|
||||
*
|
||||
|
@ -33,7 +33,7 @@ use Log;
|
||||
*/
|
||||
class ParseDateString
|
||||
{
|
||||
private $keywords
|
||||
private array $keywords
|
||||
= [
|
||||
'today',
|
||||
'yesterday',
|
||||
@ -80,6 +80,7 @@ class ParseDateString
|
||||
*/
|
||||
public function parseDate(string $date): Carbon
|
||||
{
|
||||
Log::debug(sprintf('parseDate("%s")', $date));
|
||||
$date = strtolower($date);
|
||||
// parse keywords:
|
||||
if (in_array($date, $this->keywords, true)) {
|
||||
@ -118,7 +119,7 @@ class ParseDateString
|
||||
return new Carbon(sprintf('%d-01-01', $date));
|
||||
}
|
||||
|
||||
throw new FireflyException(sprintf('[d]Not a recognised date format: "%s"', $date));
|
||||
throw new FireflyException(sprintf('[d] Not a recognised date format: "%s"', $date));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,7 +190,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
case Subquery::class:
|
||||
// loop all notes in subquery:
|
||||
foreach ($searchNode->getNodes() as $subNode) { // @phpstan-ignore-line
|
||||
$this->handleSearchNode($subNode); // let's hope it's not too recursive!
|
||||
$this->handleSearchNode($subNode); // let's hope it's not too recursive
|
||||
}
|
||||
break;
|
||||
case Word::class:
|
||||
@ -254,8 +254,8 @@ class OperatorQuerySearch implements SearchInterface
|
||||
private function updateCollector(string $operator, string $value, bool $prohibited): bool
|
||||
{
|
||||
if ($prohibited) {
|
||||
Log::debug(sprintf('Operator "%s" is now "%s"', $operator, '!' . $operator));
|
||||
$operator = sprintf('!%s', $operator);
|
||||
Log::debug(sprintf('Operator "%s" is now "%s"', $operator, sprintf('-%s', $operator)));
|
||||
$operator = sprintf('-%s', $operator);
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Now in updateCollector("%s", "%s")', $operator, $value));
|
||||
@ -278,97 +278,97 @@ class OperatorQuerySearch implements SearchInterface
|
||||
case 'account_is':
|
||||
$this->searchAccount($value, 3, 4);
|
||||
break;
|
||||
case '!account_is':
|
||||
case '-account_is':
|
||||
$this->searchAccount($value, 3, 4, true);
|
||||
break;
|
||||
case 'account_contains':
|
||||
$this->searchAccount($value, 3, 3);
|
||||
break;
|
||||
case '!account_contains':
|
||||
case '-account_contains':
|
||||
$this->searchAccount($value, 3, 3, true);
|
||||
break;
|
||||
case 'account_ends':
|
||||
$this->searchAccount($value, 3, 2);
|
||||
break;
|
||||
case '!account_ends':
|
||||
case '-account_ends':
|
||||
$this->searchAccount($value, 3, 2, true);
|
||||
break;
|
||||
case 'account_starts':
|
||||
$this->searchAccount($value, 3, 1);
|
||||
break;
|
||||
case '!account_starts':
|
||||
case '-account_starts':
|
||||
$this->searchAccount($value, 3, 1, true);
|
||||
break;
|
||||
case 'account_nr_is':
|
||||
$this->searchAccountNr($value, 3, 4);
|
||||
break;
|
||||
case '!account_nr_is':
|
||||
case '-account_nr_is':
|
||||
$this->searchAccountNr($value, 3, 4, true);
|
||||
break;
|
||||
case 'account_nr_contains':
|
||||
$this->searchAccountNr($value, 3, 3);
|
||||
break;
|
||||
case '!account_nr_contains':
|
||||
case '-account_nr_contains':
|
||||
$this->searchAccountNr($value, 3, 3, true);
|
||||
break;
|
||||
case 'account_nr_ends':
|
||||
$this->searchAccountNr($value, 3, 2);
|
||||
break;
|
||||
case '!account_nr_ends':
|
||||
case '-account_nr_ends':
|
||||
$this->searchAccountNr($value, 3, 2, true);
|
||||
break;
|
||||
case 'account_nr_starts':
|
||||
$this->searchAccountNr($value, 3, 1);
|
||||
break;
|
||||
case '!account_nr_starts':
|
||||
case '-account_nr_starts':
|
||||
$this->searchAccountNr($value, 3, 1, true);
|
||||
break;
|
||||
case 'source_account_starts':
|
||||
$this->searchAccount($value, 1, 1);
|
||||
break;
|
||||
case '!source_account_starts':
|
||||
case '-source_account_starts':
|
||||
$this->searchAccount($value, 1, 1, true);
|
||||
break;
|
||||
case 'source_account_ends':
|
||||
$this->searchAccount($value, 1, 2);
|
||||
break;
|
||||
case '!source_account_ends':
|
||||
case '-source_account_ends':
|
||||
$this->searchAccount($value, 1, 2, true);
|
||||
break;
|
||||
case 'source_account_is':
|
||||
$this->searchAccount($value, 1, 4);
|
||||
break;
|
||||
case '!source_account_is':
|
||||
case '-source_account_is':
|
||||
$this->searchAccount($value, 1, 4, true);
|
||||
break;
|
||||
case 'source_account_nr_starts':
|
||||
$this->searchAccountNr($value, 1, 1);
|
||||
break;
|
||||
case '!source_account_nr_starts':
|
||||
case '-source_account_nr_starts':
|
||||
$this->searchAccountNr($value, 1, 1, true);
|
||||
break;
|
||||
case 'source_account_nr_ends':
|
||||
$this->searchAccountNr($value, 1, 2);
|
||||
break;
|
||||
case '!source_account_nr_ends':
|
||||
case '-source_account_nr_ends':
|
||||
$this->searchAccountNr($value, 1, 2, true);
|
||||
break;
|
||||
case 'source_account_nr_is':
|
||||
$this->searchAccountNr($value, 1, 4);
|
||||
break;
|
||||
case '!source_account_nr_is':
|
||||
case '-source_account_nr_is':
|
||||
$this->searchAccountNr($value, 1, 4, true);
|
||||
break;
|
||||
case 'source_account_nr_contains':
|
||||
$this->searchAccountNr($value, 1, 3);
|
||||
break;
|
||||
case '!source_account_nr_contains':
|
||||
case '-source_account_nr_contains':
|
||||
$this->searchAccountNr($value, 1, 3, true);
|
||||
break;
|
||||
case 'source_account_contains':
|
||||
$this->searchAccount($value, 1, 3);
|
||||
break;
|
||||
case '!source_account_contains':
|
||||
case '-source_account_contains':
|
||||
$this->searchAccount($value, 1, 3, true);
|
||||
break;
|
||||
case 'source_account_id':
|
||||
@ -381,7 +381,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!source_account_id':
|
||||
case '-source_account_id':
|
||||
$account = $this->accountRepository->find((int) $value);
|
||||
if (null !== $account) {
|
||||
$this->collector->excludeSourceAccounts(new Collection([$account]));
|
||||
@ -395,7 +395,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$parts = explode(',', $value);
|
||||
$this->collector->setJournalIds($parts);
|
||||
break;
|
||||
case '!journal_id':
|
||||
case '-journal_id':
|
||||
$parts = explode(',', $value);
|
||||
$this->collector->excludeJournalIds($parts);
|
||||
break;
|
||||
@ -403,56 +403,56 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$parts = explode(',', $value);
|
||||
$this->collector->setIds($parts);
|
||||
break;
|
||||
case '!id':
|
||||
case '-id':
|
||||
$parts = explode(',', $value);
|
||||
$this->collector->excludeIds($parts);
|
||||
break;
|
||||
case 'destination_account_starts':
|
||||
$this->searchAccount($value, 2, 1);
|
||||
break;
|
||||
case '!destination_account_starts':
|
||||
case '-destination_account_starts':
|
||||
$this->searchAccount($value, 2, 1, true);
|
||||
break;
|
||||
case 'destination_account_ends':
|
||||
$this->searchAccount($value, 2, 2);
|
||||
break;
|
||||
case '!destination_account_ends':
|
||||
case '-destination_account_ends':
|
||||
$this->searchAccount($value, 2, 2, true);
|
||||
break;
|
||||
case 'destination_account_nr_starts':
|
||||
$this->searchAccountNr($value, 2, 1);
|
||||
break;
|
||||
case '!destination_account_nr_starts':
|
||||
case '-destination_account_nr_starts':
|
||||
$this->searchAccountNr($value, 2, 1, true);
|
||||
break;
|
||||
case 'destination_account_nr_ends':
|
||||
$this->searchAccountNr($value, 2, 2);
|
||||
break;
|
||||
case '!destination_account_nr_ends':
|
||||
case '-destination_account_nr_ends':
|
||||
$this->searchAccountNr($value, 2, 2, true);
|
||||
break;
|
||||
case 'destination_account_nr_is':
|
||||
$this->searchAccountNr($value, 2, 4);
|
||||
break;
|
||||
case '!destination_account_nr_is':
|
||||
case '-destination_account_nr_is':
|
||||
$this->searchAccountNr($value, 2, 4, true);
|
||||
break;
|
||||
case 'destination_account_is':
|
||||
$this->searchAccount($value, 2, 4);
|
||||
break;
|
||||
case '!destination_account_is':
|
||||
case '-destination_account_is':
|
||||
$this->searchAccount($value, 2, 4, true);
|
||||
break;
|
||||
case 'destination_account_nr_contains':
|
||||
$this->searchAccountNr($value, 2, 3);
|
||||
break;
|
||||
case '!destination_account_nr_contains':
|
||||
case '-destination_account_nr_contains':
|
||||
$this->searchAccountNr($value, 2, 3, true);
|
||||
break;
|
||||
case 'destination_account_contains':
|
||||
$this->searchAccount($value, 2, 3);
|
||||
break;
|
||||
case '!destination_account_contains':
|
||||
case '-destination_account_contains':
|
||||
$this->searchAccount($value, 2, 3, true);
|
||||
break;
|
||||
case 'destination_account_id':
|
||||
@ -464,7 +464,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!destination_account_id':
|
||||
case '-destination_account_id':
|
||||
$account = $this->accountRepository->find((int) $value);
|
||||
if (null !== $account) {
|
||||
$this->collector->excludeDestinationAccounts(new Collection([$account]));
|
||||
@ -489,7 +489,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!account_id':
|
||||
case '-account_id':
|
||||
$parts = explode(',', $value);
|
||||
$collection = new Collection;
|
||||
foreach ($parts as $accountId) {
|
||||
@ -512,7 +512,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$account = $this->getCashAccount();
|
||||
$this->collector->setSourceAccounts(new Collection([$account]));
|
||||
break;
|
||||
case '!source_is_cash':
|
||||
case '-source_is_cash':
|
||||
$account = $this->getCashAccount();
|
||||
$this->collector->excludeSourceAccounts(new Collection([$account]));
|
||||
break;
|
||||
@ -520,7 +520,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$account = $this->getCashAccount();
|
||||
$this->collector->setDestinationAccounts(new Collection([$account]));
|
||||
break;
|
||||
case '!destination_is_cash':
|
||||
case '-destination_is_cash':
|
||||
$account = $this->getCashAccount();
|
||||
$this->collector->excludeDestinationAccounts(new Collection([$account]));
|
||||
break;
|
||||
@ -528,7 +528,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$account = $this->getCashAccount();
|
||||
$this->collector->setAccounts(new Collection([$account]));
|
||||
break;
|
||||
case '!account_is_cash':
|
||||
case '-account_is_cash':
|
||||
$account = $this->getCashAccount();
|
||||
$this->collector->excludeAccounts(new Collection([$account]));
|
||||
break;
|
||||
@ -538,27 +538,27 @@ class OperatorQuerySearch implements SearchInterface
|
||||
case 'description_starts':
|
||||
$this->collector->descriptionStarts([$value]);
|
||||
break;
|
||||
case '!description_starts':
|
||||
case '-description_starts':
|
||||
$this->collector->descriptionDoesNotStart([$value]);
|
||||
break;
|
||||
case 'description_ends':
|
||||
$this->collector->descriptionEnds([$value]);
|
||||
break;
|
||||
case '!description_ends':
|
||||
case '-description_ends':
|
||||
$this->collector->descriptionDoesNotEnd([$value]);
|
||||
break;
|
||||
case 'description_contains':
|
||||
$this->words[] = $value;
|
||||
|
||||
return false;
|
||||
case '!description_contains':
|
||||
case '-description_contains':
|
||||
$this->prohibitedWords[] = $value;
|
||||
|
||||
break;
|
||||
case 'description_is':
|
||||
$this->collector->descriptionIs($value);
|
||||
break;
|
||||
case '!description_is':
|
||||
case '-description_is':
|
||||
$this->collector->descriptionIsNot($value);
|
||||
break;
|
||||
//
|
||||
@ -573,7 +573,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!currency_is':
|
||||
case '-currency_is':
|
||||
$currency = $this->findCurrency($value);
|
||||
if (null !== $currency) {
|
||||
$this->collector->excludeCurrency($currency);
|
||||
@ -591,7 +591,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!foreign_currency_is':
|
||||
case '-foreign_currency_is':
|
||||
$currency = $this->findCurrency($value);
|
||||
if (null !== $currency) {
|
||||
$this->collector->excludeForeignCurrency($currency);
|
||||
@ -604,22 +604,22 @@ class OperatorQuerySearch implements SearchInterface
|
||||
// attachments
|
||||
//
|
||||
case 'has_attachments':
|
||||
case '!has_no_attachments':
|
||||
case '-has_no_attachments':
|
||||
Log::debug('Set collector to filter on attachments.');
|
||||
$this->collector->hasAttachments();
|
||||
break;
|
||||
case 'has_no_attachments':
|
||||
case '!has_attachments':
|
||||
case '-has_attachments':
|
||||
Log::debug('Set collector to filter on NO attachments.');
|
||||
$this->collector->hasNoAttachments();
|
||||
break;
|
||||
//
|
||||
// categories
|
||||
case '!has_any_category':
|
||||
case '-has_any_category':
|
||||
case 'has_no_category':
|
||||
$this->collector->withoutCategory();
|
||||
break;
|
||||
case '!has_no_category':
|
||||
case '-has_no_category':
|
||||
case 'has_any_category':
|
||||
$this->collector->withCategory();
|
||||
break;
|
||||
@ -631,7 +631,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
}
|
||||
$this->collector->findNothing();
|
||||
break;
|
||||
case '!category_is':
|
||||
case '-category_is':
|
||||
$category = $this->categoryRepository->findByName($value);
|
||||
if (null !== $category) {
|
||||
$this->collector->excludeCategory($category);
|
||||
@ -647,7 +647,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!category_ends':
|
||||
case '-category_ends':
|
||||
$result = $this->categoryRepository->categoryEndsWith($value, 1337);
|
||||
if ($result->count() > 0) {
|
||||
$this->collector->excludeCategories($result);
|
||||
@ -665,7 +665,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!category_starts':
|
||||
case '-category_starts':
|
||||
$result = $this->categoryRepository->categoryStartsWith($value, 1337);
|
||||
if ($result->count() > 0) {
|
||||
$this->collector->excludeCategories($result);
|
||||
@ -683,7 +683,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!category_contains':
|
||||
case '-category_contains':
|
||||
$result = $this->categoryRepository->searchCategory($value, 1337);
|
||||
if ($result->count() > 0) {
|
||||
$this->collector->excludeCategories($result);
|
||||
@ -695,12 +695,12 @@ class OperatorQuerySearch implements SearchInterface
|
||||
//
|
||||
// budgets
|
||||
//
|
||||
case '!has_any_budget':
|
||||
case '-has_any_budget':
|
||||
case 'has_no_budget':
|
||||
$this->collector->withoutBudget();
|
||||
break;
|
||||
case 'has_any_budget':
|
||||
case '!has_no_budget':
|
||||
case '-has_no_budget':
|
||||
$this->collector->withBudget();
|
||||
break;
|
||||
case 'budget_contains':
|
||||
@ -712,7 +712,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!budget_contains':
|
||||
case '-budget_contains':
|
||||
$result = $this->budgetRepository->searchBudget($value, 1337);
|
||||
if ($result->count() > 0) {
|
||||
$this->collector->excludeBudgets($result);
|
||||
@ -729,7 +729,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
}
|
||||
$this->collector->findNothing();
|
||||
break;
|
||||
case '!budget_is':
|
||||
case '-budget_is':
|
||||
$budget = $this->budgetRepository->findByName($value);
|
||||
if (null !== $budget) {
|
||||
$this->collector->excludeBudget($budget);
|
||||
@ -746,7 +746,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!budget_ends':
|
||||
case '-budget_ends':
|
||||
$result = $this->budgetRepository->budgetEndsWith($value, 1337);
|
||||
if ($result->count() > 0) {
|
||||
$this->collector->excludeBudgets($result);
|
||||
@ -764,7 +764,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!budget_starts':
|
||||
case '-budget_starts':
|
||||
$result = $this->budgetRepository->budgetStartsWith($value, 1337);
|
||||
if ($result->count() > 0) {
|
||||
$this->collector->excludeBudgets($result);
|
||||
@ -776,11 +776,11 @@ class OperatorQuerySearch implements SearchInterface
|
||||
//
|
||||
// bill
|
||||
//
|
||||
case '!has_any_bill':
|
||||
case '-has_any_bill':
|
||||
case 'has_no_bill':
|
||||
$this->collector->withoutBill();
|
||||
break;
|
||||
case '!has_no_bill':
|
||||
case '-has_no_bill':
|
||||
case 'has_any_bill':
|
||||
$this->collector->withBill();
|
||||
break;
|
||||
@ -792,7 +792,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
}
|
||||
$this->collector->findNothing();
|
||||
break;
|
||||
case '!bill_contains':
|
||||
case '-bill_contains':
|
||||
$result = $this->billRepository->searchBill($value, 1337);
|
||||
if ($result->count() > 0) {
|
||||
$this->collector->excludeBills($result);
|
||||
@ -808,7 +808,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
}
|
||||
$this->collector->findNothing();
|
||||
break;
|
||||
case '!bill_is':
|
||||
case '-bill_is':
|
||||
$bill = $this->billRepository->findByName($value);
|
||||
if (null !== $bill) {
|
||||
$this->collector->excludeBills(new Collection([$bill]));
|
||||
@ -825,7 +825,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!bill_ends':
|
||||
case '-bill_ends':
|
||||
$result = $this->billRepository->billEndsWith($value, 1337);
|
||||
if ($result->count() > 0) {
|
||||
$this->collector->excludeBills($result);
|
||||
@ -843,7 +843,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!bill_starts':
|
||||
case '-bill_starts':
|
||||
$result = $this->billRepository->billStartsWith($value, 1337);
|
||||
if ($result->count() > 0) {
|
||||
$this->collector->excludeBills($result);
|
||||
@ -855,15 +855,15 @@ class OperatorQuerySearch implements SearchInterface
|
||||
//
|
||||
// tags
|
||||
//
|
||||
case '!has_any_tag':
|
||||
case '-has_any_tag':
|
||||
case 'has_no_tag':
|
||||
$this->collector->withoutTags();
|
||||
break;
|
||||
case '!has_no_tag':
|
||||
case '-has_no_tag':
|
||||
case 'has_any_tag':
|
||||
$this->collector->hasAnyTag();
|
||||
break;
|
||||
case '!tag_is_not':
|
||||
case '-tag_is_not':
|
||||
case 'tag_is':
|
||||
$result = $this->tagRepository->searchTag($value);
|
||||
if ($result->count() > 0) {
|
||||
@ -875,7 +875,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->findNothing();
|
||||
}
|
||||
break;
|
||||
case '!tag_is':
|
||||
case '-tag_is':
|
||||
case 'tag_is_not':
|
||||
$result = $this->tagRepository->searchTag($value);
|
||||
if ($result->count() > 0) {
|
||||
@ -888,39 +888,39 @@ class OperatorQuerySearch implements SearchInterface
|
||||
case 'notes_contains':
|
||||
$this->collector->notesContain($value);
|
||||
break;
|
||||
case '!notes_contains':
|
||||
case '-notes_contains':
|
||||
$this->collector->notesDoNotContain($value);
|
||||
break;
|
||||
case 'notes_starts':
|
||||
$this->collector->notesStartWith($value);
|
||||
break;
|
||||
case '!notes_starts':
|
||||
case '-notes_starts':
|
||||
$this->collector->notesDontStartWith($value);
|
||||
break;
|
||||
case 'notes_ends':
|
||||
$this->collector->notesEndWith($value);
|
||||
break;
|
||||
case '!notes_ends':
|
||||
case '-notes_ends':
|
||||
$this->collector->notesDontEndWith($value);
|
||||
break;
|
||||
case 'notes_is':
|
||||
$this->collector->notesExactly($value);
|
||||
break;
|
||||
case '!notes_is':
|
||||
case '-notes_is':
|
||||
$this->collector->notesExactlyNot($value);
|
||||
break;
|
||||
case '!any_notes':
|
||||
case '-any_notes':
|
||||
case 'no_notes':
|
||||
$this->collector->withoutNotes();
|
||||
break;
|
||||
case 'any_notes':
|
||||
case '!no_notes':
|
||||
case '-no_notes':
|
||||
$this->collector->withAnyNotes();
|
||||
break;
|
||||
case 'reconciled':
|
||||
$this->collector->isReconciled();
|
||||
break;
|
||||
case '!reconciled':
|
||||
case '-reconciled':
|
||||
$this->collector->isNotReconciled();
|
||||
break;
|
||||
//
|
||||
@ -934,7 +934,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
|
||||
$this->collector->amountIs($amount);
|
||||
break;
|
||||
case '!amount_is':
|
||||
case '-amount_is':
|
||||
// strip comma's, make dots.
|
||||
Log::debug(sprintf('Original value "%s"', $value));
|
||||
$value = str_replace(',', '.', (string) $value);
|
||||
@ -951,7 +951,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
|
||||
$this->collector->foreignAmountIs($amount);
|
||||
break;
|
||||
case '!foreign_amount_is':
|
||||
case '-foreign_amount_is':
|
||||
|
||||
// strip comma's, make dots.
|
||||
$value = str_replace(',', '.', (string) $value);
|
||||
@ -960,7 +960,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
|
||||
$this->collector->foreignAmountIsNot($amount);
|
||||
break;
|
||||
case '!amount_more':
|
||||
case '-amount_more':
|
||||
case 'amount_less':
|
||||
// strip comma's, make dots.
|
||||
$value = str_replace(',', '.', (string) $value);
|
||||
@ -969,7 +969,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
|
||||
$this->collector->amountLess($amount);
|
||||
break;
|
||||
case '!foreign_amount_more':
|
||||
case '-foreign_amount_more':
|
||||
case 'foreign_amount_less':
|
||||
// strip comma's, make dots.
|
||||
$value = str_replace(',', '.', (string) $value);
|
||||
@ -978,7 +978,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
|
||||
$this->collector->foreignAmountLess($amount);
|
||||
break;
|
||||
case '!amount_less':
|
||||
case '-amount_less':
|
||||
case 'amount_more':
|
||||
Log::debug(sprintf('Now handling operator "%s"', $operator));
|
||||
// strip comma's, make dots.
|
||||
@ -987,7 +987,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
|
||||
$this->collector->amountMore($amount);
|
||||
break;
|
||||
case '!foreign_amount_less':
|
||||
case '-foreign_amount_less':
|
||||
case 'foreign_amount_more':
|
||||
Log::debug(sprintf('Now handling operator "%s"', $operator));
|
||||
// strip comma's, make dots.
|
||||
@ -1003,158 +1003,158 @@ class OperatorQuerySearch implements SearchInterface
|
||||
$this->collector->setTypes([ucfirst($value)]);
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
|
||||
break;
|
||||
case '!transaction_type':
|
||||
case '-transaction_type':
|
||||
$this->collector->excludeTypes([ucfirst($value)]);
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
|
||||
break;
|
||||
//
|
||||
// dates
|
||||
//
|
||||
case '!date_on':
|
||||
case '-date_on':
|
||||
case 'date_on':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setExactDateParams($range, $prohibited);
|
||||
return false;
|
||||
case 'date_before':
|
||||
case '!date_after':
|
||||
case '-date_after':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setDateBeforeParams($range);
|
||||
return false;
|
||||
case 'date_after':
|
||||
case '!date_before':
|
||||
case '-date_before':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setDateAfterParams($range);
|
||||
return false;
|
||||
|
||||
case 'interest_date_on':
|
||||
case '!interest_date_on':
|
||||
case '-interest_date_on':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setExactMetaDateParams('interest_date', $range, $prohibited);
|
||||
return false;
|
||||
case 'interest_date_before':
|
||||
case '!interest_date_after':
|
||||
case '-interest_date_after':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setMetaDateBeforeParams('interest_date', $range);
|
||||
return false;
|
||||
case 'interest_date_after':
|
||||
case '!interest_date_before':
|
||||
case '-interest_date_before':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setMetaDateAfterParams('interest_date', $range);
|
||||
return false;
|
||||
|
||||
case 'book_date_on':
|
||||
case '!book_date_on':
|
||||
case '-book_date_on':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setExactMetaDateParams('book_date', $range, $prohibited);
|
||||
return false;
|
||||
case 'book_date_before':
|
||||
case '!book_date_after':
|
||||
case '-book_date_after':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setMetaDateBeforeParams('book_date', $range);
|
||||
return false;
|
||||
case 'book_date_after':
|
||||
case '!book_date_before':
|
||||
case '-book_date_before':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setMetaDateAfterParams('book_date', $range);
|
||||
return false;
|
||||
|
||||
case 'process_date_on':
|
||||
case '!process_date_on':
|
||||
case '-process_date_on':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setExactMetaDateParams('process_date', $range, $prohibited);
|
||||
return false;
|
||||
case 'process_date_before':
|
||||
case '!process_date_after':
|
||||
case '-process_date_after':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setMetaDateBeforeParams('process_date', $range);
|
||||
return false;
|
||||
case 'process_date_after':
|
||||
case '!process_date_before':
|
||||
case '-process_date_before':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setMetaDateAfterParams('process_date', $range);
|
||||
return false;
|
||||
|
||||
case 'due_date_on':
|
||||
case '!due_date_on':
|
||||
case '-due_date_on':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setExactMetaDateParams('due_date', $range, $prohibited);
|
||||
return false;
|
||||
case 'due_date_before':
|
||||
case '!due_date_after':
|
||||
case '-due_date_after':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setMetaDateBeforeParams('due_date', $range);
|
||||
return false;
|
||||
case 'due_date_after':
|
||||
case '!due_date_before':
|
||||
case '-due_date_before':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setMetaDateAfterParams('due_date', $range);
|
||||
return false;
|
||||
|
||||
case 'payment_date_on':
|
||||
case '!payment_date_on':
|
||||
case '-payment_date_on':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setExactMetaDateParams('payment_date', $range, $prohibited);
|
||||
return false;
|
||||
case 'payment_date_before':
|
||||
case '!payment_date_after':
|
||||
case '-payment_date_after':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setMetaDateBeforeParams('payment_date', $range);
|
||||
return false;
|
||||
case 'payment_date_after':
|
||||
case '!payment_date_before':
|
||||
case '-payment_date_before':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setMetaDateAfterParams('payment_date', $range);
|
||||
return false;
|
||||
|
||||
case 'invoice_date_on':
|
||||
case '!invoice_date_on':
|
||||
case '-invoice_date_on':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setExactMetaDateParams('invoice_date', $range, $prohibited);
|
||||
return false;
|
||||
case 'invoice_date_before':
|
||||
case '!invoice_date_after':
|
||||
case '-invoice_date_after':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setMetaDateBeforeParams('invoice_date', $range);
|
||||
return false;
|
||||
case 'invoice_date_after':
|
||||
case '!invoice_date_before':
|
||||
case '-invoice_date_before':
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setMetaDateAfterParams('invoice_date', $range);
|
||||
return false;
|
||||
|
||||
case 'created_at_on':
|
||||
case '!created_at_on':
|
||||
case '-created_at_on':
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setExactObjectDateParams('created_at', $range, $prohibited);
|
||||
return false;
|
||||
case 'created_at_before':
|
||||
case '!created_at_after':
|
||||
case '-created_at_after':
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setObjectDateBeforeParams('created_at', $range);
|
||||
return false;
|
||||
case 'created_at_after':
|
||||
case '!created_at_before':
|
||||
case '-created_at_before':
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setObjectDateAfterParams('created_at', $range);
|
||||
return false;
|
||||
|
||||
case 'updated_at_on':
|
||||
case '!updated_at_on':
|
||||
case '-updated_at_on':
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setExactObjectDateParams('updated_at', $range, $prohibited);
|
||||
return false;
|
||||
case 'updated_at_before':
|
||||
case '!updated_at_after':
|
||||
case '-updated_at_after':
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setObjectDateBeforeParams('updated_at', $range);
|
||||
return false;
|
||||
case 'updated_at_after':
|
||||
case '!updated_at_before':
|
||||
case '-updated_at_before':
|
||||
Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
|
||||
$range = $this->parseDateRange($value);
|
||||
$this->setObjectDateAfterParams('updated_at', $range);
|
||||
@ -1162,87 +1162,154 @@ class OperatorQuerySearch implements SearchInterface
|
||||
//
|
||||
// external URL
|
||||
//
|
||||
case '!any_external_url':
|
||||
case '-any_external_url':
|
||||
case 'no_external_url':
|
||||
$this->collector->withoutExternalUrl();
|
||||
break;
|
||||
case '!no_external_url':
|
||||
case '-no_external_url':
|
||||
case 'any_external_url':
|
||||
$this->collector->withExternalUrl();
|
||||
break;
|
||||
|
||||
case 'external_url_is':
|
||||
$this->collector->setExternalUrl($value);
|
||||
break;
|
||||
case '-external_url_is':
|
||||
$this->collector->excludeExternalUrl($value);
|
||||
break;
|
||||
case 'external_url_contains':
|
||||
$this->collector->externalUrlContains($value);
|
||||
break;
|
||||
case '-external_url_contains':
|
||||
$this->collector->externalUrlDoesNotContain($value);
|
||||
break;
|
||||
case 'external_url_starts':
|
||||
$this->collector->externalUrlStarts($value);
|
||||
break;
|
||||
case '-external_url_starts':
|
||||
$this->collector->externalUrlDoesNotStart($value);
|
||||
break;
|
||||
case 'external_url_ends':
|
||||
$this->collector->externalUrlEnds($value);
|
||||
break;
|
||||
case '-external_url_ends':
|
||||
$this->collector->externalUrlDoesNotEnd($value);
|
||||
break;
|
||||
|
||||
//
|
||||
// other fields
|
||||
//
|
||||
case 'external_id_is':
|
||||
$this->collector->setExternalId($value);
|
||||
break;
|
||||
case '-external_id_is':
|
||||
$this->collector->excludeExternalId($value);
|
||||
break;
|
||||
case 'recurrence_id':
|
||||
$this->collector->setRecurrenceId($value);
|
||||
break;
|
||||
case '-recurrence_id':
|
||||
$this->collector->excludeRecurrenceId($value);
|
||||
break;
|
||||
case 'external_id_contains':
|
||||
$this->collector->externalIdContains($value);
|
||||
break;
|
||||
case '-external_id_contains':
|
||||
$this->collector->externalIdDoesNotContain($value);
|
||||
break;
|
||||
case 'external_id_starts':
|
||||
$this->collector->externalIdStarts($value);
|
||||
break;
|
||||
case '-external_id_starts':
|
||||
$this->collector->externalIdDoesNotStart($value);
|
||||
break;
|
||||
case 'external_id_ends':
|
||||
$this->collector->externalIdEnds($value);
|
||||
break;
|
||||
case '-external_id_ends':
|
||||
$this->collector->externalIdDoesNotEnd($value);
|
||||
break;
|
||||
|
||||
case 'internal_reference_is':
|
||||
$this->collector->setInternalReference($value);
|
||||
break;
|
||||
case '-internal_reference_is':
|
||||
$this->collector->excludeInternalReference($value);
|
||||
break;
|
||||
case 'internal_reference_contains':
|
||||
$this->collector->internalReferenceContains($value);
|
||||
break;
|
||||
case '-internal_reference_contains':
|
||||
$this->collector->internalReferenceDoesNotContain($value);
|
||||
break;
|
||||
case 'internal_reference_starts':
|
||||
$this->collector->internalReferenceStarts($value);
|
||||
break;
|
||||
case '-internal_reference_starts':
|
||||
$this->collector->internalReferenceDoesNotStart($value);
|
||||
break;
|
||||
case 'internal_reference_ends':
|
||||
$this->collector->internalReferenceEnds($value);
|
||||
break;
|
||||
case '-internal_reference_ends':
|
||||
$this->collector->internalReferenceDoesNotEnd($value);
|
||||
break;
|
||||
|
||||
case 'attachment_name_is':
|
||||
$this->collector->attachmentNameIs($value);
|
||||
break;
|
||||
case '-attachment_name_is':
|
||||
$this->collector->attachmentNameIsNot($value);
|
||||
break;
|
||||
case 'attachment_name_contains':
|
||||
$this->collector->attachmentNameContains($value);
|
||||
break;
|
||||
case '-attachment_name_contains':
|
||||
$this->collector->attachmentNameDoesNotContain($value);
|
||||
break;
|
||||
case 'attachment_name_starts':
|
||||
$this->collector->attachmentNameStarts($value);
|
||||
break;
|
||||
case '-attachment_name_starts':
|
||||
$this->collector->attachmentNameDoesNotStart($value);
|
||||
break;
|
||||
case 'attachment_name_ends':
|
||||
$this->collector->attachmentNameEnds($value);
|
||||
break;
|
||||
case '-attachment_name_ends':
|
||||
$this->collector->attachmentNameDoesNotEnd($value);
|
||||
break;
|
||||
|
||||
case 'attachment_notes_are':
|
||||
$this->collector->attachmentNotesAre($value);
|
||||
break;
|
||||
case '-attachment_notes_are':
|
||||
$this->collector->attachmentNotesAreNot($value);
|
||||
break;
|
||||
case 'attachment_notes_contains':
|
||||
$this->collector->attachmentNotesContains($value);
|
||||
break;
|
||||
case '-attachment_notes_contains':
|
||||
$this->collector->attachmentNotesDoNotContain($value);
|
||||
break;
|
||||
case 'attachment_notes_starts':
|
||||
$this->collector->attachmentNotesStarts($value);
|
||||
break;
|
||||
case '-attachment_notes_starts':
|
||||
$this->collector->attachmentNotesDoNotStart($value);
|
||||
break;
|
||||
case 'attachment_notes_ends':
|
||||
$this->collector->attachmentNotesEnds($value);
|
||||
break;
|
||||
|
||||
case '-attachment_notes_ends':
|
||||
$this->collector->attachmentNotesDoNotEnd($value);
|
||||
break;
|
||||
case 'exists':
|
||||
$this->collector->exists();
|
||||
break;
|
||||
case '-exists':
|
||||
$this->collector->findNothing();
|
||||
break;
|
||||
|
||||
}
|
||||
return true;
|
||||
@ -1257,9 +1324,9 @@ class OperatorQuerySearch implements SearchInterface
|
||||
public static function getRootOperator(string $operator): string
|
||||
{
|
||||
$original = $operator;
|
||||
// if the string starts with "!" (not), we can remove it and recycle
|
||||
// if the string starts with "-" (not), we can remove it and recycle
|
||||
// the configuration from the original operator.
|
||||
if (str_starts_with($operator, '!')) {
|
||||
if (str_starts_with($operator, '-')) {
|
||||
$operator = substr($operator, 1);
|
||||
}
|
||||
|
||||
@ -1269,8 +1336,8 @@ class OperatorQuerySearch implements SearchInterface
|
||||
}
|
||||
if (true === $config['alias']) {
|
||||
$return = $config['alias_for'];
|
||||
if (str_starts_with($original, '!')) {
|
||||
$return = sprintf('!%s', $config['alias_for']);
|
||||
if (str_starts_with($original, '-')) {
|
||||
$return = sprintf('-%s', $config['alias_for']);
|
||||
}
|
||||
Log::debug(sprintf('"%s" is an alias for "%s", so return that instead.', $original, $return));
|
||||
|
||||
@ -1423,7 +1490,7 @@ class OperatorQuerySearch implements SearchInterface
|
||||
Log::debug(sprintf('Found %d accounts, will filter.', $accounts->count()));
|
||||
$filtered = $accounts->filter(
|
||||
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));
|
||||
$accountNrMatch = false;
|
||||
/** @var AccountMeta $meta */
|
||||
|
@ -421,7 +421,8 @@ class General extends AbstractExtension
|
||||
return new TwigFunction(
|
||||
'getRootSearchOperator',
|
||||
static function (string $operator): string {
|
||||
return OperatorQuerySearch::getRootOperator($operator);
|
||||
$result = OperatorQuerySearch::getRootOperator($operator);
|
||||
return str_replace('-', 'not_', $result);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -327,14 +327,17 @@ return [
|
||||
'search_modifier_reconciled' => 'Transaction is reconciled',
|
||||
'search_modifier_not_reconciled' => 'Transaction is not reconciled',
|
||||
'search_modifier_id' => 'Transaction ID is ":value"',
|
||||
'search_modifier_not_id' => 'Transaction ID is not ":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_external_id_is' => 'External ID is ":value"',
|
||||
'search_modifier_not_external_id_is' => 'External ID is not ":value"',
|
||||
'search_modifier_no_external_url' => 'The transaction has no external URL',
|
||||
'search_modifier_not_any_external_url' => 'The transaction has no external URL',
|
||||
'search_modifier_any_external_url' => 'The transaction must have a (any) external URL',
|
||||
'search_modifier_not_no_external_url' => 'The transaction must have a (any) external URL',
|
||||
'search_modifier_internal_reference_is' => 'Internal reference is ":value"',
|
||||
'search_modifier_not_internal_reference_is' => 'Internal reference is not ":value"',
|
||||
'search_modifier_description_starts' => 'Description starts with ":value"',
|
||||
'search_modifier_not_description_starts' => 'Description does not start with ":value"',
|
||||
'search_modifier_description_ends' => 'Description ends on ":value"',
|
||||
@ -395,6 +398,7 @@ return [
|
||||
'search_modifier_source_account_nr_is' => 'Source account number (IBAN) is ":value"',
|
||||
'search_modifier_not_source_account_nr_is' => 'Source account number (IBAN) is not ":value"',
|
||||
'search_modifier_source_account_nr_contains' => 'Source account number (IBAN) contains ":value"',
|
||||
'search_modifier_not_source_account_nr_contains' => 'Source account number (IBAN) does not contain ":value"',
|
||||
'search_modifier_source_account_nr_starts' => 'Source account number (IBAN) starts with ":value"',
|
||||
'search_modifier_not_source_account_nr_starts' => 'Source account number (IBAN) does not start with ":value"',
|
||||
'search_modifier_source_account_nr_ends' => 'Source account number (IBAN) ends on ":value"',
|
||||
@ -414,6 +418,7 @@ return [
|
||||
'search_modifier_source_is_cash' => 'Source account is the "(cash)" account',
|
||||
'search_modifier_not_source_is_cash' => 'Source account is not the "(cash)" account',
|
||||
'search_modifier_destination_account_nr_is' => 'Destination account number (IBAN) is ":value"',
|
||||
'search_modifier_not_destination_account_nr_is' => 'Destination account number (IBAN) is ":value"',
|
||||
'search_modifier_destination_account_nr_contains' => 'Destination account number (IBAN) contains ":value"',
|
||||
'search_modifier_not_destination_account_nr_contains' => 'Destination account number (IBAN) does not contain ":value"',
|
||||
'search_modifier_destination_account_nr_starts' => 'Destination account number (IBAN) starts with ":value"',
|
||||
@ -429,6 +434,7 @@ return [
|
||||
'search_modifier_bill_is' => 'Bill is ":value"',
|
||||
'search_modifier_not_bill_is' => 'Bill is not ":value"',
|
||||
'search_modifier_transaction_type' => 'Transaction type is ":value"',
|
||||
'search_modifier_not_transaction_type' => 'Transaction type is not ":value"',
|
||||
'search_modifier_tag_is' => 'Tag is ":value"',
|
||||
'search_modifier_not_tag_is' => 'No tag is ":value"',
|
||||
'search_modifier_date_on_year' => 'Transaction is in year ":value"',
|
||||
@ -469,6 +475,7 @@ return [
|
||||
'search_modifier_category_ends' => 'Category ends on ":value"',
|
||||
'search_modifier_not_category_ends' => 'Category does not end on ":value"',
|
||||
'search_modifier_category_starts' => 'Category starts with ":value"',
|
||||
'search_modifier_not_category_starts' => 'Category does not start with ":value"',
|
||||
'search_modifier_budget_contains' => 'Budget contains ":value"',
|
||||
'search_modifier_not_budget_contains' => 'Budget does not contain ":value"',
|
||||
'search_modifier_budget_ends' => 'Budget ends with ":value"',
|
||||
@ -482,15 +489,25 @@ return [
|
||||
'search_modifier_bill_starts' => 'Bill starts with ":value"',
|
||||
'search_modifier_not_bill_starts' => 'Bill does not start with ":value"',
|
||||
'search_modifier_external_id_contains' => 'External ID contains ":value"',
|
||||
'search_modifier_not_external_id_contains' => 'External ID does not contain ":value"',
|
||||
'search_modifier_external_id_ends' => 'External ID ends with ":value"',
|
||||
'search_modifier_not_external_id_ends' => 'External ID does not end with ":value"',
|
||||
'search_modifier_external_id_starts' => 'External ID starts with ":value"',
|
||||
'search_modifier_not_external_id_starts' => 'External ID does not start with ":value"',
|
||||
'search_modifier_internal_reference_contains' => 'Internal reference contains ":value"',
|
||||
'search_modifier_not_internal_reference_contains' => 'Internal reference does not contain ":value"',
|
||||
'search_modifier_internal_reference_ends' => 'Internal reference ends with ":value"',
|
||||
'search_modifier_internal_reference_starts' => 'Internal reference starts with ":value"',
|
||||
'search_modifier_not_internal_reference_ends' => 'Internal reference does not end with ":value"',
|
||||
'search_modifier_not_internal_reference_starts' => 'Internal reference does not start with ":value"',
|
||||
'search_modifier_external_url_is' => 'External URL is ":value"',
|
||||
'search_modifier_not_external_url_is' => 'External URL is not ":value"',
|
||||
'search_modifier_external_url_contains' => 'External URL contains ":value"',
|
||||
'search_modifier_not_external_url_contains' => 'External URL does not ":value"',
|
||||
'search_modifier_external_url_ends' => 'External URL ends with ":value"',
|
||||
'search_modifier_not_external_url_ends' => 'External URL does not end with ":value"',
|
||||
'search_modifier_external_url_starts' => 'External URL starts with ":value"',
|
||||
'search_modifier_not_external_url_starts' => 'External URL does not start with ":value"',
|
||||
'search_modifier_has_no_attachments' => 'Transaction has no attachments',
|
||||
'search_modifier_not_has_no_attachments' => 'Transaction has attachments',
|
||||
'search_modifier_not_has_attachments' => 'Transaction has no attachments',
|
||||
@ -499,12 +516,15 @@ return [
|
||||
'search_modifier_journal_id' => 'The journal ID is ":value"',
|
||||
'search_modifier_not_journal_id' => 'The journal ID is not ":value"',
|
||||
'search_modifier_recurrence_id' => 'The recurring transaction ID is ":value"',
|
||||
'search_modifier_not_recurrence_id' => 'The recurring transaction ID is not ":value"',
|
||||
'search_modifier_foreign_amount_is' => 'The foreign amount is ":value"',
|
||||
'search_modifier_not_foreign_amount_is' => 'The foreign amount is not ":value"',
|
||||
'search_modifier_foreign_amount_less' => 'The foreign amount is less than ":value"',
|
||||
'search_modifier_not_foreign_amount_more' => 'The foreign amount is less than ":value"',
|
||||
'search_modifier_not_foreign_amount_less' => 'The foreign amount is more than ":value"',
|
||||
'search_modifier_foreign_amount_more' => 'The foreign amount is more than ":value"',
|
||||
'search_modifier_exists' => 'Transaction exists (any transaction)',
|
||||
'search_modifier_not_exists' => 'Transaction does not exist (no transaction)',
|
||||
|
||||
// date fields
|
||||
'search_modifier_interest_date_on' => 'Transaction interest date is ":value"',
|
||||
@ -644,7 +664,15 @@ return [
|
||||
'search_modifier_attachment_notes_are' => 'Any attachment\'s notes are ":value"',
|
||||
'search_modifier_attachment_notes_contains' => 'Any attachment\'s notes contain ":value"',
|
||||
'search_modifier_attachment_notes_starts' => 'Any attachment\'s notes start with ":value"',
|
||||
'search_modifier_attachment_notes_ends' => 'Any attachment\'s notes end is ":value"',
|
||||
'search_modifier_attachment_notes_ends' => 'Any attachment\'s notes end with ":value"',
|
||||
'search_modifier_not_attachment_name_is' => 'Any attachment\'s name is not ":value"',
|
||||
'search_modifier_not_attachment_name_contains' => 'Any attachment\'s name does not contain ":value"',
|
||||
'search_modifier_not_attachment_name_starts' => 'Any attachment\'s name does not start with ":value"',
|
||||
'search_modifier_not_attachment_name_ends' => 'Any attachment\'s name does not end with ":value"',
|
||||
'search_modifier_not_attachment_notes_are' => 'Any attachment\'s notes are not ":value"',
|
||||
'search_modifier_not_attachment_notes_contains' => 'Any attachment\'s notes do not contain ":value"',
|
||||
'search_modifier_not_attachment_notes_starts' => 'Any attachment\'s notes start with ":value"',
|
||||
'search_modifier_not_attachment_notes_ends' => 'Any attachment\'s notes do not end with ":value"',
|
||||
'update_rule_from_query' => 'Update rule ":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.',
|
||||
@ -1001,6 +1029,136 @@ return [
|
||||
'rule_trigger_exists_choice' => 'Any transaction matches(!)',
|
||||
'rule_trigger_exists' => 'Any transaction matches',
|
||||
|
||||
// more values for new types:
|
||||
'rule_trigger_not_account_id' => 'Account ID is not ":trigger_value"',
|
||||
'rule_trigger_not_source_account_id' => 'Source account ID is not ":trigger_value"',
|
||||
'rule_trigger_not_destination_account_id' => 'Destination account ID is not ":trigger_value"',
|
||||
'rule_trigger_not_transaction_type' => 'Transaction type is not ":trigger_value"',
|
||||
'rule_trigger_not_tag_is' => 'Tag is not ":trigger_value"',
|
||||
'rule_trigger_not_tag_is_not' => 'Tag is ":trigger_value"',
|
||||
'rule_trigger_not_description_is' => 'Description is not ":trigger_value"',
|
||||
'rule_trigger_not_description_contains' => 'Description does not contain',
|
||||
'rule_trigger_not_description_ends' => 'Description does not end with ":trigger_value"',
|
||||
'rule_trigger_not_description_starts' => 'Description does not start with ":trigger_value"',
|
||||
'rule_trigger_not_notes_is' => 'Notes are not ":trigger_value"',
|
||||
'rule_trigger_not_notes_contains' => 'Notes do not contain ":trigger_value"',
|
||||
'rule_trigger_not_notes_ends' => 'Notes do not end on ":trigger_value"',
|
||||
'rule_trigger_not_notes_starts' => 'Notes do not start with ":trigger_value"',
|
||||
'rule_trigger_not_source_account_is' => 'Source account is not ":trigger_value"',
|
||||
'rule_trigger_not_source_account_contains' => 'Source account does not contain ":trigger_value"',
|
||||
'rule_trigger_not_source_account_ends' => 'Source account does not end on ":trigger_value"',
|
||||
'rule_trigger_not_source_account_starts' => 'Source account does not start with ":trigger_value"',
|
||||
'rule_trigger_not_source_account_nr_is' => 'Source account number / IBAN is not ":trigger_value"',
|
||||
'rule_trigger_not_source_account_nr_contains' => 'Source account number / IBAN does not contain ":trigger_value"',
|
||||
'rule_trigger_not_source_account_nr_ends' => 'Source account number / IBAN does not end on ":trigger_value"',
|
||||
'rule_trigger_not_source_account_nr_starts' => 'Source account number / IBAN does not start with ":trigger_value"',
|
||||
'rule_trigger_not_destination_account_is' => 'Destination account is not ":trigger_value"',
|
||||
'rule_trigger_not_destination_account_contains' => 'Destination account does not contain ":trigger_value"',
|
||||
'rule_trigger_not_destination_account_ends' => 'Destination account does not end on ":trigger_value"',
|
||||
'rule_trigger_not_destination_account_starts' => 'Destination account does not start with ":trigger_value"',
|
||||
'rule_trigger_not_destination_account_nr_is' => 'Destination account number / IBAN is not ":trigger_value"',
|
||||
'rule_trigger_not_destination_account_nr_contains' => 'Destination account number / IBAN does not contain ":trigger_value"',
|
||||
'rule_trigger_not_destination_account_nr_ends' => 'Destination account number / IBAN does not end on ":trigger_value"',
|
||||
'rule_trigger_not_destination_account_nr_starts' => 'Destination account number / IBAN does not start with ":trigger_value"',
|
||||
'rule_trigger_not_account_is' => 'Neither account is ":trigger_value"',
|
||||
'rule_trigger_not_account_contains' => 'Neither account contains ":trigger_value"',
|
||||
'rule_trigger_not_account_ends' => 'Neither account ends on ":trigger_value"',
|
||||
'rule_trigger_not_account_starts' => 'Neither account starts with ":trigger_value"',
|
||||
'rule_trigger_not_account_nr_is' => 'Neither account number / IBAN is ":trigger_value"',
|
||||
'rule_trigger_not_account_nr_contains' => 'Neither account number / IBAN contains ":trigger_value"',
|
||||
'rule_trigger_not_account_nr_ends' => 'Neither account number / IBAN ends on ":trigger_value"',
|
||||
'rule_trigger_not_account_nr_starts' => 'Neither account number / IBAN starts with ":trigger_value"',
|
||||
'rule_trigger_not_category_is' => 'Neither category is ":trigger_value"',
|
||||
'rule_trigger_not_category_contains' => 'Neither category contains ":trigger_value"',
|
||||
'rule_trigger_not_category_ends' => 'Neither category ends on ":trigger_value"',
|
||||
'rule_trigger_not_category_starts' => 'Neither category starts with ":trigger_value"',
|
||||
'rule_trigger_not_budget_is' => 'Neither budget is ":trigger_value"',
|
||||
'rule_trigger_not_budget_contains' => 'Neither budget contains ":trigger_value"',
|
||||
'rule_trigger_not_budget_ends' => 'Neither budget ends on ":trigger_value"',
|
||||
'rule_trigger_not_budget_starts' => 'Neither budget starts with ":trigger_value"',
|
||||
'rule_trigger_not_bill_is' => 'Neither bill is ":trigger_value"',
|
||||
'rule_trigger_not_bill_contains' => 'Neither bill contains ":trigger_value"',
|
||||
'rule_trigger_not_bill_ends' => 'Neither bill ends on ":trigger_value"',
|
||||
'rule_trigger_not_bill_starts' => 'Neither bill starts with ":trigger_value"',
|
||||
'rule_trigger_not_external_id_is' => 'External ID is not ":trigger_value"',
|
||||
'rule_trigger_not_external_id_contains' => 'External ID does not contain ":trigger_value"',
|
||||
'rule_trigger_not_external_id_ends' => 'External ID does not end on ":trigger_value"',
|
||||
'rule_trigger_not_external_id_starts' => 'External ID does not start with ":trigger_value"',
|
||||
'rule_trigger_not_internal_reference_is' => 'Internal reference is not ":trigger_value"',
|
||||
'rule_trigger_not_internal_reference_contains' => 'Internal reference does not contain ":trigger_value"',
|
||||
'rule_trigger_not_internal_reference_ends' => 'Internal reference does not end on ":trigger_value"',
|
||||
'rule_trigger_not_internal_reference_starts' => 'Internal reference does not start with ":trigger_value"',
|
||||
'rule_trigger_not_external_url_is' => 'External URL is not ":trigger_value"',
|
||||
'rule_trigger_not_external_url_contains' => 'External URL does not contain ":trigger_value"',
|
||||
'rule_trigger_not_external_url_ends' => 'External URL does not end on ":trigger_value"',
|
||||
'rule_trigger_not_external_url_starts' => 'External URL does not start with ":trigger_value"',
|
||||
'rule_trigger_not_currency_is' => 'Currency is not ":trigger_value"',
|
||||
'rule_trigger_not_foreign_currency_is' => 'Foreign currency is not ":trigger_value"',
|
||||
'rule_trigger_not_id' => 'Transaction ID is not ":trigger_value"',
|
||||
'rule_trigger_not_journal_id' => 'Transaction journal ID is not ":trigger_value"',
|
||||
'rule_trigger_not_recurrence_id' => 'Recurrence ID is not ":trigger_value"',
|
||||
'rule_trigger_not_date_on' => 'Date is not on ":trigger_value"',
|
||||
'rule_trigger_not_date_before' => 'Date is not before ":trigger_value"',
|
||||
'rule_trigger_not_date_after' => 'Date is not after ":trigger_value"',
|
||||
'rule_trigger_not_interest_date_on' => 'Interest date is not on ":trigger_value"',
|
||||
'rule_trigger_not_interest_date_before' => 'Interest date is not before ":trigger_value"',
|
||||
'rule_trigger_not_interest_date_after' => 'Interest date is not after ":trigger_value"',
|
||||
'rule_trigger_not_book_date_on' => 'Book date is not on ":trigger_value"',
|
||||
'rule_trigger_not_book_date_before' => 'Book date is not before ":trigger_value"',
|
||||
'rule_trigger_not_book_date_after' => 'Book date is not after ":trigger_value"',
|
||||
'rule_trigger_not_process_date_on' => 'Process date is not on ":trigger_value"',
|
||||
'rule_trigger_not_process_date_before' => 'Process date is not before ":trigger_value"',
|
||||
'rule_trigger_not_process_date_after' => 'Process date is not after ":trigger_value"',
|
||||
'rule_trigger_not_due_date_on' => 'Due date is not on ":trigger_value"',
|
||||
'rule_trigger_not_due_date_before' => 'Due date is not before ":trigger_value"',
|
||||
'rule_trigger_not_due_date_after' => 'Due date is not after ":trigger_value"',
|
||||
'rule_trigger_not_payment_date_on' => 'Payment date is not on ":trigger_value"',
|
||||
'rule_trigger_not_payment_date_before' => 'Payment date is not before ":trigger_value"',
|
||||
'rule_trigger_not_payment_date_after' => 'Payment date is not after ":trigger_value"',
|
||||
'rule_trigger_not_invoice_date_on' => 'Invoice date is not on ":trigger_value"',
|
||||
'rule_trigger_not_invoice_date_before' => 'Invoice date is not before ":trigger_value"',
|
||||
'rule_trigger_not_invoice_date_after' => 'Invoice date is not after ":trigger_value"',
|
||||
'rule_trigger_not_created_at_on' => 'Transaction is not created on ":trigger_value"',
|
||||
'rule_trigger_not_created_at_before' => 'Transaction is not created before ":trigger_value"',
|
||||
'rule_trigger_not_created_at_after' => 'Transaction is not created after ":trigger_value"',
|
||||
'rule_trigger_not_updated_at_on' => 'Transaction is not updated on ":trigger_value"',
|
||||
'rule_trigger_not_updated_at_before' => 'Transaction is not updated before ":trigger_value"',
|
||||
'rule_trigger_not_updated_at_after' => 'Transaction is not updated after ":trigger_value"',
|
||||
'rule_trigger_not_amount_is' => 'Transaction amount is not ":trigger_value"',
|
||||
'rule_trigger_not_amount_less' => 'Transaction amount is more than ":trigger_value"',
|
||||
'rule_trigger_not_amount_more' => 'Transaction amount is less than ":trigger_value"',
|
||||
'rule_trigger_not_foreign_amount_is' => 'Foreign transaction amount is not ":trigger_value"',
|
||||
'rule_trigger_not_foreign_amount_less' => 'Foreign transaction amount is more than ":trigger_value"',
|
||||
'rule_trigger_not_foreign_amount_more' => 'Foreign transaction amount is less than ":trigger_value"',
|
||||
'rule_trigger_not_attachment_name_is' => 'No attachment is named ":trigger_value"',
|
||||
'rule_trigger_not_attachment_name_contains' => 'No attachment name contains ":trigger_value"',
|
||||
'rule_trigger_not_attachment_name_starts' => 'No attachment name starts with ":trigger_value"',
|
||||
'rule_trigger_not_attachment_name_ends' => 'No attachment name ends on ":trigger_value"',
|
||||
'rule_trigger_not_attachment_notes_are' => 'No attachment notes are ":trigger_value"',
|
||||
'rule_trigger_not_attachment_notes_contains' => 'No attachment notes contain ":trigger_value"',
|
||||
'rule_trigger_not_attachment_notes_starts' => 'No attachment notes start with ":trigger_value"',
|
||||
'rule_trigger_not_attachment_notes_ends' => 'No attachment notes end on ":trigger_value"',
|
||||
'rule_trigger_not_reconciled' => 'Transaction is not reconciled',
|
||||
'rule_trigger_not_exists' => 'Transaction does not exist',
|
||||
'rule_trigger_not_has_attachments' => 'Transaction has no attachments',
|
||||
'rule_trigger_not_has_any_category' => 'Transaction has no category',
|
||||
'rule_trigger_not_has_any_budget' => 'Transaction has no category',
|
||||
'rule_trigger_not_has_any_bill' => 'Transaction has no bill',
|
||||
'rule_trigger_not_has_any_tag' => 'Transaction has no tags',
|
||||
'rule_trigger_not_any_notes' => 'Transaction has no notes',
|
||||
'rule_trigger_not_any_external_url' => 'Transaction has no external URL',
|
||||
'rule_trigger_not_has_no_attachments' => 'Transaction has a (any) attachment(s)',
|
||||
'rule_trigger_not_has_no_category' => 'Transaction has a (any) category',
|
||||
'rule_trigger_not_has_no_budget' => 'Transaction has a (any) budget',
|
||||
'rule_trigger_not_has_no_bill' => 'Transaction has a (any) bill',
|
||||
'rule_trigger_not_has_no_tag' => 'Transaction has a (any) tag',
|
||||
'rule_trigger_not_no_notes' => 'Transaction has any notes',
|
||||
'rule_trigger_not_no_external_url' => 'Transaction has an external URL',
|
||||
'rule_trigger_not_source_is_cash' => 'Source account is a not a cash account',
|
||||
'rule_trigger_not_destination_is_cash' => 'Destination account is a not a cash account',
|
||||
'rule_trigger_not_account_is_cash' => 'Neither account is a cash account',
|
||||
|
||||
|
||||
// actions
|
||||
'rule_action_delete_transaction_choice' => 'DELETE transaction(!)',
|
||||
'rule_action_delete_transaction' => 'DELETE transaction(!)',
|
||||
|
Loading…
Reference in New Issue
Block a user