🤖 Auto commit for release 'develop' on 2025-09-26

This commit is contained in:
JC5
2025-09-26 19:43:39 +02:00
parent 853a99852e
commit d3c557ca22
103 changed files with 1411 additions and 1336 deletions

View File

@@ -102,6 +102,7 @@ class StoredGroupEventHandler
{ {
/** @var PeriodStatisticRepositoryInterface $repository */ /** @var PeriodStatisticRepositoryInterface $repository */
$repository = app(PeriodStatisticRepositoryInterface::class); $repository = app(PeriodStatisticRepositoryInterface::class);
/** @var TransactionJournal $journal */ /** @var TransactionJournal $journal */
foreach ($event->transactionGroup->transactionJournals as $journal) { foreach ($event->transactionGroup->transactionJournals as $journal) {
$source = $journal->transactions()->where('amount', '<', '0')->first(); $source = $journal->transactions()->where('amount', '<', '0')->first();

View File

@@ -26,7 +26,6 @@ namespace FireflyIII\Handlers\Events;
use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Enums\WebhookTrigger; use FireflyIII\Enums\WebhookTrigger;
use FireflyIII\Events\RequestedSendWebhookMessages; use FireflyIII\Events\RequestedSendWebhookMessages;
use FireflyIII\Events\StoredTransactionGroup;
use FireflyIII\Events\UpdatedTransactionGroup; use FireflyIII\Events\UpdatedTransactionGroup;
use FireflyIII\Generator\Webhook\MessageGeneratorInterface; use FireflyIII\Generator\Webhook\MessageGeneratorInterface;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
@@ -63,6 +62,7 @@ class UpdatedGroupEventHandler
{ {
/** @var PeriodStatisticRepositoryInterface $repository */ /** @var PeriodStatisticRepositoryInterface $repository */
$repository = app(PeriodStatisticRepositoryInterface::class); $repository = app(PeriodStatisticRepositoryInterface::class);
/** @var TransactionJournal $journal */ /** @var TransactionJournal $journal */
foreach ($event->transactionGroup->transactionJournals as $journal) { foreach ($event->transactionGroup->transactionJournals as $journal) {
$source = $journal->transactions()->where('amount', '<', '0')->first(); $source = $journal->transactions()->where('amount', '<', '0')->first();

View File

@@ -54,6 +54,4 @@ class PeriodStatistic extends Model
return $this->morphTo(); return $this->morphTo();
} }
} }

View File

@@ -547,6 +547,7 @@ class AccountRepository implements AccountRepositoryInterface, UserGroupInterfac
public function periodCollection(Account $account, Carbon $start, Carbon $end): array public function periodCollection(Account $account, Carbon $start, Carbon $end): array
{ {
Log::debug(sprintf('periodCollection(#%d, %s, %s)', $account->id, $start->format('Y-m-d'), $end->format('Y-m-d'))); Log::debug(sprintf('periodCollection(#%d, %s, %s)', $account->id, $start->format('Y-m-d'), $end->format('Y-m-d')));
return $account->transactions() return $account->transactions()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')

View File

@@ -37,7 +37,8 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface
->where('start', $start) ->where('start', $start)
->where('end', $end) ->where('end', $end)
->whereIn('type', $types) ->whereIn('type', $types)
->get(); ->get()
;
} }
public function findPeriodStatistic(Model $model, Carbon $start, Carbon $end, string $type): Collection public function findPeriodStatistic(Model $model, Carbon $start, Carbon $end, string $type): Collection
@@ -46,7 +47,8 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface
->where('start', $start) ->where('start', $start)
->where('end', $end) ->where('end', $end)
->where('type', $type) ->where('type', $type)
->get(); ->get()
;
} }
public function saveStatistic(Model $model, int $currencyId, Carbon $start, Carbon $end, string $type, int $count, string $amount): PeriodStatistic public function saveStatistic(Model $model, int $currencyId, Carbon $start, Carbon $end, string $type, int $count, string $amount): PeriodStatistic
@@ -63,8 +65,16 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface
$stat->type = $type; $stat->type = $type;
$stat->save(); $stat->save();
Log::debug(sprintf('Saved #%d [currency #%d, Model %s #%d, %s to %s, %d, %s] as new statistic.', Log::debug(sprintf(
$stat->id, get_class($model), $model->id, $stat->transaction_currency_id, $stat->start->toW3cString(), $stat->end->toW3cString(), $count, $amount 'Saved #%d [currency #%d, Model %s #%d, %s to %s, %d, %s] as new statistic.',
$stat->id,
get_class($model),
$model->id,
$stat->transaction_currency_id,
$stat->start->toW3cString(),
$stat->end->toW3cString(),
$count,
$amount
)); ));
return $stat; return $stat;

View File

@@ -105,10 +105,10 @@ class Amount
} }
if ($csPrecedes) { if ($csPrecedes) {
return $posA . $posB . '%s' . $posC . $space . $posD . '%v' . $posE; return $posA.$posB.'%s'.$posC.$space.$posD.'%v'.$posE;
} }
return $posA . $posD . '%v' . $space . $posB . '%s' . $posC . $posE; return $posA.$posD.'%v'.$space.$posB.'%s'.$posC.$posE;
} }
public function convertToPrimary(?User $user = null): bool public function convertToPrimary(?User $user = null): bool

View File

