mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2026-02-12 06:42:19 +00:00
Compare commits
49 Commits
develop-20
...
develop-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c2ebae8fa | ||
|
|
aff9afb767 | ||
|
|
c8e95fe131 | ||
|
|
cef514c22b | ||
|
|
46d2ba3d3b | ||
|
|
45a0504eba | ||
|
|
9711bc1d04 | ||
|
|
cf2343c0dd | ||
|
|
34097cecf0 | ||
|
|
8735be2f6b | ||
|
|
0e8cc91308 | ||
|
|
5cbb311e4d | ||
|
|
c334641b90 | ||
|
|
4c2356881d | ||
|
|
d9a0d06712 | ||
|
|
65b9dedc03 | ||
|
|
e46ef138b1 | ||
|
|
f0fdb57754 | ||
|
|
09799582aa | ||
|
|
850c824da1 | ||
|
|
34160da67a | ||
|
|
2848a64c13 | ||
|
|
998d6bf874 | ||
|
|
b85200e1f6 | ||
|
|
6944001887 | ||
|
|
154abf1fc0 | ||
|
|
0113cc1651 | ||
|
|
38b5b656a1 | ||
|
|
e74163a7ec | ||
|
|
c60094d231 | ||
|
|
39d46d469c | ||
|
|
6caea5ffa3 | ||
|
|
4024f76a51 | ||
|
|
de84946371 | ||
|
|
6d4aca54de | ||
|
|
256262b2ba | ||
|
|
fb035ba594 | ||
|
|
20776949a6 | ||
|
|
ad5a8a2934 | ||
|
|
e37ef69491 | ||
|
|
df8a406c58 | ||
|
|
88d3e01065 | ||
|
|
7a1c32f1aa | ||
|
|
54df0d44f7 | ||
|
|
1f7775032b | ||
|
|
8cfe1e8047 | ||
|
|
f0be634829 | ||
|
|
485e1138f8 | ||
|
|
9abf08b3be |
BIN
.github/assets/img/testmu.png
vendored
Normal file
BIN
.github/assets/img/testmu.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
90
app/Console/Commands/Correction/RollbacksSingleMigration.php
Normal file
90
app/Console/Commands/Correction/RollbacksSingleMigration.php
Normal file
@@ -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]],
|
||||
|
||||
@@ -36,6 +36,7 @@ class UpdatedExistingAccount extends Event
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public function __construct(
|
||||
public Account $account
|
||||
public Account $account,
|
||||
public array $oldData
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* TriggeredStoredTransactionGroup.php
|
||||
* Copyright (c) 2025 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\Events\Model\TransactionGroup;
|
||||
|
||||
use FireflyIII\Events\Event;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
class TriggeredStoredTransactionGroup extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public ?RuleGroup $ruleGroup = null;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public function __construct(
|
||||
public TransactionGroup $transactionGroup,
|
||||
?RuleGroup $ruleGroup = null
|
||||
) {
|
||||
$this->ruleGroup = $ruleGroup;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -29,6 +29,7 @@ use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\ObjectGroup\OrganisesObjectGroups;
|
||||
use FireflyIII\Support\Facades\Navigation;
|
||||
use FireflyIII\Support\Facades\Preferences;
|
||||
use FireflyIII\Support\JsonApi\Enrichments\SubscriptionEnrichment;
|
||||
use FireflyIII\Transformers\BillTransformer;
|
||||
use FireflyIII\User;
|
||||
@@ -73,8 +74,18 @@ class IndexController extends Controller
|
||||
$this->cleanupObjectGroups();
|
||||
$this->repository->correctOrder();
|
||||
$this->repository->correctTransfers();
|
||||
$start = session('start');
|
||||
$end = session('end');
|
||||
$start = session('start')->clone();
|
||||
$end = session('end')->clone();
|
||||
$viewRange = Preferences::get('viewRange', '1M')->data;
|
||||
|
||||
// give the end some extra space when the user has last7, last30 or last90.
|
||||
if ('last7' === $viewRange || 'last30' === $viewRange) {
|
||||
$end->addDays(30);
|
||||
}
|
||||
if ('last90' === $viewRange) {
|
||||
$end->addDays(90);
|
||||
}
|
||||
|
||||
$collection = $this->repository->getBills();
|
||||
$total = $collection->count();
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -152,7 +152,7 @@ class ProfileController extends Controller
|
||||
}
|
||||
$repository->unblockUser($user);
|
||||
// also remove the "remote_guard_alt_email" preference.
|
||||
Preferences::delete('remote_guard_alt_email');
|
||||
Preferences::deleteForUser($user, 'remote_guard_alt_email');
|
||||
|
||||
// return to log in.
|
||||
session()->flash('success', (string) trans('firefly.login_with_new_email'));
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -26,16 +26,15 @@ namespace FireflyIII\Http\Controllers\RuleGroup;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Events\Model\TransactionGroup\TriggeredStoredTransactionGroup;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\SelectTransactionsRequest;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
|
||||
use FireflyIII\TransactionRules\Engine\RuleEngineInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\View\View;
|
||||
|
||||
@@ -45,6 +44,7 @@ use Illuminate\View\View;
|
||||
class ExecutionController extends Controller
|
||||
{
|
||||
private readonly AccountRepositoryInterface $repository;
|
||||
private readonly RuleGroupRepositoryInterface $ruleGroupRepository;
|
||||
|
||||
/**
|
||||
* ExecutionController constructor.
|
||||
@@ -52,11 +52,13 @@ class ExecutionController extends Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
$this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
|
||||
$this->middleware(function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.rules'));
|
||||
app('view')->share('mainTitleIcon', 'fa-random');
|
||||
$this->repository->setUser(auth()->user());
|
||||
$this->ruleGroupRepository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
});
|
||||
@@ -70,44 +72,37 @@ class ExecutionController extends Controller
|
||||
public function execute(SelectTransactionsRequest $request, RuleGroup $ruleGroup): RedirectResponse
|
||||
{
|
||||
Log::debug(sprintf('You have selected rule group #%d', $ruleGroup->id));
|
||||
// Get parameters specified by the user
|
||||
$accounts = $request->get('accounts');
|
||||
$set = new Collection();
|
||||
if (is_array($accounts)) {
|
||||
$set = $this->repository->getAccountsById($accounts);
|
||||
}
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
if (count($set) > 0) {
|
||||
$collector->setAccounts($set);
|
||||
}
|
||||
// start code
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$accounts = implode(',', $request->get('accounts'));
|
||||
// create new rule engine:
|
||||
$newRuleEngine = app(RuleEngineInterface::class);
|
||||
$newRuleEngine->setUser($user);
|
||||
|
||||
// add date operators.
|
||||
if (null !== $request->get('start')) {
|
||||
$startDate = new Carbon($request->get('start'));
|
||||
$collector->setStart($startDate);
|
||||
$newRuleEngine->addOperator(['type' => 'date_after', 'value' => $startDate->format('Y-m-d')]);
|
||||
}
|
||||
if (null !== $request->get('end')) {
|
||||
$endDate = new Carbon($request->get('end'));
|
||||
$collector->setEnd($endDate);
|
||||
$newRuleEngine->addOperator(['type' => 'date_before', 'value' => $endDate->format('Y-m-d')]);
|
||||
}
|
||||
$final = $collector->getGroups();
|
||||
$ids = $final->pluck('id')->toArray();
|
||||
Log::debug(sprintf('Found %d groups collected from %d account(s)', $final->count(), $set->count()));
|
||||
foreach (array_chunk($ids, 1337) as $setOfIds) {
|
||||
Log::debug(sprintf('Now processing %d groups', count($setOfIds)));
|
||||
$groups = TransactionGroup::whereIn('id', $setOfIds)->get();
|
||||
|
||||
/** @var TransactionGroup $group */
|
||||
foreach ($groups as $group) {
|
||||
Log::debug(sprintf('Processing group #%d.', $group->id));
|
||||
event(new TriggeredStoredTransactionGroup($group, $ruleGroup));
|
||||
}
|
||||
}
|
||||
// add extra operators:
|
||||
$newRuleEngine->addOperator(['type' => 'account_id', 'value' => $accounts]);
|
||||
|
||||
// set rules:
|
||||
$rules = $this->ruleGroupRepository->getActiveRules($ruleGroup);
|
||||
|
||||
$newRuleEngine->setRules($rules);
|
||||
$newRuleEngine->fire();
|
||||
$resultCount = $newRuleEngine->getResults();
|
||||
|
||||
// Tell the user that the job is queued
|
||||
session()->flash('success', (string) trans('firefly.applied_rule_group_selection', ['title' => $ruleGroup->title]));
|
||||
session()->flash('success', trans_choice('firefly.applied_rule_group_selection', $resultCount, ['title' => $ruleGroup->title]));
|
||||
|
||||
return redirect()->route('rules.index');
|
||||
}
|
||||
|
||||
@@ -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' => [],
|
||||
];
|
||||
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -194,7 +194,12 @@ class ShowController extends Controller
|
||||
foreach ($group['transactions'] as $transaction) {
|
||||
// add normal amount:
|
||||
$symbol = $transaction['currency_symbol'];
|
||||
$amounts[$symbol] ??= ['amount' => '0', 'symbol' => $symbol, 'decimal_places' => $transaction['currency_decimal_places']];
|
||||
$amounts[$symbol] ??= [
|
||||
'amount' => '0',
|
||||
'symbol' => $symbol,
|
||||
'decimal_places' => $transaction['currency_decimal_places'],
|
||||
'approximate' => false,
|
||||
];
|
||||
$amounts[$symbol]['amount'] = bcadd($amounts[$symbol]['amount'], (string) $transaction['amount']);
|
||||
|
||||
// add foreign amount:
|
||||
@@ -207,17 +212,23 @@ class ShowController extends Controller
|
||||
$foreignSymbol = $transaction['foreign_currency_symbol'];
|
||||
$amounts[$foreignSymbol] ??= [
|
||||
'amount' => '0',
|
||||
'approximate' => false,
|
||||
'symbol' => $foreignSymbol,
|
||||
'decimal_places' => $transaction['foreign_currency_decimal_places'],
|
||||
];
|
||||
$amounts[$foreignSymbol]['amount'] = bcadd($amounts[$foreignSymbol]['amount'], (string) $transaction['foreign_amount']);
|
||||
}
|
||||
// add primary currency amount
|
||||
if (null !== $transaction['pc_amount'] && $transaction['currency_id'] !== $this->primaryCurrency->id) {
|
||||
// add primary currency amount, but only if it is not the foreign amount or the current one.
|
||||
if (
|
||||
null !== $transaction['pc_amount']
|
||||
&& $transaction['currency_id'] !== $this->primaryCurrency->id
|
||||
&& $transaction['foreign_currency_code'] !== $this->primaryCurrency->code
|
||||
) {
|
||||
// same for foreign currency:
|
||||
$primarySymbol = $this->primaryCurrency->symbol;
|
||||
$amounts[$primarySymbol] ??= [
|
||||
'amount' => '0',
|
||||
'approximate' => true,
|
||||
'symbol' => $this->primaryCurrency->symbol,
|
||||
'decimal_places' => $this->primaryCurrency->decimal_places,
|
||||
];
|
||||
|
||||
@@ -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__));
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ class CreateAutoBudgetLimits implements ShouldQueue
|
||||
|
||||
/** @var BudgetLimitRepositoryInterface $repository */
|
||||
$repository = app(BudgetLimitRepositoryInterface::class);
|
||||
$repository->setUserGroup($autoBudget->budget->user->userGroup);
|
||||
$repository->setUser($autoBudget->budget->user);
|
||||
|
||||
$budgetLimit = $repository->store([
|
||||
'currency_id' => $autoBudget->transaction_currency_id,
|
||||
|
||||
@@ -29,7 +29,11 @@ use FireflyIII\Events\Model\Account\UpdatedExistingAccount;
|
||||
use FireflyIII\Handlers\ExchangeRate\ConversionParameters;
|
||||
use FireflyIII\Handlers\ExchangeRate\ConvertsAmountToPrimaryAmount;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\RuleTrigger;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
|
||||
use FireflyIII\Services\Internal\Support\CreditRecalculateService;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
@@ -40,6 +44,89 @@ class UpdatesAccountInformation implements ShouldQueue
|
||||
{
|
||||
$this->recalculateCredit($event->account);
|
||||
$this->updateVirtualBalance($event->account);
|
||||
if ($event instanceof UpdatedExistingAccount) {
|
||||
$this->renameRules($event->account, $event->oldData);
|
||||
}
|
||||
}
|
||||
|
||||
private function correctRuleActions(Account $account, array $oldData, Rule $rule): void
|
||||
{
|
||||
$fields = ['set_source_account', 'set_destination_account'];
|
||||
|
||||
Log::debug(sprintf('Check if rule #%d actions reference account #%d "%s"', $rule->id, $account->id, $account->name));
|
||||
$fixed = 0;
|
||||
|
||||
/** @var RuleAction $action */
|
||||
foreach ($rule->ruleActions as $action) {
|
||||
// fix name:
|
||||
if ($oldData['name'] === $action->action_value && in_array($action->action_type, $fields, true)) {
|
||||
Log::debug(sprintf('Rule action #%d "%s" has old account name, replace with new.', $action->id, $action->action_type));
|
||||
$action->action_value = $account->name;
|
||||
$action->save();
|
||||
++$fixed;
|
||||
}
|
||||
}
|
||||
Log::debug(sprintf('Corrected %d action(s) for rule #%d', $fixed, $rule->id));
|
||||
}
|
||||
|
||||
private function correctRuleTriggers(Account $account, array $oldData, Rule $rule): void
|
||||
{
|
||||
$nameFields = [
|
||||
'source_account_is',
|
||||
'source_account_contains',
|
||||
'source_account_ends',
|
||||
'source_account_starts',
|
||||
'destination_account_is',
|
||||
'destination_account_contains',
|
||||
'destination_account_ends',
|
||||
'destination_account_starts',
|
||||
'account_is',
|
||||
'account_contains',
|
||||
'account_ends',
|
||||
'account_starts',
|
||||
];
|
||||
$numberFields = [
|
||||
'source_account_nr_is',
|
||||
'source_account_nr_contains',
|
||||
'source_account_nr_ends',
|
||||
'source_account_nr_starts',
|
||||
'destination_account_nr_is',
|
||||
'destination_account_nr_contains',
|
||||
'destination_account_nr_starts',
|
||||
'account_nr_is',
|
||||
'account_nr_contains',
|
||||
'account_nr_ends',
|
||||
'account_nr_starts',
|
||||
];
|
||||
|
||||
Log::debug(sprintf('Check if rule #%d triggers reference account #%d "%s"', $rule->id, $account->id, $account->name));
|
||||
$fixed = 0;
|
||||
|
||||
/** @var RuleTrigger $trigger */
|
||||
foreach ($rule->ruleTriggers as $trigger) {
|
||||
// fix name:
|
||||
if ($oldData['name'] === $trigger->trigger_value && in_array($trigger->trigger_type, $nameFields, true)) {
|
||||
Log::debug(sprintf('Rule trigger #%d "%s" has old account name, replace with new.', $trigger->id, $trigger->trigger_type));
|
||||
$trigger->trigger_value = $account->name;
|
||||
$trigger->save();
|
||||
++$fixed;
|
||||
}
|
||||
// fix IBAN:
|
||||
if ($oldData['iban'] === $trigger->trigger_value && in_array($trigger->trigger_type, $numberFields, true)) {
|
||||
Log::debug(sprintf('Rule trigger #%d "%s" has old account IBAN, replace with new.', $trigger->id, $trigger->trigger_type));
|
||||
$trigger->trigger_value = $account->iban;
|
||||
$trigger->save();
|
||||
++$fixed;
|
||||
}
|
||||
// fix account number: // account_number
|
||||
if ($oldData['account_number'] === $trigger->trigger_value && in_array($trigger->trigger_type, $numberFields, true)) {
|
||||
Log::debug(sprintf('Rule trigger #%d "%s" has old account account_number, replace with new.', $trigger->id, $trigger->trigger_type));
|
||||
$trigger->trigger_value = $account->iban;
|
||||
$trigger->save();
|
||||
++$fixed;
|
||||
}
|
||||
}
|
||||
Log::debug(sprintf('Corrected %d trigger(s) for rule #%d', $fixed, $rule->id));
|
||||
}
|
||||
|
||||
private function recalculateCredit(Account $account): void
|
||||
@@ -52,6 +139,20 @@ class UpdatesAccountInformation implements ShouldQueue
|
||||
$object->recalculate();
|
||||
}
|
||||
|
||||
private function renameRules(Account $account, array $oldData): void
|
||||
{
|
||||
Log::debug('Updated account, will now correct rules.');
|
||||
$repository = app(RuleRepositoryInterface::class);
|
||||
$repository->setUser($account->user);
|
||||
$rules = $repository->getAll();
|
||||
|
||||
/** @var Rule $rule */
|
||||
foreach ($rules as $rule) {
|
||||
$this->correctRuleTriggers($account, $oldData, $rule);
|
||||
$this->correctRuleActions($account, $oldData, $rule);
|
||||
}
|
||||
}
|
||||
|
||||
private function updateVirtualBalance(Account $account): void
|
||||
{
|
||||
Log::debug('Will updateVirtualBalance');
|
||||
|
||||
@@ -29,13 +29,18 @@ trait SupportsGroupProcessingTrait
|
||||
protected function processRules(Collection $set, string $type): void
|
||||
{
|
||||
Log::debug(sprintf('Will now processRules("%s") for %d journal(s)', $type, $set->count()));
|
||||
|
||||
if (0 === $set->count()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$array = $set->pluck('id')->toArray();
|
||||
|
||||
/** @var TransactionJournal $first */
|
||||
$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);
|
||||
@@ -63,10 +68,16 @@ trait SupportsGroupProcessingTrait
|
||||
|
||||
return;
|
||||
}
|
||||
// find the earliest date in the set, based on date and _internal_previous_date
|
||||
$earliest = $objects->transactionJournals->pluck('date')->sort()->first();
|
||||
$fromInternalDate = $this->getFromInternalDate($objects->transactionJournals->pluck('id')->toArray());
|
||||
$earliest = $fromInternalDate->lt($earliest) ? $fromInternalDate : $earliest;
|
||||
if (0 === $objects->accounts->count()) {
|
||||
return;
|
||||
}
|
||||
$earliest = today()->subDays(2);
|
||||
if ($objects->transactionJournals->count() > 0) {
|
||||
// find the earliest date in the set, based on date and _internal_previous_date
|
||||
$earliest = $objects->transactionJournals->pluck('date')->sort()->first();
|
||||
$fromInternalDate = $this->getFromInternalDate($objects->transactionJournals->pluck('id')->toArray());
|
||||
$earliest = $fromInternalDate->lt($earliest) ? $fromInternalDate : $earliest;
|
||||
}
|
||||
Log::debug(sprintf('Found earliest date: %s', $earliest->toW3cString()));
|
||||
|
||||
Log::debug('Found accounts to process', $objects->accounts->pluck('id')->toArray());
|
||||
@@ -78,6 +89,8 @@ trait SupportsGroupProcessingTrait
|
||||
{
|
||||
if (!auth()->check()) {
|
||||
Log::debug('Will NOT remove period statistics for all objects, because no user detected.');
|
||||
|
||||
return;
|
||||
}
|
||||
Log::debug('Will now remove period statistics for all objects.');
|
||||
|
||||
@@ -122,6 +135,10 @@ trait SupportsGroupProcessingTrait
|
||||
{
|
||||
Log::debug(sprintf('Will now create webhook messages for %d group(s)', $groups->count()));
|
||||
|
||||
if (0 === $groups->count()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var TransactionGroup $first */
|
||||
$first = $groups->first();
|
||||
$user = $first->user;
|
||||
|
||||
@@ -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']);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -35,10 +35,10 @@ use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Override;
|
||||
use Spatie\Period\Boundaries;
|
||||
use Spatie\Period\Period;
|
||||
use Spatie\Period\Precision;
|
||||
use Override;
|
||||
|
||||
/**
|
||||
* Class AvailableBudgetRepository
|
||||
|
||||
@@ -91,7 +91,14 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface, UserGroup
|
||||
|
||||
/** @var BudgetLimit $budgetLimit */
|
||||
foreach ($set as $budgetLimit) {
|
||||
$result = bcadd((string) $budgetLimit->amount, $result);
|
||||
if ($budgetLimit->start_date->isSameDay($start) && $budgetLimit->end_date->isSameDay($end)) {
|
||||
$result = bcadd((string) $budgetLimit->amount, $result);
|
||||
|
||||
continue;
|
||||
}
|
||||
$period = Period::make($start, $end, precision: Precision::DAY(), boundaries: Boundaries::EXCLUDE_NONE());
|
||||
$amountPerDay = $this->getDailyAmount($budgetLimit);
|
||||
$result = bcadd($result, bcmul((string) $period->length(), $amountPerDay));
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -60,6 +60,7 @@ class CategoryRepository implements CategoryRepositoryInterface, UserGroupInterf
|
||||
|
||||
public function categoryStartsWith(string $query, int $limit): Collection
|
||||
{
|
||||
Log::debug(sprintf('Find a category that starts with "%s"', $query));
|
||||
$search = $this->user->categories();
|
||||
if ('' !== $query) {
|
||||
$search->whereLike('name', sprintf('%s%%', $query));
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -95,6 +95,11 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface, U
|
||||
#[Override]
|
||||
public function deleteStatisticsForPrefix(string $prefix, Collection $dates): void
|
||||
{
|
||||
if (null === $this->userGroup) {
|
||||
Log::warning('No user group, so cannot continue.');
|
||||
|
||||
return;
|
||||
}
|
||||
$count = $this->userGroup
|
||||
->periodStatistics()
|
||||
->where(function (Builder $q) use ($dates): void {
|
||||
|
||||
@@ -144,7 +144,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte
|
||||
|
||||
public function getActiveRules(RuleGroup $group): Collection
|
||||
{
|
||||
return $group->rules()->where('rules.active', true)->get(['rules.*']);
|
||||
return $group->rules()->where('rules.active', true)->orderBy('rules.order', 'ASC')->get(['rules.*']);
|
||||
}
|
||||
|
||||
public function getActiveStoreRules(RuleGroup $group): Collection
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
@@ -27,6 +27,10 @@ namespace FireflyIII\Services\Internal\Support;
|
||||
use Carbon\Carbon;
|
||||
use Deprecated;
|
||||
use FireflyIII\Enums\AccountTypeEnum;
|
||||
use FireflyIII\Events\Model\TransactionGroup\CreatedSingleTransactionGroup;
|
||||
use FireflyIII\Events\Model\TransactionGroup\TransactionGroupEventFlags;
|
||||
use FireflyIII\Events\Model\TransactionGroup\TransactionGroupEventObjects;
|
||||
use FireflyIII\Events\Model\TransactionGroup\UpdatedSingleTransactionGroup;
|
||||
use FireflyIII\Exceptions\DuplicateTransactionException;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Factory\AccountMetaFactory;
|
||||
@@ -58,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));
|
||||
@@ -224,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.
|
||||
@@ -253,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,
|
||||
@@ -348,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,
|
||||
@@ -384,15 +388,15 @@ trait AccountServiceTrait
|
||||
protected function createOBGroupV2(Account $account, string $openingBalance, Carbon $openingBalanceDate): TransactionGroup
|
||||
{
|
||||
Log::debug('Now going to create an OB group.');
|
||||
$language = Preferences::getForUser($account->user, 'language', 'en_US')->data;
|
||||
$language = Preferences::getForUser($account->user, 'language', 'en_US')->data;
|
||||
if (is_array($language)) {
|
||||
$language = 'en_US';
|
||||
}
|
||||
$language = (string) $language;
|
||||
$sourceId = null;
|
||||
$sourceName = null;
|
||||
$destId = null;
|
||||
$destName = null;
|
||||
$language = (string) $language;
|
||||
$sourceId = null;
|
||||
$sourceName = null;
|
||||
$destId = null;
|
||||
$destName = null;
|
||||
|
||||
// amount is positive.
|
||||
if (1 === bccomp($openingBalance, '0')) {
|
||||
@@ -414,16 +418,16 @@ trait AccountServiceTrait
|
||||
}
|
||||
|
||||
// make amount positive, regardless:
|
||||
$amount = Steam::positive($openingBalance);
|
||||
$amount = Steam::positive($openingBalance);
|
||||
|
||||
// get or grab currency:
|
||||
$currency = $this->accountRepository->getAccountCurrency($account);
|
||||
$currency = $this->accountRepository->getAccountCurrency($account);
|
||||
if (null === $currency) {
|
||||
$currency = Amount::getPrimaryCurrencyByUserGroup($account->user->userGroup);
|
||||
}
|
||||
|
||||
// submit to factory:
|
||||
$submission = [
|
||||
$submission = [
|
||||
'group_title' => null,
|
||||
'user' => $account->user,
|
||||
'user_group' => $account->user->userGroup,
|
||||
@@ -440,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,
|
||||
@@ -455,7 +459,7 @@ trait AccountServiceTrait
|
||||
Log::debug('Going for submission in createOBGroupV2', $submission);
|
||||
|
||||
/** @var TransactionGroupFactory $factory */
|
||||
$factory = app(TransactionGroupFactory::class);
|
||||
$factory = app(TransactionGroupFactory::class);
|
||||
$factory->setUser($account->user);
|
||||
|
||||
try {
|
||||
@@ -466,6 +470,13 @@ trait AccountServiceTrait
|
||||
|
||||
throw new FireflyException($e->getMessage(), 0, $e);
|
||||
}
|
||||
Preferences::mark();
|
||||
$objects = TransactionGroupEventObjects::collectFromTransactionGroup($group);
|
||||
$flags = new TransactionGroupEventFlags();
|
||||
$flags->applyRules = false;
|
||||
$flags->fireWebhooks = false;
|
||||
$flags->batchSubmission = false;
|
||||
event(new CreatedSingleTransactionGroup($flags, $objects));
|
||||
|
||||
return $group;
|
||||
}
|
||||
@@ -610,23 +621,23 @@ trait AccountServiceTrait
|
||||
{
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
// create if not exists:
|
||||
$obGroup = $this->getOBGroup($account);
|
||||
$obGroup = $this->getOBGroup($account);
|
||||
if (null === $obGroup) {
|
||||
return $this->createOBGroupV2($account, $openingBalance, $openingBalanceDate);
|
||||
}
|
||||
Log::debug('Update OB group');
|
||||
|
||||
// if exists, update:
|
||||
$currency = $this->accountRepository->getAccountCurrency($account);
|
||||
$currency = $this->accountRepository->getAccountCurrency($account);
|
||||
if (null === $currency) {
|
||||
$currency = Amount::getPrimaryCurrencyByUserGroup($account->user->userGroup);
|
||||
}
|
||||
|
||||
// simply grab the first journal and change it:
|
||||
$journal = $this->getObJournal($obGroup);
|
||||
$obTransaction = $this->getOBTransaction($journal, $account);
|
||||
$accountTransaction = $this->getNotOBTransaction($journal, $account);
|
||||
$journal->date = $openingBalanceDate;
|
||||
$journal = $this->getObJournal($obGroup);
|
||||
$obTransaction = $this->getOBTransaction($journal, $account);
|
||||
$accountTransaction = $this->getNotOBTransaction($journal, $account);
|
||||
$journal->date = $openingBalanceDate;
|
||||
$journal->transactionCurrency()->associate($currency);
|
||||
|
||||
// if amount is negative:
|
||||
@@ -656,6 +667,13 @@ trait AccountServiceTrait
|
||||
$journal->save();
|
||||
$obGroup->refresh();
|
||||
|
||||
$objects = TransactionGroupEventObjects::collectFromTransactionGroup($obGroup);
|
||||
$flags = new TransactionGroupEventFlags();
|
||||
$flags->applyRules = false;
|
||||
$flags->fireWebhooks = false;
|
||||
$flags->batchSubmission = false;
|
||||
event(new UpdatedSingleTransactionGroup($flags, $objects));
|
||||
|
||||
return $obGroup;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,9 +78,11 @@ class AccountUpdateService
|
||||
{
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
$this->accountRepository->setUser($account->user);
|
||||
$this->user = $account->user;
|
||||
$account = $this->updateAccount($account, $data);
|
||||
$account = $this->updateAccountOrder($account, $data);
|
||||
$this->user = $account->user;
|
||||
$oldData = $account->toArray();
|
||||
$oldData['account_number'] = $this->accountRepository->getMetaValue($account, 'account_number');
|
||||
$account = $this->updateAccount($account, $data);
|
||||
$account = $this->updateAccountOrder($account, $data);
|
||||
|
||||
// find currency, or use default currency instead.
|
||||
if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) {
|
||||
@@ -109,7 +111,7 @@ class AccountUpdateService
|
||||
// update preferences if inactive:
|
||||
$this->updatePreferences($account);
|
||||
|
||||
event(new UpdatedExistingAccount($account));
|
||||
event(new UpdatedExistingAccount($account, $oldData));
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -37,6 +37,16 @@ class Calculator
|
||||
|
||||
private static ?SplObjectStorage $intervalMap = null; // @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @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
|
||||
|
||||
@@ -92,6 +92,26 @@ class ExportDataGenerator
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->accounts = new Collection();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -82,10 +82,40 @@ trait PeriodOverview
|
||||
protected PeriodStatisticRepositoryInterface $periodStatisticRepo;
|
||||
private Collection $statistics; // temp data holder
|
||||
// temp data holder
|
||||
// temp data holder
|
||||
// temp data holder
|
||||
// temp data holder
|
||||
// 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
|
||||
|
||||
// temp data holder
|
||||
|
||||
// temp data holder
|
||||
|
||||
// temp data holder
|
||||
|
||||
// temp data holder
|
||||
|
||||
// temp data holder
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -42,8 +42,28 @@ class AvailableBudgetEnrichment implements EnrichmentInterface
|
||||
{
|
||||
private Collection $collection; // @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @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
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @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 = [];
|
||||
|
||||
@@ -42,6 +42,16 @@ class BudgetLimitEnrichment implements EnrichmentInterface
|
||||
private Collection $collection;
|
||||
private readonly bool $convertToPrimary; // @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @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);
|
||||
|
||||
|
||||
@@ -44,8 +44,28 @@ class PiggyBankEnrichment implements EnrichmentInterface
|
||||
{
|
||||
private array $accountIds = []; // @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @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
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @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 = [];
|
||||
|
||||
@@ -39,8 +39,28 @@ class PiggyBankEventEnrichment implements EnrichmentInterface
|
||||
{
|
||||
private array $accountCurrencies = []; // @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @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
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @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 = [];
|
||||
|
||||
@@ -48,6 +48,16 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
||||
private BillDateCalculator $calculator;
|
||||
private Collection $collection; // @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @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 = [];
|
||||
|
||||
@@ -57,6 +57,26 @@ class TransactionGroupEnrichment implements EnrichmentInterface
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @phpstan-ignore-line
|
||||
|
||||
// @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'];
|
||||
@@ -66,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();
|
||||
|
||||
@@ -44,8 +44,28 @@ class WebhookEnrichment implements EnrichmentInterface
|
||||
private Collection $collection;
|
||||
private array $deliveries = []; // @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @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
|
||||
// @phpstan-ignore-line
|
||||
// @phpstan-ignore-line
|
||||
// @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';
|
||||
}
|
||||
|
||||
@@ -75,6 +75,17 @@ class Preferences
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deleteForUser(User $user, string $name): bool
|
||||
{
|
||||
$fullName = sprintf('preference%s%s', auth()->user()->id, $name);
|
||||
if (Cache::has($fullName)) {
|
||||
Cache::forget($fullName);
|
||||
}
|
||||
Preference::where('user_id', $user->id)->where('name', $name)->delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find by name, has no user ID in it, because the method is called from an unauthenticated route any way.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -57,12 +57,13 @@ class QueryParser implements QueryParserInterface
|
||||
while ($this->position < $count) {
|
||||
$char = $chrArray[$this->position];
|
||||
$nextChar = $chrArray[$this->position + 1] ?? '';
|
||||
$prevChar = $chrArray[$this->position - 1] ?? '';
|
||||
// Log::debug(sprintf('Char #%d: %s', $this->position, $char));
|
||||
|
||||
// If we're in a quoted string, we treat all characters except another quote as ordinary characters
|
||||
if ($inQuotes) {
|
||||
if ('\\' === $char && '"' === $nextChar) {
|
||||
// Log::debug('BACKSLASH!');
|
||||
if ('\\' === $char && '"' === $nextChar && '\\' !== $prevChar) {
|
||||
// Log::debug('Found a backslash and the next one is a double quote.');
|
||||
// escaped quote, pretend it's a normal char and continue two places (skipping the actual character).
|
||||
$tokenUnderConstruction .= '\\'.$nextChar;
|
||||
$this->position += 2;
|
||||
@@ -77,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);
|
||||
}
|
||||
@@ -199,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;
|
||||
}
|
||||
|
||||
|
||||
46
changelog.md
46
changelog.md
@@ -3,6 +3,52 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## v6.4.18
|
||||
|
||||
### Fixed
|
||||
- [Discussion 11671](https://github.com/orgs/firefly-iii/discussions/11671) (Subscriptions Next Expected Match) started by @idgaron
|
||||
- [Issue 11667](https://github.com/firefly-iii/firefly-iii/issues/11667) (Account names and numbers are not corrected in rules when the account is updated) reported by @Kage1
|
||||
- [Issue 11668](https://github.com/firefly-iii/firefly-iii/issues/11668) (Auto-budget cron crashes on develop: Call to a member function budgets() on null (BudgetLimitRepository.php:311)) reported by @sykmer
|
||||
|
||||
## v6.4.17 - 2026-02-06
|
||||
|
||||
### Added
|
||||
|
||||
- Batch processing. Firefly III now has a setting (under `/settings`) that allows you to send `"batch_processing": true` with new transactions over the API. If this setting is enabled and the value is `true`, Firefly III will not fire rules, webhooks or other events untill you either send `false` with a transaction OR use the [API end point](https://api-docs.firefly-iii.org/) `/v1/api/batch/finish`. This should speed up (large) data imports. It's a little experimental, use at your own risk.
|
||||
- [Issue 11614](https://github.com/firefly-iii/firefly-iii/issues/11614) (Add New Taiwan Dollar to Currency Seeder) reported by @nick322
|
||||
- [Issue 11246](https://github.com/firefly-iii/firefly-iii/issues/11246) (Distinguish automatically converted amount from foreign amount) reported by @jfpedroza
|
||||
|
||||
### Changed
|
||||
|
||||
- A lot of code in Firefly III is code responding to changes made by other code. These lines of code are called events, listeners, observers, handlers, etc. They were a bit of a mess and I cleaned them all up. This should greatly improve the reliability of debt amounts and running balance consistency. Bugs are always possible, let me know.
|
||||
|
||||
### Deprecated
|
||||
|
||||
- PHP 8.4 is still on my list to be disabled, beware.
|
||||
|
||||
### Fixed
|
||||
|
||||
- [Issue 11399](https://github.com/firefly-iii/firefly-iii/issues/11399) (Unusual behavior in audit logs (multi-currency)) reported by @jgmm81
|
||||
- [Discussion 11431](https://github.com/orgs/firefly-iii/discussions/11431) (Settings don't get saved) started by @PVTejas
|
||||
- [Issue 11541](https://github.com/firefly-iii/firefly-iii/issues/11541) (Display running balance fails for transactions between accounts with different currencies) reported by @SledgehammerPL
|
||||
- [Issue 11544](https://github.com/firefly-iii/firefly-iii/issues/11544) (Clean up events and handlers) reported by @JC5
|
||||
- [Issue 11546](https://github.com/firefly-iii/firefly-iii/issues/11546) (Wrong invitation expiry time) reported by @GunoH
|
||||
- [Issue 11563](https://github.com/firefly-iii/firefly-iii/issues/11563) (Tag Report/Insight API Endpoint for Tags Non Functional) reported by @Unsantae
|
||||
- [PR 11569](https://github.com/firefly-iii/firefly-iii/pull/11569) (Fix layout overflow issues with long content in v1 and v2 layouts) reported by @gian21391
|
||||
- [PR 11589](https://github.com/firefly-iii/firefly-iii/pull/11589) (apply user-selected light/dark mode to form elements (checkboxes, date picker) [Issue 8613](https://github.com/firefly-iii/firefly-iii/issues/8613) (Some minor color issues) reported by @rumpff [Issue 7620](https://github.com/firefly-iii/firefly-iii/issues/7620) (Issues with light mode) reported by @rchl) reported by @mateuszkulapl
|
||||
- [Issue 11597](https://github.com/firefly-iii/firefly-iii/issues/11597) (Changing category doesn't recompute stats) reported by @jlauwers
|
||||
- [Issue 11601](https://github.com/firefly-iii/firefly-iii/issues/11601) (Only ungrouped piggy banks are listed when creating a transaction) reported by @jgmm81
|
||||
- [Issue 11620](https://github.com/firefly-iii/firefly-iii/issues/11620) (Add database indexes to improve reporting query performance) reported by @Zakmaf
|
||||
- [PR 11632](https://github.com/firefly-iii/firefly-iii/pull/11632) (fix v2 layout dashboard transactions load) reported by @mateuszkulapl
|
||||
- [Issue 11657](https://github.com/firefly-iii/firefly-iii/issues/11657) (since v6.4.16: Backslash in category names cannot be matched in rules) reported by @37-b-j
|
||||
- [Issue 11660](https://github.com/firefly-iii/firefly-iii/issues/11660) (Display of negative values of transfers) reported by @Robubble
|
||||
- Confirming your new email address would result in an error.
|
||||
|
||||
### API
|
||||
|
||||
- [API end point](https://api-docs.firefly-iii.org/) `/v1/api/batch/finish`.
|
||||
|
||||
|
||||
## v6.4.16 - 2026-01-18
|
||||
|
||||
> [!WARNING]
|
||||
|
||||
@@ -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",
|
||||
|
||||
116
composer.lock
generated
116
composer.lock
generated
@@ -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",
|
||||
@@ -130,16 +130,16 @@
|
||||
},
|
||||
{
|
||||
"name": "brick/math",
|
||||
"version": "0.14.6",
|
||||
"version": "0.14.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/brick/math.git",
|
||||
"reference": "32498d5e1897e7642c0b961ace2df6d7dc9a3bc3"
|
||||
"reference": "07ff363b16ef8aca9692bba3be9e73fe63f34e50"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/brick/math/zipball/32498d5e1897e7642c0b961ace2df6d7dc9a3bc3",
|
||||
"reference": "32498d5e1897e7642c0b961ace2df6d7dc9a3bc3",
|
||||
"url": "https://api.github.com/repos/brick/math/zipball/07ff363b16ef8aca9692bba3be9e73fe63f34e50",
|
||||
"reference": "07ff363b16ef8aca9692bba3be9e73fe63f34e50",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -178,7 +178,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/brick/math/issues",
|
||||
"source": "https://github.com/brick/math/tree/0.14.6"
|
||||
"source": "https://github.com/brick/math/tree/0.14.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -186,7 +186,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2026-02-05T07:59:58+00:00"
|
||||
"time": "2026-02-07T10:57:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "carbonphp/carbon-doctrine-types",
|
||||
@@ -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",
|
||||
@@ -3829,16 +3829,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nette/schema",
|
||||
"version": "v1.3.3",
|
||||
"version": "v1.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nette/schema.git",
|
||||
"reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004"
|
||||
"reference": "086497a2f34b82fede9b5a41cc8e131d087cd8f7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nette/schema/zipball/2befc2f42d7c715fd9d95efc31b1081e5d765004",
|
||||
"reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004",
|
||||
"url": "https://api.github.com/repos/nette/schema/zipball/086497a2f34b82fede9b5a41cc8e131d087cd8f7",
|
||||
"reference": "086497a2f34b82fede9b5a41cc8e131d087cd8f7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3846,8 +3846,8 @@
|
||||
"php": "8.1 - 8.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"nette/tester": "^2.5.2",
|
||||
"phpstan/phpstan-nette": "^2.0@stable",
|
||||
"nette/tester": "^2.6",
|
||||
"phpstan/phpstan": "^2.0@stable",
|
||||
"tracy/tracy": "^2.8"
|
||||
},
|
||||
"type": "library",
|
||||
@@ -3888,9 +3888,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nette/schema/issues",
|
||||
"source": "https://github.com/nette/schema/tree/v1.3.3"
|
||||
"source": "https://github.com/nette/schema/tree/v1.3.4"
|
||||
},
|
||||
"time": "2025-10-30T22:57:59+00:00"
|
||||
"time": "2026-02-08T02:54:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/utils",
|
||||
@@ -10530,16 +10530,16 @@
|
||||
},
|
||||
{
|
||||
"name": "fruitcake/laravel-debugbar",
|
||||
"version": "v4.0.6",
|
||||
"version": "v4.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fruitcake/laravel-debugbar.git",
|
||||
"reference": "0cbf2986de59f66870cee565491b81eb89f8d25e"
|
||||
"reference": "a9cc62c81cd0bda4ca7410229487638d7df786be"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fruitcake/laravel-debugbar/zipball/0cbf2986de59f66870cee565491b81eb89f8d25e",
|
||||
"reference": "0cbf2986de59f66870cee565491b81eb89f8d25e",
|
||||
"url": "https://api.github.com/repos/fruitcake/laravel-debugbar/zipball/a9cc62c81cd0bda4ca7410229487638d7df786be",
|
||||
"reference": "a9cc62c81cd0bda4ca7410229487638d7df786be",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -10616,7 +10616,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/fruitcake/laravel-debugbar/issues",
|
||||
"source": "https://github.com/fruitcake/laravel-debugbar/tree/v4.0.6"
|
||||
"source": "https://github.com/fruitcake/laravel-debugbar/tree/v4.0.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -10628,7 +10628,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2026-02-04T11:48:53+00:00"
|
||||
"time": "2026-02-06T20:53:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "hamcrest/hamcrest-php",
|
||||
@@ -11198,16 +11198,16 @@
|
||||
},
|
||||
{
|
||||
"name": "php-debugbar/php-debugbar",
|
||||
"version": "v3.3.0",
|
||||
"version": "v3.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-debugbar/php-debugbar.git",
|
||||
"reference": "e22287890107602af6a113dc7975b3d77c542e5f"
|
||||
"reference": "afdaa2e56aca9d56b5bb2bad041bd2f6002017cf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/e22287890107602af6a113dc7975b3d77c542e5f",
|
||||
"reference": "e22287890107602af6a113dc7975b3d77c542e5f",
|
||||
"url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/afdaa2e56aca9d56b5bb2bad041bd2f6002017cf",
|
||||
"reference": "afdaa2e56aca9d56b5bb2bad041bd2f6002017cf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -11284,7 +11284,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-debugbar/php-debugbar/issues",
|
||||
"source": "https://github.com/php-debugbar/php-debugbar/tree/v3.3.0"
|
||||
"source": "https://github.com/php-debugbar/php-debugbar/tree/v3.3.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -11296,7 +11296,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2026-01-28T12:57:47+00:00"
|
||||
"time": "2026-02-06T21:09:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-debugbar/symfony-bridge",
|
||||
@@ -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,25 +12010,25 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-02-05T08:01:09+00:00"
|
||||
"time": "2026-02-10T12:32:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "rector/rector",
|
||||
"version": "2.3.5",
|
||||
"version": "2.3.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/rectorphp/rector.git",
|
||||
"reference": "9442f4037de6a5347ae157fe8e6c7cda9d909070"
|
||||
"reference": "ca9ebb81d280cd362ea39474dabd42679e32ca6b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/rectorphp/rector/zipball/9442f4037de6a5347ae157fe8e6c7cda9d909070",
|
||||
"reference": "9442f4037de6a5347ae157fe8e6c7cda9d909070",
|
||||
"url": "https://api.github.com/repos/rectorphp/rector/zipball/ca9ebb81d280cd362ea39474dabd42679e32ca6b",
|
||||
"reference": "ca9ebb81d280cd362ea39474dabd42679e32ca6b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4|^8.0",
|
||||
"phpstan/phpstan": "^2.1.36"
|
||||
"phpstan/phpstan": "^2.1.38"
|
||||
},
|
||||
"conflict": {
|
||||
"rector/rector-doctrine": "*",
|
||||
@@ -12062,7 +12062,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/rectorphp/rector/issues",
|
||||
"source": "https://github.com/rectorphp/rector/tree/2.3.5"
|
||||
"source": "https://github.com/rectorphp/rector/tree/2.3.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -12070,7 +12070,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2026-01-28T15:22:48+00:00"
|
||||
"time": "2026-02-06T14:25:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
|
||||
@@ -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-06',
|
||||
'build_time' => 1770382386,
|
||||
'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.
|
||||
|
||||
|
||||
@@ -33,16 +33,12 @@ class ChangesFor3101 extends Migration
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
}
|
||||
public function down(): void {}
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @SuppressWarnings("PHPMD.ShortMethodName")
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
}
|
||||
public function up(): void {}
|
||||
}
|
||||
|
||||
@@ -39,9 +39,7 @@ class FixNullables extends Migration
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
}
|
||||
public function down(): void {}
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
||||
@@ -34,16 +34,12 @@ class ChangesForV474 extends Migration
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
}
|
||||
public function down(): void {}
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @SuppressWarnings("PHPMD.ShortMethodName")
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
}
|
||||
public function up(): void {}
|
||||
}
|
||||
|
||||
@@ -37,9 +37,7 @@ class ChangesForV4711 extends Migration
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
}
|
||||
public function down(): void {}
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
||||
@@ -37,9 +37,7 @@ class ChangesForV4712 extends Migration
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
}
|
||||
public function down(): void {}
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
||||
@@ -35,9 +35,7 @@ class ExtendCurrencyInfo extends Migration
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
}
|
||||
public function down(): void {}
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
||||
@@ -34,9 +34,7 @@ return new class() extends Migration {
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
}
|
||||
public function down(): void {}
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
@@ -67,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,9 +31,7 @@ return new class() extends Migration {
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
}
|
||||
public function down(): void {}
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
||||
@@ -51,9 +51,7 @@ return new class() extends Migration {
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
}
|
||||
public function down(): void {}
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
70
package-lock.json
generated
70
package-lock.json
generated
@@ -3246,9 +3246,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "25.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.1.tgz",
|
||||
"integrity": "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg==",
|
||||
"version": "25.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.2.tgz",
|
||||
"integrity": "sha512-BkmoP5/FhRYek5izySdkOneRyXYN35I860MFAGupTdebyE66uZaR+bXLHq8k4DirE5DwQi3NuhvRU1jqTVwUrQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -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"
|
||||
}
|
||||
},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user