mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2024-11-25 18:30:55 -06:00
884 lines
29 KiB
PHP
884 lines
29 KiB
PHP
<?php
|
|
|
|
/**
|
|
* MetaCollection.php
|
|
* Copyright (c) 2020 james@firefly-iii.org
|
|
*
|
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace FireflyIII\Helpers\Collector\Extensions;
|
|
|
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
|
use FireflyIII\Models\Bill;
|
|
use FireflyIII\Models\Budget;
|
|
use FireflyIII\Models\Category;
|
|
use FireflyIII\Models\Tag;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
|
use Illuminate\Database\Query\JoinClause;
|
|
use Illuminate\Support\Collection;
|
|
|
|
/**
|
|
* Trait MetaCollection
|
|
*/
|
|
trait MetaCollection
|
|
{
|
|
public function excludeBills(Collection $bills): GroupCollectorInterface
|
|
{
|
|
$this->withBillInformation();
|
|
$this->query->where(static function (EloquentBuilder $q1) use ($bills): void { // @phpstan-ignore-line
|
|
$q1->whereNotIn('transaction_journals.bill_id', $bills->pluck('id')->toArray());
|
|
$q1->orWhereNull('transaction_journals.bill_id');
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Will include bill name + ID, if any.
|
|
*/
|
|
public function withBillInformation(): GroupCollectorInterface
|
|
{
|
|
if (false === $this->hasBillInformation) {
|
|
// join bill table
|
|
$this->query->leftJoin('bills', 'bills.id', '=', 'transaction_journals.bill_id');
|
|
// add fields
|
|
$this->fields[] = 'bills.id as bill_id';
|
|
$this->fields[] = 'bills.name as bill_name';
|
|
$this->hasBillInformation = true;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Exclude a specific budget.
|
|
*/
|
|
public function excludeBudget(Budget $budget): GroupCollectorInterface
|
|
{
|
|
$this->withBudgetInformation();
|
|
|
|
$this->query->where(static function (EloquentBuilder $q2) use ($budget): void { // @phpstan-ignore-line
|
|
$q2->where('budgets.id', '!=', $budget->id);
|
|
$q2->orWhereNull('budgets.id');
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Will include budget ID + name, if any.
|
|
*/
|
|
public function withBudgetInformation(): GroupCollectorInterface
|
|
{
|
|
if (false === $this->hasBudgetInformation) {
|
|
// join link table
|
|
$this->query->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
|
|
// join cat table
|
|
$this->query->leftJoin('budgets', 'budget_transaction_journal.budget_id', '=', 'budgets.id');
|
|
// add fields
|
|
$this->fields[] = 'budgets.id as budget_id';
|
|
$this->fields[] = 'budgets.name as budget_name';
|
|
$this->hasBudgetInformation = true;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function excludeBudgets(Collection $budgets): GroupCollectorInterface
|
|
{
|
|
if ($budgets->count() > 0) {
|
|
$this->withBudgetInformation();
|
|
$this->query->where(static function (EloquentBuilder $q1) use ($budgets): void { // @phpstan-ignore-line
|
|
$q1->whereNotIn('budgets.id', $budgets->pluck('id')->toArray());
|
|
$q1->orWhereNull('budgets.id');
|
|
});
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function excludeCategories(Collection $categories): GroupCollectorInterface
|
|
{
|
|
if ($categories->count() > 0) {
|
|
$this->withCategoryInformation();
|
|
$this->query->where(static function (EloquentBuilder $q1) use ($categories): void { // @phpstan-ignore-line
|
|
$q1->whereNotIn('categories.id', $categories->pluck('id')->toArray());
|
|
$q1->orWhereNull('categories.id');
|
|
});
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Will include category ID + name, if any.
|
|
*/
|
|
public function withCategoryInformation(): GroupCollectorInterface
|
|
{
|
|
if (false === $this->hasCatInformation) {
|
|
// join link table
|
|
$this->query->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
|
|
// join cat table
|
|
$this->query->leftJoin('categories', 'category_transaction_journal.category_id', '=', 'categories.id');
|
|
// add fields
|
|
$this->fields[] = 'categories.id as category_id';
|
|
$this->fields[] = 'categories.name as category_name';
|
|
$this->hasCatInformation = true;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Exclude a specific category.
|
|
*/
|
|
public function excludeCategory(Category $category): GroupCollectorInterface
|
|
{
|
|
$this->withCategoryInformation();
|
|
|
|
$this->query->where(static function (EloquentBuilder $q2) use ($category): void { // @phpstan-ignore-line
|
|
$q2->where('categories.id', '!=', $category->id);
|
|
$q2->orWhereNull('categories.id');
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
public function excludeInternalReference(string $internalReference): GroupCollectorInterface
|
|
{
|
|
$internalReference = (string)json_encode($internalReference);
|
|
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'internal_reference');
|
|
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s%%', $internalReference));
|
|
|
|
return $this;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
public function externalIdContains(string $externalId): GroupCollectorInterface
|
|
{
|
|
$externalId = (string)json_encode($externalId);
|
|
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'external_id');
|
|
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $externalId));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function externalIdDoesNotContain(string $externalId): GroupCollectorInterface
|
|
{
|
|
$externalId = (string)json_encode($externalId);
|
|
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'external_id');
|
|
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s%%', $externalId));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function externalIdDoesNotEnd(string $externalId): GroupCollectorInterface
|
|
{
|
|
$externalId = (string)json_encode($externalId);
|
|
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'external_id');
|
|
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s"', $externalId));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function externalIdDoesNotStart(string $externalId): GroupCollectorInterface
|
|
{
|
|
$externalId = (string)json_encode($externalId);
|
|
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'external_id');
|
|
$this->query->where('journal_meta.data', 'LIKE', sprintf('"%s%%', $externalId));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function externalIdEnds(string $externalId): GroupCollectorInterface
|
|
{
|
|
$externalId = (string)json_encode($externalId);
|
|
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'external_id');
|
|
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s"', $externalId));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function externalIdStarts(string $externalId): GroupCollectorInterface
|
|
{
|
|
$externalId = (string)json_encode($externalId);
|
|
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'external_id');
|
|
$this->query->where('journal_meta.data', 'LIKE', sprintf('"%s%%', $externalId));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function externalUrlContains(string $url): GroupCollectorInterface
|
|
{
|
|
$this->joinMetaDataTables();
|
|
$url = (string)json_encode($url);
|
|
$url = str_replace('\\', '\\\\', trim($url, '"'));
|
|
$this->query->where('journal_meta.name', '=', 'external_url');
|
|
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $url));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function externalUrlDoesNotContain(string $url): GroupCollectorInterface
|
|
{
|
|
$this->joinMetaDataTables();
|
|
$url = (string)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;
|
|
}
|
|
|
|
public function externalUrlDoesNotEnd(string $url): GroupCollectorInterface
|
|
{
|
|
$this->joinMetaDataTables();
|
|
$url = (string)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;
|
|
}
|
|
|
|
public function externalUrlDoesNotStart(string $url): GroupCollectorInterface
|
|
{
|
|
$this->joinMetaDataTables();
|
|
$url = (string)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;
|
|
}
|
|
|
|
public function externalUrlEnds(string $url): GroupCollectorInterface
|
|
{
|
|
$this->joinMetaDataTables();
|
|
$url = (string)json_encode($url);
|
|
$url = str_replace('\\', '\\\\', ltrim($url, '"'));
|
|
$this->query->where('journal_meta.name', '=', 'external_url');
|
|
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s', $url));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function externalUrlStarts(string $url): GroupCollectorInterface
|
|
{
|
|
$this->joinMetaDataTables();
|
|
$url = (string)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', 'LIKE', sprintf('%s%%', $url));
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Where has no tags.
|
|
*/
|
|
public function hasAnyTag(): GroupCollectorInterface
|
|
{
|
|
$this->withTagInformation();
|
|
$this->query->whereNotNull('tag_transaction_journal.tag_id');
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function withTagInformation(): GroupCollectorInterface
|
|
{
|
|
$this->fields[] = 'tags.id as tag_id';
|
|
$this->fields[] = 'tags.tag as tag_name';
|
|
$this->fields[] = 'tags.date as tag_date';
|
|
$this->fields[] = 'tags.description as tag_description';
|
|
$this->fields[] = 'tags.latitude as tag_latitude';
|
|
$this->fields[] = 'tags.longitude as tag_longitude';
|
|
$this->fields[] = 'tags.zoomLevel as tag_zoom_level';
|
|
|
|
$this->joinTagTables();
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function internalReferenceContains(string $internalReference): GroupCollectorInterface
|
|
{
|
|
$internalReference = (string)json_encode($internalReference);
|
|
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
|
|
// var_dump($internalReference);
|
|
// exit;
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'internal_reference');
|
|
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $internalReference));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function internalReferenceDoesNotContain(string $internalReference): GroupCollectorInterface
|
|
{
|
|
$internalReference = (string)json_encode($internalReference);
|
|
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'internal_reference');
|
|
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s%%', $internalReference));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function internalReferenceDoesNotEnd(string $internalReference): GroupCollectorInterface
|
|
{
|
|
$internalReference = (string)json_encode($internalReference);
|
|
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'internal_reference');
|
|
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s"', $internalReference));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function internalReferenceDoesNotStart(string $internalReference): GroupCollectorInterface
|
|
{
|
|
$internalReference = (string)json_encode($internalReference);
|
|
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'internal_reference');
|
|
$this->query->where('journal_meta.data', 'LIKE', sprintf('"%s%%', $internalReference));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function internalReferenceEnds(string $internalReference): GroupCollectorInterface
|
|
{
|
|
$internalReference = (string)json_encode($internalReference);
|
|
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'internal_reference');
|
|
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s"', $internalReference));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function internalReferenceStarts(string $internalReference): GroupCollectorInterface
|
|
{
|
|
$internalReference = (string)json_encode($internalReference);
|
|
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'internal_reference');
|
|
$this->query->where('journal_meta.data', 'LIKE', sprintf('"%s%%', $internalReference));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function notesContain(string $value): GroupCollectorInterface
|
|
{
|
|
$this->withNotes();
|
|
$this->query->where('notes.text', 'LIKE', sprintf('%%%s%%', $value));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function withNotes(): GroupCollectorInterface
|
|
{
|
|
if (false === $this->hasNotesInformation) {
|
|
// join bill table
|
|
$this->query->leftJoin(
|
|
'notes',
|
|
static function (JoinClause $join): void {
|
|
$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;
|
|
}
|
|
|
|
public function notesDoNotContain(string $value): GroupCollectorInterface
|
|
{
|
|
$this->withNotes();
|
|
$this->query->where(static function (Builder $q) use ($value): void { // @phpstan-ignore-line
|
|
$q->whereNull('notes.text');
|
|
$q->orWhere('notes.text', 'NOT LIKE', sprintf('%%%s%%', $value));
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function notesDontEndWith(string $value): GroupCollectorInterface
|
|
{
|
|
$this->withNotes();
|
|
$this->query->where(static function (Builder $q) use ($value): void { // @phpstan-ignore-line
|
|
$q->whereNull('notes.text');
|
|
$q->orWhere('notes.text', 'NOT LIKE', sprintf('%%%s', $value));
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function notesDontStartWith(string $value): GroupCollectorInterface
|
|
{
|
|
$this->withNotes();
|
|
$this->query->where(static function (Builder $q) use ($value): void { // @phpstan-ignore-line
|
|
$q->whereNull('notes.text');
|
|
$q->orWhere('notes.text', 'NOT LIKE', sprintf('%s%%', $value));
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function notesEndWith(string $value): GroupCollectorInterface
|
|
{
|
|
$this->withNotes();
|
|
$this->query->where('notes.text', 'LIKE', sprintf('%%%s', $value));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function notesExactly(string $value): GroupCollectorInterface
|
|
{
|
|
$this->withNotes();
|
|
$this->query->where('notes.text', '=', sprintf('%s', $value));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function notesExactlyNot(string $value): GroupCollectorInterface
|
|
{
|
|
$this->withNotes();
|
|
$this->query->where(static function (Builder $q) use ($value): void { // @phpstan-ignore-line
|
|
$q->whereNull('notes.text');
|
|
$q->orWhere('notes.text', '!=', sprintf('%s', $value));
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function notesStartWith(string $value): GroupCollectorInterface
|
|
{
|
|
$this->withNotes();
|
|
$this->query->where('notes.text', 'LIKE', sprintf('%s%%', $value));
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit the search to a specific bill.
|
|
*/
|
|
public function setBill(Bill $bill): GroupCollectorInterface
|
|
{
|
|
$this->withBillInformation();
|
|
$this->query->where('transaction_journals.bill_id', '=', $bill->id);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit the search to a specific set of bills.
|
|
*/
|
|
public function setBills(Collection $bills): GroupCollectorInterface
|
|
{
|
|
$this->withBillInformation();
|
|
$this->query->whereIn('transaction_journals.bill_id', $bills->pluck('id')->toArray());
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit the search to a specific budget.
|
|
*/
|
|
public function setBudget(Budget $budget): GroupCollectorInterface
|
|
{
|
|
$this->withBudgetInformation();
|
|
$this->query->where('budgets.id', $budget->id);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit the search to a specific set of budgets.
|
|
*/
|
|
public function setBudgets(Collection $budgets): GroupCollectorInterface
|
|
{
|
|
if ($budgets->count() > 0) {
|
|
$this->withBudgetInformation();
|
|
$this->query->whereIn('budgets.id', $budgets->pluck('id')->toArray());
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit the search to a specific bunch of categories.
|
|
*/
|
|
public function setCategories(Collection $categories): GroupCollectorInterface
|
|
{
|
|
if ($categories->count() > 0) {
|
|
$this->withCategoryInformation();
|
|
$this->query->whereIn('categories.id', $categories->pluck('id')->toArray());
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit the search to a specific category.
|
|
*/
|
|
public function setCategory(Category $category): GroupCollectorInterface
|
|
{
|
|
$this->withCategoryInformation();
|
|
$this->query->where('categories.id', $category->id);
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setExternalId(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;
|
|
}
|
|
|
|
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));
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setInternalReference(string $internalReference): GroupCollectorInterface
|
|
{
|
|
$internalReference = (string)json_encode($internalReference);
|
|
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
|
|
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'internal_reference');
|
|
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $internalReference));
|
|
|
|
return $this;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
public function setSepaCT(string $sepaCT): GroupCollectorInterface
|
|
{
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'sepa_ct_id');
|
|
$this->query->where('journal_meta.data', '=', sprintf('%s', json_encode($sepaCT)));
|
|
$this->query->whereNull('journal_meta.deleted_at');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit results to a specific tag.
|
|
*/
|
|
public function setTag(Tag $tag): GroupCollectorInterface
|
|
{
|
|
$this->withTagInformation();
|
|
$this->query->where('tag_transaction_journal.tag_id', $tag->id);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit results to a specific set of tags.
|
|
*/
|
|
public function setTags(Collection $tags): GroupCollectorInterface
|
|
{
|
|
$this->withTagInformation();
|
|
$this->tags = array_merge($this->tags, $tags->pluck('id')->toArray());
|
|
$this->query->whereIn('tag_transaction_journal.tag_id', $this->tags);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Without tags
|
|
*/
|
|
public function setWithoutSpecificTags(Collection $tags): GroupCollectorInterface
|
|
{
|
|
$this->withTagInformation();
|
|
|
|
// this method adds a "postFilter" to the collector.
|
|
$list = $tags->pluck('tag')->toArray();
|
|
$filter = static function (array $object) use ($list): bool {
|
|
foreach ($object['transactions'] as $transaction) {
|
|
app('log')->debug(sprintf('Transaction has %d tag(s)', count($transaction['tags'])));
|
|
foreach ($transaction['tags'] as $tag) {
|
|
if (in_array($tag['name'], $list, true)) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
};
|
|
$this->postFilters[] = $filter;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function withAnyNotes(): GroupCollectorInterface
|
|
{
|
|
$this->withNotes();
|
|
$this->query->whereNotNull('notes.text');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit results to transactions without a bill.
|
|
*/
|
|
public function withBill(): GroupCollectorInterface
|
|
{
|
|
$this->withBillInformation();
|
|
$this->query->whereNotNull('transaction_journals.bill_id');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit results to a transactions without a budget..
|
|
*/
|
|
public function withBudget(): GroupCollectorInterface
|
|
{
|
|
$this->withBudgetInformation();
|
|
$this->query->whereNotNull('budget_transaction_journal.budget_id');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit results to a transactions without a category.
|
|
*/
|
|
public function withCategory(): GroupCollectorInterface
|
|
{
|
|
$this->withCategoryInformation();
|
|
$this->query->whereNotNull('category_transaction_journal.category_id');
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function withExternalId(): GroupCollectorInterface
|
|
{
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'external_id');
|
|
$this->query->whereNotNull('journal_meta.data');
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function withExternalUrl(): GroupCollectorInterface
|
|
{
|
|
$this->joinMetaDataTables();
|
|
$this->query->where('journal_meta.name', '=', 'external_url');
|
|
$this->query->whereNotNull('journal_meta.data');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit results to a transactions without a bill.
|
|
*/
|
|
public function withoutBill(): GroupCollectorInterface
|
|
{
|
|
$this->query->whereNull('transaction_journals.bill_id');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit results to a transactions without a budget..
|
|
*/
|
|
public function withoutBudget(): GroupCollectorInterface
|
|
{
|
|
$this->withBudgetInformation();
|
|
$this->query->whereNull('budget_transaction_journal.budget_id');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Limit results to a transactions without a category.
|
|
*/
|
|
public function withoutCategory(): GroupCollectorInterface
|
|
{
|
|
$this->withCategoryInformation();
|
|
$this->query->whereNull('category_transaction_journal.category_id');
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function withoutExternalId(): GroupCollectorInterface
|
|
{
|
|
$this->joinMetaDataTables();
|
|
// TODO not sure if this will work properly.
|
|
$this->query->where(static function (Builder $q1): void { // @phpstan-ignore-line
|
|
$q1->where(static function (Builder $q2): void {
|
|
$q2->where('journal_meta.name', '=', 'external_id');
|
|
$q2->whereNull('journal_meta.data');
|
|
})->orWhere(static function (Builder $q3): void {
|
|
$q3->where('journal_meta.name', '!=', 'external_id');
|
|
})->orWhere(static function (Builder $q4): void {
|
|
$q4->whereNull('journal_meta.name');
|
|
});
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function withoutExternalUrl(): GroupCollectorInterface
|
|
{
|
|
$this->joinMetaDataTables();
|
|
// TODO not sure if this will work properly.
|
|
$this->query->where(static function (Builder $q1): void { // @phpstan-ignore-line
|
|
$q1->where(static function (Builder $q2): void {
|
|
$q2->where('journal_meta.name', '=', 'external_url');
|
|
$q2->whereNull('journal_meta.data');
|
|
})->orWhere(static function (Builder $q3): void {
|
|
$q3->where('journal_meta.name', '!=', 'external_url');
|
|
})->orWhere(static function (Builder $q4): void {
|
|
$q4->whereNull('journal_meta.name');
|
|
});
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function withoutNotes(): GroupCollectorInterface
|
|
{
|
|
$this->withNotes();
|
|
$this->query->where(static function (Builder $q): void { // @phpstan-ignore-line
|
|
$q->whereNull('notes.text');
|
|
$q->orWhere('notes.text', '');
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Where has no tags.
|
|
*/
|
|
public function withoutTags(): GroupCollectorInterface
|
|
{
|
|
$this->withTagInformation();
|
|
$this->query->whereNull('tag_transaction_journal.tag_id');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Join table to get tag information.
|
|
*/
|
|
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';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Join table to get tag information.
|
|
*/
|
|
protected function joinTagTables(): void
|
|
{
|
|
if (false === $this->hasJoinedTagTables) {
|
|
// join some extra tables:
|
|
$this->hasJoinedTagTables = true;
|
|
$this->query->leftJoin('tag_transaction_journal', 'tag_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
|
|
$this->query->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id');
|
|
}
|
|
}
|
|
}
|