diff --git a/app/Helpers/Collector/Extensions/AccountCollection.php b/app/Helpers/Collector/Extensions/AccountCollection.php index eb335150e2..3906b06fcc 100644 --- a/app/Helpers/Collector/Extensions/AccountCollection.php +++ b/app/Helpers/Collector/Extensions/AccountCollection.php @@ -34,6 +34,26 @@ use Illuminate\Support\Collection; trait AccountCollection { + /** + * These accounts must not be included. + * + * @param Collection $accounts + * + * @return GroupCollectorInterface + */ + public function excludeAccounts(Collection $accounts): GroupCollectorInterface + { + if ($accounts->count() > 0) { + $accountIds = $accounts->pluck('id')->toArray(); + $this->query->whereNotIn('source.account_id', $accountIds); + $this->query->whereNotIn('destination.account_id', $accountIds); + + app('log')->debug(sprintf('GroupCollector: excludeAccounts: %s', implode(', ', $accountIds))); + } + + return $this; + } + /** * These accounts must not be destination accounts. * @@ -72,26 +92,6 @@ trait AccountCollection return $this; } - /** - * These accounts must not be included. - * - * @param Collection $accounts - * - * @return GroupCollectorInterface - */ - public function excludeAccounts(Collection $accounts): GroupCollectorInterface - { - if ($accounts->count() > 0) { - $accountIds = $accounts->pluck('id')->toArray(); - $this->query->whereNotIn('source.account_id', $accountIds); - $this->query->whereNotIn('destination.account_id', $accountIds); - - app('log')->debug(sprintf('GroupCollector: excludeAccounts: %s', implode(', ', $accountIds))); - } - - return $this; - } - /** * Define which accounts can be part of the source and destination transactions. * @@ -115,29 +115,6 @@ trait AccountCollection return $this; } - /** - * Define which accounts can NOT be part of the source and destination transactions. - * - * @param Collection $accounts - * - * @return GroupCollectorInterface - */ - public function setNotAccounts(Collection $accounts): GroupCollectorInterface - { - if ($accounts->count() > 0) { - $accountIds = $accounts->pluck('id')->toArray(); - $this->query->where( - static function (EloquentBuilder $query) use ($accountIds) { - $query->whereNotIn('source.account_id', $accountIds); - $query->whereNotIn('destination.account_id', $accountIds); - } - ); - //app('log')->debug(sprintf('GroupCollector: setAccounts: %s', implode(', ', $accountIds))); - } - - return $this; - } - /** * Both source AND destination must be in this list of accounts. * @@ -180,6 +157,29 @@ trait AccountCollection return $this; } + /** + * Define which accounts can NOT be part of the source and destination transactions. + * + * @param Collection $accounts + * + * @return GroupCollectorInterface + */ + public function setNotAccounts(Collection $accounts): GroupCollectorInterface + { + if ($accounts->count() > 0) { + $accountIds = $accounts->pluck('id')->toArray(); + $this->query->where( + static function (EloquentBuilder $query) use ($accountIds) { + $query->whereNotIn('source.account_id', $accountIds); + $query->whereNotIn('destination.account_id', $accountIds); + } + ); + //app('log')->debug(sprintf('GroupCollector: setAccounts: %s', implode(', ', $accountIds))); + } + + return $this; + } + /** * Define which accounts can be part of the source and destination transactions. * diff --git a/app/Helpers/Collector/Extensions/AmountCollection.php b/app/Helpers/Collector/Extensions/AmountCollection.php index 93ce6cee8b..8f1e7c5b3c 100644 --- a/app/Helpers/Collector/Extensions/AmountCollection.php +++ b/app/Helpers/Collector/Extensions/AmountCollection.php @@ -58,7 +58,7 @@ trait AmountCollection { $this->query->where( static function (EloquentBuilder $q) use ($amount) { - $q->where('source.amount','!=', app('steam')->negative($amount)); + $q->where('source.amount', '!=', app('steam')->negative($amount)); } ); @@ -132,7 +132,7 @@ trait AmountCollection $this->query->where( static function (EloquentBuilder $q) use ($amount) { $q->whereNull('source.foreign_amount'); - $q->orWhere('source.foreign_amount','!=', app('steam')->negative($amount)); + $q->orWhere('source.foreign_amount', '!=', app('steam')->negative($amount)); } ); diff --git a/app/Helpers/Collector/Extensions/CollectorProperties.php b/app/Helpers/Collector/Extensions/CollectorProperties.php index 39c8e50b6a..3d5d7a37da 100644 --- a/app/Helpers/Collector/Extensions/CollectorProperties.php +++ b/app/Helpers/Collector/Extensions/CollectorProperties.php @@ -33,7 +33,6 @@ use Illuminate\Database\Eloquent\Relations\HasMany; trait CollectorProperties { private array $fields; - private array $stringFields; private bool $hasAccountInfo; private bool $hasBillInformation; private bool $hasBudgetInformation; @@ -47,6 +46,7 @@ trait CollectorProperties private ?int $page; private array $postFilters; private HasMany $query; + private array $stringFields; private int $total; private ?User $user; } diff --git a/app/Helpers/Collector/Extensions/MetaCollection.php b/app/Helpers/Collector/Extensions/MetaCollection.php index 835b981460..15113475f8 100644 --- a/app/Helpers/Collector/Extensions/MetaCollection.php +++ b/app/Helpers/Collector/Extensions/MetaCollection.php @@ -39,6 +39,90 @@ use Illuminate\Support\Collection; */ trait MetaCollection { + /** + * @inheritDoc + */ + public function excludeBills(Collection $bills): GroupCollectorInterface + { + $this->withBillInformation(); + $this->query->where(static function (EloquentBuilder $q1) use ($bills) { + $q1->whereNotIn('transaction_journals.bill_id', $bills->pluck('id')->toArray()); + $q1->orWhereNull('transaction_journals.bill_id'); + }); + + return $this; + } + + /** + * Exclude a specific budget. + * + * @param Budget $budget + * + * @return GroupCollectorInterface + */ + public function excludeBudget(Budget $budget): GroupCollectorInterface + { + $this->withBudgetInformation(); + + $this->query->where(static function (EloquentBuilder $q2) use ($budget) { + $q2->where('budgets.id', '!=', $budget->id); + $q2->orWhereNull('budgets.id'); + }); + + return $this; + } + + /** + * @inheritDoc + */ + public function excludeBudgets(Collection $budgets): GroupCollectorInterface + { + if ($budgets->count() > 0) { + $this->withBudgetInformation(); + $this->query->where(static function (EloquentBuilder $q1) use ($budgets) { + $q1->whereNotIn('budgets.id', $budgets->pluck('id')->toArray()); + $q1->orWhereNull('budgets.id'); + }); + } + + return $this; + } + + /** + * @inheritDoc + */ + public function excludeCategories(Collection $categories): GroupCollectorInterface + { + if ($categories->count() > 0) { + $this->withCategoryInformation(); + $this->query->where(static function (EloquentBuilder $q1) use ($categories) { + $q1->whereNotIn('categories.id', $categories->pluck('id')->toArray()); + $q1->orWhereNull('categories.id'); + }); + } + + return $this; + } + + /** + * Exclude a specific category. + * + * @param Category $category + * + * @return GroupCollectorInterface + */ + public function excludeCategory(Category $category): GroupCollectorInterface + { + $this->withCategoryInformation(); + + $this->query->where(static function (EloquentBuilder $q2) use ($category) { + $q2->where('categories.id', '!=', $category->id); + $q2->orWhereNull('categories.id'); + }); + + return $this; + } + /** * @inheritDoc */ @@ -227,6 +311,30 @@ trait MetaCollection return $this; } + + /** + * @inheritDoc + */ + public function withNotes(): GroupCollectorInterface + { + if (false === $this->hasNotesInformation) { + // join bill table + $this->query->leftJoin( + 'notes', + static function (JoinClause $join) { + $join->on('notes.noteable_id', '=', 'transaction_journals.id'); + $join->where('notes.noteable_type', '=', 'FireflyIII\Models\TransactionJournal'); + $join->whereNull('notes.deleted_at'); + } + ); + // add fields + $this->fields[] = 'notes.text as notes'; + $this->hasNotesInformation = true; + } + + return $this; + } + /** * @param string $value * @@ -243,22 +351,6 @@ trait MetaCollection return $this; } - /** - * @param string $value - * - * @return GroupCollectorInterface - */ - public function notesDontStartWith(string $value): GroupCollectorInterface - { - $this->withNotes(); - $this->query->where(static function (Builder $q) use ($value) { - $q->whereNull('notes.text'); - $q->orWhere('notes.text', 'NOT LIKE', sprintf('%s%%', $value)); - }); - - return $this; - } - /** * @param string $value * @@ -276,24 +368,17 @@ trait MetaCollection } /** - * @inheritDoc + * @param string $value + * + * @return GroupCollectorInterface */ - public function withNotes(): GroupCollectorInterface + public function notesDontStartWith(string $value): GroupCollectorInterface { - if (false === $this->hasNotesInformation) { - // join bill table - $this->query->leftJoin( - 'notes', - static function (JoinClause $join) { - $join->on('notes.noteable_id', '=', 'transaction_journals.id'); - $join->where('notes.noteable_type', '=', 'FireflyIII\Models\TransactionJournal'); - $join->whereNull('notes.deleted_at'); - } - ); - // add fields - $this->fields[] = 'notes.text as notes'; - $this->hasNotesInformation = true; - } + $this->withNotes(); + $this->query->where(static function (Builder $q) use ($value) { + $q->whereNull('notes.text'); + $q->orWhere('notes.text', 'NOT LIKE', sprintf('%s%%', $value)); + }); return $this; } @@ -402,20 +487,6 @@ trait MetaCollection return $this; } - /** - * @inheritDoc - */ - public function excludeBills(Collection $bills): GroupCollectorInterface - { - $this->withBillInformation(); - $this->query->where(static function(EloquentBuilder $q1) use ($bills) { - $q1->whereNotIn('transaction_journals.bill_id', $bills->pluck('id')->toArray()); - $q1->orWhereNull('transaction_journals.bill_id'); - }); - - return $this; - } - /** * Limit the search to a specific budget. * @@ -469,22 +540,6 @@ trait MetaCollection return $this; } - /** - * @inheritDoc - */ - public function excludeBudgets(Collection $budgets): GroupCollectorInterface - { - if ($budgets->count() > 0) { - $this->withBudgetInformation(); - $this->query->where(static function (EloquentBuilder $q1) use ($budgets) { - $q1->whereNotIn('budgets.id', $budgets->pluck('id')->toArray()); - $q1->orWhereNull('budgets.id'); - }); - } - - return $this; - } - /** * Limit the search to a specific bunch of categories. * @@ -502,22 +557,6 @@ trait MetaCollection return $this; } - /** - * @inheritDoc - */ - public function excludeCategories(Collection $categories): GroupCollectorInterface - { - if ($categories->count() > 0) { - $this->withCategoryInformation(); - $this->query->where(static function (EloquentBuilder $q1) use ($categories) { - $q1->whereNotIn('categories.id', $categories->pluck('id')->toArray()); - $q1->orWhereNull('categories.id'); - }); - } - - return $this; - } - /** * Will include category ID + name, if any. * @@ -554,44 +593,6 @@ trait MetaCollection return $this; } - /** - * Exclude a specific category. - * - * @param Category $category - * - * @return GroupCollectorInterface - */ - public function excludeCategory(Category $category): GroupCollectorInterface - { - $this->withCategoryInformation(); - - $this->query->where(static function(EloquentBuilder $q2) use ($category) { - $q2->where('categories.id','!=', $category->id); - $q2->orWhereNull('categories.id'); - }); - - return $this; - } - - /** - * Exclude a specific budget. - * - * @param Budget $budget - * - * @return GroupCollectorInterface - */ - public function excludeBudget(Budget $budget): GroupCollectorInterface - { - $this->withBudgetInformation(); - - $this->query->where(static function(EloquentBuilder $q2) use ($budget) { - $q2->where('budgets.id','!=', $budget->id); - $q2->orWhereNull('budgets.id'); - }); - - return $this; - } - /** * @inheritDoc */ diff --git a/app/Helpers/Collector/Extensions/TimeCollection.php b/app/Helpers/Collector/Extensions/TimeCollection.php index 8fe5b6bf74..8a2e715d5a 100644 --- a/app/Helpers/Collector/Extensions/TimeCollection.php +++ b/app/Helpers/Collector/Extensions/TimeCollection.php @@ -72,6 +72,73 @@ trait TimeCollection return $this; } + /** + * @param Carbon $start + * @param Carbon $end + * @param string $field + * @return GroupCollectorInterface + */ + public function excludeMetaDateRange(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($field, $transaction) && $transaction[$field] instanceof Carbon) { + return $transaction[$field]->lt($start) || $transaction[$field]->gt($end); + } + } + + return false; + }; + $this->postFilters[] = $filter; + + return $this; + + } + + /** + * @param Carbon $start + * @param Carbon $end + * @param string $field + * @return GroupCollectorInterface + */ + public function excludeObjectRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface + { + $after = $start->format('Y-m-d 00:00:00'); + $before = $end->format('Y-m-d 23:59:59'); + + $this->query->where(sprintf('transaction_journals.%s', $field), '<', $after); + $this->query->orWhere(sprintf('transaction_journals.%s', $field), '>', $before); + + return $this; + } + + /** + * @param Carbon $start + * @param Carbon $end + * @return GroupCollectorInterface + */ + public function excludeRange(Carbon $start, Carbon $end): GroupCollectorInterface + { + if ($end < $start) { + [$start, $end] = [$end, $start]; + } + $startStr = $start->format('Y-m-d 00:00:00'); + $endStr = $end->format('Y-m-d 23:59:59'); + + $this->query->where('transaction_journals.date', '<', $startStr); + $this->query->orWhere('transaction_journals.date', '>', $endStr); + + return $this; + } + /** * @param string $day * @param string $field @@ -654,37 +721,6 @@ trait TimeCollection } - /** - * @param Carbon $start - * @param Carbon $end - * @param string $field - * @return GroupCollectorInterface - */ - public function excludeMetaDateRange(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($field, $transaction) && $transaction[$field] instanceof Carbon) { - return $transaction[$field]->lt($start) || $transaction[$field]->gt($end); - } - } - - return false; - }; - $this->postFilters[] = $filter; - - return $this; - - } - /** * @param Carbon $date * @param string $field @@ -726,23 +762,6 @@ trait TimeCollection return $this; } - /** - * @param Carbon $start - * @param Carbon $end - * @param string $field - * @return GroupCollectorInterface - */ - public function excludeObjectRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface - { - $after = $start->format('Y-m-d 00:00:00'); - $before = $end->format('Y-m-d 23:59:59'); - - $this->query->where(sprintf('transaction_journals.%s', $field), '<', $after); - $this->query->orWhere(sprintf('transaction_journals.%s', $field), '>', $before); - - return $this; - } - /** * Set the start and end time of the results to return. * @@ -766,27 +785,6 @@ trait TimeCollection return $this; } - /** - * @param Carbon $start - * @param Carbon $end - * @return GroupCollectorInterface - */ - public function excludeRange(Carbon $start, Carbon $end): GroupCollectorInterface - { - if ($end < $start) { - [$start, $end] = [$end, $start]; - } - $startStr = $start->format('Y-m-d 00:00:00'); - $endStr = $end->format('Y-m-d 23:59:59'); - - $this->query->where('transaction_journals.date', '<', $startStr); - $this->query->orWhere('transaction_journals.date', '>', $endStr); - - return $this; - } - - - /** * Collect transactions updated on a specific date. * diff --git a/app/Helpers/Collector/GroupCollector.php b/app/Helpers/Collector/GroupCollector.php index c13886697e..a744774891 100644 --- a/app/Helpers/Collector/GroupCollector.php +++ b/app/Helpers/Collector/GroupCollector.php @@ -133,35 +133,6 @@ class GroupCollector implements GroupCollectorInterface ]; } - /** - * @inheritDoc - */ - public function descriptionEnds(array $array): GroupCollectorInterface - { - $this->query->where( - static function (EloquentBuilder $q) use ($array) { - $q->where( - static function (EloquentBuilder $q1) use ($array) { - foreach ($array as $word) { - $keyword = sprintf('%%%s', $word); - $q1->where('transaction_journals.description', 'LIKE', $keyword); - } - } - ); - $q->orWhere( - static function (EloquentBuilder $q2) use ($array) { - foreach ($array as $word) { - $keyword = sprintf('%%%s', $word); - $q2->where('transaction_groups.title', 'LIKE', $keyword); - } - } - ); - } - ); - - return $this; - } - /** * @inheritDoc */ @@ -192,6 +163,65 @@ class GroupCollector implements GroupCollectorInterface return $this; } + /** + * @inheritDoc + */ + public function descriptionDoesNotStart(array $array): GroupCollectorInterface + { + $this->query->where( + static function (EloquentBuilder $q) use ($array) { + $q->where( + static function (EloquentBuilder $q1) use ($array) { + foreach ($array as $word) { + $keyword = sprintf('%s%%', $word); + $q1->where('transaction_journals.description', 'NOT LIKE', $keyword); + } + } + ); + $q->where( + static function (EloquentBuilder $q2) use ($array) { + foreach ($array as $word) { + $keyword = sprintf('%s%%', $word); + $q2->where('transaction_groups.title', 'NOT LIKE', $keyword); + $q2->orWhereNull('transaction_groups.title'); + } + } + ); + } + ); + + return $this; + } + + /** + * @inheritDoc + */ + public function descriptionEnds(array $array): GroupCollectorInterface + { + $this->query->where( + static function (EloquentBuilder $q) use ($array) { + $q->where( + static function (EloquentBuilder $q1) use ($array) { + foreach ($array as $word) { + $keyword = sprintf('%%%s', $word); + $q1->where('transaction_journals.description', 'LIKE', $keyword); + } + } + ); + $q->orWhere( + static function (EloquentBuilder $q2) use ($array) { + foreach ($array as $word) { + $keyword = sprintf('%%%s', $word); + $q2->where('transaction_groups.title', 'LIKE', $keyword); + } + } + ); + } + ); + + return $this; + } + /** * @inheritDoc */ @@ -256,36 +286,6 @@ class GroupCollector implements GroupCollectorInterface return $this; } - /** - * @inheritDoc - */ - public function descriptionDoesNotStart(array $array): GroupCollectorInterface - { - $this->query->where( - static function (EloquentBuilder $q) use ($array) { - $q->where( - static function (EloquentBuilder $q1) use ($array) { - foreach ($array as $word) { - $keyword = sprintf('%s%%', $word); - $q1->where('transaction_journals.description', 'NOT LIKE', $keyword); - } - } - ); - $q->where( - static function (EloquentBuilder $q2) use ($array) { - foreach ($array as $word) { - $keyword = sprintf('%s%%', $word); - $q2->where('transaction_groups.title', 'NOT LIKE', $keyword); - $q2->orWhereNull('transaction_groups.title'); - } - } - ); - } - ); - - return $this; - } - /** * */ @@ -306,6 +306,134 @@ class GroupCollector implements GroupCollectorInterface Log::debug('Bindings', $this->query->getBindings()); } + /** + * Limit results to NOT a specific currency, either foreign or normal one. + * + * @param TransactionCurrency $currency + * + * @return GroupCollectorInterface + */ + public function excludeCurrency(TransactionCurrency $currency): GroupCollectorInterface + { + $this->query->where( + static function (EloquentBuilder $q) use ($currency) { + $q->where('source.transaction_currency_id', '!=', $currency->id); + $q->where( + static function (EloquentBuilder $q2) use ($currency) { + $q2->where('source.foreign_currency_id', '!=', $currency->id); + $q2->orWhereNull('source.foreign_currency_id'); + } + ); + } + ); + + return $this; + } + + /** + * @inheritDoc + */ + public function excludeForeignCurrency(TransactionCurrency $currency): GroupCollectorInterface + { + $this->query->where(static function (EloquentBuilder $q2) use ($currency) { + $q2->where('source.foreign_currency_id', '!=', $currency->id); + $q2->orWhereNull('source.foreign_currency_id'); + }); + + return $this; + } + + /** + * Limit the result to NOT a set of specific transaction groups. + * + * @param array $groupIds + * + * @return GroupCollectorInterface + */ + public function excludeIds(array $groupIds): GroupCollectorInterface + { + + $this->query->whereNotIn('transaction_groups.id', $groupIds); + + return $this; + } + + /** + * Limit the result to NOT a set of specific journals. + * + * @param array $journalIds + * + * @return GroupCollectorInterface + */ + public function excludeJournalIds(array $journalIds): GroupCollectorInterface + { + if (!empty($journalIds)) { + // make all integers. + $integerIDs = array_map('intval', $journalIds); + + + $this->query->whereNotIn('transaction_journals.id', $integerIDs); + } + + return $this; + } + + /** + * Search for words in descriptions. + * + * @param array $array + * + * @return GroupCollectorInterface + */ + public function excludeSearchWords(array $array): GroupCollectorInterface + { + if (0 === count($array)) { + return $this; + } + $this->query->where( + static function (EloquentBuilder $q) use ($array) { + $q->where( + static function (EloquentBuilder $q1) use ($array) { + foreach ($array as $word) { + $keyword = sprintf('%%%s%%', $word); + $q1->where('transaction_journals.description', 'NOT LIKE', $keyword); + } + } + ); + $q->where( + static function (EloquentBuilder $q2) use ($array) { + foreach ($array as $word) { + $keyword = sprintf('%%%s%%', $word); + $q2->where('transaction_groups.title', 'NOT LIKE', $keyword); + $q2->orWhereNull('transaction_groups.title'); + } + } + ); + } + ); + + return $this; + } + + /** + * @inheritDoc + */ + public function excludeTypes(array $types): GroupCollectorInterface + { + $this->query->whereNotIn('transaction_types.type', $types); + + return $this; + } + + /** + * @inheritDoc + */ + public function exists(): GroupCollectorInterface + { + $this->query->whereNull('transaction_groups.deleted_at'); + return $this; + } + /** * @inheritDoc */ @@ -516,6 +644,19 @@ class GroupCollector implements GroupCollectorInterface return $array; } + /** + * @param array $array + * @return array + */ + private function convertToStrings(array $array): array + { + foreach ($this->stringFields as $field) { + $array[$field] = array_key_exists($field, $array) && null !== $array[$field] ? (string) $array[$field] : null; + } + + return $array; + } + /** * @param array $existingJournal * @param TransactionJournal $newJournal @@ -677,6 +818,23 @@ class GroupCollector implements GroupCollectorInterface return $this; } + /** + * @inheritDoc + */ + public function isNotReconciled(): GroupCollectorInterface + { + $this->query->where('source.reconciled', 0)->where('destination.reconciled', 0); + return $this; + } + + /** + * @inheritDoc + */ + public function isReconciled(): GroupCollectorInterface + { + $this->query->where('source.reconciled', 1)->where('destination.reconciled', 1); + return $this; + } /** * Limit results to a specific currency, either foreign or normal one. @@ -697,30 +855,6 @@ class GroupCollector implements GroupCollectorInterface return $this; } - /** - * Limit results to NOT a specific currency, either foreign or normal one. - * - * @param TransactionCurrency $currency - * - * @return GroupCollectorInterface - */ - public function excludeCurrency(TransactionCurrency $currency): GroupCollectorInterface - { - $this->query->where( - static function (EloquentBuilder $q) use ($currency) { - $q->where('source.transaction_currency_id','!=', $currency->id); - $q->where( - static function (EloquentBuilder $q2) use ($currency) { - $q2->where('source.foreign_currency_id','!=', $currency->id); - $q2->orWhereNull('source.foreign_currency_id'); - } - ); - } - ); - - return $this; - } - /** * @inheritDoc */ @@ -731,19 +865,6 @@ class GroupCollector implements GroupCollectorInterface return $this; } - /** - * @inheritDoc - */ - public function excludeForeignCurrency(TransactionCurrency $currency): GroupCollectorInterface - { - $this->query->where(static function(EloquentBuilder $q2) use ($currency) { - $q2->where('source.foreign_currency_id','!=', $currency->id); - $q2->orWhereNull('source.foreign_currency_id'); - }); - - return $this; - } - /** * Limit the result to a set of specific transaction groups. * @@ -759,21 +880,6 @@ class GroupCollector implements GroupCollectorInterface return $this; } - /** - * Limit the result to NOT a set of specific transaction groups. - * - * @param array $groupIds - * - * @return GroupCollectorInterface - */ - public function excludeIds(array $groupIds): GroupCollectorInterface - { - - $this->query->whereNotIn('transaction_groups.id', $groupIds); - - return $this; - } - /** * Limit the result to a set of specific journals. * @@ -794,26 +900,6 @@ class GroupCollector implements GroupCollectorInterface return $this; } - /** - * Limit the result to NOT a set of specific journals. - * - * @param array $journalIds - * - * @return GroupCollectorInterface - */ - public function excludeJournalIds(array $journalIds): GroupCollectorInterface - { - if (!empty($journalIds)) { - // make all integers. - $integerIDs = array_map('intval', $journalIds); - - - $this->query->whereNotIn('transaction_journals.id', $integerIDs); - } - - return $this; - } - /** * Set the page to get. * @@ -866,43 +952,6 @@ class GroupCollector implements GroupCollectorInterface return $this; } - /** - * Search for words in descriptions. - * - * @param array $array - * - * @return GroupCollectorInterface - */ - public function excludeSearchWords(array $array): GroupCollectorInterface - { - if (0 === count($array)) { - return $this; - } - $this->query->where( - static function (EloquentBuilder $q) use ($array) { - $q->where( - static function (EloquentBuilder $q1) use ($array) { - foreach ($array as $word) { - $keyword = sprintf('%%%s%%', $word); - $q1->where('transaction_journals.description', 'NOT LIKE', $keyword); - } - } - ); - $q->where( - static function (EloquentBuilder $q2) use ($array) { - foreach ($array as $word) { - $keyword = sprintf('%%%s%%', $word); - $q2->where('transaction_groups.title', 'NOT LIKE', $keyword); - $q2->orWhereNull('transaction_groups.title'); - } - } - ); - } - ); - - return $this; - } - /** * Limit the search to one specific transaction group. * @@ -931,16 +980,6 @@ class GroupCollector implements GroupCollectorInterface return $this; } - /** - * @inheritDoc - */ - public function excludeTypes(array $types): GroupCollectorInterface - { - $this->query->whereNotIn('transaction_types.type', $types); - - return $this; - } - /** * Set the user object and start the query. * @@ -1020,44 +1059,4 @@ class GroupCollector implements GroupCollectorInterface return $this; } - - /** - * @param array $array - * @return array - */ - private function convertToStrings(array $array): array - { - foreach ($this->stringFields as $field) { - $array[$field] = array_key_exists($field, $array) && null !== $array[$field] ? (string) $array[$field] : null; - } - - return $array; - } - - /** - * @inheritDoc - */ - public function isReconciled(): GroupCollectorInterface - { - $this->query->where('source.reconciled', 1)->where('destination.reconciled', 1); - return $this; - } - - /** - * @inheritDoc - */ - public function isNotReconciled(): GroupCollectorInterface - { - $this->query->where('source.reconciled', 0)->where('destination.reconciled', 0); - return $this; - } - - /** - * @inheritDoc - */ - public function exists(): GroupCollectorInterface - { - $this->query->whereNull('transaction_groups.deleted_at'); - return $this; - } } diff --git a/app/Helpers/Collector/GroupCollectorInterface.php b/app/Helpers/Collector/GroupCollectorInterface.php index ca11ebb896..fb162d8203 100644 --- a/app/Helpers/Collector/GroupCollectorInterface.php +++ b/app/Helpers/Collector/GroupCollectorInterface.php @@ -55,25 +55,6 @@ interface GroupCollectorInterface */ public function amountIsNot(string $amount): GroupCollectorInterface; - /** - * Only journals that are reconciled. - * - * @return GroupCollectorInterface - */ - public function isReconciled(): GroupCollectorInterface; - - /** - * Only journals that are reconciled. - * - * @return GroupCollectorInterface - */ - public function isNotReconciled(): GroupCollectorInterface; - - /** - * @return GroupCollectorInterface - */ - public function exists(): GroupCollectorInterface; - /** * Get transactions where the amount is less than. * @@ -164,15 +145,6 @@ interface GroupCollectorInterface */ public function dayIsNot(string $day): GroupCollectorInterface; - /** - * End of the description must match: - * - * @param array $array - * - * @return GroupCollectorInterface - */ - public function descriptionEnds(array $array): GroupCollectorInterface; - /** * End of the description must not match: * @@ -182,6 +154,24 @@ interface GroupCollectorInterface */ public function descriptionDoesNotEnd(array $array): GroupCollectorInterface; + /** + * Beginning of the description must not start with: + * + * @param array $array + * + * @return GroupCollectorInterface + */ + public function descriptionDoesNotStart(array $array): GroupCollectorInterface; + + /** + * End of the description must match: + * + * @param array $array + * + * @return GroupCollectorInterface + */ + public function descriptionEnds(array $array): GroupCollectorInterface; + /** * Description must be: * @@ -210,14 +200,66 @@ interface GroupCollectorInterface public function descriptionStarts(array $array): GroupCollectorInterface; /** - * Beginning of the description must not start with: + * These accounts must not be accounts. * - * @param array $array + * @param Collection $accounts * * @return GroupCollectorInterface */ - public function descriptionDoesNotStart(array $array): GroupCollectorInterface; + public function excludeAccounts(Collection $accounts): GroupCollectorInterface; + /** + * Exclude a specific set of bills + * + * @param Collection $bills + * + * @return GroupCollectorInterface + */ + public function excludeBills(Collection $bills): GroupCollectorInterface; + + /** + * Exclude a budget + * + * @param Budget $budget + * + * @return GroupCollectorInterface + */ + public function excludeBudget(Budget $budget): GroupCollectorInterface; + + /** + * Exclude a budget. + * + * @param Collection $budgets + * + * @return GroupCollectorInterface + */ + public function excludeBudgets(Collection $budgets): GroupCollectorInterface; + + /** + * Exclude a set of categories. + * + * @param Collection $categories + * @return GroupCollectorInterface + */ + public function excludeCategories(Collection $categories): GroupCollectorInterface; + + /** + * Exclude a specific category + * + * @param Category $category + * + * @return GroupCollectorInterface + */ + public function excludeCategory(Category $category): GroupCollectorInterface; + + /** + * Limit results to NOT a specific currency, either foreign or normal one. + * + * @param TransactionCurrency $currency + * + * @return GroupCollectorInterface + */ + public function excludeCurrency(TransactionCurrency $currency): GroupCollectorInterface; /** * Exclude destination accounts. @@ -228,6 +270,65 @@ interface GroupCollectorInterface */ public function excludeDestinationAccounts(Collection $accounts): GroupCollectorInterface; + /** + * Limit results to exclude a specific foreign currency. + * + * @param TransactionCurrency $currency + * + * @return GroupCollectorInterface + */ + public function excludeForeignCurrency(TransactionCurrency $currency): GroupCollectorInterface; + + /** + * Limit the result to NOT a set of specific transaction groups. + * + * @param array $groupIds + * + * @return GroupCollectorInterface + */ + public function excludeIds(array $groupIds): GroupCollectorInterface; + + /** + * Limit the result to NOT a set of specific transaction journals. + * + * @param array $journalIds + * + * @return GroupCollectorInterface + */ + public function excludeJournalIds(array $journalIds): GroupCollectorInterface; + + /** + * @param Carbon $start + * @param Carbon $end + * @param string $field + * @return GroupCollectorInterface + */ + public function excludeMetaDateRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface; + + /** + * @param Carbon $start + * @param Carbon $end + * @param string $field + * @return GroupCollectorInterface + */ + public function excludeObjectRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface; + + /** + * @param Carbon $start + * @param Carbon $end + * @return GroupCollectorInterface + */ + public function excludeRange(Carbon $start, Carbon $end): GroupCollectorInterface; + + /** + * Exclude words in descriptions. + * + * @param array $array + * + * @return GroupCollectorInterface + */ + public function excludeSearchWords(array $array): GroupCollectorInterface; + /** * These accounts must not be source accounts. * @@ -238,13 +339,18 @@ interface GroupCollectorInterface public function excludeSourceAccounts(Collection $accounts): GroupCollectorInterface; /** - * These accounts must not be accounts. + * Limit the included transaction types. * - * @param Collection $accounts + * @param array $types * * @return GroupCollectorInterface */ - public function excludeAccounts(Collection $accounts): GroupCollectorInterface; + public function excludeTypes(array $types): GroupCollectorInterface; + + /** + * @return GroupCollectorInterface + */ + public function exists(): GroupCollectorInterface; /** * @param string $externalId @@ -383,6 +489,20 @@ interface GroupCollectorInterface */ public function internalReferenceStarts(string $externalId): GroupCollectorInterface; + /** + * Only journals that are reconciled. + * + * @return GroupCollectorInterface + */ + public function isNotReconciled(): GroupCollectorInterface; + + /** + * Only journals that are reconciled. + * + * @return GroupCollectorInterface + */ + public function isReconciled(): GroupCollectorInterface; + /** * @param string $day * @param string $field @@ -460,7 +580,6 @@ interface GroupCollectorInterface */ public function metaYearIs(string $year, string $field): GroupCollectorInterface; - /** * @param string $year * @param string $field @@ -511,14 +630,20 @@ interface GroupCollectorInterface * * @return GroupCollectorInterface */ - public function notesEndWith(string $value): GroupCollectorInterface; + public function notesDontEndWith(string $value): GroupCollectorInterface; + + /** + * @param string $value + * @return GroupCollectorInterface + */ + public function notesDontStartWith(string $value): GroupCollectorInterface; /** * @param string $value * * @return GroupCollectorInterface */ - public function notesDontEndWith(string $value): GroupCollectorInterface; + public function notesEndWith(string $value): GroupCollectorInterface; /** * @param string $value @@ -541,12 +666,6 @@ interface GroupCollectorInterface */ public function notesStartWith(string $value): GroupCollectorInterface; - /** - * @param string $value - * @return GroupCollectorInterface - */ - public function notesDontStartWith(string $value): GroupCollectorInterface; - /** * @param string $day * @param string $field @@ -640,18 +759,6 @@ interface GroupCollectorInterface */ public function setAccounts(Collection $accounts): GroupCollectorInterface; - - /** - * Define which accounts can NOT be part of the source and destination transactions. - * - * @param Collection $accounts - * - * @return GroupCollectorInterface - */ - public function setNotAccounts(Collection $accounts): GroupCollectorInterface; - - - /** * Collect transactions after a specific date. * @@ -688,15 +795,6 @@ interface GroupCollectorInterface */ public function setBills(Collection $bills): GroupCollectorInterface; - /** - * Exclude a specific set of bills - * - * @param Collection $bills - * - * @return GroupCollectorInterface - */ - public function excludeBills(Collection $bills): GroupCollectorInterface; - /** * Both source AND destination must be in this list of accounts. * @@ -715,15 +813,6 @@ interface GroupCollectorInterface */ public function setBudget(Budget $budget): GroupCollectorInterface; - /** - * Exclude a budget - * - * @param Budget $budget - * - * @return GroupCollectorInterface - */ - public function excludeBudget(Budget $budget): GroupCollectorInterface; - /** * Limit the search to a specific set of budgets. * @@ -733,15 +822,6 @@ interface GroupCollectorInterface */ public function setBudgets(Collection $budgets): GroupCollectorInterface; - /** - * Exclude a budget. - * - * @param Collection $budgets - * - * @return GroupCollectorInterface - */ - public function excludeBudgets(Collection $budgets): GroupCollectorInterface; - /** * Limit the search to a specific bunch of categories. * @@ -751,14 +831,6 @@ interface GroupCollectorInterface */ public function setCategories(Collection $categories): GroupCollectorInterface; - /** - * Exclude a set of categories. - * - * @param Collection $categories - * @return GroupCollectorInterface - */ - public function excludeCategories(Collection $categories): GroupCollectorInterface; - /** * Limit the search to a specific category. * @@ -768,15 +840,6 @@ interface GroupCollectorInterface */ public function setCategory(Category $category): GroupCollectorInterface; - /** - * Exclude a specific category - * - * @param Category $category - * - * @return GroupCollectorInterface - */ - public function excludeCategory(Category $category): GroupCollectorInterface; - /** * Collect transactions created on a specific date. * @@ -795,15 +858,6 @@ interface GroupCollectorInterface */ public function setCurrency(TransactionCurrency $currency): GroupCollectorInterface; - /** - * Limit results to NOT a specific currency, either foreign or normal one. - * - * @param TransactionCurrency $currency - * - * @return GroupCollectorInterface - */ - public function excludeCurrency(TransactionCurrency $currency): GroupCollectorInterface; - /** * Set destination accounts. * @@ -837,15 +891,6 @@ interface GroupCollectorInterface */ public function setForeignCurrency(TransactionCurrency $currency): GroupCollectorInterface; - /** - * Limit results to exclude a specific foreign currency. - * - * @param TransactionCurrency $currency - * - * @return GroupCollectorInterface - */ - public function excludeForeignCurrency(TransactionCurrency $currency): GroupCollectorInterface; - /** * Limit the result to a set of specific transaction groups. * @@ -855,15 +900,6 @@ interface GroupCollectorInterface */ public function setIds(array $groupIds): GroupCollectorInterface; - /** - * Limit the result to NOT a set of specific transaction groups. - * - * @param array $groupIds - * - * @return GroupCollectorInterface - */ - public function excludeIds(array $groupIds): GroupCollectorInterface; - /** * Look for specific external ID's. * @@ -882,15 +918,6 @@ interface GroupCollectorInterface */ public function setJournalIds(array $journalIds): GroupCollectorInterface; - /** - * Limit the result to NOT a set of specific transaction journals. - * - * @param array $journalIds - * - * @return GroupCollectorInterface - */ - public function excludeJournalIds(array $journalIds): GroupCollectorInterface; - /** * Limit the number of returned entries. * @@ -930,14 +957,13 @@ interface GroupCollectorInterface public function setMetaDateRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface; /** - * @param Carbon $start - * @param Carbon $end - * @param string $field + * Define which accounts can NOT be part of the source and destination transactions. + * + * @param Collection $accounts + * * @return GroupCollectorInterface */ - public function excludeMetaDateRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface; - - + public function setNotAccounts(Collection $accounts): GroupCollectorInterface; /** * @param Carbon $date @@ -961,14 +987,6 @@ interface GroupCollectorInterface */ public function setObjectRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface; - /** - * @param Carbon $start - * @param Carbon $end - * @param string $field - * @return GroupCollectorInterface - */ - public function excludeObjectRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface; - /** * Set the page to get. * @@ -988,13 +1006,6 @@ interface GroupCollectorInterface */ public function setRange(Carbon $start, Carbon $end): GroupCollectorInterface; - /** - * @param Carbon $start - * @param Carbon $end - * @return GroupCollectorInterface - */ - public function excludeRange(Carbon $start, Carbon $end): GroupCollectorInterface; - /** * Look for specific recurring ID's. * @@ -1013,15 +1024,6 @@ interface GroupCollectorInterface */ public function setSearchWords(array $array): GroupCollectorInterface; - /** - * Exclude words in descriptions. - * - * @param array $array - * - * @return GroupCollectorInterface - */ - public function excludeSearchWords(array $array): GroupCollectorInterface; - /** * Set source accounts. * @@ -1067,15 +1069,6 @@ interface GroupCollectorInterface */ public function setTypes(array $types): GroupCollectorInterface; - /** - * Limit the included transaction types. - * - * @param array $types - * - * @return GroupCollectorInterface - */ - public function excludeTypes(array $types): GroupCollectorInterface; - /** * Collect transactions updated on a specific date. *