New rule triggers for account balance.

This commit is contained in:
James Cole
2024-12-23 08:22:54 +01:00
parent 42305672ac
commit 847984f678
5 changed files with 186 additions and 3 deletions

View File

@@ -25,8 +25,11 @@ declare(strict_types=1);
namespace FireflyIII\Helpers\Collector\Extensions;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Account;
use FireflyIII\Support\Facades\Steam;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
/**
* Trait AccountCollection
@@ -228,4 +231,61 @@ trait AccountCollection
return $this;
}
#[\Override] public function accountBalanceIs(string $direction, string $operator, string $value): GroupCollectorInterface
{
Log::warning(sprintf('GroupCollector will be SLOW: accountBalanceIs: "%s" "%s" "%s"', $direction, $operator, $value));
/**
* @param int $index
* @param array $object
*
* @return bool
*/
$filter = static function (array $object) use ($direction, $operator, $value): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
$key = sprintf('%s_account_id', $direction);
$accountId = $transaction[$key] ?? 0;
if (0 === $accountId) {
return false;
}
// in theory, this could lead to finding other users accounts.
$balance = Steam::finalAccountBalance(Account::find($accountId), $transaction['date']);
$result = bccomp($balance['balance'], $value);
Log::debug(sprintf('"%s" vs "%s" is %d', $balance['balance'], $value, $result));
switch ($operator) {
default:
Log::error(sprintf('GroupCollector: accountBalanceIs: unknown operator "%s"', $operator));
return false;
case '==':
Log::debug('Expect result to be 0 (equal)');
return 0 === $result;
case '!=':
Log::debug('Expect result to be -1 or 1 (not equal)');
return 0 !== $result;
case '>':
Log::debug('Expect result to be 1 (greater then)');
return 1 === $result;
case '>=':
Log::debug('Expect result to be 0 or 1 (greater then or equal)');
return -1 !== $result;
case '<':
Log::debug('Expect result to be -1 (less than)');
return -1 === $result;
case '<=':
Log::debug('Expect result to be -1 or 0 (less than or equal)');
return 1 !== $result;
}
//if($balance['balance'] $operator $value) {
//}
}
return false;
};
$this->postFilters[] = $filter;
return $this;
}
}

View File

@@ -732,4 +732,6 @@ interface GroupCollectorInterface
public function yearIs(string $year): self;
public function yearIsNot(string $year): self;
public function accountBalanceIs(string $direction, string $operator, string $value): self;
}

View File

@@ -1822,6 +1822,50 @@ class OperatorQuerySearch implements SearchInterface
case 'sepa_ct_is':
$this->collector->setSepaCT($value);
break;
case 'source_balance_gte':
case '-source_balance_lt':
$this->collector->accountBalanceIs('source', '>=', $value);
break;
case '-source_balance_gte':
case 'source_balance_lt':
$this->collector->accountBalanceIs('source', '<', $value);
break;
case 'source_balance_gt':
case '-source_balance_lte':
$this->collector->accountBalanceIs('source', '>', $value);
break;
case '-source_balance_gt':
case 'source_balance_lte':
$this->collector->accountBalanceIs('source', '<=', $value);
break;
case 'source_balance_is':
$this->collector->accountBalanceIs('source', '==', $value);
break;
case '-source_balance_is':
$this->collector->accountBalanceIs('source', '!=', $value);
break;
case 'destination_balance_gte':
case '-destination_balance_lt':
$this->collector->accountBalanceIs('destination', '>=', $value);
break;
case '-destination_balance_gte':
case 'destination_balance_lt':
$this->collector->accountBalanceIs('destination', '<', $value);
break;
case 'destination_balance_gt':
case '-destination_balance_lte':
$this->collector->accountBalanceIs('destination', '>', $value);
break;
case '-destination_balance_gt':
case 'destination_balance_lte':
$this->collector->accountBalanceIs('destination', '<=', $value);
break;
case 'destination_balance_is':
$this->collector->accountBalanceIs('destination', '==', $value);
break;
case '-destination_balance_is':
$this->collector->accountBalanceIs('destination', '!=', $value);
break;
}

View File

@@ -240,5 +240,17 @@ return [
'sepa_ct_is' => ['alias' => false, 'needs_context' => true],
'no_external_id' => ['alias' => false, 'needs_context' => false],
'any_external_id' => ['alias' => false, 'needs_context' => false],
// based on source or destination balance. Very heavy search.
'source_balance_gte' => ['alias' => false, 'needs_context' => true],
'source_balance_gt' => ['alias' => false, 'needs_context' => true],
'source_balance_lte' => ['alias' => false, 'needs_context' => true],
'source_balance_lt' => ['alias' => false, 'needs_context' => true],
'source_balance_is' => ['alias' => false, 'needs_context' => true],
'destination_balance_gte' => ['alias' => false, 'needs_context' => true],
'destination_balance_gt' => ['alias' => false, 'needs_context' => true],
'destination_balance_lte' => ['alias' => false, 'needs_context' => true],
'destination_balance_lt' => ['alias' => false, 'needs_context' => true],
'destination_balance_is' => ['alias' => false, 'needs_context' => true],
],
];

View File

@@ -699,6 +699,33 @@ return [
'create_rule_from_query' => 'Create new rule from search query',
'rule_from_search_words' => 'The rule engine has a hard time handling ":string". The suggested rule that fits your search query may give different results. Please verify the rule triggers carefully.',
// more new stuff
'search_modifier_destination_balance_is' => 'Destination account balance is exactly ":value"',
'search_modifier_not_destination_balance_is' => 'Destination account balance is NOT exactly ":value"',
'search_modifier_source_balance_is' => 'Source account balance is exactly ":value"',
'search_modifier_not_source_balance_is' => 'Source account balance is NOT exactly ":value"',
'search_modifier_destination_balance_lte' => 'Destination account balance is less than or equal to ":value"',
'search_modifier_not_destination_balance_lte' => 'Destination account balance is more than ":value"',
'search_modifier_source_balance_lte' => 'Source account balance is less than or equal to ":value"',
'search_modifier_not_source_balance_lte' => 'Source account balance is more than ":value"',
'search_modifier_destination_balance_lt' => 'Destination account balance is less than ":value"',
'search_modifier_not_destination_balance_lt' => 'Destination account balance is more than or equal to ":value"',
'search_modifier_source_balance_lt' => 'Source account balance is less than ":value"',
'search_modifier_not_source_balance_lt' => 'Source account balance is more than or equal to ":value"',
'search_modifier_destination_balance_gte' => 'Destination account balance is more than or equal to ":value"',
'search_modifier_not_destination_balance_gte' => 'Destination account balance is less than ":value"',
'search_modifier_source_balance_gte' => 'Source account balance is more than or equal to ":value"',
'search_modifier_not_source_balance_gte' => 'Source account balance is less than ":value"',
'search_modifier_destination_balance_gt' => 'Destination account balance is more than ":value"',
'search_modifier_not_destination_balance_gt' => 'Destination account balance is less than or equal to ":value"',
'search_modifier_source_balance_gt' => 'Source account balance is more than ":value"',
'search_modifier_not_source_balance_gt' => 'Source account balance is less than or equal to ":value"',
// Ignore this comment
// END
@@ -1196,6 +1223,44 @@ return [
'rule_trigger_not_destination_is_cash' => 'Destination account is not a cash account',
'rule_trigger_not_account_is_cash' => 'Neither account is a cash account',
// new account balance things.
'rule_trigger_destination_balance_gt_choice' => 'Destination account balance is more than..',
'rule_trigger_destination_balance_gte_choice' => 'Destination account balance is more than or equal to..',
'rule_trigger_destination_balance_is_choice' => 'Destination account balance is exactly..',
'rule_trigger_destination_balance_lt_choice' => 'Destination account balance is less than..',
'rule_trigger_destination_balance_lte_choice' => 'Destination account balance is less than or equal to..',
'rule_trigger_source_balance_gt_choice' => 'Source account balance is more than..',
'rule_trigger_source_balance_gte_choice' => 'Source account balance is more than or equal to..',
'rule_trigger_source_balance_is_choice' => 'Source account balance is exactly..',
'rule_trigger_source_balance_lt_choice' => 'Source account balance is less than..',
'rule_trigger_source_balance_lte_choice' => 'Source account balance is less than or equal to..',
'rule_trigger_destination_balance_gt' => 'Destination account balance is more than :trigger_value',
'rule_trigger_destination_balance_gte' => 'Destination account balance is more than or equal to :trigger_value',
'rule_trigger_destination_balance_is' => 'Destination account balance is exactly :trigger_value',
'rule_trigger_destination_balance_lt' => 'Destination account balance is less than :trigger_value',
'rule_trigger_destination_balance_lte' => 'Destination account balance is less than or equal to :trigger_value',
'rule_trigger_source_balance_gt' => 'Source account balance is more than :trigger_value',
'rule_trigger_source_balance_gte' => 'Source account balance is more than or equal to :trigger_value',
'rule_trigger_source_balance_is' => 'Source account balance is exactly :trigger_value',
'rule_trigger_source_balance_lt' => 'Source account balance is less than :trigger_value',
'rule_trigger_source_balance_lte' => 'Source account balance is less than or equal to :trigger_value',
// NOT
'rule_trigger_not_destination_balance_gt' => 'Destination account balance is less than or equal to :trigger_value',
'rule_trigger_not_destination_balance_gte' => 'Destination account balance is less than :trigger_value',
'rule_trigger_not_destination_balance_is' => 'Destination account balance is not :trigger_value',
'rule_trigger_not_destination_balance_lt' => 'Destination account balance is more than or equal to :trigger_value',
'rule_trigger_not_destination_balance_lte' => 'Destination account balance is more than :trigger_value',
'rule_trigger_not_source_balance_gt' => 'Source account balance is less than or equal to :trigger_value',
'rule_trigger_not_source_balance_gte' => 'Source account balance is less than :trigger_value',
'rule_trigger_not_source_balance_is' => 'Source account balance is not :trigger_value',
'rule_trigger_not_source_balance_lt' => 'Source account balance is greater than or equal to :trigger_value',
'rule_trigger_not_source_balance_lte' => 'Source account balance is greater than :trigger_value',
// Ignore this comment
// actions