Compare commits

...

3 Commits

Author SHA1 Message Date
github-actions[bot]
b670f81dcd Merge pull request #10875 from firefly-iii/release-1757313349
🤖 Automatically merge the PR into the develop branch.
2025-09-08 08:36:01 +02:00
JC5
7aac1cdf67 🤖 Auto commit for release 'develop' on 2025-09-08 2025-09-08 08:35:49 +02:00
Sander Dorigo
fa0ac8a16c Fix php files 2025-09-08 08:31:09 +02:00
17 changed files with 40 additions and 39 deletions

View File

@@ -46,7 +46,7 @@ class TransactionCurrencyFactory
$data['decimal_places'] = (int)$data['decimal_places'];
// if the code already exists (deleted)
// force delete it and then create the transaction:
$count = TransactionCurrency::withTrashed()->whereCode($data['code'])->count();
$count = TransactionCurrency::withTrashed()->whereCode($data['code'])->count();
if (1 === $count) {
$old = TransactionCurrency::withTrashed()->whereCode($data['code'])->first();
$old->forceDelete();
@@ -104,6 +104,7 @@ class TransactionCurrencyFactory
}
}
Log::info(sprintf('Found currency #%d based on ID %d and code "%s".', $currency->id, $currencyId, $currencyCode));
return $currency;
}
}

View File

@@ -1177,7 +1177,8 @@ class GroupCollector implements GroupCollectorInterface
// include budget ID + name (if any)
->withBudgetInformation()
// include bill ID + name (if any)
->withBillInformation();
->withBillInformation()
;
return $this;
}

View File

@@ -62,7 +62,7 @@ class SubscriptionsOverdueReminder extends Notification
'bill' => $item['bill'],
];
$current['pay_dates'] = array_map(
static fn(string $date): string => new Carbon($date)->isoFormat((string)trans('config.month_and_day_moment_js')),
static fn (string $date): string => new Carbon($date)->isoFormat((string)trans('config.month_and_day_moment_js')),
$item['dates']['pay_dates']
);
$info[] = $current;

View File

@@ -294,7 +294,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
$summarizer->setConvertToPrimary($convertToPrimary);
// filter $journals by range AND currency if it is present.
$expenses = array_filter($expenses, static fn(array $expense): bool => $expense['date']->between($start, $end) && $expense['currency_id'] === $transactionCurrency->id);
$expenses = array_filter($expenses, static fn (array $expense): bool => $expense['date']->between($start, $end) && $expense['currency_id'] === $transactionCurrency->id);
return $summarizer->groupByCurrencyId($expenses, 'negative', false);
}
@@ -306,7 +306,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
$summarizer->setConvertToPrimary($convertToPrimary);
// filter $journals by range AND currency if it is present.
$expenses = array_filter($expenses, static fn(array $expense): bool => $expense['budget_id'] === $budget->id);
$expenses = array_filter($expenses, static fn (array $expense): bool => $expense['budget_id'] === $budget->id);
return $summarizer->groupByCurrencyId($expenses, 'negative', false);
}

View File