@@ -126,14 +126,14 @@ class RemoteUserGuard implements Guard
/** /**
* @SuppressWarnings("PHPMD.ShortMethodName") * @SuppressWarnings("PHPMD.ShortMethodName")
*/ */
public function id(): int | string | null public function id(): int|string|null
{ {
Log::debug(sprintf('Now at %s', __METHOD__)); Log::debug(sprintf('Now at %s', __METHOD__));
return $this->user?->id; return $this->user?->id;
} }
public function setUser(Authenticatable | User | null $user): void // @phpstan-ignore-line public function setUser(Authenticatable|User|null $user): void // @phpstan-ignore-line
{ {
Log::debug(sprintf('Now at %s', __METHOD__)); Log::debug(sprintf('Now at %s', __METHOD__));
if ($user instanceof User) { if ($user instanceof User) {

View File

@@ -54,7 +54,8 @@ class Balance
->orderBy('transaction_journals.order', 'asc') ->orderBy('transaction_journals.order', 'asc')
->orderBy('transaction_journals.description', 'desc') ->orderBy('transaction_journals.description', 'desc')
->orderBy('transactions.amount', 'desc') ->orderBy('transactions.amount', 'desc')
->where('transaction_journals.date', '<=', $date); ->where('transaction_journals.date', '<=', $date)
;
$result = $query->get(['transactions.account_id', 'transactions.transaction_currency_id', 'transactions.balance_after']); $result = $query->get(['transactions.account_id', 'transactions.transaction_currency_id', 'transactions.balance_after']);
foreach ($result as $entry) { foreach ($result as $entry) {

View File

@@ -46,7 +46,8 @@ class AccountList implements BinderInterface
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereIn('account_types.type', [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value]) ->whereIn('account_types.type', [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value])
->orderBy('accounts.name', 'ASC') ->orderBy('accounts.name', 'ASC')
->get(['accounts.*']); ->get(['accounts.*'])
;
} }
if ('allAssetAccounts' !== $value) { if ('allAssetAccounts' !== $value) {
$incoming = array_map('\intval', explode(',', $value)); $incoming = array_map('\intval', explode(',', $value));
@@ -57,7 +58,8 @@ class AccountList implements BinderInterface
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereIn('accounts.id', $list) ->whereIn('accounts.id', $list)
->orderBy('accounts.name', 'ASC') ->orderBy('accounts.name', 'ASC')
->get(['accounts.*']); ->get(['accounts.*'])
;
} }
if ($collection->count() > 0) { if ($collection->count() > 0) {

View File

@@ -43,7 +43,8 @@ class BudgetList implements BinderInterface
return auth()->user()->budgets()->where('active', true) return auth()->user()->budgets()->where('active', true)
->orderBy('order', 'ASC') ->orderBy('order', 'ASC')
->orderBy('name', 'ASC') ->orderBy('name', 'ASC')
->get(); ->get()
;
} }
$list = array_unique(array_map('\intval', explode(',', $value))); $list = array_unique(array_map('\intval', explode(',', $value)));
@@ -58,7 +59,8 @@ class BudgetList implements BinderInterface
$collection = auth()->user()->budgets() $collection = auth()->user()->budgets()
->where('active', true) ->where('active', true)
->whereIn('id', $list) ->whereIn('id', $list)
->get(); ->get()
;
// add empty budget if applicable. // add empty budget if applicable.
if (in_array(0, $list, true)) { if (in_array(0, $list, true)) {

View File

@@ -42,7 +42,8 @@ class CategoryList implements BinderInterface
if ('allCategories' === $value) { if ('allCategories' === $value) {
return auth()->user()->categories() return auth()->user()->categories()
->orderBy('name', 'ASC') ->orderBy('name', 'ASC')
->get(); ->get()
;
} }
$list = array_unique(array_map('\intval', explode(',', $value))); $list = array_unique(array_map('\intval', explode(',', $value)));
@@ -53,7 +54,8 @@ class CategoryList implements BinderInterface
/** @var Collection $collection */ /** @var Collection $collection */
$collection = auth()->user()->categories() $collection = auth()->user()->categories()
->whereIn('id', $list) ->whereIn('id', $list)
->get(); ->get()
;
// add empty category if applicable. // add empty category if applicable.
if (in_array(0, $list, true)) { if (in_array(0, $list, true)) {

View File

@@ -68,7 +68,7 @@ class Date implements BinderInterface
try { try {
$result = new Carbon($value); $result = new Carbon($value);
} catch (InvalidDateException | InvalidFormatException $e) { // @phpstan-ignore-line } catch (InvalidDateException|InvalidFormatException $e) { // @phpstan-ignore-line
$message = sprintf('Could not parse date "%s" for user #%d: %s', $value, auth()->user()->id, $e->getMessage()); $message = sprintf('Could not parse date "%s" for user #%d: %s', $value, auth()->user()->id, $e->getMessage());
app('log')->error($message); app('log')->error($message);

View File

@@ -44,7 +44,8 @@ class TagList implements BinderInterface
if ('allTags' === $value) { if ('allTags' === $value) {
return auth()->user()->tags() return auth()->user()->tags()
->orderBy('tag', 'ASC') ->orderBy('tag', 'ASC')
->get(); ->get()
;
} }
$list = array_unique(array_map('\strtolower', explode(',', $value))); $list = array_unique(array_map('\strtolower', explode(',', $value)));
app('log')->debug('List of tags is', $list); app('log')->debug('List of tags is', $list);

View File

@@ -43,7 +43,8 @@ class UserGroupAccount implements BinderInterface
$user = auth()->user(); $user = auth()->user();
$account = Account::where('id', (int)$value) $account = Account::where('id', (int)$value)
->where('user_group_id', $user->user_group_id) ->where('user_group_id', $user->user_group_id)
->first(); ->first()
;
if (null !== $account) { if (null !== $account) {
return $account; return $account;
} }

View File

@@ -43,7 +43,8 @@ class UserGroupBill implements BinderInterface
$user = auth()->user(); $user = auth()->user();
$currency = Bill::where('id', (int)$value) $currency = Bill::where('id', (int)$value)
->where('user_group_id', $user->user_group_id) ->where('user_group_id', $user->user_group_id)
->first(); ->first()
;
if (null !== $currency) { if (null !== $currency) {
return $currency; return $currency;
} }

View File

@@ -40,7 +40,8 @@ class UserGroupExchangeRate implements BinderInterface
$user = auth()->user(); $user = auth()->user();
$rate = CurrencyExchangeRate::where('id', (int)$value) $rate = CurrencyExchangeRate::where('id', (int)$value)
->where('user_group_id', $user->user_group_id) ->where('user_group_id', $user->user_group_id)
->first(); ->first()
;
if (null !== $rate) { if (null !== $rate) {
return $rate; return $rate;
} }

View File

@@ -40,7 +40,8 @@ class UserGroupTransaction implements BinderInterface
$user = auth()->user(); $user = auth()->user();
$group = TransactionGroup::where('id', (int)$value) $group = TransactionGroup::where('id', (int)$value)
->where('user_group_id', $user->user_group_id) ->where('user_group_id', $user->user_group_id)
->first(); ->first()
;
if (null !== $group) { if (null !== $group) {
return $group; return $group;
} }

View File

@@ -27,6 +27,7 @@ use Carbon\Carbon;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use JsonException; use JsonException;
use function Safe\json_encode; use function Safe\json_encode;
/** /**

View File

@@ -39,7 +39,7 @@ class FireflyConfig
{ {
public function delete(string $name): void public function delete(string $name): void
{ {
$fullName = 'ff3-config-' . $name; $fullName = 'ff3-config-'.$name;
if (Cache::has($fullName)) { if (Cache::has($fullName)) {
Cache::forget($fullName); Cache::forget($fullName);
} }
@@ -53,7 +53,7 @@ class FireflyConfig
*/ */
public function get(string $name, mixed $default = null): ?Configuration public function get(string $name, mixed $default = null): ?Configuration
{ {
$fullName = 'ff3-config-' . $name; $fullName = 'ff3-config-'.$name;
if (Cache::has($fullName)) { if (Cache::has($fullName)) {
return Cache::get($fullName); return Cache::get($fullName);
} }
@@ -61,7 +61,7 @@ class FireflyConfig
try { try {
/** @var null|Configuration $config */ /** @var null|Configuration $config */
$config = Configuration::where('name', $name)->first(['id', 'name', 'data']); $config = Configuration::where('name', $name)->first(['id', 'name', 'data']);
} catch (Exception | QueryException $e) { } catch (Exception|QueryException $e) {
throw new FireflyException(sprintf('Could not poll the database: %s', $e->getMessage()), 0, $e); throw new FireflyException(sprintf('Could not poll the database: %s', $e->getMessage()), 0, $e);
} }
@@ -146,13 +146,13 @@ class FireflyConfig
$item->name = $name; $item->name = $name;
$item->data = $value; $item->data = $value;
$item->save(); $item->save();
Cache::forget('ff3-config-' . $name); Cache::forget('ff3-config-'.$name);
return $item; return $item;
} }
$config->data = $value; $config->data = $value;
$config->save(); $config->save();
Cache::forget('ff3-config-' . $name); Cache::forget('ff3-config-'.$name);
return $config; return $config;
} }

View File

@@ -77,7 +77,7 @@ class CurrencyForm
/** @var TransactionCurrency $currency */ /** @var TransactionCurrency $currency */
foreach ($list as $currency) { foreach ($list as $currency) {
$array[$currency->id] = $currency->name . ' (' . $currency->symbol . ')'; $array[$currency->id] = $currency->name.' ('.$currency->symbol.')';
} }
return $this->select($name, $array, $value, $options); return $this->select($name, $array, $value, $options);
@@ -101,7 +101,7 @@ class CurrencyForm
/** @var TransactionCurrency $currency */ /** @var TransactionCurrency $currency */
foreach ($list as $currency) { foreach ($list as $currency) {
$array[$currency->id] = $currency->name . ' (' . $currency->symbol . ')'; $array[$currency->id] = $currency->name.' ('.$currency->symbol.')';
} }
return $this->select($name, $array, $value, $options); return $this->select($name, $array, $value, $options);
@@ -132,7 +132,7 @@ class CurrencyForm
if (!is_array($preFilled)) { if (!is_array($preFilled)) {
$preFilled = []; $preFilled = [];
} }
$key = 'amount_currency_id_' . $name; $key = 'amount_currency_id_'.$name;
$sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $primaryCurrency->id; $sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $primaryCurrency->id;
app('log')->debug(sprintf('Sent currency ID is %d', $sentCurrencyId)); app('log')->debug(sprintf('Sent currency ID is %d', $sentCurrencyId));
@@ -153,7 +153,7 @@ class CurrencyForm
} }
try { try {
$html = view('form.' . $view, compact('primaryCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render(); $html = view('form.'.$view, compact('primaryCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) { } catch (Throwable $e) {
app('log')->debug(sprintf('Could not render currencyField(): %s', $e->getMessage())); app('log')->debug(sprintf('Could not render currencyField(): %s', $e->getMessage()));
$html = 'Could not render currencyField.'; $html = 'Could not render currencyField.';
@@ -186,7 +186,7 @@ class CurrencyForm
if (!is_array($preFilled)) { if (!is_array($preFilled)) {
$preFilled = []; $preFilled = [];
} }
$key = 'amount_currency_id_' . $name; $key = 'amount_currency_id_'.$name;
$sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $primaryCurrency->id; $sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $primaryCurrency->id;
app('log')->debug(sprintf('Sent currency ID is %d', $sentCurrencyId)); app('log')->debug(sprintf('Sent currency ID is %d', $sentCurrencyId));
@@ -207,7 +207,7 @@ class CurrencyForm
} }
try { try {
$html = view('form.' . $view, compact('primaryCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render(); $html = view('form.'.$view, compact('primaryCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) { } catch (Throwable $e) {
app('log')->debug(sprintf('Could not render currencyField(): %s', $e->getMessage())); app('log')->debug(sprintf('Could not render currencyField(): %s', $e->getMessage()));
$html = 'Could not render currencyField.'; $html = 'Could not render currencyField.';

View File

@@ -84,7 +84,7 @@ trait FormSupport
$options ??= []; $options ??= [];
$name = str_replace('[]', '', $name); $name = str_replace('[]', '', $name);
$options['class'] = 'form-control'; $options['class'] = 'form-control';
$options['id'] = 'ffInput_' . $name; $options['id'] = 'ffInput_'.$name;
$options['autocomplete'] = 'off'; $options['autocomplete'] = 'off';
$options['placeholder'] = ucfirst((string)$label); $options['placeholder'] = ucfirst((string)$label);
@@ -145,6 +145,6 @@ trait FormSupport
} }
$name = str_replace('[]', '', $name); $name = str_replace('[]', '', $name);
return (string)trans('form.' . $name); return (string)trans('form.'.$name);
} }
} }

View File

@@ -203,7 +203,8 @@ class ExchangeRateConverter
->where('to_currency_id', $to) ->where('to_currency_id', $to)
->where('date', '<=', $date) ->where('date', '<=', $date)
->orderBy('date', 'DESC') ->orderBy('date', 'DESC')
->first(); ->first()
;
++$this->queryCount; ++$this->queryCount;
$rate = (string)$result?->rate; $rate = (string)$result?->rate;

View File

@@ -32,6 +32,7 @@ use FireflyIII\User;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Laravel\Passport\Passport; use Laravel\Passport\Passport;
use phpseclib3\Crypt\RSA; use phpseclib3\Crypt\RSA;
use function Safe\file_put_contents; use function Safe\file_put_contents;
/** /**

View File

@@ -64,7 +64,7 @@ trait GetConfigurationData
$currentStep = $options; $currentStep = $options;
// get the text: // get the text:
$currentStep['intro'] = (string)trans('intro.' . $route . '_' . $key); $currentStep['intro'] = (string)trans('intro.'.$route.'_'.$key);
// save in array: // save in array:
$steps[] = $currentStep; $steps[] = $currentStep;
@@ -186,13 +186,13 @@ trait GetConfigurationData
// user is on page with specific instructions: // user is on page with specific instructions:
if ('' !== $specificPage) { if ('' !== $specificPage) {
$routeKey = str_replace('.', '_', $route); $routeKey = str_replace('.', '_', $route);
$elements = config(sprintf('intro.%s', $routeKey . '_' . $specificPage)); $elements = config(sprintf('intro.%s', $routeKey.'_'.$specificPage));
if (is_array($elements) && count($elements) > 0) { if (is_array($elements) && count($elements) > 0) {
foreach ($elements as $key => $options) { foreach ($elements as $key => $options) {
$currentStep = $options; $currentStep = $options;
// get the text: // get the text:
$currentStep['intro'] = (string)trans('intro.' . $route . '_' . $specificPage . '_' . $key); $currentStep['intro'] = (string)trans('intro.'.$route.'_'.$specificPage.'_'.$key);
// save in array: // save in array:
$steps[] = $currentStep; $steps[] = $currentStep;

View File

@@ -353,6 +353,7 @@ trait PeriodOverview
echo sprintf('End: "%s" vs "%s": %s', $statistic->end->toW3cString(), $end->toW3cString(), var_export($statistic->end->eq($end), true)); echo sprintf('End: "%s" vs "%s": %s', $statistic->end->toW3cString(), $end->toW3cString(), var_export($statistic->end->eq($end), true));
var_dump($statistic->end); var_dump($statistic->end);
var_dump($end); var_dump($end);
exit; exit;
} }

View File

@@ -35,6 +35,7 @@ use Illuminate\Routing\Route;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Route as RouteFacade; use Illuminate\Support\Facades\Route as RouteFacade;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use function Safe\parse_url; use function Safe\parse_url;
/** /**

View File

@@ -46,7 +46,8 @@ trait TransactionCalculation
$collector->setAccounts($total) $collector->setAccounts($total)
->setRange($start, $end) ->setRange($start, $end)
->withAccountInformation() ->withAccountInformation()
->setTypes([TransactionTypeEnum::WITHDRAWAL->value]); ->setTypes([TransactionTypeEnum::WITHDRAWAL->value])
;
return $collector->getExtractedJournals(); return $collector->getExtractedJournals();
} }
@@ -60,7 +61,8 @@ trait TransactionCalculation
$collector = app(GroupCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::TRANSFER->value]) $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::TRANSFER->value])
->setTags($tags)->withAccountInformation(); ->setTags($tags)->withAccountInformation()
;
return $collector->getExtractedJournals(); return $collector->getExtractedJournals();
} }
@@ -73,7 +75,8 @@ trait TransactionCalculation
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::TRANSFER->value]) $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::TRANSFER->value])
->setBudgets($budgets)->withAccountInformation(); ->setBudgets($budgets)->withAccountInformation()
;
return $collector->getExtractedJournals(); return $collector->getExtractedJournals();
} }
@@ -90,7 +93,8 @@ trait TransactionCalculation
->setRange($start, $end) ->setRange($start, $end)
->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::TRANSFER->value]) ->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::TRANSFER->value])
->setCategories($categories) ->setCategories($categories)
->withAccountInformation(); ->withAccountInformation()
;
return $collector->getExtractedJournals(); return $collector->getExtractedJournals();
} }
@@ -103,7 +107,8 @@ trait TransactionCalculation
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value]) $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value])
->setCategories($categories)->withAccountInformation(); ->setCategories($categories)->withAccountInformation()
;
return $collector->getExtractedJournals(); return $collector->getExtractedJournals();
} }
@@ -130,7 +135,8 @@ trait TransactionCalculation
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value]) $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value])
->setTags($tags)->withAccountInformation(); ->setTags($tags)->withAccountInformation()
;
return $collector->getExtractedJournals(); return $collector->getExtractedJournals();
} }

View File

@@ -112,7 +112,7 @@ class AccountEnrichment implements EnrichmentInterface
} }
#[Override] #[Override]
public function enrichSingle(array | Model $model): Account | array public function enrichSingle(array|Model $model): Account|array
{ {
Log::debug(__METHOD__); Log::debug(__METHOD__);
$collection = new Collection()->push($model); $collection = new Collection()->push($model);
@@ -313,7 +313,8 @@ class AccountEnrichment implements EnrichmentInterface
private function collectLocations(): void private function collectLocations(): void
{ {
$locations = Location::query()->whereIn('locatable_id', $this->ids) $locations = Location::query()->whereIn('locatable_id', $this->ids)
->where('locatable_type', Account::class)->get(['locations.locatable_id', 'locations.latitude', 'locations.longitude', 'locations.zoom_level'])->toArray(); ->where('locatable_type', Account::class)->get(['locations.locatable_id', 'locations.latitude', 'locations.longitude', 'locations.zoom_level'])->toArray()
;
foreach ($locations as $location) { foreach ($locations as $location) {
$this->locations[(int)$location['locatable_id']] $this->locations[(int)$location['locatable_id']]
= [ = [
@@ -329,7 +330,8 @@ class AccountEnrichment implements EnrichmentInterface
{ {
$set = AccountMeta::whereIn('name', ['is_multi_currency', 'include_net_worth', 'currency_id', 'account_role', 'account_number', 'BIC', 'liability_direction', 'interest', 'interest_period', 'current_debt']) $set = AccountMeta::whereIn('name', ['is_multi_currency', 'include_net_worth', 'currency_id', 'account_role', 'account_number', 'BIC', 'liability_direction', 'interest', 'interest_period', 'current_debt'])
->whereIn('account_id', $this->ids) ->whereIn('account_id', $this->ids)
->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data'])->toArray(); ->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data'])->toArray()
;
/** @var array $entry */ /** @var array $entry */
foreach ($set as $entry) { foreach ($set as $entry) {
@@ -357,7 +359,8 @@ class AccountEnrichment implements EnrichmentInterface
$notes = Note::query()->whereIn('noteable_id', $this->ids) $notes = Note::query()->whereIn('noteable_id', $this->ids)
->whereNotNull('notes.text') ->whereNotNull('notes.text')
->where('notes.text', '!=', '') ->where('notes.text', '!=', '')
->where('noteable_type', Account::class)->get(['notes.noteable_id', 'notes.text'])->toArray(); ->where('noteable_type', Account::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
;
foreach ($notes as $note) { foreach ($notes as $note) {
$this->notes[(int)$note['noteable_id']] = (string)$note['text']; $this->notes[(int)$note['noteable_id']] = (string)$note['text'];
} }
@@ -369,7 +372,8 @@ class AccountEnrichment implements EnrichmentInterface
$set = DB::table('object_groupables') $set = DB::table('object_groupables')
->whereIn('object_groupable_id', $this->ids) ->whereIn('object_groupable_id', $this->ids)
->where('object_groupable_type', Account::class) ->where('object_groupable_type', Account::class)
->get(['object_groupable_id', 'object_group_id']); ->get(['object_groupable_id', 'object_group_id'])
;
$ids = array_unique($set->pluck('object_group_id')->toArray()); $ids = array_unique($set->pluck('object_group_id')->toArray());
@@ -395,7 +399,8 @@ class AccountEnrichment implements EnrichmentInterface
->setUserGroup($this->userGroup) ->setUserGroup($this->userGroup)
->setAccounts($this->collection) ->setAccounts($this->collection)
->withAccountInformation() ->withAccountInformation()
->setTypes([TransactionTypeEnum::OPENING_BALANCE->value]); ->setTypes([TransactionTypeEnum::OPENING_BALANCE->value])
;
$journals = $collector->getExtractedJournals(); $journals = $collector->getExtractedJournals();
foreach ($journals as $journal) { foreach ($journals as $journal) {
$this->openingBalances[(int)$journal['source_account_id']] $this->openingBalances[(int)$journal['source_account_id']]
@@ -453,7 +458,7 @@ class AccountEnrichment implements EnrichmentInterface
case 'current_balance': case 'current_balance':
case 'pc_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; break;
} }

View File

@@ -79,7 +79,7 @@ class AvailableBudgetEnrichment implements EnrichmentInterface
} }
#[Override] #[Override]
public function enrichSingle(array | Model $model): array | Model public function enrichSingle(array|Model $model): array|Model
{ {
Log::debug(__METHOD__); Log::debug(__METHOD__);
$collection = new Collection()->push($model); $collection = new Collection()->push($model);

View File

@@ -70,7 +70,7 @@ class BudgetEnrichment implements EnrichmentInterface
return $this->collection; return $this->collection;
} }
public function enrichSingle(array | Model $model): array | Model public function enrichSingle(array|Model $model): array|Model
{ {
Log::debug(__METHOD__); Log::debug(__METHOD__);
$collection = new Collection()->push($model); $collection = new Collection()->push($model);
@@ -179,7 +179,8 @@ class BudgetEnrichment implements EnrichmentInterface
$notes = Note::query()->whereIn('noteable_id', $this->ids) $notes = Note::query()->whereIn('noteable_id', $this->ids)
->whereNotNull('notes.text') ->whereNotNull('notes.text')
->where('notes.text', '!=', '') ->where('notes.text', '!=', '')
->where('noteable_type', Budget::class)->get(['notes.noteable_id', 'notes.text'])->toArray(); ->where('noteable_type', Budget::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
;
foreach ($notes as $note) { foreach ($notes as $note) {
$this->notes[(int)$note['noteable_id']] = (string)$note['text']; $this->notes[(int)$note['noteable_id']] = (string)$note['text'];
} }
@@ -191,7 +192,8 @@ class BudgetEnrichment implements EnrichmentInterface
$set = DB::table('object_groupables') $set = DB::table('object_groupables')
->whereIn('object_groupable_id', $this->ids) ->whereIn('object_groupable_id', $this->ids)
->where('object_groupable_type', Budget::class) ->where('object_groupable_type', Budget::class)
->get(['object_groupable_id', 'object_group_id']); ->get(['object_groupable_id', 'object_group_id'])
;
$ids = array_unique($set->pluck('object_group_id')->toArray()); $ids = array_unique($set->pluck('object_group_id')->toArray());

View File

@@ -73,7 +73,7 @@ class BudgetLimitEnrichment implements EnrichmentInterface
return $this->collection; return $this->collection;
} }
public function enrichSingle(array | Model $model): array | Model public function enrichSingle(array|Model $model): array|Model
{ {
Log::debug(__METHOD__); Log::debug(__METHOD__);
$collection = new Collection()->push($model); $collection = new Collection()->push($model);
@@ -171,7 +171,8 @@ class BudgetLimitEnrichment implements EnrichmentInterface
$notes = Note::query()->whereIn('noteable_id', $this->ids) $notes = Note::query()->whereIn('noteable_id', $this->ids)
->whereNotNull('notes.text') ->whereNotNull('notes.text')
->where('notes.text', '!=', '') ->where('notes.text', '!=', '')
->where('noteable_type', BudgetLimit::class)->get(['notes.noteable_id', 'notes.text'])->toArray(); ->where('noteable_type', BudgetLimit::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
;
foreach ($notes as $note) { foreach ($notes as $note) {
$this->notes[(int)$note['noteable_id']] = (string)$note['text']; $this->notes[(int)$note['noteable_id']] = (string)$note['text'];
} }
@@ -180,7 +181,7 @@ class BudgetLimitEnrichment implements EnrichmentInterface
private function filterToBudget(array $expenses, int $budget): array private function filterToBudget(array $expenses, int $budget): array
{ {
$result = array_filter($expenses, fn(array $item) => (int)$item['budget_id'] === $budget); $result = array_filter($expenses, fn (array $item) => (int)$item['budget_id'] === $budget);
Log::debug(sprintf('filterToBudget for budget #%d, from %d to %d items', $budget, count($expenses), count($result))); Log::debug(sprintf('filterToBudget for budget #%d, from %d to %d items', $budget, count($expenses), count($result)));
return $result; return $result;
@@ -188,13 +189,13 @@ class BudgetLimitEnrichment implements EnrichmentInterface
private function stringifyIds(): void 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); $second['currency_id'] = (string)($second['currency_id'] ?? 0);
return $second; return $second;
}, $first), $this->expenses); }, $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); $second['currency_id'] = (string)($second['currency_id'] ?? 0);
return $second; return $second;

View File

@@ -62,7 +62,7 @@ class CategoryEnrichment implements EnrichmentInterface
return $collection; return $collection;
} }
public function enrichSingle(array | Model $model): array | Model public function enrichSingle(array|Model $model): array|Model
{ {
Log::debug(__METHOD__); Log::debug(__METHOD__);
$collection = new Collection()->push($model); $collection = new Collection()->push($model);
@@ -125,7 +125,8 @@ class CategoryEnrichment implements EnrichmentInterface
$notes = Note::query()->whereIn('noteable_id', $this->ids) $notes = Note::query()->whereIn('noteable_id', $this->ids)
->whereNotNull('notes.text') ->whereNotNull('notes.text')
->where('notes.text', '!=', '') ->where('notes.text', '!=', '')
->where('noteable_type', Category::class)->get(['notes.noteable_id', 'notes.text'])->toArray(); ->where('noteable_type', Category::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
;
foreach ($notes as $note) { foreach ($notes as $note) {
$this->notes[(int)$note['noteable_id']] = (string)$note['text']; $this->notes[(int)$note['noteable_id']] = (string)$note['text'];
} }

View File

@@ -33,7 +33,7 @@ interface EnrichmentInterface
{ {
public function enrich(Collection $collection): Collection; public function enrich(Collection $collection): Collection;
public function enrichSingle(array | Model $model): array | Model; public function enrichSingle(array|Model $model): array|Model;
public function setUser(User $user): void; public function setUser(User $user): void;

View File

@@ -77,7 +77,7 @@ class PiggyBankEnrichment implements EnrichmentInterface
return $this->collection; return $this->collection;
} }
public function enrichSingle(array | Model $model): array | Model public function enrichSingle(array|Model $model): array|Model
{ {
Log::debug(__METHOD__); Log::debug(__METHOD__);
$collection = new Collection()->push($model); $collection = new Collection()->push($model);
@@ -236,7 +236,8 @@ class PiggyBankEnrichment implements EnrichmentInterface
$notes = Note::query()->whereIn('noteable_id', $this->ids) $notes = Note::query()->whereIn('noteable_id', $this->ids)
->whereNotNull('notes.text') ->whereNotNull('notes.text')
->where('notes.text', '!=', '') ->where('notes.text', '!=', '')
->where('noteable_type', PiggyBank::class)->get(['notes.noteable_id', 'notes.text'])->toArray(); ->where('noteable_type', PiggyBank::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
;
foreach ($notes as $note) { foreach ($notes as $note) {
$this->notes[(int)$note['noteable_id']] = (string)$note['text']; $this->notes[(int)$note['noteable_id']] = (string)$note['text'];
} }
@@ -248,7 +249,8 @@ class PiggyBankEnrichment implements EnrichmentInterface
$set = DB::table('object_groupables') $set = DB::table('object_groupables')
->whereIn('object_groupable_id', $this->ids) ->whereIn('object_groupable_id', $this->ids)
->where('object_groupable_type', PiggyBank::class) ->where('object_groupable_type', PiggyBank::class)
->get(['object_groupable_id', 'object_group_id']); ->get(['object_groupable_id', 'object_group_id'])
;
$ids = array_unique($set->pluck('object_group_id')->toArray()); $ids = array_unique($set->pluck('object_group_id')->toArray());

View File

@@ -66,7 +66,7 @@ class PiggyBankEventEnrichment implements EnrichmentInterface
return $this->collection; return $this->collection;
} }
public function enrichSingle(array | Model $model): array | Model public function enrichSingle(array|Model $model): array|Model
{ {
Log::debug(__METHOD__); Log::debug(__METHOD__);
$collection = new Collection()->push($model); $collection = new Collection()->push($model);

View File

@@ -51,6 +51,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use function Safe\json_decode; use function Safe\json_decode;
class RecurringEnrichment implements EnrichmentInterface class RecurringEnrichment implements EnrichmentInterface
@@ -97,7 +98,7 @@ class RecurringEnrichment implements EnrichmentInterface
return $this->collection; return $this->collection;
} }
public function enrichSingle(array | Model $model): array | Model public function enrichSingle(array|Model $model): array|Model
{ {
Log::debug(__METHOD__); Log::debug(__METHOD__);
$collection = new Collection()->push($model); $collection = new Collection()->push($model);
@@ -305,7 +306,8 @@ class RecurringEnrichment implements EnrichmentInterface
$notes = Note::query()->whereIn('noteable_id', $this->ids) $notes = Note::query()->whereIn('noteable_id', $this->ids)
->whereNotNull('notes.text') ->whereNotNull('notes.text')
->where('notes.text', '!=', '') ->where('notes.text', '!=', '')
->where('noteable_type', Recurrence::class)->get(['notes.noteable_id', 'notes.text'])->toArray(); ->where('noteable_type', Recurrence::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
;
foreach ($notes as $note) { foreach ($notes as $note) {
$this->notes[(int)$note['noteable_id']] = (string)$note['text']; $this->notes[(int)$note['noteable_id']] = (string)$note['text'];
} }
@@ -339,8 +341,8 @@ class RecurringEnrichment implements EnrichmentInterface
/** @var RecurrenceRepetition $repetition */ /** @var RecurrenceRepetition $repetition */
foreach ($set as $repetition) { foreach ($set as $repetition) {
$recurrence = $this->collection->filter(fn(Recurrence $item) => (int)$item->id === (int)$repetition->recurrence_id)->first(); $recurrence = $this->collection->filter(fn (Recurrence $item) => (int)$item->id === (int)$repetition->recurrence_id)->first();
$fromDate = clone($recurrence->latest_date ?? $recurrence->first_date); $fromDate = clone ($recurrence->latest_date ?? $recurrence->first_date);
$id = (int)$repetition->recurrence_id; $id = (int)$repetition->recurrence_id;
$repId = (int)$repetition->id; $repId = (int)$repetition->id;
$this->repetitions[$id] ??= []; $this->repetitions[$id] ??= [];

View File

@@ -142,7 +142,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
return $collection; return $collection;
} }
public function enrichSingle(array | Model $model): array | Model public function enrichSingle(array|Model $model): array|Model
{ {
Log::debug(__METHOD__); Log::debug(__METHOD__);
$collection = new Collection()->push($model); $collection = new Collection()->push($model);
@@ -177,7 +177,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
*/ */
protected function lastPaidDate(Bill $subscription, Collection $dates, Carbon $default): Carbon 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)); Log::debug(sprintf('Filtered down from %d to %d entries for bill #%d.', $dates->count(), $filtered->count(), $subscription->id));
if (0 === $filtered->count()) { if (0 === $filtered->count()) {
return $default; return $default;
@@ -200,7 +200,8 @@ class SubscriptionEnrichment implements EnrichmentInterface
$notes = Note::query()->whereIn('noteable_id', $this->subscriptionIds) $notes = Note::query()->whereIn('noteable_id', $this->subscriptionIds)
->whereNotNull('notes.text') ->whereNotNull('notes.text')
->where('notes.text', '!=', '') ->where('notes.text', '!=', '')
->where('noteable_type', Bill::class)->get(['notes.noteable_id', 'notes.text'])->toArray(); ->where('noteable_type', Bill::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
;
foreach ($notes as $note) { foreach ($notes as $note) {
$this->notes[(int)$note['noteable_id']] = (string)$note['text']; $this->notes[(int)$note['noteable_id']] = (string)$note['text'];
} }
@@ -212,7 +213,8 @@ class SubscriptionEnrichment implements EnrichmentInterface
$set = DB::table('object_groupables') $set = DB::table('object_groupables')
->whereIn('object_groupable_id', $this->subscriptionIds) ->whereIn('object_groupable_id', $this->subscriptionIds)
->where('object_groupable_type', Bill::class) ->where('object_groupable_type', Bill::class)
->get(['object_groupable_id', 'object_group_id']); ->get(['object_groupable_id', 'object_group_id'])
;
$ids = array_unique($set->pluck('object_group_id')->toArray()); $ids = array_unique($set->pluck('object_group_id')->toArray());
@@ -280,7 +282,8 @@ class SubscriptionEnrichment implements EnrichmentInterface
'transactions.amount', 'transactions.amount',
'transactions.foreign_amount', 'transactions.foreign_amount',
] ]
); )
;
Log::debug(sprintf('Count %d entries in set', $set->count())); Log::debug(sprintf('Count %d entries in set', $set->count()));
// for each bill, do a loop. // for each bill, do a loop.
@@ -295,7 +298,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
// At this point the "next match" is exactly after the last time the bill was paid. // At this point the "next match" is exactly after the last time the bill was paid.
$result = []; $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) { foreach ($filtered as $entry) {
$array = [ $array = [
'transaction_group_id' => (string)$entry->transaction_group_id, 'transaction_group_id' => (string)$entry->transaction_group_id,

View File

@@ -83,7 +83,7 @@ class TransactionGroupEnrichment implements EnrichmentInterface
} }
#[Override] #[Override]
public function enrichSingle(array | Model $model): array | TransactionGroup public function enrichSingle(array|Model $model): array|TransactionGroup
{ {
Log::debug(__METHOD__); Log::debug(__METHOD__);
if (is_array($model)) { if (is_array($model)) {
@@ -179,7 +179,8 @@ class TransactionGroupEnrichment implements EnrichmentInterface
->where('attachable_type', TransactionJournal::class) ->where('attachable_type', TransactionJournal::class)
->groupBy('attachable_id') ->groupBy('attachable_id')
->get(['attachable_id', DB::raw('COUNT(id) as nr_of_attachments')]) ->get(['attachable_id', DB::raw('COUNT(id) as nr_of_attachments')])
->toArray(); ->toArray()
;
foreach ($attachments as $row) { foreach ($attachments as $row) {
$this->attachmentCount[(int)$row['attachable_id']] = (int)$row['nr_of_attachments']; $this->attachmentCount[(int)$row['attachable_id']] = (int)$row['nr_of_attachments'];
} }
@@ -199,7 +200,8 @@ class TransactionGroupEnrichment implements EnrichmentInterface
private function collectLocations(): void private function collectLocations(): void
{ {
$locations = Location::query()->whereIn('locatable_id', $this->journalIds) $locations = Location::query()->whereIn('locatable_id', $this->journalIds)
->where('locatable_type', TransactionJournal::class)->get(['locations.locatable_id', 'locations.latitude', 'locations.longitude', 'locations.zoom_level'])->toArray(); ->where('locatable_type', TransactionJournal::class)->get(['locations.locatable_id', 'locations.latitude', 'locations.longitude', 'locations.zoom_level'])->toArray()
;
foreach ($locations as $location) { foreach ($locations as $location) {
$this->locations[(int)$location['locatable_id']] $this->locations[(int)$location['locatable_id']]
= [ = [
@@ -236,7 +238,8 @@ class TransactionGroupEnrichment implements EnrichmentInterface
$notes = Note::query()->whereIn('noteable_id', $this->journalIds) $notes = Note::query()->whereIn('noteable_id', $this->journalIds)
->whereNotNull('notes.text') ->whereNotNull('notes.text')
->where('notes.text', '!=', '') ->where('notes.text', '!=', '')
->where('noteable_type', TransactionJournal::class)->get(['notes.noteable_id', 'notes.text'])->toArray(); ->where('noteable_type', TransactionJournal::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
;
foreach ($notes as $note) { foreach ($notes as $note) {
$this->notes[(int)$note['noteable_id']] = (string)$note['text']; $this->notes[(int)$note['noteable_id']] = (string)$note['text'];
} }
@@ -247,7 +250,8 @@ class TransactionGroupEnrichment implements EnrichmentInterface
{ {
$set = Tag::leftJoin('tag_transaction_journal', 'tags.id', '=', 'tag_transaction_journal.tag_id') $set = Tag::leftJoin('tag_transaction_journal', 'tags.id', '=', 'tag_transaction_journal.tag_id')
->whereIn('tag_transaction_journal.transaction_journal_id', $this->journalIds) ->whereIn('tag_transaction_journal.transaction_journal_id', $this->journalIds)
->get(['tag_transaction_journal.transaction_journal_id', 'tags.tag'])->toArray(); ->get(['tag_transaction_journal.transaction_journal_id', 'tags.tag'])->toArray()
;
foreach ($set as $item) { foreach ($set as $item) {
$journalId = $item['transaction_journal_id']; $journalId = $item['transaction_journal_id'];
$this->tags[$journalId] ??= []; $this->tags[$journalId] ??= [];

View File

@@ -66,7 +66,7 @@ class WebhookEnrichment implements EnrichmentInterface
return $this->collection; return $this->collection;
} }
public function enrichSingle(array | Model $model): array | Model public function enrichSingle(array|Model $model): array|Model
{ {
Log::debug(__METHOD__); Log::debug(__METHOD__);
$collection = new Collection()->push($model); $collection = new Collection()->push($model);

View File

@@ -91,7 +91,8 @@ class AccountBalanceCalculator
->orderBy('transaction_journals.id', 'DESC') ->orderBy('transaction_journals.id', 'DESC')
->orderBy('transaction_journals.description', 'DESC') ->orderBy('transaction_journals.description', 'DESC')
->orderBy('transactions.amount', 'DESC') ->orderBy('transactions.amount', 'DESC')
->where('transactions.account_id', $accountId); ->where('transactions.account_id', $accountId)
;
$notBefore->startOfDay(); $notBefore->startOfDay();
$query->where('transaction_journals.date', '<', $notBefore); $query->where('transaction_journals.date', '<', $notBefore);
@@ -119,7 +120,8 @@ class AccountBalanceCalculator
->orderBy('transaction_journals.order', 'desc') ->orderBy('transaction_journals.order', 'desc')
->orderBy('transaction_journals.id', 'asc') ->orderBy('transaction_journals.id', 'asc')
->orderBy('transaction_journals.description', 'asc') ->orderBy('transaction_journals.description', 'asc')
->orderBy('transactions.amount', 'asc'); ->orderBy('transactions.amount', 'asc')
;
if ($accounts->count() > 0) { if ($accounts->count() > 0) {
$query->whereIn('transactions.account_id', $accounts->pluck('id')->toArray()); $query->whereIn('transactions.account_id', $accounts->pluck('id')->toArray());
} }

View File

@@ -118,7 +118,7 @@ class BillDateCalculator
} }
Log::debug('end of loop'); Log::debug('end of loop');
$simple = $set->map( // @phpstan-ignore-line $simple = $set->map( // @phpstan-ignore-line
static fn(Carbon $date) => $date->format('Y-m-d') static fn (Carbon $date) => $date->format('Y-m-d')
); );
Log::debug(sprintf('Found %d pay dates', $set->count()), $simple->toArray()); Log::debug(sprintf('Found %d pay dates', $set->count()), $simple->toArray());

View File

@@ -39,7 +39,7 @@ trait ReturnsIntegerIdTrait
protected function id(): Attribute protected function id(): Attribute
{ {
return Attribute::make( return Attribute::make(
get: static fn($value) => (int)$value, get: static fn ($value) => (int)$value,
); );
} }
} }

View File

@@ -37,14 +37,14 @@ trait ReturnsIntegerUserIdTrait
protected function userGroupId(): Attribute protected function userGroupId(): Attribute
{ {
return Attribute::make( return Attribute::make(
get: static fn($value) => (int)$value, get: static fn ($value) => (int)$value,
); );
} }
protected function userId(): Attribute protected function userId(): Attribute
{ {
return Attribute::make( return Attribute::make(
get: static fn($value) => (int)$value, get: static fn ($value) => (int)$value,
); );
} }
} }

View File

@@ -439,6 +439,7 @@ class Navigation
// special formatter for quarter of year // special formatter for quarter of year
Log::error(sprintf('No date formats for frequency "%s"!', $repeatFrequency)); Log::error(sprintf('No date formats for frequency "%s"!', $repeatFrequency));
throw new FireflyException(sprintf('No date formats for frequency "%s"!', $repeatFrequency)); throw new FireflyException(sprintf('No date formats for frequency "%s"!', $repeatFrequency));
return $date->format('Y-m-d'); return $date->format('Y-m-d');

View File

@@ -161,7 +161,7 @@ trait RecalculatesAvailableBudgetsTrait
// all have to be created or updated. // all have to be created or updated.
try { try {
$viewRange = app('preferences')->getForUser($user, 'viewRange', '1M')->data; $viewRange = app('preferences')->getForUser($user, 'viewRange', '1M')->data;
} catch (ContainerExceptionInterface | NotFoundExceptionInterface $e) { } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) {
Log::error($e->getMessage()); Log::error($e->getMessage());
$viewRange = '1M'; $viewRange = '1M';
} }

View File

@@ -29,6 +29,7 @@ use Carbon\CarbonInterface;
use Carbon\Exceptions\InvalidFormatException; use Carbon\Exceptions\InvalidFormatException;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use function Safe\preg_match; use function Safe\preg_match;
/** /**

View File

@@ -53,7 +53,8 @@ class Preferences
$q->whereNull('user_group_id'); $q->whereNull('user_group_id');
$q->orWhere('user_group_id', $user->user_group_id); $q->orWhere('user_group_id', $user->user_group_id);
}) })
->get(); ->get()
;
} }
public function beginsWith(User $user, string $search): Collection public function beginsWith(User $user, string $search): Collection
@@ -89,7 +90,7 @@ class Preferences
Cache::put($key, '', 5); Cache::put($key, '', 5);
} }
public function get(string $name, array | bool | int | string | null $default = null): ?Preference public function get(string $name, array|bool|int|string|null $default = null): ?Preference
{ {
/** @var null|User $user */ /** @var null|User $user */
$user = auth()->user(); $user = auth()->user();
@@ -112,7 +113,8 @@ class Preferences
$q->orWhere('user_group_id', $user->user_group_id); $q->orWhere('user_group_id', $user->user_group_id);
}) })
->whereIn('name', $list) ->whereIn('name', $list)
->get(['id', 'name', 'data']); ->get(['id', 'name', 'data'])
;
/** @var Preference $preference */ /** @var Preference $preference */
foreach ($preferences as $preference) { foreach ($preferences as $preference) {
@@ -154,7 +156,7 @@ class Preferences
return $result; return $result;
} }
public function getEncryptedForUser(User $user, string $name, array | bool | int | string | null $default = null): ?Preference public function getEncryptedForUser(User $user, string $name, array|bool|int|string|null $default = null): ?Preference
{ {
$result = $this->getForUser($user, $name, $default); $result = $this->getForUser($user, $name, $default);
if ('' === $result->data) { if ('' === $result->data) {
@@ -179,7 +181,7 @@ class Preferences
return $result; return $result;
} }
public function getForUser(User $user, string $name, array | bool | int | string | null $default = null): ?Preference public function getForUser(User $user, string $name, array|bool|int|string|null $default = null): ?Preference
{ {
// Log::debug(sprintf('getForUser(#%d, "%s")', $user->id, $name)); // Log::debug(sprintf('getForUser(#%d, "%s")', $user->id, $name));
// don't care about user group ID, except for some specific preferences. // don't care about user group ID, except for some specific preferences.
@@ -214,7 +216,7 @@ class Preferences
return $this->setForUser($user, $name, $default); return $this->setForUser($user, $name, $default);
} }
public function getFresh(string $name, array | bool | int | string | null $default = null): ?Preference public function getFresh(string $name, array|bool|int|string|null $default = null): ?Preference
{ {
/** @var null|User $user */ /** @var null|User $user */
$user = auth()->user(); $user = auth()->user();
@@ -262,7 +264,7 @@ class Preferences
Session::forget('first'); Session::forget('first');
} }
public function set(string $name, array | bool | int | string | null $value): Preference public function set(string $name, array|bool|int|string|null $value): Preference
{ {
/** @var null|User $user */ /** @var null|User $user */
$user = auth()->user(); $user = auth()->user();
@@ -291,7 +293,7 @@ class Preferences
return $this->set($name, $encrypted); return $this->set($name, $encrypted);
} }
public function setForUser(User $user, string $name, array | bool | int | string | null $value): Preference public function setForUser(User $user, string $name, array|bool|int|string|null $value): Preference
{ {
$fullName = sprintf('preference%s%s', $user->id, $name); $fullName = sprintf('preference%s%s', $user->id, $name);
$userGroupId = $this->getUserGroupId($user, $name); $userGroupId = $this->getUserGroupId($user, $name);

View File

@@ -37,7 +37,7 @@ interface UserGroupInterface
public function getUserGroup(): ?UserGroup; public function getUserGroup(): ?UserGroup;
public function setUser(Authenticatable | User | null $user): void; public function setUser(Authenticatable|User|null $user): void;
public function setUserGroup(UserGroup $userGroup): void; public function setUserGroup(UserGroup $userGroup): void;

View File

@@ -61,7 +61,7 @@ trait UserGroupTrait
/** /**
* @throws FireflyException * @throws FireflyException
*/ */
public function setUser(Authenticatable | User | null $user): void public function setUser(Authenticatable|User|null $user): void
{ {
if ($user instanceof User) { if ($user instanceof User) {
$this->user = $user; $this->user = $user;
@@ -100,7 +100,8 @@ trait UserGroupTrait
{ {
$memberships = GroupMembership::where('user_id', $this->user->id) $memberships = GroupMembership::where('user_id', $this->user->id)
->where('user_group_id', $userGroupId) ->where('user_group_id', $userGroupId)
->count(); ->count()
;
if (0 === $memberships) { if (0 === $memberships) {
throw new FireflyException(sprintf('User #%d has no access to administration #%d', $this->user->id, $userGroupId)); throw new FireflyException(sprintf('User #%d has no access to administration #%d', $this->user->id, $userGroupId));
} }

View File

@@ -31,6 +31,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Facades\Steam;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use function Safe\preg_replace; use function Safe\preg_replace;
/** /**

View File

@@ -28,6 +28,7 @@ use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use function Safe\json_encode; use function Safe\json_encode;
/** /**
@@ -64,7 +65,8 @@ class AccountSearch implements GenericSearchInterface
$searchQuery = $this->user->accounts() $searchQuery = $this->user->accounts()
->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id') ->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id') ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->whereIn('account_types.type', $this->types); ->whereIn('account_types.type', $this->types)
;
$like = sprintf('%%%s%%', $this->query); $like = sprintf('%%%s%%', $this->query);
$originalQuery = $this->query; $originalQuery = $this->query;
@@ -135,7 +137,7 @@ class AccountSearch implements GenericSearchInterface
$this->types = $types; $this->types = $types;
} }
public function setUser(Authenticatable | User | null $user): void public function setUser(Authenticatable|User|null $user): void
{ {
if ($user instanceof User) { if ($user instanceof User) {
$this->user = $user; $this->user = $user;

View File

@@ -186,7 +186,7 @@ class OperatorQuerySearch implements SearchInterface
try { try {
$parsedQuery = $parser->parse($query); $parsedQuery = $parser->parse($query);
} catch (LogicException | TypeError $e) { } catch (LogicException|TypeError $e) {
Log::error($e->getMessage()); Log::error($e->getMessage());
Log::error(sprintf('Could not parse search: "%s".', $query)); Log::error(sprintf('Could not parse search: "%s".', $query));
@@ -505,7 +505,7 @@ class OperatorQuerySearch implements SearchInterface
} }
Log::debug(sprintf('Found %d accounts, will filter.', $accounts->count())); Log::debug(sprintf('Found %d accounts, will filter.', $accounts->count()));
$filtered = $accounts->filter( $filtered = $accounts->filter(
static fn(Account $account) => $stringMethod(strtolower($account->name), strtolower($value)) static fn (Account $account) => $stringMethod(strtolower($account->name), strtolower($value))
); );
if (0 === $filtered->count()) { if (0 === $filtered->count()) {

View File

@@ -32,6 +32,7 @@ use Gdbots\QueryParser\QueryParser as BaseQueryParser;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use LogicException; use LogicException;
use TypeError; use TypeError;
use function Safe\fwrite; use function Safe\fwrite;
class GdbotsQueryParser implements QueryParserInterface class GdbotsQueryParser implements QueryParserInterface
@@ -51,12 +52,12 @@ class GdbotsQueryParser implements QueryParserInterface
try { try {
$result = $this->parser->parse($query); $result = $this->parser->parse($query);
$nodes = array_map( $nodes = array_map(
fn(GdbotsNode\Node $node) => $this->convertNode($node), fn (GdbotsNode\Node $node) => $this->convertNode($node),
$result->getNodes() $result->getNodes()
); );
return new NodeGroup($nodes); return new NodeGroup($nodes);
} catch (LogicException | TypeError $e) { } catch (LogicException|TypeError $e) {
fwrite(STDERR, "Setting up GdbotsQueryParserTest\n"); fwrite(STDERR, "Setting up GdbotsQueryParserTest\n");
app('log')->error($e->getMessage()); app('log')->error($e->getMessage());
app('log')->error(sprintf('Could not parse search: "%s".', $query)); app('log')->error(sprintf('Could not parse search: "%s".', $query));
@@ -84,7 +85,7 @@ class GdbotsQueryParser implements QueryParserInterface
return new NodeGroup( return new NodeGroup(
array_map( array_map(
fn(GdbotsNode\Node $subNode) => $this->convertNode($subNode), fn (GdbotsNode\Node $subNode) => $this->convertNode($subNode),
$node->getNodes() $node->getNodes()
) )
); );

View File

@@ -38,6 +38,7 @@ use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use ValueError; use ValueError;
use function Safe\parse_url; use function Safe\parse_url;
use function Safe\preg_replace; use function Safe\preg_replace;
@@ -60,7 +61,8 @@ class Steam
->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id')
->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s'))
->groupBy(['transactions.account_id', 'transaction_currencies.code']) ->groupBy(['transactions.account_id', 'transaction_currencies.code'])
->get(['transactions.account_id', 'transaction_currencies.code', DB::raw('SUM(transactions.amount) as sum_of_amount')])->toArray(); ->get(['transactions.account_id', 'transaction_currencies.code', DB::raw('SUM(transactions.amount) as sum_of_amount')])->toArray()
;
/** @var Account $account */ /** @var Account $account */
foreach ($accounts as $account) { foreach ($accounts as $account) {
@@ -72,7 +74,7 @@ class Steam
$currency = $currencies[$account->id]; $currency = $currencies[$account->id];
// second array // 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)) { if (0 === count($accountSum)) {
$result[$account->id] = $return; $result[$account->id] = $return;
@@ -140,10 +142,10 @@ class Steam
// Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision)); // Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision));
if (str_contains($number, '.')) { if (str_contains($number, '.')) {
if ('-' !== $number[0]) { if ('-' !== $number[0]) {
return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision); return bcadd($number, '0.'.str_repeat('0', $precision).'5', $precision);
} }
return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision); return bcsub($number, '0.'.str_repeat('0', $precision).'5', $precision);
} }
return $number; return $number;
@@ -322,7 +324,8 @@ class Steam
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id')
->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s'))
->get(['transaction_currencies.code', 'transactions.amount'])->toArray(); ->get(['transaction_currencies.code', 'transactions.amount'])->toArray()
;
$others = $this->groupAndSumTransactions($array, 'code', 'amount'); $others = $this->groupAndSumTransactions($array, 'code', 'amount');
// Log::debug('All balances are (joined)', $others); // Log::debug('All balances are (joined)', $others);
// if there is no request to convert, take this as "balance" and "pc_balance". // if there is no request to convert, take this as "balance" and "pc_balance".
@@ -429,7 +432,8 @@ class Steam
'transactions.transaction_currency_id', 'transactions.transaction_currency_id',
DB::raw('SUM(transactions.amount) AS sum_of_day'), DB::raw('SUM(transactions.amount) AS sum_of_day'),
] ]
); )
;
$currentBalance = $startBalance; $currentBalance = $startBalance;
$converter = new ExchangeRateConverter(); $converter = new ExchangeRateConverter();
@@ -592,7 +596,7 @@ class Steam
{ {
$singleton = PreferencesSingleton::getInstance(); $singleton = PreferencesSingleton::getInstance();
$cached = $singleton->getPreference('locale'); $cached = $singleton->getPreference('locale');
if(null !== $cached) { if (null !== $cached) {
return $cached; return $cached;
} }
$locale = app('preferences')->get('locale', config('firefly.default_locale', 'equal'))->data; $locale = app('preferences')->get('locale', config('firefly.default_locale', 'equal'))->data;
@@ -609,6 +613,7 @@ class Steam
$locale = str_replace('_', '-', $locale); $locale = str_replace('_', '-', $locale);
} }
$singleton->setPreference('locale', $locale); $singleton->setPreference('locale', $locale);
return $locale; return $locale;
} }

View File

@@ -31,6 +31,7 @@ use Illuminate\Support\Facades\Crypt;
use Laravel\Passport\Console\KeysCommand; use Laravel\Passport\Console\KeysCommand;
use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface; use Psr\Container\NotFoundExceptionInterface;
use function Safe\file_get_contents; use function Safe\file_get_contents;
use function Safe\file_put_contents; use function Safe\file_put_contents;
@@ -65,7 +66,7 @@ class OAuthKeys
try { try {
$privateKey = (string)app('fireflyconfig')->get(self::PRIVATE_KEY)?->data; $privateKey = (string)app('fireflyconfig')->get(self::PRIVATE_KEY)?->data;
$publicKey = (string)app('fireflyconfig')->get(self::PUBLIC_KEY)?->data; $publicKey = (string)app('fireflyconfig')->get(self::PUBLIC_KEY)?->data;
} catch (ContainerExceptionInterface | FireflyException | NotFoundExceptionInterface $e) { } catch (ContainerExceptionInterface|FireflyException|NotFoundExceptionInterface $e) {
app('log')->error(sprintf('Could not validate keysInDatabase(): %s', $e->getMessage())); app('log')->error(sprintf('Could not validate keysInDatabase(): %s', $e->getMessage()));
app('log')->error($e->getTraceAsString()); app('log')->error($e->getTraceAsString());
} }

View File

@@ -37,6 +37,7 @@ use Override;
use Twig\Extension\AbstractExtension; use Twig\Extension\AbstractExtension;
use Twig\TwigFilter; use Twig\TwigFilter;
use Twig\TwigFunction; use Twig\TwigFunction;
use function Safe\parse_url; use function Safe\parse_url;
/** /**
@@ -196,7 +197,7 @@ class General extends AbstractExtension
{ {
return new TwigFunction( return new TwigFunction(
'carbonize', 'carbonize',
static fn(string $date): Carbon => new Carbon($date, config('app.timezone')) static fn (string $date): Carbon => new Carbon($date, config('app.timezone'))
); );
} }
@@ -225,15 +226,15 @@ class General extends AbstractExtension
static function (int $size): string { static function (int $size): string {
// less than one GB, more than one MB // less than one GB, more than one MB
if ($size < (1024 * 1024 * 2014) && $size >= (1024 * 1024)) { if ($size < (1024 * 1024 * 2014) && $size >= (1024 * 1024)) {
return round($size / (1024 * 1024), 2) . ' MB'; return round($size / (1024 * 1024), 2).' MB';
} }
// less than one MB // less than one MB
if ($size < (1024 * 1024)) { if ($size < (1024 * 1024)) {
return round($size / 1024, 2) . ' KB'; return round($size / 1024, 2).' KB';
} }
return $size . ' bytes'; return $size.' bytes';
} }
); );
} }
@@ -337,7 +338,7 @@ class General extends AbstractExtension
{ {
return new TwigFilter( return new TwigFilter(
'mimeIcon', 'mimeIcon',
static fn(string $string): string => match ($string) { static fn (string $string): string => match ($string) {
'application/pdf' => 'fa-file-pdf-o', 'application/pdf' => 'fa-file-pdf-o',
'image/webp', 'image/png', 'image/jpeg', 'image/svg+xml', 'image/heic', 'image/heic-sequence', 'application/vnd.oasis.opendocument.image' => 'fa-file-image-o', 'image/webp', 'image/png', 'image/jpeg', 'image/svg+xml', 'image/heic', 'image/heic-sequence', 'application/vnd.oasis.opendocument.image' => 'fa-file-image-o',
'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'application/x-iwork-pages-sffpages', 'application/vnd.sun.xml.writer', 'application/vnd.sun.xml.writer.template', 'application/vnd.sun.xml.writer.global', 'application/vnd.stardivision.writer', 'application/vnd.stardivision.writer-global', 'application/vnd.oasis.opendocument.text', 'application/vnd.oasis.opendocument.text-template', 'application/vnd.oasis.opendocument.text-web', 'application/vnd.oasis.opendocument.text-master' => 'fa-file-word-o', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'application/x-iwork-pages-sffpages', 'application/vnd.sun.xml.writer', 'application/vnd.sun.xml.writer.template', 'application/vnd.sun.xml.writer.global', 'application/vnd.stardivision.writer', 'application/vnd.stardivision.writer-global', 'application/vnd.oasis.opendocument.text', 'application/vnd.oasis.opendocument.text-template', 'application/vnd.oasis.opendocument.text-web', 'application/vnd.oasis.opendocument.text-master' => 'fa-file-word-o',
@@ -380,7 +381,7 @@ class General extends AbstractExtension
{ {
return new TwigFunction( return new TwigFunction(
'phpdate', 'phpdate',
static fn(string $str): string => date($str) static fn (string $str): string => date($str)
); );
} }
} }

View File

@@ -42,7 +42,7 @@ class Rule extends AbstractExtension
$ruleActions = array_keys(Config::get('firefly.rule-actions')); $ruleActions = array_keys(Config::get('firefly.rule-actions'));
$possibleActions = []; $possibleActions = [];
foreach ($ruleActions as $key) { foreach ($ruleActions as $key) {
$possibleActions[$key] = (string)trans('firefly.rule_action_' . $key . '_choice'); $possibleActions[$key] = (string)trans('firefly.rule_action_'.$key.'_choice');
} }
unset($ruleActions); unset($ruleActions);
asort($possibleActions); asort($possibleActions);
@@ -56,7 +56,7 @@ class Rule extends AbstractExtension
{ {
return new TwigFunction( return new TwigFunction(
'allJournalTriggers', 'allJournalTriggers',
static fn() => [ static fn () => [
'store-journal' => (string)trans('firefly.rule_trigger_store_journal'), 'store-journal' => (string)trans('firefly.rule_trigger_store_journal'),
'update-journal' => (string)trans('firefly.rule_trigger_update_journal'), 'update-journal' => (string)trans('firefly.rule_trigger_update_journal'),
'manual-activation' => (string)trans('firefly.rule_trigger_manual'), 'manual-activation' => (string)trans('firefly.rule_trigger_manual'),
@@ -73,7 +73,7 @@ class Rule extends AbstractExtension
$possibleTriggers = []; $possibleTriggers = [];
foreach ($ruleTriggers as $key) { foreach ($ruleTriggers as $key) {
if ('user_action' !== $key) { if ('user_action' !== $key) {
$possibleTriggers[$key] = (string)trans('firefly.rule_trigger_' . $key . '_choice'); $possibleTriggers[$key] = (string)trans('firefly.rule_trigger_'.$key.'_choice');
} }
} }
unset($ruleTriggers); unset($ruleTriggers);

View File

@@ -34,6 +34,7 @@ use Illuminate\Support\Facades\DB;
use Override; use Override;
use Twig\Extension\AbstractExtension; use Twig\Extension\AbstractExtension;
use Twig\TwigFunction; use Twig\TwigFunction;
use function Safe\json_decode; use function Safe\json_decode;
/** /**
@@ -85,7 +86,8 @@ class TransactionGroupTwig extends AbstractExtension
->where('name', $metaField) ->where('name', $metaField)
->where('transaction_journal_id', $journalId) ->where('transaction_journal_id', $journalId)
->whereNull('deleted_at') ->whereNull('deleted_at')
->first(); ->first()
;
if (null === $entry) { if (null === $entry) {
return today(config('app.timezone')); return today(config('app.timezone'));
} }
@@ -105,7 +107,8 @@ class TransactionGroupTwig extends AbstractExtension
->where('name', $metaField) ->where('name', $metaField)
->where('transaction_journal_id', $journalId) ->where('transaction_journal_id', $journalId)
->whereNull('deleted_at') ->whereNull('deleted_at')
->first(); ->first()
;
if (null === $entry) { if (null === $entry) {
return ''; return '';
} }
@@ -124,7 +127,8 @@ class TransactionGroupTwig extends AbstractExtension
->where('name', $metaField) ->where('name', $metaField)
->where('transaction_journal_id', $journalId) ->where('transaction_journal_id', $journalId)
->whereNull('deleted_at') ->whereNull('deleted_at')
->count(); ->count()
;
return 1 === $count; return 1 === $count;
} }

View File

@@ -39,7 +39,7 @@ class Translation extends AbstractExtension
return [ return [
new TwigFilter( new TwigFilter(
'_', '_',
static fn($name) => (string)trans(sprintf('firefly.%s', $name)), static fn ($name) => (string)trans(sprintf('firefly.%s', $name)),
['is_safe' => ['html']] ['is_safe' => ['html']]
), ),
]; ];

14
composer.lock generated
View File

@@ -11511,21 +11511,21 @@
}, },
{ {
"name": "phpstan/phpstan-strict-rules", "name": "phpstan/phpstan-strict-rules",
"version": "2.0.6", "version": "2.0.7",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan-strict-rules.git", "url": "https://github.com/phpstan/phpstan-strict-rules.git",
"reference": "f9f77efa9de31992a832ff77ea52eb42d675b094" "reference": "d6211c46213d4181054b3d77b10a5c5cb0d59538"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/f9f77efa9de31992a832ff77ea52eb42d675b094", "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/d6211c46213d4181054b3d77b10a5c5cb0d59538",
"reference": "f9f77efa9de31992a832ff77ea52eb42d675b094", "reference": "d6211c46213d4181054b3d77b10a5c5cb0d59538",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.4 || ^8.0", "php": "^7.4 || ^8.0",
"phpstan/phpstan": "^2.0.4" "phpstan/phpstan": "^2.1.29"
}, },
"require-dev": { "require-dev": {
"php-parallel-lint/php-parallel-lint": "^1.2", "php-parallel-lint/php-parallel-lint": "^1.2",
@@ -11553,9 +11553,9 @@
"description": "Extra strict and opinionated rules for PHPStan", "description": "Extra strict and opinionated rules for PHPStan",
"support": { "support": {
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues", "issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.6" "source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.7"
}, },
"time": "2025-07-21T12:19:29+00:00" "time": "2025-09-26T11:19:08+00:00"
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",

View File

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

6
package-lock.json generated
View File

@@ -5736,9 +5736,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.223", "version": "1.5.224",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.223.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.224.tgz",
"integrity": "sha512-qKm55ic6nbEmagFlTFczML33rF90aU+WtrJ9MdTCThrcvDNdUHN4p6QfVN78U06ZmguqXIyMPyYhw2TrbDUwPQ==", "integrity": "sha512-kWAoUu/bwzvnhpdZSIc6KUyvkI1rbRXMT0Eq8pKReyOyaPZcctMli+EgvcN1PAvwVc7Tdo4Fxi2PsLNDU05mdg==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },