Fix a few small bugs and rearrange code.

This commit is contained in:
James Cole
2024-03-10 11:57:21 +01:00
parent 3413b9b5b5
commit d5ea78025e
10 changed files with 192 additions and 40 deletions

View File

@@ -67,12 +67,12 @@ class RuleAction extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'active' => 'boolean',
'order' => 'int',
'stop_processing' => 'boolean',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'active' => 'boolean',
'order' => 'int',
'stop_processing' => 'boolean',
];
protected $fillable = ['rule_id', 'action_type', 'action_value', 'order', 'active', 'stop_processing'];

View File

@@ -0,0 +1,127 @@
<?php
/*
* SetAmount.php
* Copyright (c) 2024 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\TransactionRules\Actions;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\TransactionRules\Traits\RefreshNotesTrait;
class SetAmount implements ActionInterface
{
use RefreshNotesTrait;
private RuleAction $action;
/**
* TriggerInterface constructor.
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
public function actOnArray(array $journal): bool
{
$this->refreshNotes($journal);
// not on slpit transactions
$groupCount = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count();
if ($groupCount > 1) {
app('log')->error(sprintf('Group #%d has more than one transaction in it, cannot convert to transfer.', $journal['transaction_group_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.split_group')));
return false;
}
$value = $this->action->getValue($journal);
if (!is_numeric($value) || '' === $value || 0 === bccomp((string)$value, '0')) {
app('log')->debug(sprintf('RuleAction SetAmount, amount "%s" is not a number or is zero, will not continue.', $value));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_invalid_amount', ['amount' => $value])));
return false;
}
/** @var TransactionJournal $object */
$object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
// doesn't actually do anything!
$positive = Steam::positive($value);
$negative = Steam::negative($value);
$this->updatePositive($object, $positive);
$this->updateNegative($object, $negative);
$object->transactionGroup->touch();
// event for audit log entry
event(new TriggeredAuditLog(
$this->action->rule,
$object,
'update_amount',
[
'currency_symbol' => $object->transactionCurrency->symbol,
'decimal_places' => $object->transactionCurrency->decimal_places,
'amount' => $journal['amount'],
],
[
'currency_symbol' => $object->transactionCurrency->symbol,
'decimal_places' => $object->transactionCurrency->decimal_places,
'amount' => $value,
]
));
return true;
}
private function updatePositive(TransactionJournal $object, string $amount): void
{
/** @var null|Transaction $transaction */
$transaction = $object->transactions()->where('amount', '>', 0)->first();
if (null === $transaction) {
return;
}
$this->updateAmount($transaction, $amount);
}
private function updateNegative(TransactionJournal $object, string $amount): void
{
/** @var null|Transaction $transaction */
$transaction = $object->transactions()->where('amount', '<', 0)->first();
if (null === $transaction) {
return;
}
$this->updateAmount($transaction, $amount);
}
private function updateAmount(Transaction $transaction, string $amount): void
{
$transaction->amount = $amount;
$transaction->save();
$transaction->transactionJournal->touch();
}
}

View File

@@ -30,31 +30,31 @@ use Symfony\Component\ExpressionLanguage\SyntaxError;
class ActionExpression
{
private static array $NAMES = [
'transaction_group_id',
'user_id',
'user_group_id',
// 'transaction_group_id',
// 'user_id',
// 'user_group_id',
'created_at',
'updated_at',
'transaction_group_title',
'group_created_at',
'group_updated_at',
'transaction_journal_id',
'transaction_type_id',
// 'transaction_journal_id',
// 'transaction_type_id',
'description',
'date',
'order',
// 'order',
'transaction_type_type',
'source_transaction_id',
// 'source_transaction_id',
'source_account_id',
'reconciled',
// 'reconciled',
'amount',
'currency_id',
// 'currency_id',
'currency_code',
'currency_name',
'currency_symbol',
'currency_decimal_places',
'foreign_amount',
'foreign_currency_id',
// 'foreign_currency_id',
'foreign_currency_code',
'foreign_currency_name',
'foreign_currency_symbol',
@@ -71,14 +71,14 @@ class ActionExpression
'budget_id',
'budget_name',
'tags',
'attachments',
// 'attachments',
'interest_date',
'payment_date',
'invoice_date',
'book_date',
'due_date',
'process_date',
'destination_transaction_id',
// 'destination_transaction_id',
'notes',
];

View File

@@ -32,24 +32,34 @@ class ActionExpressionLanguageProvider implements ExpressionFunctionProviderInte
public function getFunctions(): array
{
return [
new ExpressionFunction('constant', function ($str): string {
return sprintf('(is_string(%1$s) ? strtolower(%1$s) : %1$s)', $str.'!');
}, function ($arguments, $str): string {
if (!is_string($str)) {
return $str;
}
new ExpressionFunction(
'constant',
function ($str): string {
return sprintf('(is_string(%1$s) ? strtolower(%1$s) : %1$s)', $str.'!');
},
// @SuppressWarnings(PHPMD.UnusedFormalParameter)
function ($arguments, $str): string {
if (!is_string($str)) {
return (string) $str;
}
return strtolower($str.'!');
}),
new ExpressionFunction('enum', function ($str): string {
return sprintf('(is_string(%1$s) ? strtolower(%1$s) : %1$s)', $str.'?');
}, function ($arguments, $str): string {
if (!is_string($str)) {
return $str;
return strtolower($str.'!');
}
),
new ExpressionFunction(
'enum',
function ($str): string {
return sprintf('(is_string(%1$s) ? strtolower(%1$s) : %1$s)', $str.'?');
},
// @SuppressWarnings(PHPMD.UnusedFormalParameter)
function ($arguments, $str): string {
if (!is_string($str)) {
return (string) $str;
}
return strtolower($str).'?';
}),
return strtolower($str).'?';
}
),
ExpressionFunction::fromPhp('substr'),
ExpressionFunction::fromPhp('strlen'),

View File

@@ -91,7 +91,7 @@ class AccountTransformer extends AbstractTransformer
// TODO needs separate method.
$sort = $this->parameters->get('sort');
if (count($sort) > 0) {
if (is_countable($sort) && count($sort) > 0) {
foreach ($sort as $column => $direction) {
// account_number + iban
if ('iban' === $column) {

View File

@@ -829,7 +829,8 @@ class FireflyValidator extends Validator
->where('trigger', $trigger)
->where('response', $response)
->where('delivery', $delivery)
->where('url', $url)->count();
->where('url', $url)->count()
;
}
return false;