Compare commits

...

19 Commits

Author SHA1 Message Date
github-actions[bot] 2c2ebae8fa Merge pull request #11691 from firefly-iii/release-1770727195
🤖 Automatically merge the PR into the develop branch.
2026-02-10 13:40:04 +01:00
JC5 aff9afb767 🤖 Auto commit for release 'develop' on 2026-02-10 2026-02-10 13:39:55 +01:00
James Cole c8e95fe131 Fix audit log entry position. 2026-02-09 20:05:38 +01:00
James Cole cef514c22b Merge pull request #11680 from firefly-iii/dependabot/composer/develop/mailersend/laravel-driver-3.0.0 2026-02-09 05:57:03 +01:00
github-actions[bot] 46d2ba3d3b Merge pull request #11681 from firefly-iii/release-1770609440
🤖 Automatically merge the PR into the develop branch.
2026-02-09 04:57:28 +01:00
JC5 45a0504eba 🤖 Auto commit for release 'develop' on 2026-02-09 2026-02-09 04:57:20 +01:00
dependabot[bot] 9711bc1d04 Bump mailersend/laravel-driver from 2.12.0 to 3.0.0
Bumps [mailersend/laravel-driver](https://github.com/mailersend/mailersend-laravel-driver) from 2.12.0 to 3.0.0.
- [Release notes](https://github.com/mailersend/mailersend-laravel-driver/releases)
- [Commits](https://github.com/mailersend/mailersend-laravel-driver/compare/v2.12.0...v3.0.0)

---
updated-dependencies:
- dependency-name: mailersend/laravel-driver
  dependency-version: 3.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-09 03:52:32 +00:00
James Cole cf2343c0dd Catch errors in DB thing. 2026-02-08 21:07:50 +01:00
James Cole 34097cecf0 Fix viewrange. 2026-02-08 08:29:59 +01:00
github-actions[bot] 8735be2f6b Merge pull request #11676 from firefly-iii/develop
🤖 Automatically merge the PR into the main branch.
2026-02-08 08:27:47 +01:00
github-actions[bot] 0e8cc91308 Merge pull request #11675 from firefly-iii/release-1770535655
🤖 Automatically merge the PR into the develop branch.
2026-02-08 08:27:42 +01:00
JC5 5cbb311e4d 🤖 Auto commit for release 'v6.4.18' on 2026-02-08 2026-02-08 08:27:35 +01:00
James Cole c334641b90 Add class reference. 2026-02-08 08:21:24 +01:00
James Cole 4c2356881d Remove unused debug logging. 2026-02-08 08:20:50 +01:00
James Cole d9a0d06712 Clean up some debug logging. 2026-02-08 08:16:33 +01:00
github-actions[bot] 65b9dedc03 Merge pull request #11674 from firefly-iii/release-1770534470
🤖 Automatically merge the PR into the develop branch.
2026-02-08 08:07:56 +01:00
JC5 e46ef138b1 🤖 Auto commit for release 'develop' on 2026-02-08 2026-02-08 08:07:50 +01:00
James Cole f0fdb57754 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2026-02-08 08:04:05 +01:00
James Cole 09799582aa Remove debug comments. 2026-02-08 08:03:59 +01:00
78 changed files with 447 additions and 256 deletions
@@ -167,7 +167,7 @@ class BasicController extends Controller
],
];
$newIncomes = [
$primary->id => [
$primary->id => [
'currency_id' => $primary->id,
'currency_code' => $primary->code,
'currency_symbol' => $primary->symbol,
@@ -176,7 +176,7 @@ class BasicController extends Controller
],
];
$sums = [
$primary->id => [
$primary->id => [
'currency_id' => $primary->id,
'currency_code' => $primary->code,
'currency_symbol' => $primary->symbol,
@@ -244,7 +244,7 @@ class BasicController extends Controller
// create objects for big array.
$return[] = [
'key' => sprintf('balance-in-%s', $currency->code),
'title' => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]),
'title' => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => $sums[$currencyId]['sum'] ?? '0',
'currency_id' => (string) $currency->id,
'currency_code' => $currency->code,
@@ -258,7 +258,7 @@ class BasicController extends Controller
];
$return[] = [
'key' => sprintf('spent-in-%s', $currency->code),
'title' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
'title' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => $expenses[$currencyId]['sum'] ?? '0',
'currency_id' => (string) $currency->id,
'currency_code' => $currency->code,
@@ -270,7 +270,7 @@ class BasicController extends Controller
];
$return[] = [
'key' => sprintf('earned-in-%s', $currency->code),
'title' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
'title' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => $incomes[$currencyId]['sum'] ?? '0',
'currency_id' => (string) $currency->id,
'currency_code' => $currency->code,
@@ -286,7 +286,7 @@ class BasicController extends Controller
// create objects for big array.
$return[] = [
'key' => sprintf('balance-in-%s', $currency->code),
'title' => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]),
'title' => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => '0',
'currency_id' => (string) $currency->id,
'currency_code' => $currency->code,
@@ -298,7 +298,7 @@ class BasicController extends Controller
];
$return[] = [
'key' => sprintf('spent-in-%s', $currency->code),
'title' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
'title' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => '0',
'currency_id' => (string) $currency->id,
'currency_code' => $currency->code,
@@ -310,7 +310,7 @@ class BasicController extends Controller
];
$return[] = [
'key' => sprintf('earned-in-%s', $currency->code),
'title' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
'title' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => '0',
'currency_id' => (string) $currency->id,
'currency_code' => $currency->code,
@@ -345,7 +345,7 @@ class BasicController extends Controller
$currencies[$currencyId] ??= $this->currencyRepos->find($currencyId);
$return[$currencyId] = [
'key' => sprintf('left-to-spend-in-%s', $currencies[$currencyId]->code),
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $currencies[$currencyId]->symbol]),
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $currencies[$currencyId]->symbol]),
'no_available_budgets' => false,
'monetary_value' => $availableBudget,
'currency_id' => (string) $currencies[$currencyId]->id,
@@ -386,7 +386,7 @@ class BasicController extends Controller
$return[$currencyId] = [
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]),
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]),
'no_available_budgets' => false,
'monetary_value' => $leftToSpend,
'currency_id' => (string) $row['currency_id'],
@@ -493,7 +493,7 @@ class BasicController extends Controller
// return stuff
$return[] = [
'key' => sprintf('net-worth-in-%s', $data['currency_code']),
'title' => trans('firefly.box_net_worth_in_currency', ['currency' => $data['currency_symbol']]),
'title' => trans('firefly.box_net_worth_in_currency', ['currency' => $data['currency_symbol']]),
'monetary_value' => $amount,
'currency_id' => (string) $data['currency_id'],
'currency_code' => $data['currency_code'],
@@ -507,7 +507,7 @@ class BasicController extends Controller
if (0 === count($return)) {
$return[] = [
'key' => sprintf('net-worth-in-%s', $this->primaryCurrency->code),
'title' => trans('firefly.box_net_worth_in_currency', ['currency' => $this->primaryCurrency->symbol]),
'title' => trans('firefly.box_net_worth_in_currency', ['currency' => $this->primaryCurrency->symbol]),
'monetary_value' => '0',
'currency_id' => (string) $this->primaryCurrency->id,
'currency_code' => $this->primaryCurrency->code,
@@ -533,7 +533,7 @@ class BasicController extends Controller
*/
$paidAmount = $this->billRepository->sumPaidInRange($start, $end);
$unpaidAmount = $this->billRepository->sumUnpaidInRange($start, $end);
$currencies = [$this->primaryCurrency->id => $this->primaryCurrency];
$currencies = [$this->primaryCurrency->id => $this->primaryCurrency];
if ($this->convertToPrimary) {
$converter = new ExchangeRateConverter();
@@ -598,7 +598,7 @@ class BasicController extends Controller
$amount = bcmul((string) $info['sum'], '-1');
$return[] = [
'key' => sprintf('bills-paid-in-%s', $info['code']),
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $info['symbol']]),
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $info['symbol']]),
'monetary_value' => $amount,
'currency_id' => (string) $info['id'],
'currency_code' => $info['code'],
@@ -617,7 +617,7 @@ class BasicController extends Controller
$amount = bcmul((string) $info['sum'], '-1');
$return[] = [
'key' => sprintf('bills-unpaid-in-%s', $info['code']),
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $info['symbol']]),
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $info['symbol']]),
'monetary_value' => $amount,
'currency_id' => (string) $info['id'],
'currency_code' => $info['code'],
@@ -636,7 +636,7 @@ class BasicController extends Controller
$return[] = [
'key' => sprintf('bills-paid-in-%s', $currency->code),
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $currency->symbol]),
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => '0',
'currency_id' => (string) $currency->id,
'currency_code' => $currency->code,
@@ -648,7 +648,7 @@ class BasicController extends Controller
];
$return[] = [
'key' => sprintf('bills-unpaid-in-%s', $currency->code),
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $currency->symbol]),
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => '0',
'currency_id' => (string) $currency->id,
'currency_code' => $currency->code,
@@ -113,7 +113,7 @@ class UpdateRequest extends FormRequest
];
$this->booleanFields = ['reconciled'];
$this->arrayFields = ['tags'];
$data = ['batch_submission' => false];
$data = ['batch_submission' => false];
if ($this->has('transactions')) {
$data['transactions'] = $this->getTransactionData();
}
@@ -68,7 +68,7 @@ class CorrectsMetaDataFields extends Command
private function rename(string $original, string $update): void
{
$total = DB::table('journal_meta')->where('name', '=', $original)->update(['name' => $update]);
$total = DB::table('journal_meta')->where('name', '=', $original)->update(['name' => $update]);
$this->count += $total;
}
}
@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
/*
* RollbackSingleMigration.php
* Copyright (c) 2026 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/>.
*/
namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class RollbacksSingleMigration extends Command
{
use ShowsFriendlyMessages;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'correction:rollback-single-migration {--force}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Removes the last entry from the migration table. ';
/**
* Execute the console command.
*/
public function handle(): int
{
$entry = DB::table('migrations')->orderBy('id', 'DESC')->first();
if (null === $entry) {
$this->friendlyError('There are no more database migrations to rollback.');
return Command::FAILURE;
}
$this->friendlyLine(sprintf('This command will remove the database migration entry called "%s" from your database.', $entry->migration));
$this->friendlyLine('This does not change the database in anyway. It makes Firefly III forget it made the changes in this particular migration.');
$this->friendlyLine('');
$this->friendlyLine('If you run "php artisan migrate" after doing this, Firefly III will try to run the database migration again.');
$this->friendlyLine('Missing tables or indices will be created.');
$this->friendlyLine('This may not work, or give you warnings, but if you have a botched database it may restore it again.');
$this->friendlyLine('');
$this->friendlyLine('If this doesn\'t work, run the command a few times to remove more rows and try "php artisan migrate" again.');
$this->friendlyLine('');
$res = true;
if (!$this->option('force')) {
$this->friendlyWarning('Use this command at your own risk.');
$res = $this->confirm('Are you sure you want to continue?');
}
if ($res) {
DB::table('migrations')->where('id', (int) $entry->id)->delete();
$this->friendlyInfo(sprintf('Database migration #%d ("%s") is deleted.', $entry->id, $entry->migration));
$this->friendlyLine('');
$this->friendlyLine('Try running "php artisan migrate" now.');
$this->friendlyLine('');
}
if (!$res) {
$this->friendlyError('User cancelled, will not delete anything.');
}
return Command::SUCCESS;
}
}
@@ -110,7 +110,7 @@ class UpgradesBillsToRules extends Command
'active' => true,
'strict' => false,
'stop_processing' => false, // field is no longer used.
'title' => (string) trans('firefly.rule_for_bill_title', ['name' => $bill->name], $languageString),
'title' => (string) trans('firefly.rule_for_bill_title', ['name' => $bill->name], $languageString),
'description' => (string) trans('firefly.rule_for_bill_description', ['name' => $bill->name], $languageString),
'trigger' => 'store-journal',
'triggers' => [['type' => 'description_contains', 'value' => $match]],
+1 -1
View File
@@ -157,7 +157,7 @@ class Handler extends ExceptionHandler
return response()->json([
'message' => sprintf('Validation exception: %s', $e->getMessage()),
'errors' => ['field' => 'Field is invalid'],
'errors' => ['field' => 'Field is invalid'],
], $errorCode);
}
+2 -2
View File
@@ -433,7 +433,7 @@ class GroupCollector implements GroupCollectorInterface
*/
public function getGroups(): Collection
{
Log::debug('Now in getGroups()');
// Log::debug('Now in getGroups()');
if ($this->expandGroupSearch) {
// get group ID's for the query:
$groupIds = $this->getCollectedGroupIds();
@@ -556,7 +556,7 @@ class GroupCollector implements GroupCollectorInterface
if (0 !== count($journalIds)) {
// make all integers.
$integerIDs = array_map(intval(...), $journalIds);
Log::debug(sprintf('GroupCollector: setJournalIds: %s', implode(', ', $integerIDs)));
// Log::debug(sprintf('GroupCollector: setJournalIds: %s', implode(', ', $integerIDs)));
$this->query->whereIn('transaction_journals.id', $integerIDs);
}
@@ -72,7 +72,7 @@ class DeleteController extends Controller
}
$typeName = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type));
$subTitle = (string) trans(sprintf('firefly.delete_%s_account', $typeName), ['name' => $account->name]);
$subTitle = (string) trans(sprintf('firefly.delete_%s_account', $typeName), ['name' => $account->name]);
$accountList = app('expandedform')->makeSelectListWithEmpty($this->repository->getAccountsByType([$account->accountType->type]));
$objectType = $typeName;
unset($accountList[$account->id]);
@@ -86,7 +86,7 @@ class EditController extends Controller
}
$objectType = config('firefly.shortNamesByFullName')[$account->accountType->type];
$subTitle = (string) trans(sprintf('firefly.edit_%s_account', $objectType), ['name' => $account->name]);
$subTitle = (string) trans(sprintf('firefly.edit_%s_account', $objectType), ['name' => $account->name]);
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
$roles = $this->getRoles();
$liabilityTypes = $this->getLiabilityTypes();
@@ -137,7 +137,7 @@ class ReconcileController extends Controller
);
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type));
$subTitle = (string) trans('firefly.reconcile_account', ['account' => $account->name]);
$subTitle = (string) trans('firefly.reconcile_account', ['account' => $account->name]);
// various links
$transactionsUrl = route('accounts.reconcile.transactions', [$account->id, '%start%', '%end%']);
@@ -219,7 +219,7 @@ class ShowController extends Controller
$page = (int) $request->get('page');
$pageSize = (int) Preferences::get('listPageSize', 50)->data;
$currency = $this->repository->getAccountCurrency($account) ?? $this->primaryCurrency;
$subTitle = (string) trans('firefly.all_journals_for_account', ['name' => $account->name]);
$subTitle = (string) trans('firefly.all_journals_for_account', ['name' => $account->name]);
$periods = new Collection();
$end->endOfDay();
@@ -94,7 +94,7 @@ class LinkController extends Controller
}
Log::channel('audit')->info(sprintf('User wants to delete link type #%d', $linkType->id));
$subTitle = (string) trans('firefly.delete_link_type', ['name' => $linkType->name]);
$subTitle = (string) trans('firefly.delete_link_type', ['name' => $linkType->name]);
$otherTypes = $this->repository->get();
$count = $this->repository->countJournals($linkType);
$moveTo = [];
@@ -141,7 +141,7 @@ class LinkController extends Controller
return redirect(route('settings.links.index'));
}
$subTitle = (string) trans('firefly.edit_link_type', ['name' => $linkType->name]);
$subTitle = (string) trans('firefly.edit_link_type', ['name' => $linkType->name]);
$subTitleIcon = 'fa-link';
Log::channel('audit')->info(sprintf('User wants to edit link type #%d', $linkType->id));
@@ -181,7 +181,7 @@ class LinkController extends Controller
*/
public function show(LinkType $linkType): Factory|\Illuminate\Contracts\View\View
{
$subTitle = (string) trans('firefly.overview_for_link', ['name' => $linkType->name]);
$subTitle = (string) trans('firefly.overview_for_link', ['name' => $linkType->name]);
$subTitleIcon = 'fa-link';
$links = $this->repository->getJournalLinks($linkType);
@@ -135,7 +135,7 @@ class UserController extends Controller
}
session()->forget('users.edit.fromUpdate');
$subTitle = (string) trans('firefly.edit_user', ['email' => $user->email]);
$subTitle = (string) trans('firefly.edit_user', ['email' => $user->email]);
$subTitleIcon = 'fa-user-o';
$currentUser = auth()->user();
$isAdmin = $this->repository->hasRole($user, 'owner');
@@ -216,7 +216,7 @@ class UserController extends Controller
{
$title = (string) trans('firefly.system_settings');
$mainTitleIcon = 'fa-hand-spock-o';
$subTitle = (string) trans('firefly.single_user_administration', ['email' => $user->email]);
$subTitle = (string) trans('firefly.single_user_administration', ['email' => $user->email]);
$subTitleIcon = 'fa-user';
$information = $this->repository->getUserData($user);
@@ -131,7 +131,7 @@ class AttachmentController extends Controller
public function edit(Request $request, Attachment $attachment): Factory|\Illuminate\Contracts\View\View
{
$subTitleIcon = 'fa-pencil';
$subTitle = (string) trans('firefly.edit_attachment', ['name' => $attachment->filename]);
$subTitle = (string) trans('firefly.edit_attachment', ['name' => $attachment->filename]);
// put previous url in session if not redirect from store (not "return_to_edit").
if (true !== session('attachments.edit.fromUpdate')) {
@@ -251,7 +251,7 @@ class LoginController extends Controller
*/
protected function sendFailedLoginResponse(Request $request): void
{
$exception = ValidationException::withMessages([$this->username() => [trans('auth.failed')]]);
$exception = ValidationException::withMessages([$this->username() => [trans('auth.failed')]]);
$exception->redirectTo = route('login');
throw $exception;
@@ -82,7 +82,7 @@ class IndexController extends Controller
if ('last7' === $viewRange || 'last30' === $viewRange) {
$end->addDays(30);
}
if ('last90') {
if ('last90' === $viewRange) {
$end->addDays(90);
}
@@ -71,7 +71,7 @@ class EditController extends Controller
*/
public function edit(Request $request, Budget $budget): Factory|\Illuminate\Contracts\View\View
{
$subTitle = (string) trans('firefly.edit_budget', ['name' => $budget->name]);
$subTitle = (string) trans('firefly.edit_budget', ['name' => $budget->name]);
$autoBudget = $this->repository->getAutoBudget($budget);
// auto budget types
@@ -73,7 +73,7 @@ class BillController extends Controller
*/
foreach ($paid as $info) {
$amount = $info['sum'];
$label = (string) trans('firefly.paid_in_currency', ['currency' => $info['name']]);
$label = (string) trans('firefly.paid_in_currency', ['currency' => $info['name']]);
$chartData[$label] = ['amount' => $amount, 'currency_symbol' => $info['symbol'], 'currency_code' => $info['code']];
}
@@ -82,7 +82,7 @@ class BillController extends Controller
*/
foreach ($unpaid as $info) {
$amount = $info['sum'];
$label = (string) trans('firefly.unpaid_in_currency', ['currency' => $info['name']]);
$label = (string) trans('firefly.unpaid_in_currency', ['currency' => $info['name']]);
$chartData[$label] = ['amount' => $amount, 'currency_symbol' => $info['symbol'], 'currency_code' => $info['code']];
}
@@ -505,14 +505,14 @@ class BudgetController extends Controller
$preferredRange = Navigation::preferredRangeFormat($start, $end);
$chartData = [
[
'label' => (string) trans('firefly.box_spent_in_currency', ['currency' => $currency->name]),
'label' => (string) trans('firefly.box_spent_in_currency', ['currency' => $currency->name]),
'type' => 'bar',
'entries' => [],
'currency_symbol' => $currency->symbol,
'currency_code' => $currency->code,
],
[
'label' => (string) trans('firefly.box_budgeted_in_currency', ['currency' => $currency->name]),
'label' => (string) trans('firefly.box_budgeted_in_currency', ['currency' => $currency->name]),
'type' => 'bar',
'currency_symbol' => $currency->symbol,
'currency_code' => $currency->code,
@@ -171,7 +171,7 @@ class BudgetReportController extends Controller
$chartData[$spentKey] ??= [
'label' => sprintf(
'%s (%s)',
(string) trans('firefly.spent_in_specific_budget', ['budget' => $budget->name]),
(string) trans('firefly.spent_in_specific_budget', ['budget' => $budget->name]),
$currency['currency_name']
),
'type' => 'bar',
@@ -216,7 +216,7 @@ class CategoryReportController extends Controller
$chartData[$spentKey] ??= [
'label' => sprintf(
'%s (%s)',
(string) trans('firefly.spent_in_specific_category', ['category' => $category->name]),
(string) trans('firefly.spent_in_specific_category', ['category' => $category->name]),
$currency['currency_name']
),
'type' => 'bar',
@@ -243,7 +243,7 @@ class CategoryReportController extends Controller
$chartData[$spentKey] ??= [
'label' => sprintf(
'%s (%s)',
(string) trans('firefly.earned_in_specific_category', ['category' => $category->name]),
(string) trans('firefly.earned_in_specific_category', ['category' => $category->name]),
$currency['currency_name']
),
'type' => 'bar',
@@ -162,11 +162,7 @@ class DoubleReportController extends Controller
$name = $this->getCounterpartName($accounts, $account->id, $account->name, $account->iban);
$chartData[$spentKey] ??= [
'label' => sprintf(
'%s (%s)',
(string) trans('firefly.spent_in_specific_double', ['account' => $name]),
$currency['currency_name']
),
'label' => sprintf('%s (%s)', (string) trans('firefly.spent_in_specific_double', ['account' => $name]), $currency['currency_name']),
'type' => 'bar',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -188,11 +184,7 @@ class DoubleReportController extends Controller
$name = $this->getCounterpartName($accounts, $account->id, $account->name, $account->iban);
$chartData[$earnedKey] ??= [
'label' => sprintf(
'%s (%s)',
(string) trans('firefly.earned_in_specific_double', ['account' => $name]),
$currency['currency_name']
),
'label' => sprintf('%s (%s)', (string) trans('firefly.earned_in_specific_double', ['account' => $name]), $currency['currency_name']),
'type' => 'bar',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -212,7 +212,7 @@ class ReportController extends Controller
foreach ($data as $currency) {
Log::debug(sprintf('Now processing currency "%s"', $currency['currency_name']));
$income = [
'label' => (string) trans('firefly.box_earned_in_currency', ['currency' => $currency['currency_name']]),
'label' => (string) trans('firefly.box_earned_in_currency', ['currency' => $currency['currency_name']]),
'type' => 'bar',
'backgroundColor' => 'rgba(0, 141, 76, 0.5)', // green
'currency_id' => $currency['currency_id'],
@@ -221,7 +221,7 @@ class ReportController extends Controller
'entries' => [],
];
$expense = [
'label' => (string) trans('firefly.box_spent_in_currency', ['currency' => $currency['currency_name']]),
'label' => (string) trans('firefly.box_spent_in_currency', ['currency' => $currency['currency_name']]),
'type' => 'bar',
'backgroundColor' => 'rgba(219, 68, 55, 0.5)', // red
'currency_id' => $currency['currency_id'],
@@ -220,11 +220,7 @@ class TagReportController extends Controller
// add things to chart Data for each currency:
$spentKey = sprintf('%d-spent', $currency['currency_id']);
$chartData[$spentKey] ??= [
'label' => sprintf(
'%s (%s)',
(string) trans('firefly.spent_in_specific_tag', ['tag' => $tag->tag]),
$currency['currency_name']
),
'label' => sprintf('%s (%s)', (string) trans('firefly.spent_in_specific_tag', ['tag' => $tag->tag]), $currency['currency_name']),
'type' => 'bar',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -247,11 +243,7 @@ class TagReportController extends Controller
// add things to chart Data for each currency:
$spentKey = sprintf('%d-earned', $currency['currency_id']);
$chartData[$spentKey] ??= [
'label' => sprintf(
'%s (%s)',
(string) trans('firefly.earned_in_specific_tag', ['tag' => $tag->tag]),
$currency['currency_name']
),
'label' => sprintf('%s (%s)', (string) trans('firefly.earned_in_specific_tag', ['tag' => $tag->tag]), $currency['currency_name']),
'type' => 'bar',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -183,11 +183,11 @@ class RecurrenceController extends Controller
$result = [
'daily' => ['label' => (string) trans('firefly.recurring_daily'), 'selected' => str_starts_with($preSelected, 'daily')],
$weekly => [
'label' => (string) trans('firefly.recurring_weekly', ['weekday' => $dayOfWeek]),
'label' => (string) trans('firefly.recurring_weekly', ['weekday' => $dayOfWeek]),
'selected' => str_starts_with($preSelected, 'weekly'),
],
$monthly => [
'label' => (string) trans('firefly.recurring_monthly', ['dayOfMonth' => $date->day]),
'label' => (string) trans('firefly.recurring_monthly', ['dayOfMonth' => $date->day]),
'selected' => str_starts_with($preSelected, 'monthly'),
],
$ndom => [
@@ -195,7 +195,7 @@ class RecurrenceController extends Controller
'selected' => str_starts_with($preSelected, 'ndom'),
],
$yearly => [
'label' => (string) trans('firefly.recurring_yearly', ['date' => $yearlyDate]),
'label' => (string) trans('firefly.recurring_yearly', ['date' => $yearlyDate]),
'selected' => str_starts_with($preSelected, 'yearly'),
],
];
@@ -61,7 +61,7 @@ class DeleteController extends Controller
*/
public function delete(ObjectGroup $objectGroup): Factory|View
{
$subTitle = (string) trans('firefly.delete_object_group', ['title' => $objectGroup->title]);
$subTitle = (string) trans('firefly.delete_object_group', ['title' => $objectGroup->title]);
$piggyBanks = $objectGroup->piggyBanks()->count();
// put previous url in session
@@ -64,7 +64,7 @@ class EditController extends Controller
*/
public function edit(ObjectGroup $objectGroup): Factory|View
{
$subTitle = (string) trans('firefly.edit_object_group', ['title' => $objectGroup->title]);
$subTitle = (string) trans('firefly.edit_object_group', ['title' => $objectGroup->title]);
$subTitleIcon = 'fa-pencil';
if (true !== session('object-groups.edit.fromUpdate')) {
@@ -70,7 +70,7 @@ class EditController extends Controller
*/
public function edit(PiggyBank $piggyBank): Factory|\Illuminate\Contracts\View\View
{
$subTitle = (string) trans('firefly.update_piggy_title', ['name' => $piggyBank->name]);
$subTitle = (string) trans('firefly.update_piggy_title', ['name' => $piggyBank->name]);
$subTitleIcon = 'fa-pencil';
$note = $piggyBank->notes()->first();
// Flash some data to fill the form.
@@ -80,7 +80,7 @@ class CreateController extends Controller
public function create(Request $request, ?RuleGroup $ruleGroup = null): Factory|\Illuminate\Contracts\View\View
{
$this->createDefaultRuleGroup();
$preFilled = ['strict' => true];
$preFilled = ['strict' => true];
$oldTriggers = [];
$oldActions = [];
@@ -159,7 +159,7 @@ class CreateController extends Controller
$this->createDefaultRuleGroup();
$preFilled = [
'strict' => true,
'title' => (string) trans('firefly.new_rule_for_bill_title', ['name' => $bill->name]),
'title' => (string) trans('firefly.new_rule_for_bill_title', ['name' => $bill->name]),
'description' => (string) trans('firefly.new_rule_for_bill_description', ['name' => $bill->name]),
];
@@ -221,7 +221,7 @@ class CreateController extends Controller
// collect pre-filled information:
$preFilled = [
'strict' => true,
'title' => (string) trans('firefly.new_rule_for_journal_title', ['description' => $journal->description]),
'title' => (string) trans('firefly.new_rule_for_journal_title', ['description' => $journal->description]),
'description' => (string) trans('firefly.new_rule_for_journal_description', ['description' => $journal->description]),
];
@@ -70,7 +70,7 @@ class EditController extends Controller
$subTitle = (string) trans('firefly.edit_rule_group', ['title' => $ruleGroup->title]);
$hasOldInput = null !== $request->old('_token');
$preFilled = ['active' => $hasOldInput ? (bool) $request->old('active') : $ruleGroup->active];
$preFilled = ['active' => $hasOldInput ? (bool) $request->old('active') : $ruleGroup->active];
// put previous url in session if not redirect from store (not "return_to_edit").
if (true !== session('rule-groups.edit.fromUpdate')) {
$this->rememberPreviousUrl('rule-groups.edit.url');
+1 -1
View File
@@ -87,7 +87,7 @@ class SearchController extends Controller
$excludedWords = $searcher->getExcludedWords();
$operators = $searcher->getOperators();
$invalidOperators = $searcher->getInvalidOperators();
$subTitle = (string) trans('breadcrumbs.search_result', ['query' => $fullQuery]);
$subTitle = (string) trans('breadcrumbs.search_result', ['query' => $fullQuery]);
return view('search.index', [
'words' => $words,
@@ -61,7 +61,7 @@ class InstallController extends Controller
'migrate' => ['--seed' => true, '--force' => true],
'generate-keys' => [], // an exception :(
'firefly-iii:upgrade-database' => [],
'firefly-iii:set-latest-version' => ['--james-is-cool' => true],
'firefly-iii:set-latest-version' => ['--james-is-cool' => true],
'firefly-iii:verify-security-alerts' => [],
];
+2 -2
View File
@@ -134,7 +134,7 @@ class TagController extends Controller
*/
public function edit(Tag $tag): Factory|\Illuminate\Contracts\View\View
{
$subTitle = (string) trans('firefly.edit_tag', ['tag' => $tag->tag]);
$subTitle = (string) trans('firefly.edit_tag', ['tag' => $tag->tag]);
$subTitleIcon = 'fa-tag';
$location = $this->repository->getLocation($tag);
@@ -289,7 +289,7 @@ class TagController extends Controller
$page = (int) $request->get('page');
$pageSize = (int) Preferences::get('listPageSize', 50)->data;
$periods = [];
$subTitle = (string) trans('firefly.all_journals_for_tag', ['tag' => $tag->tag]);
$subTitle = (string) trans('firefly.all_journals_for_tag', ['tag' => $tag->tag]);
$start = $this->repository->firstUseDate($tag) ?? today(config('app.timezone'));
$end = $this->repository->lastUseDate($tag) ?? today(config('app.timezone'));
$attachments = $this->repository->getAttachments($tag);
@@ -103,7 +103,7 @@ class ConvertController extends Controller
$groupTitle = $group->title ?? $first->description;
$groupArray = $transformer->transformObject($group);
$subTitle = (string) trans('firefly.convert_to_'.$destinationType->type, ['description' => $groupTitle]);
$subTitle = (string) trans('firefly.convert_to_'.$destinationType->type, ['description' => $groupTitle]);
$subTitleIcon = 'fa-exchange';
// get a list of asset accounts and liabilities and stuff, in various combinations:
@@ -77,7 +77,7 @@ class DeleteController extends Controller
throw new NotFoundHttpException();
}
$objectType = strtolower($journal->transaction_type_type ?? $journal->transactionType->type);
$subTitle = (string) trans('firefly.delete_'.$objectType, ['description' => $group->title ?? $journal->description]);
$subTitle = (string) trans('firefly.delete_'.$objectType, ['description' => $group->title ?? $journal->description]);
$previous = Steam::getSafePreviousUrl();
// put previous url in session
Log::debug('Will try to remember previous URL');
@@ -91,7 +91,7 @@ class EditController extends Controller
$title = $transactionGroup->transactionJournals()->count() > 1
? $transactionGroup->title
: $transactionGroup->transactionJournals()->first()->description;
$subTitle = (string) trans('firefly.edit_transaction_title', ['description' => $title]);
$subTitle = (string) trans('firefly.edit_transaction_title', ['description' => $title]);
$subTitleIcon = 'fa-plus';
$cash = $repository->getCashAccount();
$previousUrl = $this->rememberPreviousUrl('transactions.edit.url');
@@ -78,7 +78,7 @@ class EditController extends Controller
}
$subTitleIcon = 'fa-pencil';
$subTitle = (string) trans('breadcrumbs.edit_currency', ['name' => $currency->name]);
$subTitle = (string) trans('breadcrumbs.edit_currency', ['name' => $currency->name]);
$currency->symbol = htmlentities($currency->symbol);
// is currently enabled (for this user?)
@@ -91,7 +91,7 @@ class EditController extends Controller
// code to handle active-checkboxes
$hasOldInput = null !== $request->old('_token');
$preFilled = ['enabled' => $hasOldInput ? (bool) $request->old('enabled') : $enabled];
$preFilled = ['enabled' => $hasOldInput ? (bool) $request->old('enabled') : $enabled];
$request->session()->flash('preFilled', $preFilled);
Log::channel('audit')->info('Edit currency.', $currency->toArray());
@@ -39,7 +39,7 @@ class EditController extends Controller
public function edit(UserGroup $userGroup)
{
$title = (string) trans('firefly.administrations_page_title');
$subTitle = (string) trans('firefly.administrations_page_edit_sub_title', ['title' => $userGroup->title]);
$subTitle = (string) trans('firefly.administrations_page_edit_sub_title', ['title' => $userGroup->title]);
$mainTitleIcon = 'fa-book';
Log::debug(sprintf('Now at %s', __METHOD__));
@@ -40,7 +40,7 @@ trait SupportsGroupProcessingTrait
$first = $set->first();
$journalIds = implode(',', $array);
$user = $first->user;
Log::debug(sprintf('Add local operator for journal(s): %s', $journalIds));
// Log::debug(sprintf('Add local operator for journal(s): %s', $journalIds));
// collect rules:
$ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
@@ -56,7 +56,7 @@ class MFABackupFewLeftNotification extends Notification
*/
public function toMail(User $notifiable): MailMessage
{
$subject = (string) trans('email.mfa_few_backups_left_subject', ['count' => $this->count]);
$subject = (string) trans('email.mfa_few_backups_left_subject', ['count' => $this->count]);
$ip = Request::ip();
$host = Steam::getHostName($ip);
$userAgent = Request::userAgent();
@@ -53,7 +53,7 @@ class MFAManyFailedAttemptsNotification extends Notification
*/
public function toMail(User $notifiable): MailMessage
{
$subject = (string) trans('email.mfa_many_failed_subject', ['count' => $this->count]);
$subject = (string) trans('email.mfa_many_failed_subject', ['count' => $this->count]);
$ip = Request::ip();
$host = Steam::getHostName($ip);
$userAgent = Request::userAgent();
@@ -58,7 +58,7 @@ class SubscriptionsOverdueReminder extends Notification
$info = [];
$count = 0;
foreach ($this->overdue as $item) {
$current = ['bill' => $item['bill']];
$current = ['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'
)), $item['dates']['pay_dates']);
+2 -2
View File
@@ -178,7 +178,7 @@ class AccountTasker implements AccountTaskerInterface, UserGroupInterface
/** @var CurrencyRepositoryInterface $currencyRepos */
$currencyRepos = app(CurrencyRepositoryInterface::class);
$currencies = [$primaryCurrency->id => $primaryCurrency];
$currencies = [$primaryCurrency->id => $primaryCurrency];
$report = ['accounts' => [], 'sums' => []];
/** @var array $journal */
@@ -232,7 +232,7 @@ class AccountTasker implements AccountTaskerInterface, UserGroupInterface
/** @var CurrencyRepositoryInterface $currencyRepos */
$currencyRepos = app(CurrencyRepositoryInterface::class);
$currencies = [$primaryCurrency->id => $primaryCurrency];
$currencies = [$primaryCurrency->id => $primaryCurrency];
$report = ['accounts' => [], 'sums' => []];
/** @var array $journal */
@@ -85,7 +85,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
?Collection $budgets = null,
?TransactionCurrency $currency = null
): array {
Log::debug(sprintf('Start of %s(%s, %s, array, array, "%s").', __METHOD__, $start->toW3cString(), $end->toW3cString(), $currency?->code));
// Log::debug(sprintf('Start of %s(%s, %s, array, array, "%s").', __METHOD__, $start->toW3cString(), $end->toW3cString(), $currency?->code));
// this collector excludes all transfers TO liabilities (which are also withdrawals)
// because those expenses only become expenses once they move from the liability to the friend.
// 2024-12-24 disable the exclusion for now.
@@ -204,7 +204,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
$currencySymbol = $primaryCurrency->symbol;
$currencyDecimalPlaces = $primaryCurrency->decimal_places;
$converter = new ExchangeRateConverter();
$currencies = [$currencyId => $primaryCurrency];
$currencies = [$currencyId => $primaryCurrency];
foreach ($journals as $journal) {
$amount = Steam::negative($journal['amount']);
@@ -275,7 +275,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
TransactionCurrency $transactionCurrency,
bool $convertToPrimary = false
): array {
Log::debug(sprintf('Start of %s.', __METHOD__));
// Log::debug(sprintf('Start of %s.', __METHOD__));
$summarizer = new TransactionSummarizer($this->user);
$summarizer->setConvertToPrimary($convertToPrimary);
@@ -290,7 +290,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
public function sumCollectedExpensesByBudget(array $expenses, Budget $budget, bool $convertToPrimary = false): array
{
Log::debug(sprintf('Start of %s.', __METHOD__));
// Log::debug(sprintf('Start of %s.', __METHOD__));
$summarizer = new TransactionSummarizer($this->user);
$summarizer->setConvertToPrimary($convertToPrimary);
@@ -311,7 +311,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
?TransactionCurrency $currency = null,
bool $convertToPrimary = false
): array {
Log::debug(sprintf('Start of %s(date, date, array, array, "%s", %s).', __METHOD__, $currency?->code, var_export($convertToPrimary, true)));
// Log::debug(sprintf('Start of %s(date, date, array, array, "%s", %s).', __METHOD__, $currency?->code, var_export($convertToPrimary, true)));
// this collector excludes all transfers TO liabilities (which are also withdrawals)
// because those expenses only become expenses once they move from the liability to the friend.
// 2024-12-24 disable the exclusion for now.
@@ -372,7 +372,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
public function sumCollectedTransactionsByCategory(array $expenses, Category $category, string $method, bool $convertToPrimary = false): array
{
Log::debug(sprintf('Start of %s.', __METHOD__));
// Log::debug(sprintf('Start of %s.', __METHOD__));
$summarizer = new TransactionSummarizer($this->user);
$summarizer->setConvertToPrimary($convertToPrimary);
@@ -195,21 +195,21 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte
if (null === $filter) {
return $groups;
}
Log::debug(sprintf('Will filter getRuleGroupsWithRules on "%s".', $filter));
// Log::debug(sprintf('Will filter getRuleGroupsWithRules on "%s".', $filter));
return $groups->map(static function (RuleGroup $group) use ($filter): RuleGroup { // @phpstan-ignore-line
Log::debug(sprintf('Now filtering group #%d', $group->id));
// Log::debug(sprintf('Now filtering group #%d', $group->id));
// filter the rules in the rule group:
$group->rules = $group->rules->filter(static function (Rule $rule) use ($filter, $group): bool {
Log::debug(sprintf('Now filtering rule #%d', $rule->id));
$group->rules = $group->rules->filter(static function (Rule $rule) use ($filter): bool {
// Log::debug(sprintf('Now filtering rule #%d', $rule->id));
foreach ($rule->ruleTriggers as $trigger) {
if ('user_action' === $trigger->trigger_type && $filter === $trigger->trigger_value) {
Log::debug(sprintf('Rule #%d triggers on %s, include it in rule group #%d.', $rule->id, $filter, $group->id));
// Log::debug(sprintf('Rule #%d triggers on %s, include it in rule group #%d.', $rule->id, $filter, $group->id));
return true;
}
}
Log::debug(sprintf('Rule #%d does not trigger on %s, do not include it.', $rule->id, $filter));
// Log::debug(sprintf('Rule #%d does not trigger on %s, do not include it.', $rule->id, $filter));
return false;
});
@@ -251,18 +251,18 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte
Log::debug(sprintf('Will filter getRuleGroupsWithRules on "%s".', $filter));
return $groups->map(static function (RuleGroup $group) use ($filter): RuleGroup { // @phpstan-ignore-line
Log::debug(sprintf('Now filtering group #%d', $group->id));
// Log::debug(sprintf('Now filtering group #%d', $group->id));
// filter the rules in the rule group:
$group->rules = $group->rules->filter(static function (Rule $rule) use ($filter, $group): bool {
Log::debug(sprintf('Now filtering rule #%d', $rule->id));
$group->rules = $group->rules->filter(static function (Rule $rule) use ($filter): bool {
// Log::debug(sprintf('Now filtering rule #%d', $rule->id));
foreach ($rule->ruleTriggers as $trigger) {
if ('user_action' === $trigger->trigger_type && $filter === $trigger->trigger_value) {
Log::debug(sprintf('Rule #%d triggers on %s, include it in rule group #%d.', $rule->id, $filter, $group->id));
// Log::debug(sprintf('Rule #%d triggers on %s, include it in rule group #%d.', $rule->id, $filter, $group->id));
return true;
}
}
Log::debug(sprintf('Rule #%d does not trigger on %s, do not include it.', $rule->id, $filter));
// Log::debug(sprintf('Rule #%d does not trigger on %s, do not include it.', $rule->id, $filter));
return false;
});
@@ -62,8 +62,8 @@ trait AccountServiceTrait
if (null === $iban) {
return null;
}
$data = ['iban' => $iban];
$rules = ['iban' => 'required|iban'];
$data = ['iban' => $iban];
$rules = ['iban' => 'required|iban'];
$validator = Validator::make($data, $rules);
if ($validator->fails()) {
Log::info(sprintf('Detected invalid IBAN ("%s"). Return NULL instead.', $iban));
@@ -228,7 +228,7 @@ trait AccountServiceTrait
$sourceId = $account->id;
$sourceName = null;
$destId = null;
$destName = trans('firefly.liability_credit_description', ['account' => $account->name], $language);
$destName = trans('firefly.liability_credit_description', ['account' => $account->name], $language);
}
// amount must be positive for the transaction to work.
@@ -257,7 +257,7 @@ trait AccountServiceTrait
'order' => 0,
'amount' => $amount,
'foreign_amount' => null,
'description' => trans('firefly.liability_credit_description', ['account' => $account->name]),
'description' => trans('firefly.liability_credit_description', ['account' => $account->name]),
'budget_id' => null,
'budget_name' => null,
'category_id' => null,
@@ -352,7 +352,7 @@ trait AccountServiceTrait
'order' => 0,
'amount' => $amount,
'foreign_amount' => null,
'description' => trans('firefly.initial_balance_description', ['account' => $account->name]),
'description' => trans('firefly.initial_balance_description', ['account' => $account->name]),
'budget_id' => null,
'budget_name' => null,
'category_id' => null,
@@ -444,7 +444,7 @@ trait AccountServiceTrait
'order' => 0,
'amount' => $amount,
'foreign_amount' => null,
'description' => trans('firefly.initial_balance_description', ['account' => $account->name]),
'description' => trans('firefly.initial_balance_description', ['account' => $account->name]),
'budget_id' => null,
'budget_name' => null,
'category_id' => null,
@@ -551,7 +551,7 @@ class JournalUpdateService
event(
new TransactionGroupRequestsAuditLogEntry(
$group->user,
$group,
$this->transactionJournal,
'update_amount',
[
'currency_symbol' => $recordCurrency->symbol,
@@ -767,7 +767,7 @@ class JournalUpdateService
event(
new TransactionGroupRequestsAuditLogEntry(
$group->user,
$group,
$this->transactionJournal,
'update_foreign_amount',
[
'currency_symbol' => $recordCurrency->symbol,
+4
View File
@@ -43,6 +43,10 @@ class Calculator
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
private static array $intervals = [];
public function isAvailablePeriodicity(Periodicity $periodicity): bool
@@ -81,14 +81,14 @@ class WholePeriodChartGenerator
$code = $currency['currency_code'];
$name = $currency['currency_name'];
$chartData[sprintf('spent-in-%s', $code)] = [
'label' => (string) trans('firefly.box_spent_in_currency', ['currency' => $name]),
'label' => (string) trans('firefly.box_spent_in_currency', ['currency' => $name]),
'entries' => [],
'type' => 'bar',
'backgroundColor' => 'rgba(219, 68, 55, 0.5)', // red
];
$chartData[sprintf('earned-in-%s', $code)] = [
'label' => (string) trans('firefly.box_earned_in_currency', ['currency' => $name]),
'label' => (string) trans('firefly.box_earned_in_currency', ['currency' => $name]),
'entries' => [],
'type' => 'bar',
'backgroundColor' => 'rgba(0, 141, 76, 0.5)', // green
@@ -104,6 +104,14 @@ class ExportDataGenerator
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
public function __construct()
{
$this->accounts = new Collection();
+2 -2
View File
@@ -49,7 +49,7 @@ class PiggyBankForm
$piggyBanks = $repository->getPiggyBanksWithAmount();
$title = (string) trans('firefly.default_group_title_name');
$array = [];
$subList = [0 => ['group' => ['title' => $title], 'piggies' => [(string) trans('firefly.none_in_select_list')]]];
$subList = [0 => ['group' => ['title' => $title], 'piggies' => [(string) trans('firefly.none_in_select_list')]]];
/** @var PiggyBank $piggy */
foreach ($piggyBanks as $piggy) {
@@ -60,7 +60,7 @@ class PiggyBankForm
$groupTitle = $group->title;
$groupOrder = $group->order;
}
$subList[$groupOrder] ??= ['group' => ['title' => $groupTitle], 'piggies' => []];
$subList[$groupOrder] ??= ['group' => ['title' => $groupTitle], 'piggies' => []];
$subList[$groupOrder]['piggies'][$piggy->id] = $piggy->name;
}
ksort($subList);
@@ -170,7 +170,7 @@ class AccountBalanceGrouped
{
$this->primary = $primary;
$primaryCurrencyId = $primary->id;
$this->currencies = [$primary->id => $primary]; // currency cache
$this->currencies = [$primary->id => $primary]; // currency cache
$this->data[$primaryCurrencyId] = [
'currency_id' => (string) $primaryCurrencyId,
'currency_symbol' => $primary->symbol,
@@ -157,7 +157,7 @@ trait GetConfigurationData
// previous year:
$yearBegin = today(config('app.timezone'))->subYear()->startOfYear();
$index = (string) trans('firefly.previous_year', ['year' => $yearBegin->year]);
$index = (string) trans('firefly.previous_year', ['year' => $yearBegin->year]);
$ranges[$index] = [$yearBegin, $yearBegin->clone()->endOfYear()];
// everything
@@ -88,6 +88,10 @@ trait PeriodOverview
// temp data holder
// temp data holder
// temp data holder
// temp data holder
// temp data holder
// temp data holder
// temp data holder
private array $transactions; // temp data holder
// temp data holder
@@ -104,6 +108,14 @@ trait PeriodOverview
// temp data holder
// temp data holder
// temp data holder
// temp data holder
// temp data holder
/**
* This method returns "period entries", so nov-2015, dec-2015, etc. (this depends on the users session range)
* and for each period, the amount of money spent and earned. This is a complex operation which is cached for
@@ -92,7 +92,7 @@ class AccountEnrichment implements EnrichmentInterface
*/
public function enrich(Collection $collection): Collection
{
Log::debug(sprintf('Now doing account enrichment for %d account(s)', $collection->count()));
// Log::debug(sprintf('Now doing account enrichment for %d account(s)', $collection->count()));
// prep local fields
$this->collection = $collection;
@@ -48,6 +48,10 @@ class AvailableBudgetEnrichment implements EnrichmentInterface
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
private readonly bool $convertToPrimary; // @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
@@ -56,6 +60,10 @@ class AvailableBudgetEnrichment implements EnrichmentInterface
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
private array $currencies = [];
private array $currencyIds = [];
private array $ids = [];
@@ -48,6 +48,10 @@ class BudgetLimitEnrichment implements EnrichmentInterface
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
private array $currencies = [];
private array $currencyIds = [];
private Carbon $end;
@@ -63,7 +63,7 @@ class CategoryEnrichment implements EnrichmentInterface
public function enrichSingle(array|Model $model): array|Model
{
Log::debug(__METHOD__);
// Log::debug(__METHOD__);
$collection = new Collection()->push($model);
$collection = $this->enrich($collection);
@@ -50,6 +50,10 @@ class PiggyBankEnrichment implements EnrichmentInterface
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
private array $accounts = []; // @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
@@ -58,6 +62,10 @@ class PiggyBankEnrichment implements EnrichmentInterface
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
private array $amounts = [];
private Collection $collection;
private array $currencies = [];
@@ -45,6 +45,10 @@ class PiggyBankEventEnrichment implements EnrichmentInterface
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
private array $accountIds = []; // @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
@@ -53,6 +57,10 @@ class PiggyBankEventEnrichment implements EnrichmentInterface
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
private Collection $collection;
private array $currencies = [];
private array $groupIds = [];
@@ -54,6 +54,10 @@ class SubscriptionEnrichment implements EnrichmentInterface
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
private readonly bool $convertToPrimary;
private ?Carbon $end = null;
private array $mappedObjects = [];
@@ -69,6 +69,14 @@ class TransactionGroupEnrichment implements EnrichmentInterface
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
public function __construct()
{
$this->dateFields = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date'];
@@ -78,7 +86,7 @@ class TransactionGroupEnrichment implements EnrichmentInterface
#[Override]
public function enrich(Collection $collection): Collection
{
Log::debug(sprintf('Now doing account enrichment for %d transaction group(s)', $collection->count()));
// Log::debug(sprintf('Now doing account enrichment for %d transaction group(s)', $collection->count()));
// prep local fields
$this->collection = $collection;
$this->collectJournalIds();
@@ -50,6 +50,10 @@ class WebhookEnrichment implements EnrichmentInterface
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
private array $ids = []; // @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
@@ -58,6 +62,10 @@ class WebhookEnrichment implements EnrichmentInterface
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
// @phpstan-ignore-line
private array $responses = [];
private array $triggers = [];
private array $webhookDeliveries = [];
@@ -78,7 +78,7 @@ class AccountBalanceCalculator
]);
if (null === $first) {
Log::debug(sprintf('Found no transactions for currency #%d and account #%d, return 0.', $currencyId, $accountId));
// Log::debug(sprintf('Found no transactions for currency #%d and account #%d, return 0.', $currencyId, $accountId));
return '0';
}
@@ -45,7 +45,7 @@ class TransactionSummarizer
public function groupByCurrencyId(array $journals, string $method = 'negative', bool $includeForeign = true): array
{
Log::debug(sprintf('Now in groupByCurrencyId([%d journals], "%s", %s)', count($journals), $method, var_export($includeForeign, true)));
// Log::debug(sprintf('Now in groupByCurrencyId([%d journals], "%s", %s)', count($journals), $method, var_export($includeForeign, true)));
$array = [];
foreach ($journals as $journal) {
$field = 'amount';
@@ -146,7 +146,7 @@ class TransactionSummarizer
// $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], \FireflyIII\Support\Facades\Steam::{$method}($amount));
// Log::debug(sprintf('Journal #%d adds amount %s %s', $journal['transaction_journal_id'], $currencyCode, $amount));
}
Log::debug('End of sumExpenses.', $array);
// Log::debug('End of sumExpenses.', $array);
return $array;
}
@@ -234,7 +234,7 @@ class TransactionSummarizer
public function setConvertToPrimary(bool $convertToPrimary): void
{
Log::debug(sprintf('Overrule convertToPrimary to become %s', var_export($convertToPrimary, true)));
// Log::debug(sprintf('Overrule convertToPrimary to become %s', var_export($convertToPrimary, true)));
$this->convertToPrimary = $convertToPrimary;
}
+7 -6
View File
@@ -39,14 +39,14 @@ trait ChecksLogin
*/
public function authorize(): bool
{
Log::debug(sprintf('Now in %s', __METHOD__));
// Log::debug(sprintf('Now in %s', __METHOD__));
// Only allow logged-in users
$check = auth()->check();
if (!$check) {
return false;
}
if (!property_exists($this, 'acceptedRoles')) { // @phpstan-ignore-line
Log::debug('Request class has no acceptedRoles array');
Log::debug(sprintf('Request class %s has no acceptedRoles array', static::class));
return true; // check for false already took place.
}
@@ -81,15 +81,15 @@ trait ChecksLogin
{
/** @var User $user */
$user = auth()->user();
Log::debug('Now in getUserGroup()');
// Log::debug('Now in getUserGroup()');
/** @var null|UserGroup $userGroup */
$userGroup = $this->route()?->parameter('userGroup');
if (null === $userGroup) {
Log::debug('Request class has no userGroup parameter, but perhaps there is a parameter.');
// Log::debug('Request class has no userGroup parameter, but perhaps there is a parameter.');
$userGroupId = (int) $this->get('user_group_id');
if (0 === $userGroupId) {
Log::debug(sprintf('Request class has no user_group_id parameter, grab default from user (group #%d).', $user->user_group_id));
// Log::debug(sprintf('Request class has no user_group_id parameter, grab default from user (group #%d).', $user->user_group_id));
$userGroupId = (int) $user->user_group_id;
}
$userGroup = UserGroup::find($userGroupId);
@@ -98,7 +98,8 @@ trait ChecksLogin
return null;
}
Log::debug('Request class has valid user_group_id.');
// Log::debug('Request class has valid user_group_id.');
}
return $userGroup;
+3 -3
View File
@@ -122,11 +122,11 @@ class OperatorQuerySearch implements SearchInterface
if (str_starts_with($original, '-')) {
$return = sprintf('-%s', $config['alias_for']);
}
Log::debug(sprintf('"%s" is an alias for "%s", so return that instead.', $original, $return));
// Log::debug(sprintf('"%s" is an alias for "%s", so return that instead.', $original, $return));
return $return;
}
Log::debug(sprintf('"%s" is not an alias.', $operator));
// Log::debug(sprintf('"%s" is not an alias.', $operator));
return $original;
}
@@ -174,7 +174,7 @@ class OperatorQuerySearch implements SearchInterface
*/
public function parseQuery(string $query): void
{
Log::debug(sprintf('Now in parseQuery("%s")', $query));
// Log::debug(sprintf('Now in parseQuery("%s")', $query));
/** @var QueryParserInterface $parser */
$parser = app(QueryParserInterface::class);
@@ -39,7 +39,7 @@ class QueryParser implements QueryParserInterface
public function parse(string $query): NodeGroup
{
Log::debug(sprintf('Parsing query in QueryParser: "%s"', $query));
// Log::debug(sprintf('Parsing query in QueryParser: "%s"', $query));
$this->query = $query;
$this->position = 0;
@@ -78,7 +78,7 @@ class QueryParser implements QueryParserInterface
}
// char is "
++$this->position;
Log::debug(sprintf('Constructed token: %s', $tokenUnderConstruction));
// Log::debug(sprintf('Constructed token: %s', $tokenUnderConstruction));
return new NodeResult($this->createNode($tokenUnderConstruction, $fieldName, $prohibited), false);
}
@@ -200,11 +200,11 @@ class QueryParser implements QueryParserInterface
$token = rtrim($token, '"');
}
$token = str_replace('\"', '"', $token);
Log::debug(sprintf('Create FieldNode %s:%s (%s)', $fieldName, $token, var_export($prohibited, true)));
// Log::debug(sprintf('Create FieldNode %s:%s (%s)', $fieldName, $token, var_export($prohibited, true)));
return new FieldNode(trim($fieldName), trim($token), $prohibited);
}
Log::debug(sprintf('Create StringNode "%s" (%s)', $token, var_export($prohibited, true)));
// F Now in handleSearchNodeLog::debug(sprintf('Create StringNode "%s" (%s)', $token, var_export($prohibited, true)));
return new StringNode(trim($token), $prohibited);
}
@@ -60,7 +60,7 @@ class SearchRuleEngine implements RuleEngineInterface
public function addOperator(array $operator): void
{
Log::debug('Add extra operator: ', $operator);
// Log::debug('Add extra operator: ', $operator);
$this->operators[] = $operator;
}
+1 -1
View File
@@ -99,7 +99,7 @@
"league/commonmark": "^2",
"league/csv": "^9.10",
"league/fractal": "0.*",
"mailersend/laravel-driver": "^2.12",
"mailersend/laravel-driver": "^3.0",
"nunomaduro/collision": "^8",
"pragmarx/google2fa": "^8.0",
"predis/predis": "^3",
Generated
+25 -25
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "72404106289a876b0046dceacbaccf24",
"content-hash": "c4e7dd2df7bae96ea6e4df82530411b9",
"packages": [
{
"name": "bacon/bacon-qr-code",
@@ -3486,29 +3486,29 @@
},
{
"name": "mailersend/laravel-driver",
"version": "v2.12.0",
"version": "v3.0.0",
"source": {
"type": "git",
"url": "https://github.com/mailersend/mailersend-laravel-driver.git",
"reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb"
"reference": "cbda1bdcbd35e54f27a329df3c011389636eb783"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/15e1ec41e29e65d3ca226929c65804190aaa93eb",
"reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb",
"url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/cbda1bdcbd35e54f27a329df3c011389636eb783",
"reference": "cbda1bdcbd35e54f27a329df3c011389636eb783",
"shasum": ""
},
"require": {
"ext-json": "*",
"illuminate/support": "^9.0 || ^10.0 || ^11.0 || ^12.0",
"mailersend/mailersend": "^0.35.0",
"illuminate/support": "^10.0 || ^11.0 || ^12.0",
"mailersend/mailersend": "^0.36.0",
"nyholm/psr7": "^1.5",
"php": ">=8.0",
"php": ">=8.2",
"php-http/guzzle7-adapter": "^1.0",
"symfony/mailer": "^6.0 || ^7.0"
},
"require-dev": {
"orchestra/testbench": "^7.0 || ^9.0 || ^10.0",
"orchestra/testbench": "^9.0 || ^10.0",
"phpunit/phpunit": "^9.0 || ^10.5 || ^12.0"
},
"type": "library",
@@ -3549,28 +3549,28 @@
],
"support": {
"issues": "https://github.com/mailersend/mailersend-laravel-driver/issues",
"source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.12.0"
"source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v3.0.0"
},
"time": "2025-10-28T14:59:16+00:00"
"time": "2026-02-05T12:32:37+00:00"
},
{
"name": "mailersend/mailersend",
"version": "v0.35.0",
"version": "v0.36.0",
"source": {
"type": "git",
"url": "https://github.com/mailersend/mailersend-php.git",
"reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276"
"reference": "0a28852bba61f31c3668a2af6426dc0b2c866432"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/f1696cf9e727e9503fbc5882d2a111bd966ad276",
"reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276",
"url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/0a28852bba61f31c3668a2af6426dc0b2c866432",
"reference": "0a28852bba61f31c3668a2af6426dc0b2c866432",
"shasum": ""
},
"require": {
"beberlei/assert": "^3.2",
"ext-json": "*",
"php": "^7.4 || ^8.0 <8.5",
"php": "^7.4 || ^8.0 <8.6",
"php-http/client-common": "^2.2",
"php-http/discovery": "^1.9",
"php-http/httplug": "^2.1",
@@ -3615,9 +3615,9 @@
],
"support": {
"issues": "https://github.com/mailersend/mailersend-php/issues",
"source": "https://github.com/mailersend/mailersend-php/tree/v0.35.0"
"source": "https://github.com/mailersend/mailersend-php/tree/v0.36.0"
},
"time": "2025-10-28T13:11:43+00:00"
"time": "2026-02-02T09:26:45+00:00"
},
{
"name": "monolog/monolog",
@@ -11908,16 +11908,16 @@
},
{
"name": "phpunit/phpunit",
"version": "12.5.9",
"version": "12.5.11",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "83d4c158526c879b4c5cf7149d27958b6d912373"
"reference": "9b518cb40f9474572c9f0178e96ff3dc1cf02bf1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/83d4c158526c879b4c5cf7149d27958b6d912373",
"reference": "83d4c158526c879b4c5cf7149d27958b6d912373",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9b518cb40f9474572c9f0178e96ff3dc1cf02bf1",
"reference": "9b518cb40f9474572c9f0178e96ff3dc1cf02bf1",
"shasum": ""
},
"require": {
@@ -11931,7 +11931,7 @@
"phar-io/manifest": "^2.0.4",
"phar-io/version": "^3.2.1",
"php": ">=8.3",
"phpunit/php-code-coverage": "^12.5.2",
"phpunit/php-code-coverage": "^12.5.3",
"phpunit/php-file-iterator": "^6.0.1",
"phpunit/php-invoker": "^6.0.0",
"phpunit/php-text-template": "^5.0.0",
@@ -11986,7 +11986,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.9"
"source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.11"
},
"funding": [
{
@@ -12010,7 +12010,7 @@
"type": "tidelift"
}
],
"time": "2026-02-05T08:01:09+00:00"
"time": "2026-02-10T12:32:02+00:00"
},
{
"name": "rector/rector",
+2 -2
View File
@@ -78,8 +78,8 @@ return [
'running_balance_column' => (bool)envNonEmpty('USE_RUNNING_BALANCE', true), // this is only the default value, is not used.
// see cer.php for exchange rates feature flag.
],
'version' => 'develop/2026-02-08',
'build_time' => 1770531224,
'version' => 'develop/2026-02-10',
'build_time' => 1770727063,
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 28, // field is no longer used.
@@ -65,11 +65,19 @@ return new class() extends Migration {
foreach ($set as $table => $fields) {
foreach ($fields as $field) {
try {
Schema::table($table, static function (Blueprint $blueprint) use ($field): void {
$blueprint->index($field);
Schema::table($table, static function (Blueprint $blueprint) use ($table, $field): void {
if (!Schema::hasIndex($table, $field)) {
$blueprint->index($field);
}
});
} catch (QueryException $e) {
app('log')->error(sprintf(self::QUERY_ERROR, $table, $field, $e->getMessage()));
$message = $e->getMessage();
// ignore duplicate key name as error.
if (str_contains($message, ' Duplicate key name')) {
continue;
}
app('log')->error(sprintf(self::QUERY_ERROR, $table, $field, $message));
app('log')->error(self::EXPL);
}
}
@@ -23,6 +23,7 @@
declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\QueryException;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
@@ -97,10 +98,14 @@ return new class() extends Migration {
} catch (RuntimeException $e) {
Log::error('Could not drop foreign key "piggy_banks_account_id_foreign". Probably not an issue.');
}
Schema::table('piggy_banks', static function (Blueprint $table): void {
// 2. make column nullable.
$table->unsignedInteger('account_id')->nullable()->change();
});
try {
Schema::table('piggy_banks', static function (Blueprint $table): void {
// 2. make column nullable.
$table->unsignedInteger('account_id')->nullable()->change();
});
} catch (QueryException $e) {
app('log')->error($e->getMessage());
}
Schema::table('piggy_banks', static function (Blueprint $table): void {
// 3. add currency
if (!Schema::hasColumn('piggy_banks', 'transaction_currency_id')) {
@@ -1,7 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\QueryException;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
/**
@@ -18,15 +20,44 @@ return new class extends Migration {
public function up(): void
{
Schema::table('transactions', static function (Blueprint $blueprint): void {
$blueprint->index(['transaction_journal_id', 'amount'], 'idx_tx_journal_amount');
});
try {
Schema::table('transactions', static function (Blueprint $blueprint): void {
$blueprint->index(['transaction_journal_id', 'amount'], 'idx_tx_journal_amount');
});
} catch (QueryException $e) {
$message = $e->getMessage();
Schema::table('tag_transaction_journal', static function (Blueprint $blueprint): void {
$blueprint->index(['transaction_journal_id', 'tag_id'], 'idx_ttj_journal_tag');
});
Schema::table('transaction_journals', static function (Blueprint $blueprint): void {
$blueprint->index(['deleted_at'], 'idx_tj_deleted');
});
// ignore duplicate key name as error.
if (str_contains($message, ' Duplicate key name')) {
return;
}
Log::error(sprintf('Error when creating index: %s', $e->getMessage()));
}
try {
Schema::table('tag_transaction_journal', static function (Blueprint $blueprint): void {
$blueprint->index(['transaction_journal_id', 'tag_id'], 'idx_ttj_journal_tag');
});
} catch (QueryException $e) {
$message = $e->getMessage();
// ignore duplicate key name as error.
if (str_contains($message, ' Duplicate key name')) {
return;
}
Log::error(sprintf('Error when creating index: %s', $e->getMessage()));
}
try {
Schema::table('transaction_journals', static function (Blueprint $blueprint): void {
$blueprint->index(['deleted_at'], 'idx_tj_deleted');
});
} catch (QueryException $e) {
$message = $e->getMessage();
// ignore duplicate key name as error.
if (str_contains($message, ' Duplicate key name')) {
return;
}
Log::error(sprintf('Error when creating index: %s', $e->getMessage()));
}
}
};
+32 -32
View File
@@ -3364,42 +3364,42 @@
}
},
"node_modules/@vue/compiler-core": {
"version": "3.5.27",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.27.tgz",
"integrity": "sha512-gnSBQjZA+//qDZen+6a2EdHqJ68Z7uybrMf3SPjEGgG4dicklwDVmMC1AeIHxtLVPT7sn6sH1KOO+tS6gwOUeQ==",
"version": "3.5.28",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.28.tgz",
"integrity": "sha512-kviccYxTgoE8n6OCw96BNdYlBg2GOWfBuOW4Vqwrt7mSKWKwFVvI8egdTltqRgITGPsTFYtKYfxIG8ptX2PJHQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.28.5",
"@vue/shared": "3.5.27",
"entities": "^7.0.0",
"@babel/parser": "^7.29.0",
"@vue/shared": "3.5.28",
"entities": "^7.0.1",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.5.27",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.27.tgz",
"integrity": "sha512-oAFea8dZgCtVVVTEC7fv3T5CbZW9BxpFzGGxC79xakTr6ooeEqmRuvQydIiDAkglZEAd09LgVf1RoDnL54fu5w==",
"version": "3.5.28",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.28.tgz",
"integrity": "sha512-/1ZepxAb159jKR1btkefDP+J2xuWL5V3WtleRmxaT+K2Aqiek/Ab/+Ebrw2pPj0sdHO8ViAyyJWfhXXOP/+LQA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/compiler-core": "3.5.27",
"@vue/shared": "3.5.27"
"@vue/compiler-core": "3.5.28",
"@vue/shared": "3.5.28"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.5.27",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.27.tgz",
"integrity": "sha512-sHZu9QyDPeDmN/MRoshhggVOWE5WlGFStKFwu8G52swATgSny27hJRWteKDSUUzUH+wp+bmeNbhJnEAel/auUQ==",
"version": "3.5.28",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.28.tgz",
"integrity": "sha512-6TnKMiNkd6u6VeVDhZn/07KhEZuBSn43Wd2No5zaP5s3xm8IqFTHBj84HJah4UepSUJTro5SoqqlOY22FKY96g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.28.5",
"@vue/compiler-core": "3.5.27",
"@vue/compiler-dom": "3.5.27",
"@vue/compiler-ssr": "3.5.27",
"@vue/shared": "3.5.27",
"@babel/parser": "^7.29.0",
"@vue/compiler-core": "3.5.28",
"@vue/compiler-dom": "3.5.28",
"@vue/compiler-ssr": "3.5.28",
"@vue/shared": "3.5.28",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.21",
"postcss": "^8.5.6",
@@ -3407,14 +3407,14 @@
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.5.27",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.27.tgz",
"integrity": "sha512-Sj7h+JHt512fV1cTxKlYhg7qxBvack+BGncSpH+8vnN+KN95iPIcqB5rsbblX40XorP+ilO7VIKlkuu3Xq2vjw==",
"version": "3.5.28",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.28.tgz",
"integrity": "sha512-JCq//9w1qmC6UGLWJX7RXzrGpKkroubey/ZFqTpvEIDJEKGgntuDMqkuWiZvzTzTA5h2qZvFBFHY7fAAa9475g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.5.27",
"@vue/shared": "3.5.27"
"@vue/compiler-dom": "3.5.28",
"@vue/shared": "3.5.28"
}
},
"node_modules/@vue/component-compiler-utils": {
@@ -3496,9 +3496,9 @@
"license": "MIT"
},
"node_modules/@vue/shared": {
"version": "3.5.27",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.27.tgz",
"integrity": "sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ==",
"version": "3.5.28",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.28.tgz",
"integrity": "sha512-cfWa1fCGBxrvaHRhvV3Is0MgmrbSCxYTXCSCau2I0a1Xw1N1pHAvkWCiXPRAqjvToILvguNyEwjevUqAuBQWvQ==",
"dev": true,
"license": "MIT"
},
@@ -4033,14 +4033,14 @@
}
},
"node_modules/axios": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.4.tgz",
"integrity": "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==",
"version": "1.13.5",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
"integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.4",
"follow-redirects": "^1.15.11",
"form-data": "^4.0.5",
"proxy-from-env": "^1.1.0"
}
},
+37 -37
View File
@@ -1,26 +1,26 @@
{
"firefly": {
"administrations_page_title": "Financial administrations",
"administrations_index_menu": "Financial administrations",
"expires_at": "Expires at",
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its primary currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
"administration_currency_form_help": "It may take a long time for the page to load if you change the primary currency because transaction may need to be converted to your (new) primary currency.",
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
"administrations_page_title": "\u00d8konomisk administrasjon",
"administrations_index_menu": "\u00d8konomisk administrasjon",
"expires_at": "Utl\u00f8per den",
"temp_administrations_introduction": "Firefly III vil snart f\u00e5 muligheten til \u00e5 h\u00e5ndtere flere \u00f8konomiske administrasjoner. Akkurat n\u00e5 kan du kun ha en. Du kan angi navnet p\u00e5 denne administrasjonen og hovedvalutaen. Dette erstatter den tidligere innstillingen hvor du kunne sette din \"standardvaluta\". Innstillingen er n\u00e5 knyttet til din \u00f8konomiske administrasjon og den kan v\u00e6re forskjellig per administrasjon.",
"administration_currency_form_help": "Det kan ta lang tid for siden \u00e5 laste inn hvis du endrer prim\u00e6rvalutaen fordi det kan hende at transaksjonene m\u00e5 konverteres til din (nye) prim\u00e6rvaluta.",
"administrations_page_edit_sub_title_js": "Endre \u00f8konomisk administrasjon \"{title}\"",
"table": "Tabell",
"welcome_back": "Hvordan g\u00e5r det?",
"flash_error": "Feil!",
"flash_warning": "Advarsel!",
"flash_success": "Suksess!",
"close": "Lukk",
"select_dest_account": "Please select or type a valid destination account name",
"select_source_account": "Please select or type a valid source account name",
"select_dest_account": "Velg eller skriv inn et gyldig m\u00e5lkontonavn",
"select_source_account": "Vennligst velg eller skriv inn et gyldig kildekontonavn",
"split_transaction_title": "Beskrivelse av den splittende transaksjon",
"errors_submission": "There was something wrong with your submission. Please check out the errors below.",
"is_reconciled": "Is reconciled",
"errors_submission": "Det oppsto en feil med innsendingen. Vennligst sjekk feilmeldingene nedenfor.",
"is_reconciled": "Er avstemt",
"split": "Del opp",
"single_split": "Del opp",
"not_enough_currencies": "Not enough currencies",
"not_enough_currencies_enabled": "If you have just one currency enabled, there is no need to add exchange rates.",
"not_enough_currencies": "Ikke nok valutaer",
"not_enough_currencies_enabled": "Hvis du bare har \u00e9n valuta aktivert, er det ikke n\u00f8dvendig \u00e5 legge til valutakurser.",
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Transaksjon #{ID} (\"{title}\")<\/a> har blitt lagret.",
"webhook_stored_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID} (\"{title}\")<\/a> er lagret.",
"webhook_updated_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID}<\/a> (\"{title}\") er oppdatert.",
@@ -31,9 +31,9 @@
"apply_rules_checkbox": "Bruk regler",
"fire_webhooks_checkbox": "Fire webhooks",
"no_budget_pointer": "Det ser ikke ut til at du har noen budsjetter enn\u00e5. Du b\u00f8r opprette noen p\u00e5 <a href=\"\/budgets\">budsjett<\/a>-siden. Budsjetter kan hjelpe deg med \u00e5 holde oversikt over utgifter.",
"no_bill_pointer": "You seem to have no subscription yet. You should create some on the <a href=\"subscriptions\">subscription<\/a>-page. Subscriptions can help you keep track of expenses.",
"no_bill_pointer": "Det ser ut til at du ikke har noe abonnement enn\u00e5. Du b\u00f8r opprette noen p\u00e5 <a href=\"subscriptions\">abonnement<\/a>siden. Abonnementer kan hjelpe deg med \u00e5 holde oversikt over utgifter.",
"source_account": "Kildekonto",
"hidden_fields_preferences": "You can enable more transaction options in your <a href=\"preferences\">preferences<\/a>.",
"hidden_fields_preferences": "Du kan aktivere flere transaksjonsalternativer i <a href=\"preferences\">preferansene<\/a>.",
"destination_account": "Destinasjonskonto",
"add_another_split": "Legg til en oppdeling til",
"submission": "Innlevering",
@@ -43,10 +43,10 @@
"submit": "Send inn",
"amount": "Bel\u00f8p",
"date": "Dato",
"is_reconciled_fields_dropped": "Because this transaction is reconciled, you will not be able to update the accounts, nor the amount(s) unless you remove the reconciliation flag.",
"is_reconciled_fields_dropped": "Fordi denne transaksjonen er avstemt, vil du ikke kunne oppdatere kontoene eller bel\u00f8p(ene) med mindre du fjerner avstemt-flagget.",
"tags": "Tagger",
"no_budget": "(ingen budsjett)",
"no_bill": "(no subscription)",
"no_bill": "(ingen abonnement)",
"category": "Kategori",
"attachments": "Vedlegg",
"notes": "Notater",
@@ -62,7 +62,7 @@
"destination_account_reconciliation": "Du kan ikke redigere kildekontoen for en avstemmingstransaksjon.",
"source_account_reconciliation": "Du kan ikke redigere kildekontoen for en avstemmingstransaksjon.",
"budget": "Budsjett",
"bill": "Subscription",
"bill": "Abonnement",
"you_create_withdrawal": "Du lager et uttak.",
"you_create_transfer": "Du lager en overf\u00f8ring.",
"you_create_deposit": "Du lager en innskud.",
@@ -102,23 +102,23 @@
"profile_oauth_client_secret_title": "Klient hemmilghet",
"profile_oauth_client_secret_expl": "Her er din nye klient hemmelighet. Dette er den eneste tiden det blir vist s\u00e5 ikke mister den! Du kan n\u00e5 bruke denne hemmeligheten til \u00e5 lage API-foresp\u00f8rsler.",
"profile_oauth_confidential": "Konfidensiell",
"profile_oauth_confidential_help": "Require the client to authenticate with a secret. Confidential clients can hold credentials in a secure way without exposing them to unauthorized parties. Public applications, such as native desktop or JavaScript SPA applications, are unable to hold secrets securely.",
"profile_oauth_confidential_help": "Krev at klienten godkjenner med en hemmelighet. Konfidensielle klienter kan holde legitimasjon p\u00e5 en sikker m\u00e5te uten \u00e5 utsette de for uautoriserte parter. Offentlige programmer, som skrivebord eller JavaScript SPA-applikasjoner, kan ikke holde hemmeligheter sikre.",
"multi_account_warning_unknown": "Avhengig av hvilken type transaksjon du oppretter, Kilden og\/eller destinasjonskonto for etterf\u00f8lgende delinger kan overstyres av det som er definert i transaksjonens f\u00f8rste del.",
"multi_account_warning_withdrawal": "Husk at kildekontoen for etterf\u00f8lgende oppsplitting skal overlates av hva som defineres i den f\u00f8rste delen av uttrekket.",
"multi_account_warning_deposit": "Husk at mottakerkontoen for etterf\u00f8lgende oppsplitting skal overstyres av det som er definert i den f\u00f8rste delen av depositumet.",
"multi_account_warning_transfer": "Husk at kildens pluss destinasjonskonto med etterf\u00f8lgende oppdeling overstyres av det som er definert i en f\u00f8rste del av overf\u00f8ringen.",
"webhook_trigger_ANY": "After any event",
"webhook_trigger_ANY": "Etter enhver hendelse",
"webhook_trigger_STORE_TRANSACTION": "Etter transaksjons opprettelse",
"webhook_trigger_UPDATE_TRANSACTION": "Etter transaksjons oppdatering",
"webhook_trigger_DESTROY_TRANSACTION": "Etter transaksjons sletting",
"webhook_trigger_STORE_BUDGET": "After budget creation",
"webhook_trigger_UPDATE_BUDGET": "After budget update",
"webhook_trigger_DESTROY_BUDGET": "After budget delete",
"webhook_trigger_STORE_UPDATE_BUDGET_LIMIT": "After budgeted amount change",
"webhook_trigger_STORE_BUDGET": "Etter at nytt budsjett er laget",
"webhook_trigger_UPDATE_BUDGET": "Etter at et budsjett er oppdatert",
"webhook_trigger_DESTROY_BUDGET": "Etter at et budsjett er slettet",
"webhook_trigger_STORE_UPDATE_BUDGET_LIMIT": "Etter at et budsjetts bel\u00f8p er endret",
"webhook_response_TRANSACTIONS": "Transaksjonsdetaljer",
"webhook_response_RELEVANT": "Relevant details",
"webhook_response_RELEVANT": "Relevante detaljer",
"webhook_response_ACCOUNTS": "Kontodetaljer",
"webhook_response_NONE": "No details",
"webhook_response_NONE": "Ingen detaljer",
"webhook_delivery_JSON": "JSON",
"actions": "Handlinger",
"meta_data": "Metadata",
@@ -146,21 +146,21 @@
"response": "Respons",
"visit_webhook_url": "Bes\u00f8k URL til webhook",
"reset_webhook_secret": "Tilbakestill Webhook n\u00f8kkel",
"header_exchange_rates": "Exchange rates",
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">the documentation<\/a>.",
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
"exchange_rates_intro_rates": "Firefly III uses the following exchange rates. The inverse is automatically calculated when it is not provided. If no exchange rate exists for the date of the transaction, Firefly III will go back in time to find one. If none are present, the rate \"1\" will be used.",
"header_exchange_rates_rates": "Exchange rates",
"header_exchange_rates_table": "Table with exchange rates",
"help_rate_form": "On this day, how many {to} will you get for one {from}?",
"add_new_rate": "Add a new exchange rate",
"save_new_rate": "Save new rate"
"header_exchange_rates": "Valutakurser",
"exchange_rates_intro": "Firefly III st\u00f8tter nedlasting og bruk av valutakurser. Les mer om dette i <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">dokumentasjonen<\/a>.",
"exchange_rates_from_to": "Mellom {from} og {to} (og omvendt)",
"exchange_rates_intro_rates": "Firefly III bruker f\u00f8lgende valutakurser. Omvendt blir automatisk beregnet n\u00e5r den ikke er oppgitt. Hvis det ikke finnes noen valutakurs for datoen for transaksjonen, vil Firefly III g\u00e5 tilbake i tid for \u00e5 finne en. Hvis ingen er til stede, vil kursen \"1\" brukes.",
"header_exchange_rates_rates": "Valutakurser",
"header_exchange_rates_table": "Tabell med valutakurser",
"help_rate_form": "P\u00e5 denne dagen, hvor mange {to} vil du f\u00e5 for en {from}?",
"add_new_rate": "Legg til en ny valutakurs",
"save_new_rate": "Lagre ny kurs"
},
"form": {
"url": "Nettadresse",
"active": "Aktiv",
"interest_date": "Rentedato",
"administration_currency": "Primary currency",
"administration_currency": "Prim\u00e6rvaluta",
"title": "Tittel",
"date": "Dato",
"book_date": "Bokf\u00f8ringsdato",
@@ -175,12 +175,12 @@
"webhook_delivery": "Levering",
"from_currency_to_currency": "{from} &rarr; {to}",
"to_currency_from_currency": "{to} &rarr; {from}",
"rate": "Rate"
"rate": "Kurs"
},
"list": {
"title": "Tittel",
"active": "Er aktiv?",
"primary_currency": "Primary currency",
"primary_currency": "Prim\u00e6rvaluta",
"trigger": "Utl\u00f8ser",
"response": "Respons",
"delivery": "Levering",