mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Update internal filters.
This commit is contained in:
parent
68a01b1735
commit
c83dfc44d6
@ -18,12 +18,15 @@ use Carbon\Carbon;
|
|||||||
use Crypt;
|
use Crypt;
|
||||||
use DB;
|
use DB;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
|
use FireflyIII\Helpers\Filter\FilterInterface;
|
||||||
|
use FireflyIII\Helpers\Filter\InternalTransferFilter;
|
||||||
|
use FireflyIII\Helpers\Filter\OpposingAccountFilter;
|
||||||
|
use FireflyIII\Helpers\Filter\TransferFilter;
|
||||||
use FireflyIII\Models\AccountType;
|
use FireflyIII\Models\AccountType;
|
||||||
use FireflyIII\Models\Budget;
|
use FireflyIII\Models\Budget;
|
||||||
use FireflyIII\Models\Category;
|
use FireflyIII\Models\Category;
|
||||||
use FireflyIII\Models\Tag;
|
use FireflyIII\Models\Tag;
|
||||||
use FireflyIII\Models\Transaction;
|
use FireflyIII\Models\Transaction;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Contracts\Encryption\DecryptException;
|
use Illuminate\Contracts\Encryption\DecryptException;
|
||||||
@ -74,6 +77,9 @@ class JournalCollector implements JournalCollectorInterface
|
|||||||
private $filterInternalTransfers;
|
private $filterInternalTransfers;
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
private $filterTransfers = false;
|
private $filterTransfers = false;
|
||||||
|
/** @var array */
|
||||||
|
private $filters = [InternalTransferFilter::class];
|
||||||
|
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
private $joinedBudget = false;
|
private $joinedBudget = false;
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
@ -95,6 +101,22 @@ class JournalCollector implements JournalCollectorInterface
|
|||||||
/** @var User */
|
/** @var User */
|
||||||
private $user;
|
private $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $filter
|
||||||
|
*
|
||||||
|
* @return JournalCollectorInterface
|
||||||
|
*/
|
||||||
|
public function addFilter(string $filter): JournalCollectorInterface
|
||||||
|
{
|
||||||
|
$interfaces = class_implements($filter);
|
||||||
|
if (in_array(FilterInterface::class, $interfaces)) {
|
||||||
|
Log::debug(sprintf('Enabled filter %s', $filter));
|
||||||
|
$this->filters[] = $filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
@ -119,36 +141,6 @@ class JournalCollector implements JournalCollectorInterface
|
|||||||
return $this->count;
|
return $this->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return JournalCollectorInterface
|
|
||||||
*/
|
|
||||||
public function disableFilter(): JournalCollectorInterface
|
|
||||||
{
|
|
||||||
$this->filterTransfers = false;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return JournalCollectorInterface
|
|
||||||
*/
|
|
||||||
public function disableInternalFilter(): JournalCollectorInterface
|
|
||||||
{
|
|
||||||
$this->filterInternalTransfers = false;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return JournalCollectorInterface
|
|
||||||
*/
|
|
||||||
public function enableInternalFilter(): JournalCollectorInterface
|
|
||||||
{
|
|
||||||
$this->filterInternalTransfers = true;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
@ -157,14 +149,9 @@ class JournalCollector implements JournalCollectorInterface
|
|||||||
$this->run = true;
|
$this->run = true;
|
||||||
/** @var Collection $set */
|
/** @var Collection $set */
|
||||||
$set = $this->query->get(array_values($this->fields));
|
$set = $this->query->get(array_values($this->fields));
|
||||||
Log::debug(sprintf('Count of set is %d', $set->count()));
|
|
||||||
$set = $this->filterTransfers($set);
|
|
||||||
Log::debug(sprintf('Count of set after filterTransfers() is %d', $set->count()));
|
|
||||||
|
|
||||||
// possibly filter "internal" transfers:
|
|
||||||
$set = $this->filterInternalTransfers($set);
|
|
||||||
Log::debug(sprintf('Count of set after filterInternalTransfers() is %d', $set->count()));
|
|
||||||
|
|
||||||
|
// run all filters:
|
||||||
|
$set = $this->filter($set);
|
||||||
|
|
||||||
// loop for decryption.
|
// loop for decryption.
|
||||||
$set->each(
|
$set->each(
|
||||||
@ -204,6 +191,22 @@ class JournalCollector implements JournalCollectorInterface
|
|||||||
return $journals;
|
return $journals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $filter
|
||||||
|
*
|
||||||
|
* @return JournalCollectorInterface
|
||||||
|
*/
|
||||||
|
public function removeFilter(string $filter): JournalCollectorInterface
|
||||||
|
{
|
||||||
|
$key = array_search($filter, $this->filters, true);
|
||||||
|
if (!($key === false)) {
|
||||||
|
Log::debug('Removed filter %s', $filter);
|
||||||
|
unset($this->filters[$key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
*
|
*
|
||||||
@ -219,6 +222,7 @@ class JournalCollector implements JournalCollectorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($accounts->count() > 1) {
|
if ($accounts->count() > 1) {
|
||||||
|
$this->addFilter(TransferFilter::class);
|
||||||
$this->filterTransfers = true;
|
$this->filterTransfers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,6 +246,7 @@ class JournalCollector implements JournalCollectorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($accounts->count() > 1) {
|
if ($accounts->count() > 1) {
|
||||||
|
$this->addFilter(TransferFilter::class);
|
||||||
$this->filterTransfers = true;
|
$this->filterTransfers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,79 +568,21 @@ class JournalCollector implements JournalCollectorInterface
|
|||||||
*
|
*
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
private function filterInternalTransfers(Collection $set): Collection
|
private function filter(Collection $set): Collection
|
||||||
{
|
{
|
||||||
if ($this->filterInternalTransfers === false) {
|
// create all possible filters:
|
||||||
Log::debug('Did NO filtering for internal transfers on given set.');
|
$filters = [
|
||||||
|
InternalTransferFilter::class => new InternalTransferFilter($this->accountIds),
|
||||||
return $set;
|
OpposingAccountFilter::class => new OpposingAccountFilter($this->accountIds),
|
||||||
}
|
TransferFilter::class => new TransferFilter,
|
||||||
if ($this->joinedOpposing === false) {
|
];
|
||||||
Log::info('Cannot filter internal transfers because no opposing information is present.');
|
Log::debug(sprintf('Will run %d filters on the set.', count($this->filters)));
|
||||||
|
foreach ($this->filters as $enabled) {
|
||||||
return $set;
|
if (isset($filters[$enabled])) {
|
||||||
}
|
Log::debug(sprintf('Before filter %s: %d', $enabled, $set->count()));
|
||||||
|
$set = $filters[$enabled]->filter($set);
|
||||||
$accountIds = $this->accountIds;
|
Log::debug(sprintf('After filter %s: %d', $enabled, $set->count()));
|
||||||
$set = $set->filter(
|
|
||||||
function (Transaction $transaction) use ($accountIds) {
|
|
||||||
// both id's in $accountids?
|
|
||||||
if (in_array($transaction->account_id, $accountIds) && in_array($transaction->opposing_account_id, $accountIds)) {
|
|
||||||
Log::debug(
|
|
||||||
sprintf(
|
|
||||||
'Transaction #%d has #%d and #%d in set, so removed',
|
|
||||||
$transaction->id, $transaction->account_id, $transaction->opposing_account_id
|
|
||||||
), $accountIds
|
|
||||||
);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $transaction;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
|
||||||
return $set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the set of accounts used by the collector includes more than one asset
|
|
||||||
* account, chances are the set include double entries: transfers get selected
|
|
||||||
* on both the source, and then again on the destination account.
|
|
||||||
*
|
|
||||||
* This method filters them out by removing transfers that have been selected twice.
|
|
||||||
*
|
|
||||||
* @param Collection $set
|
|
||||||
*
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
private function filterTransfers(Collection $set): Collection
|
|
||||||
{
|
|
||||||
if ($this->filterTransfers) {
|
|
||||||
$count = [];
|
|
||||||
$new = new Collection;
|
|
||||||
/** @var Transaction $transaction */
|
|
||||||
foreach ($set as $transaction) {
|
|
||||||
if ($transaction->transaction_type_type !== TransactionType::TRANSFER) {
|
|
||||||
$new->push($transaction);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// make property string:
|
|
||||||
$journalId = $transaction->transaction_journal_id;
|
|
||||||
$amount = Steam::positive($transaction->transaction_amount);
|
|
||||||
$accountIds = [intval($transaction->account_id), intval($transaction->opposing_account_id)];
|
|
||||||
sort($accountIds);
|
|
||||||
$key = $journalId . '-' . join(',', $accountIds) . '-' . $amount;
|
|
||||||
Log::debug(sprintf('Key is %s', $key));
|
|
||||||
if (!isset($count[$key])) {
|
|
||||||
// not yet counted? add to new set and count it:
|
|
||||||
$new->push($transaction);
|
|
||||||
$count[$key] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $new;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $set;
|
return $set;
|
||||||
|
@ -28,26 +28,18 @@ use Illuminate\Support\Collection;
|
|||||||
*/
|
*/
|
||||||
interface JournalCollectorInterface
|
interface JournalCollectorInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @param string $filter
|
||||||
|
*
|
||||||
|
* @return JournalCollectorInterface
|
||||||
|
*/
|
||||||
|
public function addFilter(string $filter): JournalCollectorInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function count(): int;
|
public function count(): int;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return JournalCollectorInterface
|
|
||||||
*/
|
|
||||||
public function disableFilter(): JournalCollectorInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return JournalCollectorInterface
|
|
||||||
*/
|
|
||||||
public function disableInternalFilter(): JournalCollectorInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return JournalCollectorInterface
|
|
||||||
*/
|
|
||||||
public function enableInternalFilter(): JournalCollectorInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
@ -58,6 +50,13 @@ interface JournalCollectorInterface
|
|||||||
*/
|
*/
|
||||||
public function getPaginatedJournals(): LengthAwarePaginator;
|
public function getPaginatedJournals(): LengthAwarePaginator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $filter
|
||||||
|
*
|
||||||
|
* @return JournalCollectorInterface
|
||||||
|
*/
|
||||||
|
public function removeFilter(string $filter): JournalCollectorInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
*
|
*
|
||||||
|
@ -25,19 +25,25 @@ use Log;
|
|||||||
*/
|
*/
|
||||||
class AmountFilter implements FilterInterface
|
class AmountFilter implements FilterInterface
|
||||||
{
|
{
|
||||||
|
/** @var int */
|
||||||
|
private $modifier = 0;
|
||||||
|
|
||||||
|
public function __construct(int $modifier)
|
||||||
|
{
|
||||||
|
$this->modifier = $modifier;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $set
|
* @param Collection $set
|
||||||
* @param null $parameters
|
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
public function filter(Collection $set, $parameters = null): Collection
|
public function filter(Collection $set): Collection
|
||||||
{
|
{
|
||||||
return $set->filter(
|
return $set->filter(
|
||||||
function (Transaction $transaction) use ($parameters) {
|
function (Transaction $transaction) {
|
||||||
// remove by amount
|
// remove by amount
|
||||||
if (bccomp($transaction->transaction_amount, '0') === $parameters) {
|
if (bccomp($transaction->transaction_amount, '0') === $this->modifier) {
|
||||||
Log::debug(sprintf('Filtered #%d because amount is %f.', $transaction->id, $transaction->transaction_amount));
|
Log::debug(sprintf('Filtered #%d because amount is %f.', $transaction->id, $transaction->transaction_amount));
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -24,13 +24,11 @@ class EmptyFilter implements FilterInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $set
|
* @param Collection $set
|
||||||
* @param null $parameters
|
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
public function filter(Collection $set, $parameters = null): Collection
|
public function filter(Collection $set): Collection
|
||||||
{
|
{
|
||||||
// TODO: Implement filter() method.
|
return $set;
|
||||||
throw new NotImplementedException;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,10 +18,9 @@ interface FilterInterface
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param Collection $set
|
* @param Collection $set
|
||||||
* @param null $parameters
|
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
public function filter(Collection $set, $parameters = null): Collection;
|
public function filter(Collection $set): Collection;
|
||||||
|
|
||||||
}
|
}
|
@ -26,27 +26,38 @@ use Log;
|
|||||||
*/
|
*/
|
||||||
class InternalTransferFilter implements FilterInterface
|
class InternalTransferFilter implements FilterInterface
|
||||||
{
|
{
|
||||||
|
/** @var array */
|
||||||
|
private $accounts = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* InternalTransferFilter constructor.
|
||||||
|
*
|
||||||
|
* @param array $accounts
|
||||||
|
*/
|
||||||
|
public function __construct(array $accounts)
|
||||||
|
{
|
||||||
|
$this->accounts = $accounts;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $set
|
* @param Collection $set
|
||||||
* @param null $parameters
|
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
public function filter(Collection $set, $parameters = null): Collection
|
public function filter(Collection $set): Collection
|
||||||
{
|
{
|
||||||
return $set->filter(
|
return $set->filter(
|
||||||
function (Transaction $transaction) use ($parameters) {
|
function (Transaction $transaction) {
|
||||||
if (is_null($transaction->opposing_account_id)) {
|
if (is_null($transaction->opposing_account_id)) {
|
||||||
return $transaction;
|
return $transaction;
|
||||||
}
|
}
|
||||||
// both id's in $parameters?
|
// both id's in $parameters?
|
||||||
if (in_array($transaction->account_id, $parameters) && in_array($transaction->opposing_account_id, $parameters)) {
|
if (in_array($transaction->account_id, $this->accounts) && in_array($transaction->opposing_account_id, $this->accounts)) {
|
||||||
Log::debug(
|
Log::debug(
|
||||||
sprintf(
|
sprintf(
|
||||||
'Transaction #%d has #%d and #%d in set, so removed',
|
'Transaction #%d has #%d and #%d in set, so removed',
|
||||||
$transaction->id, $transaction->account_id, $transaction->opposing_account_id
|
$transaction->id, $transaction->account_id, $transaction->opposing_account_id
|
||||||
), $parameters
|
), $this->accounts
|
||||||
);
|
);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -26,21 +26,32 @@ use Log;
|
|||||||
*/
|
*/
|
||||||
class OpposingAccountFilter implements FilterInterface
|
class OpposingAccountFilter implements FilterInterface
|
||||||
{
|
{
|
||||||
|
/** @var array */
|
||||||
|
private $accounts = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* InternalTransferFilter constructor.
|
||||||
|
*
|
||||||
|
* @param array $accounts
|
||||||
|
*/
|
||||||
|
public function __construct(array $accounts)
|
||||||
|
{
|
||||||
|
$this->accounts = $accounts;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $set
|
* @param Collection $set
|
||||||
* @param null $parameters
|
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
public function filter(Collection $set, $parameters = null): Collection
|
public function filter(Collection $set): Collection
|
||||||
{
|
{
|
||||||
return $set->filter(
|
return $set->filter(
|
||||||
function (Transaction $transaction) use ($parameters) {
|
function (Transaction $transaction) {
|
||||||
$opposing = $transaction->opposing_account_id;
|
$opposing = $transaction->opposing_account_id;
|
||||||
// remove internal transfer
|
// remove internal transfer
|
||||||
if (in_array($opposing, $parameters)) {
|
if (in_array($opposing, $this->accounts)) {
|
||||||
Log::debug(sprintf('Filtered #%d because its opposite is in accounts.', $transaction->id), $parameters);
|
Log::debug(sprintf('Filtered #%d because its opposite is in accounts.', $transaction->id), $this->accounts);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,10 @@ class TransferFilter implements FilterInterface
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param Collection $set
|
* @param Collection $set
|
||||||
* @param null $parameters
|
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
public function filter(Collection $set, $parameters = null): Collection
|
public function filter(Collection $set): Collection
|
||||||
{
|
{
|
||||||
$count = [];
|
$count = [];
|
||||||
$new = new Collection;
|
$new = new Collection;
|
||||||
|
Loading…
Reference in New Issue
Block a user