@@ -44,6 +44,7 @@ use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Override;
use function Safe\json_encode;
/**
@@ -69,7 +70,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
public function currencyInUseAt(TransactionCurrency $currency): ?string
{
Log::debug(sprintf('Now in currencyInUse() for #%d ("%s")', $currency->id, $currency->code));
$countJournals = $this->countJournals($currency);
$countJournals = $this->countJournals($currency);
if ($countJournals > 0) {
Log::info(sprintf('Count journals is %d, return true.', $countJournals));
@@ -84,7 +85,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
}
// is being used in accounts:
$meta = AccountMeta::where('name', 'currency_id')->where('data', json_encode((string)$currency->id))->count();
$meta = AccountMeta::where('name', 'currency_id')->where('data', json_encode((string)$currency->id))->count();
if ($meta > 0) {
Log::info(sprintf('Used in %d accounts as currency_id, return true. ', $meta));
@@ -92,7 +93,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
}
// second search using integer check.
$meta = AccountMeta::where('name', 'currency_id')->where('data', json_encode((int)$currency->id))->count();
$meta = AccountMeta::where('name', 'currency_id')->where('data', json_encode((int)$currency->id))->count();
if ($meta > 0) {
Log::info(sprintf('Used in %d accounts as currency_id, return true. ', $meta));
@@ -100,7 +101,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
}
// is being used in bills:
$bills = Bill::where('transaction_currency_id', $currency->id)->count();
$bills = Bill::where('transaction_currency_id', $currency->id)->count();
if ($bills > 0) {
Log::info(sprintf('Used in %d bills as currency, return true. ', $bills));
@@ -118,9 +119,10 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
}
// is being used in accounts (as integer)
$meta = AccountMeta::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id')
->whereNull('accounts.deleted_at')
->where('account_meta.name', 'currency_id')->where('account_meta.data', json_encode($currency->id))->count();
$meta = AccountMeta::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id')
->whereNull('accounts.deleted_at')
->where('account_meta.name', 'currency_id')->where('account_meta.data', json_encode($currency->id))->count()
;
if ($meta > 0) {
Log::info(sprintf('Used in %d accounts as currency_id, return true. ', $meta));
@@ -136,7 +138,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
}
// is being used in budget limits
$budgetLimit = BudgetLimit::where('transaction_currency_id', $currency->id)->count();
$budgetLimit = BudgetLimit::where('transaction_currency_id', $currency->id)->count();
if ($budgetLimit > 0) {
Log::info(sprintf('Used in %d budget limits as currency, return true. ', $budgetLimit));
@@ -144,7 +146,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
}
// is the default currency for the user or the system
$count = $this->userGroup->currencies()->where('transaction_currencies.id', $currency->id)->wherePivot('group_default', 1)->count();
$count = $this->userGroup->currencies()->where('transaction_currencies.id', $currency->id)->wherePivot('group_default', 1)->count();
if ($count > 0) {
Log::info('Is the default currency of the user, return true.');
@@ -152,7 +154,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
}
// is the default currency for the user or the system
$count = $this->userGroup->currencies()->where('transaction_currencies.id', $currency->id)->wherePivot('group_default', 1)->count();
$count = $this->userGroup->currencies()->where('transaction_currencies.id', $currency->id)->wherePivot('group_default', 1)->count();
if ($count > 0) {
Log::info('Is the default currency of the user group, return true.');
@@ -181,8 +183,8 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
$local = $this->get();
return $all->map(static function (TransactionCurrency $current) use ($local) {
$hasId = $local->contains(static fn(TransactionCurrency $entry) => $entry->id === $current->id);
$isPrimary = $local->contains(static fn(TransactionCurrency $entry) => 1 === (int)$entry->pivot->group_default && $entry->id === $current->id);
$hasId = $local->contains(static fn (TransactionCurrency $entry) => $entry->id === $current->id);
$isPrimary = $local->contains(static fn (TransactionCurrency $entry) => 1 === (int)$entry->pivot->group_default && $entry->id === $current->id);
$current->userGroupEnabled = $hasId;
$current->userGroupNative = $isPrimary;
@@ -286,6 +288,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
} catch (FireflyException) {
return null;
}
return $result;
}
@@ -299,6 +302,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
} catch (FireflyException) {
return null;
}
return $result;
}
@@ -333,9 +337,10 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
/** @var null|CurrencyExchangeRate $rate */
$rate = $this->user->currencyExchangeRates()
->where('from_currency_id', $fromCurrency->id)
->where('to_currency_id', $toCurrency->id)
->where('date', $date->format('Y-m-d'))->first();
->where('from_currency_id', $fromCurrency->id)
->where('to_currency_id', $toCurrency->id)
->where('date', $date->format('Y-m-d'))->first()
;
if (null !== $rate) {
Log::debug(sprintf('Found cached exchange rate in database for %s to %s on %s', $fromCurrency->code, $toCurrency->code, $date->format('Y-m-d')));

View File

@@ -28,9 +28,7 @@ use Illuminate\Contracts\Validation\ValidationRule;
class IsValidSortInstruction implements ValidationRule
{
public function __construct(private readonly string $class)
{
}
public function __construct(private readonly string $class) {}
public function validate(string $attribute, mixed $value, Closure $fail): void
{

View File

@@ -221,7 +221,7 @@ class JournalUpdateService
private function hasFields(array $fields): bool
{
return array_any($fields, fn($field) => array_key_exists($field, $this->data));
return array_any($fields, fn ($field) => array_key_exists($field, $this->data));
}
private function getOriginalSourceAccount(): Account

View File

@@ -458,7 +458,7 @@ class AccountEnrichment implements EnrichmentInterface
case 'current_balance':
case 'pc_current_balance':
$this->collection = $this->collection->sortBy(static fn(Account $account) => $account->meta['balances'][$parameter[0]] ?? '0', SORT_NUMERIC, 'desc' === $parameter[1]);
$this->collection = $this->collection->sortBy(static fn (Account $account) => $account->meta['balances'][$parameter[0]] ?? '0', SORT_NUMERIC, 'desc' === $parameter[1]);
break;
}

View File

@@ -181,13 +181,13 @@ class BudgetLimitEnrichment implements EnrichmentInterface
private function stringifyIds(): void
{
$this->expenses = array_map(fn($first) => array_map(function ($second) {
$this->expenses = array_map(fn ($first) => array_map(function ($second) {
$second['currency_id'] = (string)($second['currency_id'] ?? 0);
return $second;
}, $first), $this->expenses);
$this->pcExpenses = array_map(fn($first) => array_map(function ($second) {
$this->pcExpenses = array_map(fn ($first) => array_map(function ($second) {
$second['currency_id'] = (string)($second['currency_id'] ?? 0);
return $second;
@@ -196,6 +196,6 @@ class BudgetLimitEnrichment implements EnrichmentInterface
private function filterToBudget(array $expenses, int $budget): array
{
return array_filter($expenses, fn(array $item) => (int)$item['budget_id'] === $budget);
return array_filter($expenses, fn (array $item) => (int)$item['budget_id'] === $budget);
}
}

View File

@@ -274,7 +274,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
// At this point the "next match" is exactly after the last time the bill was paid.
$result = [];
$filtered = $set->filter(fn(TransactionJournal $journal) => (int)$journal->bill_id === (int)$subscription->id);
$filtered = $set->filter(fn (TransactionJournal $journal) => (int)$journal->bill_id === (int)$subscription->id);
foreach ($filtered as $entry) {
$array = [
'transaction_group_id' => (string)$entry->transaction_group_id,
@@ -344,7 +344,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
*/
protected function lastPaidDate(Bill $subscription, Collection $dates, Carbon $default): Carbon
{
$filtered = $dates->filter(fn(TransactionJournal $journal) => (int)$journal->bill_id === (int)$subscription->id);
$filtered = $dates->filter(fn (TransactionJournal $journal) => (int)$journal->bill_id === (int)$subscription->id);
Log::debug(sprintf('Filtered down from %d to %d entries for bill #%d.', $dates->count(), $filtered->count(), $subscription->id));
if (0 === $filtered->count()) {
return $default;

View File

@@ -348,7 +348,7 @@ class Steam
$currency = $currencies[$account->id];
// second array
$accountSum = array_filter($arrayOfSums, fn($entry) => $entry['account_id'] === $account->id);
$accountSum = array_filter($arrayOfSums, fn ($entry) => $entry['account_id'] === $account->id);
if (0 === count($accountSum)) {
$result[$account->id] = $return;

View File

@@ -78,8 +78,8 @@ return [
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
// see cer.php for exchange rates feature flag.
],
'version' => 'develop/2025-09-07',
'build_time' => 1757249809,
'version' => 'develop/2025-09-08',
'build_time' => 1757313229,
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 26,

View File

@@ -116,9 +116,9 @@
"webhook_trigger_DESTROY_BUDGET": "After budget delete",
"webhook_trigger_STORE_UPDATE_BUDGET_LIMIT": "After budgeted amount change",
"webhook_response_TRANSACTIONS": "\u039b\u03b5\u03c0\u03c4\u03bf\u03bc\u03ad\u03c1\u03b5\u03b9\u03b5\u03c2 \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae\u03c2",
"webhook_response_RELEVANT": "Relevant details",
"webhook_response_RELEVANT": "\u03a3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ad\u03c2 \u03bb\u03b5\u03c0\u03c4\u03bf\u03bc\u03ad\u03c1\u03b5\u03b9\u03b5\u03c2",
"webhook_response_ACCOUNTS": "\u03a0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd",
"webhook_response_NONE": "No details",
"webhook_response_NONE": "\u0394\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03c5\u03bd \u03bb\u03b5\u03c0\u03c4\u03bf\u03bc\u03ad\u03c1\u03b5\u03b9\u03b5\u03c2",
"webhook_delivery_JSON": "JSON",
"actions": "\u0395\u03bd\u03ad\u03c1\u03b3\u03b5\u03b9\u03b5\u03c2",
"meta_data": "\u039c\u03b5\u03c4\u03b1-\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1",

View File

@@ -39,7 +39,6 @@ final class AccountControllerTest extends TestCase
use RefreshDatabase;
private $user;
#[Override]
#[Override]
protected function setUp(): void
{

View File

@@ -39,7 +39,6 @@ final class BalanceControllerTest extends TestCase
use RefreshDatabase;
private $user;
#[Override]
#[Override]
protected function setUp(): void
{

View File

@@ -39,7 +39,6 @@ final class BudgetControllerTest extends TestCase
use RefreshDatabase;
private $user;
#[Override]
#[Override]
protected function setUp(): void
{

View File

@@ -39,7 +39,6 @@ final class CategoryControllerTest extends TestCase
use RefreshDatabase;
private $user;
#[Override]
#[Override]
protected function setUp(): void
{