Move code to traits.

This commit is contained in:
James Cole 2020-03-21 08:54:38 +01:00
parent ee844e970f
commit d16389748f
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
3 changed files with 297 additions and 221 deletions

View File

@ -0,0 +1,233 @@
<?php
declare(strict_types=1);
/**
* AccountCollection.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/>.
*/
namespace FireflyIII\Helpers\Collector\Extensions;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Support\Collection;
/**
* Trait AccountCollection
*/
trait AccountCollection
{
/**
* These accounts must not be destination accounts.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function excludeDestinationAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereNotIn('destination.account_id', $accountIds);
app('log')->debug(sprintf('GroupCollector: excludeDestinationAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/**
* These accounts must not be source accounts.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function excludeSourceAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereNotIn('source.account_id', $accountIds);
app('log')->debug(sprintf('GroupCollector: excludeSourceAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/**
* Define which accounts can be part of the source and destination transactions.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->where(
static function (EloquentBuilder $query) use ($accountIds) {
$query->whereIn('source.account_id', $accountIds);
$query->orWhereIn('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.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setBothAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->where(
static function (EloquentBuilder $query) use ($accountIds) {
$query->whereIn('source.account_id', $accountIds);
$query->whereIn('destination.account_id', $accountIds);
}
);
app('log')->debug(sprintf('GroupCollector: setBothAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/**
* Define which accounts can be part of the source and destination transactions.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setDestinationAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereIn('destination.account_id', $accountIds);
app('log')->debug(sprintf('GroupCollector: setDestinationAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/**
* Define which accounts can be part of the source and destination transactions.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setSourceAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereIn('source.account_id', $accountIds);
app('log')->debug(sprintf('GroupCollector: setSourceAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/**
* Either account can be set, but NOT both. This effectively excludes internal transfers.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setXorAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->where(
static function (EloquentBuilder $q1) use ($accountIds) {
// sourceAccount is in the set, and destination is NOT.
$q1->where(
static function (EloquentBuilder $q2) use ($accountIds) {
$q2->whereIn('source.account_id', $accountIds);
$q2->whereNotIn('destination.account_id', $accountIds);
}
);
// destination is in the set, and source is NOT
$q1->orWhere(
static function (EloquentBuilder $q3) use ($accountIds) {
$q3->whereNotIn('source.account_id', $accountIds);
$q3->whereIn('destination.account_id', $accountIds);
}
);
}
);
app('log')->debug(sprintf('GroupCollector: setXorAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/**
* Will include the source and destination account names and types.
*
* @return GroupCollectorInterface
*/
public function withAccountInformation(): GroupCollectorInterface
{
if (false === $this->hasAccountInfo) {
// join source account table
$this->query->leftJoin('accounts as source_account', 'source_account.id', '=', 'source.account_id');
// join source account type table
$this->query->leftJoin('account_types as source_account_type', 'source_account_type.id', '=', 'source_account.account_type_id');
// add source account fields:
$this->fields[] = 'source_account.name as source_account_name';
$this->fields[] = 'source_account.iban as source_account_iban';
$this->fields[] = 'source_account_type.type as source_account_type';
// same for dest
$this->query->leftJoin('accounts as dest_account', 'dest_account.id', '=', 'destination.account_id');
$this->query->leftJoin('account_types as dest_account_type', 'dest_account_type.id', '=', 'dest_account.account_type_id');
// and add fields:
$this->fields[] = 'dest_account.name as destination_account_name';
$this->fields[] = 'dest_account.iban as destination_account_iban';
$this->fields[] = 'dest_account_type.type as destination_account_type';
$this->hasAccountInfo = true;
}
return $this;
}
}

View File

