diff --git a/app/Helpers/Collector/Extensions/MetaCollection.php b/app/Helpers/Collector/Extensions/MetaCollection.php index 98fdb9abb9..a8717bb424 100644 --- a/app/Helpers/Collector/Extensions/MetaCollection.php +++ b/app/Helpers/Collector/Extensions/MetaCollection.php @@ -44,10 +44,7 @@ trait MetaCollection */ public function externalIdContains(string $externalId): GroupCollectorInterface { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - } + $this->joinMetaDataTables(); $this->query->where('journal_meta.name', '=', 'external_id'); $this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $externalId)); @@ -59,10 +56,7 @@ trait MetaCollection */ public function externalIdEnds(string $externalId): GroupCollectorInterface { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - } + $this->joinMetaDataTables(); $this->query->where('journal_meta.name', '=', 'external_id'); $this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s"', $externalId)); @@ -74,10 +68,7 @@ trait MetaCollection */ public function externalIdStarts(string $externalId): GroupCollectorInterface { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - } + $this->joinMetaDataTables(); $this->query->where('journal_meta.name', '=', 'external_id'); $this->query->where('journal_meta.data', 'LIKE', sprintf('"%s%%', $externalId)); @@ -129,15 +120,24 @@ trait MetaCollection } /** - * @inheritDoc + * Join table to get tag information. */ - public function setExternalUrl(string $url): GroupCollectorInterface + protected function joinMetaDataTables(): void { if (false === $this->hasJoinedMetaTables) { $this->hasJoinedMetaTables = true; $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); + $this->fields[] = 'journal_meta.name as meta_name'; + $this->fields[] = 'journal_meta.data as meta_data'; } + } + /** + * @inheritDoc + */ + public function setExternalUrl(string $url): GroupCollectorInterface + { + $this->joinMetaDataTables(); $this->query->where('journal_meta.name', '=', 'external_url'); $this->query->where('journal_meta.data', '=', json_encode($url)); @@ -150,10 +150,7 @@ trait MetaCollection */ public function externalUrlContains(string $url): GroupCollectorInterface { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - } + $this->joinMetaDataTables(); $url = json_encode($url); $url = str_replace('\\', '\\\\', trim($url, '"')); $this->query->where('journal_meta.name', '=', 'external_url'); @@ -168,10 +165,7 @@ trait MetaCollection */ public function externalUrlEnds(string $url): GroupCollectorInterface { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - } + $this->joinMetaDataTables(); $url = json_encode($url); $url = str_replace('\\', '\\\\', ltrim($url, '"')); $this->query->where('journal_meta.name', '=', 'external_url'); @@ -186,10 +180,7 @@ trait MetaCollection */ public function externalUrlStarts(string $url): GroupCollectorInterface { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - } + $this->joinMetaDataTables(); $url = json_encode($url); $url = str_replace('\\', '\\\\', rtrim($url, '"')); //var_dump($url); @@ -205,10 +196,7 @@ trait MetaCollection */ public function internalReferenceContains(string $externalId): GroupCollectorInterface { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - } + $this->joinMetaDataTables(); $this->query->where('journal_meta.name', '=', 'internal_reference'); $this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $externalId)); @@ -220,10 +208,7 @@ trait MetaCollection */ public function internalReferenceEnds(string $externalId): GroupCollectorInterface { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - } + $this->joinMetaDataTables(); $this->query->where('journal_meta.name', '=', 'internal_reference'); $this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s"', $externalId)); @@ -235,10 +220,7 @@ trait MetaCollection */ public function internalReferenceStarts(string $externalId): GroupCollectorInterface { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - } + $this->joinMetaDataTables(); $this->query->where('journal_meta.name', '=', 'internal_reference'); $this->query->where('journal_meta.data', 'LIKE', sprintf('"%s%%', $externalId)); @@ -480,25 +462,31 @@ trait MetaCollection */ public function setExternalId(string $externalId): GroupCollectorInterface { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - } + $this->joinMetaDataTables(); $this->query->where('journal_meta.name', '=', 'external_id'); $this->query->where('journal_meta.data', '=', sprintf('%s', json_encode($externalId))); return $this; } + /** + * @inheritDoc + */ + public function setRecurrenceId(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; + } + /** * @inheritDoc */ public function setInternalReference(string $internalReference): GroupCollectorInterface { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - } + $this->joinMetaDataTables(); $this->query->where('journal_meta.name', '=', 'internal_reference'); $this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $internalReference)); @@ -620,10 +608,7 @@ trait MetaCollection */ public function withExternalUrl(): GroupCollectorInterface { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - } + $this->joinMetaDataTables(); $this->query->where('journal_meta.name', '=', 'external_url'); $this->query->whereNotNull('journal_meta.data'); @@ -673,16 +658,16 @@ trait MetaCollection */ public function withoutExternalUrl(): GroupCollectorInterface { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - } + $this->joinMetaDataTables(); + // TODO not sure if this will work properly. $this->query->where(function (Builder $q1) { $q1->where(function (Builder $q2) { $q2->where('journal_meta.name', '=', 'external_url'); $q2->whereNull('journal_meta.data'); })->orWhere(function (Builder $q3) { $q3->where('journal_meta.name', '!=', 'external_url'); + })->orWhere(function (Builder $q4) { + $q4->whereNull('journal_meta.name'); }); }); diff --git a/app/Helpers/Collector/Extensions/TimeCollection.php b/app/Helpers/Collector/Extensions/TimeCollection.php index fd238b7f81..22ff48ee29 100644 --- a/app/Helpers/Collector/Extensions/TimeCollection.php +++ b/app/Helpers/Collector/Extensions/TimeCollection.php @@ -142,6 +142,49 @@ trait TimeCollection return $this; } + /** + * @param Carbon $start + * @param Carbon $end + * @param string $field + * @return GroupCollectorInterface + */ + public function setMetaDateRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface + { + if ($end < $start) { + [$start, $end] = [$end, $start]; + } + $end = clone $end; // this is so weird, but it works if $end and $start secretly point to the same object. + $end->endOfDay(); + $start->startOfDay(); + $this->withMetaDate($field); + + $filter = function (int $index, array $object) use ($field, $start, $end): bool { + foreach ($object['transactions'] as $transaction) { + if (array_key_exists('interest_date', $transaction) && $transaction['interest_date'] instanceof Carbon + ) { + return $transaction['interest_date']->gte($start) && $transaction['interest_date']->lte($end); + } + } + + return true; + }; + $this->postFilters[] = $filter; + return $this; + + } + + /** + * @inheritDoc + */ + public function withMetaDate(string $field): GroupCollectorInterface + { + $this->joinMetaDataTables(); + $this->query->where('journal_meta.name', '=', $field); + $this->query->whereNotNull('journal_meta.data'); + + return $this; + } + /** * Collect transactions updated on a specific date. * diff --git a/app/Helpers/Collector/GroupCollector.php b/app/Helpers/Collector/GroupCollector.php index 257f1ab0e9..6004f7639e 100644 --- a/app/Helpers/Collector/GroupCollector.php +++ b/app/Helpers/Collector/GroupCollector.php @@ -339,9 +339,15 @@ class GroupCollector implements GroupCollectorInterface */ private function parseAugmentedJournal(TransactionJournal $augumentedJournal): array { - $result = $augumentedJournal->toArray(); - $result['tags'] = []; - $result['attachments'] = []; + $result = $augumentedJournal->toArray(); + $result['tags'] = []; + $result['attachments'] = []; + $result['interest_date'] = null; + $result['payment_date'] = null; + $result['invoice_date'] = null; + $result['book_date'] = null; + $result['due_date'] = null; + $result['process_date'] = null; try { $result['date'] = new Carbon($result['date'], 'UTC'); $result['created_at'] = new Carbon($result['created_at'], 'UTC'); @@ -355,6 +361,15 @@ class GroupCollector implements GroupCollectorInterface Log::error($e->getMessage()); } + // try to process meta date value (if present) + $dates = ['interest_date', 'payment_date', 'invoice_date', 'book_date', 'due_date', 'process_date']; + if (array_key_exists('meta_name', $result) && in_array($result['meta_name'], $dates, true)) { + $name = $result['meta_name']; + if (array_key_exists('meta_data', $result) && '' !== (string) $result['meta_data']) { + $result[$name] = Carbon::createFromFormat('!Y-m-d', substr(json_decode($result['meta_data']), 0, 10)); + } + } + // convert values to integers: $result = $this->convertToInteger($result); @@ -387,7 +402,7 @@ 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']); + unset($result['tag_id'],$result['meta_data'], $result['meta_name'], $result['tag_name'], $result['tag_date'], $result['tag_description'], $result['tag_latitude'], $result['tag_longitude'], $result['tag_zoom_level']); return $result; } @@ -515,7 +530,7 @@ class GroupCollector implements GroupCollectorInterface 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())); + Log::debug(sprintf('Now working on item #%d/%d', (int) $i + 1, $collection->count())); foreach ($this->postFilters as $func) { if (false === $func($i, $item)) { // skip other filters, continue to next item. @@ -573,6 +588,20 @@ class GroupCollector implements GroupCollectorInterface return $this; } + /** + * Has attachments + * + * @return GroupCollectorInterface + */ + public function hasNoAttachments(): GroupCollectorInterface + { + Log::debug('Add filter on no attachments.'); + $this->joinAttachmentTables(); + $this->query->whereNull('attachments.attachable_id'); + + return $this; + } + /** * Join table to get attachment information. */ diff --git a/app/Helpers/Collector/GroupCollectorInterface.php b/app/Helpers/Collector/GroupCollectorInterface.php index 82dfcfb992..cf42d881d4 100644 --- a/app/Helpers/Collector/GroupCollectorInterface.php +++ b/app/Helpers/Collector/GroupCollectorInterface.php @@ -205,6 +205,13 @@ interface GroupCollectorInterface */ public function hasAttachments(): GroupCollectorInterface; + /** + * Has no attachments + * + * @return GroupCollectorInterface + */ + public function hasNoAttachments(): GroupCollectorInterface; + /** * @param string $externalId * @return GroupCollectorInterface @@ -395,6 +402,15 @@ interface GroupCollectorInterface */ public function setExternalId(string $externalId): GroupCollectorInterface; + /** + * Look for specific recurring ID's. + * + * @param string $recurringId + * + * @return GroupCollectorInterface + */ + public function setRecurrenceId(string $recurringId): GroupCollectorInterface; + /** * Limit results to a specific foreign currency. * @@ -459,6 +475,17 @@ interface GroupCollectorInterface */ public function setRange(Carbon $start, Carbon $end): GroupCollectorInterface; + /** + * Set the start and end time of the results to return, based on meta data. + * + * @param Carbon $start + * @param Carbon $end + * @param string $field + * + * @return GroupCollectorInterface + */ + public function setMetaDateRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface; + /** * Search for words in descriptions. * @@ -626,6 +653,14 @@ interface GroupCollectorInterface */ public function withExternalUrl(): GroupCollectorInterface; + /** + * Transaction must have meta date field X. + * + * @param string $field + * @return GroupCollectorInterface + */ + public function withMetaDate(string $field): GroupCollectorInterface; + /** * @param string $url * @return GroupCollectorInterface diff --git a/app/Support/Search/OperatorQuerySearch.php b/app/Support/Search/OperatorQuerySearch.php index 2f45c8986a..d40190102d 100644 --- a/app/Support/Search/OperatorQuerySearch.php +++ b/app/Support/Search/OperatorQuerySearch.php @@ -152,7 +152,7 @@ class OperatorQuerySearch implements SearchInterface */ public function parseQuery(string $query) { - Log::debug(sprintf('Now in parseQuery(%s)', $query)); + Log::debug(sprintf ('Now in parseQuery(%s)', $query)); $parser = new QueryParser(); try { $query1 = $parser->parse($query); @@ -496,6 +496,10 @@ class OperatorQuerySearch implements SearchInterface Log::debug('Set collector to filter on attachments.'); $this->collector->hasAttachments(); break; + case 'has_no_attachments': + Log::debug('Set collector to filter on NO attachments.'); + $this->collector->hasNoAttachments(); + break; // // categories case 'has_no_category': @@ -711,7 +715,7 @@ class OperatorQuerySearch implements SearchInterface // // dates // - case 'date_is': + case 'date_on': $range = $this->parseDateRange($value); $this->setExactDateParams($range); return false; @@ -723,6 +727,10 @@ class OperatorQuerySearch implements SearchInterface $range = $this->parseDateRange($value); $this->setDateAfterParams($range); return false; + case 'interest_date_on': + $range = $this->parseDateRange($value); + $this->setExactMetaDateParams('interest_date', $range); + break; case 'created_on': Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value)); $createdAt = new Carbon($value); @@ -760,6 +768,9 @@ class OperatorQuerySearch implements SearchInterface case 'external_id_is': $this->collector->setExternalId($value); break; + case 'recurrence_id': + $this->collector->setRecurrenceId($value); + break; case 'external_id_contains': $this->collector->externalIdContains($value); break; @@ -1027,22 +1038,22 @@ class OperatorQuerySearch implements SearchInterface case 'exact': Log::debug(sprintf('Set date_is_exact value "%s"', $value->format('Y-m-d'))); $this->collector->setRange($value, $value); - $this->operators->push(['type' => 'date_is', 'value' => $value->format('Y-m-d'),]); + $this->operators->push(['type' => 'date_on', 'value' => $value->format('Y-m-d'),]); break; case 'year': Log::debug(sprintf('Set date_is_exact YEAR value "%s"', $value)); $this->collector->yearIs($value); - $this->operators->push(['type' => 'date_is_year', 'value' => $value,]); + $this->operators->push(['type' => 'date_on_year', 'value' => $value,]); break; case 'month': Log::debug(sprintf('Set date_is_exact MONTH value "%s"', $value)); $this->collector->monthIs($value); - $this->operators->push(['type' => 'date_is_month', 'value' => $value,]); + $this->operators->push(['type' => 'date_on_month', 'value' => $value,]); break; case 'day': Log::debug(sprintf('Set date_is_exact DAY value "%s"', $value)); $this->collector->dayIs($value); - $this->operators->push(['type' => 'date_is_day', 'value' => $value,]); + $this->operators->push(['type' => 'date_on_day', 'value' => $value,]); break; } } @@ -1123,4 +1134,45 @@ class OperatorQuerySearch implements SearchInterface } } } + + /** + * @param string $field + * @param array $range + * @return void + * @throws FireflyException + */ + private function setExactMetaDateParams(string $field, array $range): void + { + Log::debug('Now in setExactMetaDateParams()'); + /** + * @var string $key + * @var Carbon|string $value + */ + foreach ($range as $key => $value) { + switch ($key) { + default: + throw new FireflyException(sprintf('Cannot handle key "%s" in setExactParameters()', $key)); + case 'exact': + Log::debug(sprintf('Set %s_date_is_exact value "%s"', $field, $value->format('Y-m-d'))); + $this->collector->setMetaDateRange($value, $value,'interest_date'); + //$this->operators->push(['type' => sprintf('%s_on', $field), 'value' => $value->format('Y-m-d'),]); + break; + case 'year': + Log::debug(sprintf('Set date_is_exact YEAR value "%s"', $value)); + //$this->collector->yearIs($value); + $this->operators->push(['type' => sprintf('%s_on_year', $field), 'value' => $value,]); + break; + case 'month': + Log::debug(sprintf('Set date_is_exact MONTH value "%s"', $value)); + //$this->collector->monthIs($value); + $this->operators->push(['type' => sprintf('%s_on_month', $field), 'value' => $value,]); + break; + case 'day': + Log::debug(sprintf('Set date_is_exact DAY value "%s"', $value)); + //$this->collector->dayIs($value); + $this->operators->push(['type' => sprintf('%s_on_day', $field), 'value' => $value,]); + break; + } + } + } } diff --git a/config/search.php b/config/search.php index c48e433bbd..afe1bb7794 100644 --- a/config/search.php +++ b/config/search.php @@ -85,13 +85,11 @@ return [ 'external_id' => ['alias' => true, 'alias_for' => 'external_id_contains', 'needs_context' => true,], 'external_id_ends' => ['alias' => false, 'needs_context' => true,], 'external_id_starts' => ['alias' => false, 'needs_context' => true,], - 'internal_reference_is' => ['alias' => false, 'needs_context' => true,], 'internal_reference_contains' => ['alias' => false, 'needs_context' => true,], 'internal_reference' => ['alias' => true, 'alias_for' => 'internal_reference_contains', 'needs_context' => true,], 'internal_reference_ends' => ['alias' => false, 'needs_context' => true,], 'internal_reference_starts' => ['alias' => false, 'needs_context' => true,], - 'external_url_is' => ['alias' => false, 'needs_context' => true,], 'external_url_contains' => ['alias' => false, 'needs_context' => true,], 'external_url' => ['alias' => true, 'alias_for' => 'external_url_contains', 'needs_context' => true,], @@ -99,12 +97,13 @@ return [ 'external_url_starts' => ['alias' => false, 'needs_context' => true,], 'has_attachments' => ['alias' => false, 'needs_context' => false,], 'has_any_category' => ['alias' => false, 'needs_context' => false,], - // TODO here we are 'has_any_budget' => ['alias' => false, 'needs_context' => false,], 'has_any_bill' => ['alias' => false, 'needs_context' => false,], 'has_any_tag' => ['alias' => false, 'needs_context' => false,], 'any_notes' => ['alias' => false, 'needs_context' => false,], + 'has_any_notes' => ['alias' => true, 'alias_for' => 'any_notes', 'needs_context' => false,], 'any_external_url' => ['alias' => false, 'needs_context' => false,], + 'has_any_external_url' => ['alias' => true, 'alias_for' => 'any_external_url', 'needs_context' => false,], 'has_no_attachments' => ['alias' => false, 'needs_context' => false,], 'has_no_category' => ['alias' => false, 'needs_context' => false,], 'has_no_budget' => ['alias' => false, 'needs_context' => false,], @@ -128,6 +127,7 @@ return [ 'before' => ['alias' => true, 'alias_for' => 'date_before', 'needs_context' => true,], 'date_after' => ['alias' => false, 'needs_context' => true,], 'after' => ['alias' => true, 'alias_for' => 'date_after', 'needs_context' => true,], + 'interest_date_on' => ['alias' => false, 'needs_context' => true,], 'interest_date' => ['alias' => true, 'alias_for' => 'interest_date_on', 'needs_context' => true,], 'interest_date_is' => ['alias' => true, 'alias_for' => 'interest_date_on', 'needs_context' => true,], diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 41f8a7cbae..a9e633e9e9 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -285,7 +285,7 @@ return [ // old - 'search_modifier_date_is' => 'Transaction date is ":value"', + 'search_modifier_date_on' => 'Transaction date is ":value"', 'search_modifier_id' => 'Transaction ID is ":value"', 'search_modifier_date_before' => 'Transaction date is before or on ":value"', 'search_modifier_date_after' => 'Transaction date is after or on ":value"', @@ -393,6 +393,7 @@ return [ 'search_modifier_foreign_amount_more' => 'The foreign amount is more than ":value"', // date fields + 'search_modifier_interest_date_on' => 'Transaction interest date is ":value"', '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"', @@ -465,7 +466,29 @@ return [ '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"', - + 'search_modifier_interest_date_before' => 'Transaction interest date is before ":value"', + 'search_modifier_interest_date_after' => 'Transaction interest date is after ":value"', + 'search_modifier_book_date_on' => 'Transaction book date is on ":value"', + 'search_modifier_book_date_before' => 'Transaction book date is before ":value"', + 'search_modifier_book_date_after' => 'Transaction book date is after ":value"', + 'search_modifier_process_date_on' => 'Transaction process date is on ":value"', + 'search_modifier_process_date_before' => 'Transaction process date is before ":value"', + 'search_modifier_process_date_after' => 'Transaction process date is after ":value"', + 'search_modifier_due_date_on' => 'Transaction due date is on ":value"', + 'search_modifier_due_date_before' => 'Transaction due date is before ":value"', + 'search_modifier_due_date_after' => 'Transaction due date is after ":value"', + 'search_modifier_payment_date_on' => 'Transaction payment date is on ":value"', + 'search_modifier_payment_date_before' => 'Transaction payment date is before ":value"', + 'search_modifier_payment_date_after' => 'Transaction payment date is after ":value"', + 'search_modifier_invoice_date_on' => 'Transaction invoice date is on ":value"', + 'search_modifier_invoice_date_before' => 'Transaction invoice date is before ":value"', + 'search_modifier_invoice_date_after' => 'Transaction invoice date is after ":value"', + 'search_modifier_created_at_on' => 'Transaction was created on ":value"', + 'search_modifier_created_at_before' => 'Transaction was created before ":value"', + 'search_modifier_created_at_after' => 'Transaction was created after ":value"', + 'search_modifier_updated_at_on' => 'Transaction was updated on ":value"', + 'search_modifier_updated_at_before' => 'Transaction was updated before ":value"', + 'search_modifier_updated_at_after' => 'Transaction was updated after ":value"', 'update_rule_from_query' => 'Update rule ":rule" from search query', 'create_rule_from_query' => 'Create new rule from search query', diff --git a/resources/views/list/groups.twig b/resources/views/list/groups.twig index 436cf28129..fb58105820 100644 --- a/resources/views/list/groups.twig +++ b/resources/views/list/groups.twig @@ -65,7 +65,8 @@ {{ formatAmountBySymbol(sum.amount*-1, sum.currency_symbol, sum.currency_decimal_places, false) }}{% if loop.index != group.sums|length %},{% endif %}X {% else %} - {{ formatAmountBySymbol(sum.amount, sum.currency_symbol, sum.currency_decimal_places) }}{% if loop.index != group.sums|length %},{% endif %} + X + {# {{ formatAmountBySymbol(sum.amount, sum.currency_symbol, sum.currency_decimal_places) }}{% if loop.index != group.sums|length %},{% endif %} #} {% endif %} {% endfor %} @@ -196,7 +197,7 @@ {# THE REST #} {% else %} - {{ formatAmountBySymbol(transaction.amount, transaction.currency_symbol, transaction.currency_decimal_places) }} + {# {{ formatAmountBySymbol(transaction.amount, transaction.currency_symbol, transaction.currency_decimal_places) }} #} {% if null != transaction.foreign_amount %} ({{ formatAmountBySymbol(transaction.foreign_amount, transaction.foreign_currency_symbol, transaction.foreign_currency_decimal_places) }}) {% endif %}