@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
/**
* CollectorProperties.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/>.
*/
namespace FireflyIII\Helpers\Collector\Extensions;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* Trait CollectorProperties
*/
trait CollectorProperties
{
/** @var array The standard fields to select. */
private $fields;
/** @var bool Will be set to true if query result contains account information. (see function withAccountInformation). */
private $hasAccountInfo;
/** @var bool Will be true if query result includes bill information. */
private $hasBillInformation;
/** @var bool Will be true if query result contains budget info. */
private $hasBudgetInformation;
/** @var bool Will be true if query result contains category info. */
private $hasCatInformation;
/** @var bool Will be true for attachments */
private $hasJoinedAttTables;
/** @var bool Will be true of the query has the tag info tables joined. */
private $hasJoinedTagTables;
/** @var array */
private $integerFields;
/** @var int The maximum number of results. */
private $limit;
/** @var int The page to return. */
private $page;
/** @var HasMany The query object. */
private $query;
/** @var int Total number of results. */
private $total;
/** @var User The user object. */
private $user;
}

View File

@ -26,6 +26,8 @@ namespace FireflyIII\Helpers\Collector;
use Carbon\Carbon; use Carbon\Carbon;
use Carbon\Exceptions\InvalidDateException; use Carbon\Exceptions\InvalidDateException;
use Exception; use Exception;
use FireflyIII\Helpers\Collector\Extensions\AccountCollection;
use FireflyIII\Helpers\Collector\Extensions\CollectorProperties;
use FireflyIII\Models\Bill; use FireflyIII\Models\Bill;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
use FireflyIII\Models\Category; use FireflyIII\Models\Category;
@ -48,32 +50,7 @@ use Log;
*/ */
class GroupCollector implements GroupCollectorInterface class GroupCollector implements GroupCollectorInterface
{ {
/** @var array The standard fields to select. */ use CollectorProperties, AccountCollection;
private $fields;
/** @var bool Will be set to true if query result contains account information. (see function withAccountInformation). */
private $hasAccountInfo;
/** @var bool Will be true if query result includes bill information. */
private $hasBillInformation;
/** @var bool Will be true if query result contains budget info. */
private $hasBudgetInformation;
/** @var bool Will be true if query result contains category info. */
private $hasCatInformation;
/** @var bool Will be true for attachments */
private $hasJoinedAttTables;
/** @var bool Will be true of the query has the tag info tables joined. */
private $hasJoinedTagTables;
/** @var array */
private $integerFields;
/** @var int The maximum number of results. */
private $limit;
/** @var int The page to return. */
private $page;
/** @var HasMany The query object. */
private $query;
/** @var int Total number of results. */
private $total;
/** @var User The user object. */
private $user;
/** /**
* Group collector constructor. * Group collector constructor.
@ -216,44 +193,6 @@ class GroupCollector implements GroupCollectorInterface
echo '</pre>'; echo '</pre>';
} }
/**
* These accounts must not be destination accounts.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function excludeDestinationAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereNotIn('destination.account_id', $accountIds);
app('log')->debug(sprintf('GroupCollector: excludeDestinationAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/**
* These accounts must not be source accounts.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function excludeSourceAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereNotIn('source.account_id', $accountIds);
app('log')->debug(sprintf('GroupCollector: excludeSourceAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/** /**
* Return the transaction journals without group information. Is useful in some instances. * Return the transaction journals without group information. Is useful in some instances.
* *
@ -336,29 +275,6 @@ class GroupCollector implements GroupCollectorInterface
return $sum; return $sum;
} }
/**
* Define which accounts can be part of the source and destination transactions.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->where(
static function (EloquentBuilder $query) use ($accountIds) {
$query->whereIn('source.account_id', $accountIds);
$query->orWhereIn('destination.account_id', $accountIds);
}
);
app('log')->debug(sprintf('GroupCollector: setAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/** /**
* Collect transactions after a specific date. * Collect transactions after a specific date.
* *
@ -421,29 +337,6 @@ class GroupCollector implements GroupCollectorInterface
return $this; return $this;
} }
/**
* Both source AND destination must be in this list of accounts.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setBothAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->where(
static function (EloquentBuilder $query) use ($accountIds) {
$query->whereIn('source.account_id', $accountIds);
$query->whereIn('destination.account_id', $accountIds);
}
);
app('log')->debug(sprintf('GroupCollector: setBothAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/** /**
* Limit the search to a specific budget. * Limit the search to a specific budget.
* *
@ -545,25 +438,6 @@ class GroupCollector implements GroupCollectorInterface
return $this; return $this;
} }
/**
* Define which accounts can be part of the source and destination transactions.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setDestinationAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereIn('destination.account_id', $accountIds);
app('log')->debug(sprintf('GroupCollector: setDestinationAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/** /**
* Limit the result to a specific transaction group. * Limit the result to a specific transaction group.
* *
@ -658,7 +532,7 @@ class GroupCollector implements GroupCollectorInterface
public function setSearchWords(array $array): GroupCollectorInterface public function setSearchWords(array $array): GroupCollectorInterface
{ {
$this->query->where( $this->query->where(
function (EloquentBuilder $q) use ($array) { static function (EloquentBuilder $q) use ($array) {
$q->where( $q->where(
function (EloquentBuilder $q1) use ($array) { function (EloquentBuilder $q1) use ($array) {
foreach ($array as $word) { foreach ($array as $word) {
@ -668,7 +542,7 @@ class GroupCollector implements GroupCollectorInterface
} }
); );
$q->orWhere( $q->orWhere(
function (EloquentBuilder $q2) use ($array) { static function (EloquentBuilder $q2) use ($array) {
foreach ($array as $word) { foreach ($array as $word) {
$keyword = sprintf('%%%s%%', $word); $keyword = sprintf('%%%s%%', $word);
$q2->where('transaction_groups.title', 'LIKE', $keyword); $q2->where('transaction_groups.title', 'LIKE', $keyword);
@ -681,25 +555,6 @@ class GroupCollector implements GroupCollectorInterface
return $this; return $this;
} }
/**
* Define which accounts can be part of the source and destination transactions.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setSourceAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereIn('source.account_id', $accountIds);
app('log')->debug(sprintf('GroupCollector: setSourceAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/** /**
* Limit results to a specific tag. * Limit results to a specific tag.
* *
@ -791,43 +646,6 @@ class GroupCollector implements GroupCollectorInterface
return $this; return $this;
} }
/**
* Either account can be set, but NOT both. This effectively excludes internal transfers.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setXorAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->where(
static function (EloquentBuilder $q1) use ($accountIds) {
// sourceAccount is in the set, and destination is NOT.
$q1->where(
static function (EloquentBuilder $q2) use ($accountIds) {
$q2->whereIn('source.account_id', $accountIds);
$q2->whereNotIn('destination.account_id', $accountIds);
}
);
// destination is in the set, and source is NOT
$q1->orWhere(
static function (EloquentBuilder $q3) use ($accountIds) {
$q3->whereNotIn('source.account_id', $accountIds);
$q3->whereIn('destination.account_id', $accountIds);
}
);
}
);
app('log')->debug(sprintf('GroupCollector: setXorAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/** /**
* Automatically include all stuff required to make API calls work. * Automatically include all stuff required to make API calls work.
* *
@ -847,40 +665,6 @@ class GroupCollector implements GroupCollectorInterface
return $this; return $this;
} }
/**
* Will include the source and destination account names and types.
*
* @return GroupCollectorInterface
*/
public function withAccountInformation(): GroupCollectorInterface
{
if (false === $this->hasAccountInfo) {
// join source account table
$this->query->leftJoin('accounts as source_account', 'source_account.id', '=', 'source.account_id');
// join source account type table
$this->query->leftJoin('account_types as source_account_type', 'source_account_type.id', '=', 'source_account.account_type_id');
// add source account fields:
$this->fields[] = 'source_account.name as source_account_name';
$this->fields[] = 'source_account.iban as source_account_iban';
$this->fields[] = 'source_account_type.type as source_account_type';
// same for dest
$this->query->leftJoin('accounts as dest_account', 'dest_account.id', '=', 'destination.account_id');
$this->query->leftJoin('account_types as dest_account_type', 'dest_account_type.id', '=', 'dest_account.account_type_id');
// and add fields:
$this->fields[] = 'dest_account.name as destination_account_name';
$this->fields[] = 'dest_account.iban as destination_account_iban';
$this->fields[] = 'dest_account_type.type as destination_account_type';
$this->hasAccountInfo = true;
}
return $this;
}
/** /**
* @inheritDoc * @inheritDoc
*/ */