Compare commits

...

52 Commits

Author SHA1 Message Date
github-actions[bot]
bf6e1cb0e1 Merge pull request #10642 from firefly-iii/release-1753333227
🤖 Automatically merge the PR into the develop branch.
2025-07-24 07:00:35 +02:00
JC5
6a53f5031c 🤖 Auto commit for release 'develop' on 2025-07-24 2025-07-24 07:00:27 +02:00
James Cole
ae15ec01e8 Merge branch 'main' into develop 2025-07-24 06:56:07 +02:00
James Cole
fe3c7c47c4 Filter list of bills. 2025-07-24 06:55:53 +02:00
James Cole
68b934010c Merge pull request #10640 from firefly-iii/dependabot/npm_and_yarn/npm_and_yarn-25988072ba
Bump the npm_and_yarn group across 1 directory with 2 updates
2025-07-23 19:37:09 +02:00
dependabot[bot]
22852bd238 Bump the npm_and_yarn group across 1 directory with 2 updates
Bumps the npm_and_yarn group with 1 update in the / directory: [axios](https://github.com/axios/axios).


Updates `axios` from 1.10.0 to 1.11.0
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.10.0...v1.11.0)

Updates `form-data` from 4.0.3 to 4.0.4
- [Release notes](https://github.com/form-data/form-data/releases)
- [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md)
- [Commits](https://github.com/form-data/form-data/compare/v4.0.3...v4.0.4)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.11.0
  dependency-type: direct:development
  dependency-group: npm_and_yarn
- dependency-name: form-data
  dependency-version: 4.0.4
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-23 16:51:30 +00:00
github-actions[bot]
5b3b1804f3 Merge pull request #10638 from firefly-iii/release-1753247140
🤖 Automatically merge the PR into the develop branch.
2025-07-23 07:05:49 +02:00
JC5
f2588eb343 🤖 Auto commit for release 'develop' on 2025-07-23 2025-07-23 07:05:40 +02:00
James Cole
64a643ceec Expand balances. 2025-07-23 07:01:10 +02:00
github-actions[bot]
1add505644 Merge pull request #10634 from firefly-iii/release-1753068994
🤖 Automatically merge the PR into the develop branch.
2025-07-21 05:36:42 +02:00
JC5
9663eb6a19 🤖 Auto commit for release 'develop' on 2025-07-21 2025-07-21 05:36:34 +02:00
github-actions[bot]
f30a24a02f Merge pull request #10629 from firefly-iii/release-1753029916
🤖 Automatically merge the PR into the develop branch.
2025-07-20 18:45:22 +02:00
JC5
68655d60a6 🤖 Auto commit for release 'develop' on 2025-07-20 2025-07-20 18:45:16 +02:00
James Cole
63b0efcd81 Remove sonarcloud flow. 2025-07-20 18:41:05 +02:00
James Cole
93284682c8 Improve bill overview. 2025-07-20 14:02:53 +02:00
github-actions[bot]
3bafcb6ad2 Merge pull request #10625 from firefly-iii/release-1753007822
🤖 Automatically merge the PR into the develop branch.
2025-07-20 12:37:09 +02:00
JC5
942d027556 🤖 Auto commit for release 'develop' on 2025-07-20 2025-07-20 12:37:02 +02:00
James Cole
a60882d5f5 Clean up v2. 2025-07-20 12:32:53 +02:00
James Cole
680f554981 Fix #10618 2025-07-19 21:08:37 +02:00
James Cole
20e4dc07ce Bad quote in html 2025-07-18 19:53:22 +02:00
James Cole
184d8eb027 Use new settings for php cs fixer. 2025-07-17 06:54:20 +02:00
github-actions[bot]
59725b088a Merge pull request #10608 from firefly-iii/develop
🤖 Automatically merge the PR into the main branch.
2025-07-17 06:46:17 +02:00
github-actions[bot]
32fca4a9f5 Merge pull request #10607 from firefly-iii/release-1752727561
🤖 Automatically merge the PR into the develop branch.
2025-07-17 06:46:12 +02:00
JC5
7dccf6ec48 🤖 Auto commit for release 'v6.2.21' on 2025-07-17 2025-07-17 06:46:01 +02:00
github-actions[bot]
917665feac Merge pull request #10606 from firefly-iii/release-1752727317
🤖 Automatically merge the PR into the develop branch.
2025-07-17 06:42:04 +02:00
JC5
06c50b68c2 🤖 Auto commit for release 'develop' on 2025-07-17 2025-07-17 06:41:57 +02:00
James Cole
7035c399d8 Update changelog. 2025-07-17 06:36:37 +02:00
James Cole
7c0ac5805c Fix #10601 2025-07-16 17:09:37 +02:00
James Cole
3424741583 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2025-07-14 07:00:16 +02:00
James Cole
baf0297994 Update vite 2025-07-14 07:00:10 +02:00
github-actions[bot]
31d06752fa Merge pull request #10591 from firefly-iii/release-1752464168
🤖 Automatically merge the PR into the develop branch.
2025-07-14 05:36:14 +02:00
JC5
8a27154798 🤖 Auto commit for release 'develop' on 2025-07-14 2025-07-14 05:36:08 +02:00
github-actions[bot]
6d87e38ec0 Merge pull request #10583 from firefly-iii/release-1752300569
🤖 Automatically merge the PR into the develop branch.
2025-07-12 08:09:37 +02:00
JC5
ccdc30a6fb 🤖 Auto commit for release 'develop' on 2025-07-12 2025-07-12 08:09:29 +02:00
James Cole
90005538d3 Fix one tiny date thing. 2025-07-12 08:05:30 +02:00
James Cole
f4e0428ebc Limit date ranges to fix #10581 2025-07-12 06:18:25 +02:00
github-actions[bot]
bd1326eca9 Merge pull request #10577 from firefly-iii/release-1752124263
🤖 Automatically merge the PR into the develop branch.
2025-07-10 07:11:12 +02:00
JC5
bdfa834251 🤖 Auto commit for release 'develop' on 2025-07-10 2025-07-10 07:11:04 +02:00
James Cole
4a9aeb4e44 Rename tagMode to tag_mode. 2025-07-10 07:04:20 +02:00
github-actions[bot]
3886c0fbde Merge pull request #10563 from firefly-iii/release-1751859243
🤖 Automatically merge the PR into the develop branch.
2025-07-07 05:34:17 +02:00
JC5
d998eff56e 🤖 Auto commit for release 'develop' on 2025-07-07 2025-07-07 05:34:03 +02:00
github-actions[bot]
d73df9bf0a Merge pull request #10559 from firefly-iii/release-1751823330
🤖 Automatically merge the PR into the develop branch.
2025-07-06 19:35:38 +02:00
JC5
754f2f3a34 🤖 Auto commit for release 'develop' on 2025-07-06 2025-07-06 19:35:30 +02:00
James Cole
43fd7c928a Add build_time 2025-07-06 19:32:01 +02:00
github-actions[bot]
05768c2e73 Merge pull request #10548 from firefly-iii/release-1751477916
🤖 Automatically merge the PR into the develop branch.
2025-07-02 19:38:43 +02:00
JC5
3feb2c9955 🤖 Auto commit for release 'develop' on 2025-07-02 2025-07-02 19:38:36 +02:00
James Cole
7d9f3ac473 Fix logs. 2025-07-02 19:35:01 +02:00
James Cole
8a5755c8f1 Add debug information. 2025-07-02 19:34:05 +02:00
github-actions[bot]
a75a760019 Merge pull request #10547 from firefly-iii/release-1751476883
🤖 Automatically merge the PR into the develop branch.
2025-07-02 19:21:31 +02:00
JC5
78d1a130d2 🤖 Auto commit for release 'develop' on 2025-07-02 2025-07-02 19:21:23 +02:00
github-actions[bot]
79fd43f32b Merge pull request #10538 from firefly-iii/release-1751429580
🤖 Automatically merge the PR into the develop branch.
2025-07-02 06:13:10 +02:00
JC5
7a7bd65a27 🤖 Auto commit for release 'develop' on 2025-07-02 2025-07-02 06:13:00 +02:00
87 changed files with 1216 additions and 985 deletions

View File

@@ -33,6 +33,7 @@ $finder = PhpCsFixer\Finder::create()
$config = (new PhpCsFixer\Config())
// ->setUnsupportedPhpVersionAllowed(true) // use this when PHP 8.5 comes out.
->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect())
;
return $config->setRules(

View File

@@ -406,16 +406,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.76.0",
"version": "v3.84.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "0e3c484cef0ae9314b0f85986a36296087432c40"
"reference": "38dad0767bf2a9b516b976852200ae722fe984ca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/0e3c484cef0ae9314b0f85986a36296087432c40",
"reference": "0e3c484cef0ae9314b0f85986a36296087432c40",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/38dad0767bf2a9b516b976852200ae722fe984ca",
"reference": "38dad0767bf2a9b516b976852200ae722fe984ca",
"shasum": ""
},
"require": {
@@ -499,7 +499,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.76.0"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.84.0"
},
"funding": [
{
@@ -507,7 +507,7 @@
"type": "github"
}
],
"time": "2025-06-30T14:15:06+00:00"
"time": "2025-07-15T18:21:57+00:00"
},
{
"name": "psr/container",

View File

@@ -26,7 +26,7 @@ SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
cd $SCRIPT_DIR/php-cs-fixer
composer update --quiet
rm -f .php-cs-fixer.cache
PHP_CS_FIXER_IGNORE_ENV=true ./vendor/bin/php-cs-fixer fix \
./vendor/bin/php-cs-fixer fix \
--config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php \
--format=txt \
-v \

View File

@@ -1,71 +0,0 @@
name: 'Code - Run Sonarcloud'
on:
pull_request:
workflow_dispatch:
push:
branches:
- main
env:
DB_CONNECTION: sqlite
APP_KEY: TestTestTestTestTestTestTestTest
jobs:
sonarcloud:
name: SonarCloud
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup PHP with Xdebug
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
coverage: xdebug
extensions: >-
bcmath
curl
fileinfo
iconv
intl
json
sqlite3
mbstring
openssl
pdo
session
simplexml
sodium
tokenizer
xml
xmlwriter
- name: Copy standard configuration
run: cp .env.testing .env
- name: Install Composer dependencies
run: composer install --prefer-dist --no-interaction --no-progress --no-scripts
- name: "Create database file"
run: |
touch storage/database/database.sqlite
wget -q https://github.com/firefly-iii/test-fixtures/raw/refs/heads/main/test-database.sqlite -O storage/database/database.sqlite
- name: "Upgrades the database to the latest version"
run: |
php artisan firefly-iii:upgrade-database
chmod 600 storage/oauth-public.key
chmod 600 storage/oauth-private.key
- name: "Integrity Database Report"
run: php artisan firefly-iii:report-integrity
- name: "Run tests with coverage"
run: composer coverage
- name: Fix code coverage paths
run: sed -i 's@'$GITHUB_WORKSPACE'@/github/workspace/@g' coverage.xml
- name: SonarCloud Scan
uses: SonarSource/sonarqube-scan-action@v5.2.0
env:
GITHUB_TOKEN: ${{ secrets.GH_ACTIONS_PERSONAL_ACCESS_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

View File

@@ -58,7 +58,7 @@ class AutocompleteRequest extends FormRequest
public function rules(): array
{
return [
'date' => 'date|after:1900-01-01|before:2099-12-31',
'date' => 'date|after:1970-01-02|before:2038-01-17',
];
}
}

View File

@@ -60,8 +60,8 @@ class ChartRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'required|date|after:1900-01-01|before:2099-12-31|before_or_equal:end',
'end' => 'required|date|after:1900-01-01|before:2099-12-31|after_or_equal:start',
'start' => 'required|date|after:1970-01-02|before:2038-01-17|before_or_equal:end',
'end' => 'required|date|after:1970-01-02|before:2038-01-17|after_or_equal:start',
'preselected' => sprintf('nullable|in:%s', implode(',', config('firefly.preselected_accounts'))),
'period' => sprintf('nullable|in:%s', implode(',', config('firefly.valid_view_ranges'))),
'accounts.*' => 'exists:accounts,id',

View File

@@ -65,9 +65,9 @@ class DateRequest extends FormRequest
public function rules(): array
{
return [
'date' => 'date|after:1900-01-01|before:2099-12-31',
'start' => 'date|after:1900-01-01|before:2099-12-31|before:end|required_with:end',
'end' => 'date|after:1900-01-01|before:2099-12-31|after:start|required_with:start',
'date' => 'date|after:1970-01-02|before:2038-01-17',
'start' => 'date|after:1970-01-02|before:2038-01-17|before:end|required_with:end',
'end' => 'date|after:1970-01-02|before:2038-01-17|after:start|required_with:start',
];
}
}

View File

@@ -55,8 +55,8 @@ class DateRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'required|date|after:1900-01-01|before:2099-12-31',
'end' => 'required|date|after_or_equal:start|before:2099-12-31|after:1900-01-01',
'start' => 'required|date|after:1970-01-02|before:2038-01-17',
'end' => 'required|date|after_or_equal:start|before:2038-01-17|after:1970-01-02',
];
}
}

View File

@@ -53,7 +53,7 @@ class SingleDateRequest extends FormRequest
public function rules(): array
{
return [
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
'date' => 'required|date|after:1970-01-02|before:2038-01-17',
];
}
}

View File

@@ -66,8 +66,8 @@ class Request extends FormRequest
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'amount' => ['nullable', new IsValidPositiveAmount()],
'start' => 'date|after:1900-01-01|before:2099-12-31',
'end' => 'date|after:1900-01-01|before:2099-12-31',
'start' => 'date|after:1970-01-02|before:2038-01-17',
'end' => 'date|after:1970-01-02|before:2038-01-17',
];
}

View File

@@ -80,9 +80,9 @@ class StoreRequest extends FormRequest
'amount_max' => ['required', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'date' => 'date|required|after:1900-01-01|before:2099-12-31',
'end_date' => 'nullable|date|after:date|after:1900-01-01|before:2099-12-31',
'extension_date' => 'nullable|date|after:date|after:1900-01-01|before:2099-12-31',
'date' => 'date|required|after:1970-01-02|before:2038-01-17',
'end_date' => 'nullable|date|after:date|after:1970-01-02|before:2038-01-17',
'extension_date' => 'nullable|date|after:date|after:1970-01-02|before:2038-01-17',
'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly|required',
'skip' => 'min:0|max:31|numeric',
'active' => [new IsBoolean()],

View File

@@ -81,9 +81,9 @@ class UpdateRequest extends FormRequest
'amount_max' => ['nullable', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'date' => 'date|after:1900-01-01|before:2099-12-31',
'end_date' => 'date|after:date|after:1900-01-01|before:2099-12-31',
'extension_date' => 'date|after:date|after:1900-01-01|before:2099-12-31',
'date' => 'date|after:1970-01-02|before:2038-01-17',
'end_date' => 'date|after:date|after:1970-01-02|before:2038-01-17',
'extension_date' => 'date|after:date|after:1970-01-02|before:2038-01-17',
'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly',
'skip' => 'min:0|max:31|numeric',
'active' => [new IsBoolean()],

View File

@@ -67,8 +67,8 @@ class UpdateRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'date|after:1900-01-01|before:2099-12-31',
'end' => 'date|after:1900-01-01|before:2099-12-31',
'start' => 'date|after:1970-01-02|before:2038-01-17',
'end' => 'date|after:1970-01-02|before:2038-01-17',
'amount' => ['nullable', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',

View File

@@ -45,7 +45,7 @@ class DestroyRequest extends FormRequest
public function rules(): array
{
return [
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
'date' => 'required|date|after:1970-01-02|before:2038-01-17',
];
}
}

View File

@@ -61,7 +61,7 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
'date' => 'required|date|after:1970-01-02|before:2038-01-17',
'rate' => 'required|numeric|gt:0',
'from' => 'required|exists:transaction_currencies,code',
'to' => 'required|exists:transaction_currencies,code',

View File

@@ -50,7 +50,7 @@ class UpdateRequest extends FormRequest
public function rules(): array
{
return [
'date' => 'date|after:1900-01-01|before:2099-12-31',
'date' => 'date|after:1970-01-02|before:2038-01-17',
'rate' => 'required|numeric|gt:0',
];
}

View File

@@ -154,7 +154,7 @@ class UpdateRequest extends FormRequest
return [
'title' => sprintf('min:1|max:255|uniqueObjectForUser:recurrences,title,%d', $recurrence->id),
'description' => 'min:1|max:32768',
'first_date' => 'date|after:1900-01-01|before:2099-12-31',
'first_date' => 'date|after:1970-01-02|before:2038-01-17',
'apply_rules' => [new IsBoolean()],
'active' => [new IsBoolean()],
'repeat_until' => 'nullable|date',

View File

@@ -71,8 +71,8 @@ class TestRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'date|after:1900-01-01|before:2099-12-31',
'end' => 'date|after_or_equal:start|after:1900-01-01|before:2099-12-31',
'start' => 'date|after:1970-01-02|before:2038-01-17',
'end' => 'date|after_or_equal:start|after:1970-01-02|before:2038-01-17',
'accounts' => '',
'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts',
];

View File

@@ -65,8 +65,8 @@ class TriggerRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'date|after:1900-01-01|before:2099-12-31',
'end' => 'date|after_or_equal:start|after:1900-01-01|before:2099-12-31',
'start' => 'date|after:1970-01-02|before:2038-01-17',
'end' => 'date|after_or_equal:start|after:1970-01-02|before:2038-01-17',
'accounts' => '',
'accounts.*' => 'exists:accounts,id|belongsToUser:accounts',
];

View File

@@ -65,8 +65,8 @@ class TestRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'date|after:1900-01-01|before:2099-12-31',
'end' => 'date|after_or_equal:start|after:1900-01-01|before:2099-12-31',
'start' => 'date|after:1970-01-02|before:2038-01-17',
'end' => 'date|after_or_equal:start|after:1970-01-02|before:2038-01-17',
'accounts' => '',
'accounts.*' => 'exists:accounts,id|belongsToUser:accounts',
];

View File

@@ -69,8 +69,8 @@ class TriggerRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'date|after:1900-01-01|before:2099-12-31',
'end' => 'date|after_or_equal:start|after:1900-01-01|before:2099-12-31',
'start' => 'date|after:1970-01-02|before:2038-01-17',
'end' => 'date|after_or_equal:start|after:1970-01-02|before:2038-01-17',
];
}
}

View File

@@ -62,7 +62,7 @@ class StoreRequest extends FormRequest
$rules = [
'tag' => 'required|min:1|uniqueObjectForUser:tags,tag|max:1024',
'description' => 'min:1|nullable|max:32768',
'date' => 'date|nullable|after:1900-01-01|before:2099-12-31',
'date' => 'date|nullable|after:1970-01-02|before:2038-01-17',
];
return Location::requestRules($rules);

View File

@@ -66,7 +66,7 @@ class UpdateRequest extends FormRequest
$rules = [
'tag' => 'min:1|max:1024|uniqueObjectForUser:tags,tag,'.$tag->id,
'description' => 'min:1|nullable|max:32768',
'date' => 'date|nullable|after:1900-01-01|before:2099-12-31',
'date' => 'date|nullable|after:1970-01-02|before:2038-01-17',
];
return Location::requestRules($rules);

View File

@@ -73,7 +73,7 @@ class CronRequest extends FormRequest
{
return [
'force' => 'in:true,false',
'date' => 'nullable|date|after:1900-01-01|before:2099-12-31',
'date' => 'nullable|date|after:1970-01-02|before:2038-01-17',
];
}
}

View File

@@ -116,7 +116,7 @@ class Controller extends BaseController
app('log')->warning(sprintf('Ignored invalid date "%s" in API v2 controller parameter check: %s', substr((string) $date, 0, 20), $e->getMessage()));
}
// out of range? set to null.
if ($obj instanceof Carbon && ($obj->year <= 1900 || $obj->year > 2099)) {
if ($obj instanceof Carbon && ($obj->year <= 1970 || $obj->year > 2038)) {
app('log')->warning(sprintf('Refuse to use date "%s" in API v2 controller parameter check: %s', $field, $obj->toAtomString()));
$obj = null;
}

View File

@@ -86,7 +86,7 @@ class AutocompleteRequest extends FormRequest
$valid = array_keys($this->types);
return [
'date' => 'nullable|date|after:1900-01-01|before:2100-01-01',
'date' => 'nullable|date|after:1970-01-02|before:2038-01-17',
'query' => 'nullable|string',
'size' => 'nullable|integer|min:1|max:100',
'page' => 'nullable|integer|min:1',

View File

@@ -60,8 +60,8 @@ class BalanceChartRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'required|date|after:1900-01-01|before:2099-12-31',
'end' => 'required|date|after_or_equal:start|before:2099-12-31|after:1900-01-01',
'start' => 'required|date|after:1970-01-02|before:2038-01-17',
'end' => 'required|date|after_or_equal:start|before:2038-01-17|after:1970-01-02',
'accounts.*' => 'required|exists:accounts,id',
'period' => sprintf('required|in:%s', implode(',', config('firefly.valid_view_ranges'))),
];

View File

@@ -61,8 +61,8 @@ class ChartRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'required|date|after:1900-01-01|before:2099-12-31|before_or_equal:end',
'end' => 'required|date|after:1900-01-01|before:2099-12-31|after_or_equal:start',
'start' => 'required|date|after:1970-01-02|before:2038-01-17|before_or_equal:end',
'end' => 'required|date|after:1970-01-02|before:2038-01-17|after_or_equal:start',
'preselected' => sprintf('nullable|in:%s', implode(',', config('firefly.preselected_accounts'))),
'period' => sprintf('nullable|in:%s', implode(',', config('firefly.valid_view_ranges'))),
'accounts.*' => 'exists:accounts,id',

View File

@@ -60,8 +60,8 @@ class DashboardChartRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'required|date|after:1900-01-01|before:2099-12-31',
'end' => 'required|date|after_or_equal:start|before:2099-12-31|after:1900-01-01',
'start' => 'required|date|after:1970-01-02|before:2038-01-17',
'end' => 'required|date|after_or_equal:start|before:2038-01-17|after:1970-01-02',
'preselected' => sprintf('in:%s', implode(',', config('firefly.preselected_accounts'))),
'accounts.*' => 'exists:accounts,id',
];

View File

@@ -55,8 +55,8 @@ class DateRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'required|date|after:1900-01-01|before:2099-12-31',
'end' => 'required|date|after_or_equal:start|before:2099-12-31|after:1900-01-01',
'start' => 'required|date|after:1970-01-02|before:2038-01-17',
'end' => 'required|date|after_or_equal:start|before:2038-01-17|after:1970-01-02',
];
}
}

View File

@@ -53,7 +53,7 @@ class SingleDateRequest extends FormRequest
public function rules(): array
{
return [
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
'date' => 'required|date|after:1970-01-02|before:2038-01-17',
];
}
}

View File

@@ -63,9 +63,9 @@ class IndexRequest extends FormRequest
public function rules(): array
{
return [
'date' => 'date|after:1900-01-01|before:2099-12-31',
'start' => 'date|after:1900-01-01|before:2099-12-31|before:end|required_with:end',
'end' => 'date|after:1900-01-01|before:2099-12-31|after:start|required_with:start',
'date' => 'date|after:1970-01-02|before:2038-01-17',
'start' => 'date|after:1970-01-02|before:2038-01-17|before:end|required_with:end',
'end' => 'date|after:1970-01-02|before:2038-01-17|after:start|required_with:start',
];
}
}

View File

@@ -109,8 +109,8 @@ class InfiniteListRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'date|after:1900-01-01|before:2099-12-31',
'end' => 'date|after:start|after:1900-01-01|before:2099-12-31',
'start' => 'date|after:1970-01-02|before:2038-01-17',
'end' => 'date|after:start|after:1970-01-02|before:2038-01-17',
'start_row' => 'integer|min:0|max:4294967296',
'end_row' => 'integer|min:0|max:4294967296|gt:start_row',
];

View File

@@ -84,8 +84,8 @@ class ListRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'date|after:1900-01-01|before:2099-12-31',
'end' => 'date|after:start|after:1900-01-01|before:2099-12-31',
'start' => 'date|after:1970-01-02|before:2038-01-17',
'end' => 'date|after:start|after:1970-01-02|before:2038-01-17',
];
}
}

View File

@@ -75,15 +75,15 @@ class TagFactory
$latitude = 0.0 === (float) $data['latitude'] ? null : (float) $data['latitude']; // intentional float
$longitude = 0.0 === (float) $data['longitude'] ? null : (float) $data['longitude']; // intentional float
$array = [
'user_id' => $this->user->id,
'user_group_id' => $this->userGroup->id,
'tag' => trim((string) $data['tag']),
'tagMode' => 'nothing',
'date' => $data['date'],
'description' => $data['description'],
'latitude' => null,
'longitude' => null,
'zoomLevel' => null,
'user_id' => $this->user->id,
'user_group_id' => $this->userGroup->id,
'tag' => trim((string) $data['tag']),
'tag_mode' => 'nothing',
'date' => $data['date'],
'description' => $data['description'],
'latitude' => null,
'longitude' => null,
'zoomLevel' => null,
];
/** @var null|Tag $tag */

View File

@@ -434,6 +434,7 @@ class GroupCollector implements GroupCollectorInterface
public function findNothing(): GroupCollectorInterface
{
Log::warning('The search engine was instructed to FIND NOTHING. This may be a bug.');
$this->query->where('transaction_groups.id', -1);
return $this;

View File

@@ -88,7 +88,9 @@ class IndexController extends Controller
/** @var Carbon $end */
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
$start->subDay();
// #10618 go to the end of the previous day.
$start->subSecond();
$ids = $accounts->pluck('id')->toArray();
Log::debug(sprintf('inactive start: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s')));
@@ -164,8 +166,8 @@ class IndexController extends Controller
/** @var Carbon $end */
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
// 2025-05-11 removed this so start is exactly the start of the month.
// $start->subDay();
// #10618 go to the end of the previous day.
$start->subSecond();
$ids = $accounts->pluck('id')->toArray();
Log::debug(sprintf('index start: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s')));

View File

@@ -107,7 +107,7 @@ class RecurrenceController extends Controller
$repetitionMoment = str_ireplace('ndom,', '', $request->get('type'));
}
if ('yearly' === $repetitionType) {
$repetitionMoment = explode(',', (string) $request->get('type'))[1] ?? '2018-01-01';
$repetitionMoment = explode(',', (string) $request->get('type'))[1] ?? '2025-01-01';
}
$actualStart->startOfDay();
$repetition = new RecurrenceRepetition();

View File

@@ -41,8 +41,8 @@ class SelectTransactionsRequest extends FormRequest
public function rules(): array
{
return [
'start' => 'required|date|after:1900-01-01|before:2099-12-31|before:end|required_with:end',
'end' => 'required|date|after:1900-01-01|before:2099-12-31|after:start|required_with:start',
'start' => 'required|date|after:1970-01-02|before:2038-01-17|before:end|required_with:end',
'end' => 'required|date|after:1970-01-02|before:2038-01-17|after:start|required_with:start',
'accounts' => 'required',
'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts',
];

View File

@@ -74,7 +74,7 @@ class TagFormRequest extends FormRequest
'tag' => $tagRule,
'id' => $idRule,
'description' => 'max:32768|min:1|nullable',
'date' => 'date|nullable|after:1984-09-17',
'date' => 'date|nullable|after:1970-01-02|before:2038-01-17',
];
return Location::requestRules($rules);

View File

@@ -40,7 +40,7 @@ class Tag extends Model
use ReturnsIntegerUserIdTrait;
use SoftDeletes;
protected $fillable = ['user_id', 'user_group_id', 'tag', 'date', 'date_tz', 'description', 'tagMode'];
protected $fillable = ['user_id', 'user_group_id', 'tag', 'date', 'date_tz', 'description', 'tag_mode'];
protected $hidden = ['zoomLevel', 'latitude', 'longitude'];

View File

@@ -312,11 +312,23 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
Log::debug(sprintf('Search for linked journals between %s and %s', $start->toW3cString(), $end->toW3cString()));
return $bill->transactionJournals()
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->leftJoin('transaction_currencies AS currency', 'currency.id', '=', 'transactions.transaction_currency_id')
->leftJoin('transaction_currencies AS foreign_currency', 'foreign_currency.id', '=', 'transactions.foreign_currency_id')
->where('transactions.amount', '>', 0)
->before($end)->after($start)->get(
[
'transaction_journals.id',
'transaction_journals.date',
'transaction_journals.transaction_group_id',
'transactions.transaction_currency_id',
'currency.code AS transaction_currency_code',
'currency.decimal_places AS transaction_currency_decimal_places',
'transactions.foreign_currency_id',
'foreign_currency.code AS foreign_currency_code',
'foreign_currency.decimal_places AS foreign_currency_decimal_places',
'transactions.amount',
'transactions.foreign_amount',
]
)
;

View File

@@ -50,9 +50,9 @@ class CurrencyForm
}
/**
* @throws FireflyException
*
* @phpstan-param view-string $view
*
* @throws FireflyException
*/
protected function currencyField(string $name, string $view, mixed $value = null, ?array $options = null): string
{

View File

@@ -149,7 +149,9 @@ class TransactionGroupEnrichment implements EnrichmentInterface
continue;
}
if (in_array($name, $this->dateFields, true)) {
$this->metaData[$entry['transaction_journal_id']][$name] = Carbon::parse($data);
Log::debug(sprintf('Meta data for "%s" is a date : "%s"', $name, $data));
$this->metaData[$entry['transaction_journal_id']][$name] = Carbon::parse($data, config('app.timezone'));
Log::debug(sprintf('Meta data for "%s" converts to: "%s"', $name, $this->metaData[$entry['transaction_journal_id']][$name]->toW3CString()));
continue;
}

View File

@@ -257,16 +257,16 @@ trait ConvertsDataTypes
try {
$carbon = Carbon::createFromFormat('Y-m-d', $value);
} catch (InvalidDateException $e) { // @phpstan-ignore-line
app('log')->error(sprintf('[1] "%s" is not a valid date: %s', $value, $e->getMessage()));
Log::error(sprintf('[1] "%s" is not a valid date: %s', $value, $e->getMessage()));
return null;
} catch (InvalidFormatException $e) { // @phpstan-ignore-line
app('log')->error(sprintf('[2] "%s" is of an invalid format: %s', $value, $e->getMessage()));
Log::error(sprintf('[2] "%s" is of an invalid format: %s', $value, $e->getMessage()));
return null;
}
if (!$carbon instanceof Carbon) {
app('log')->error(sprintf('[2] "%s" is of an invalid format.', $value));
Log::error(sprintf('[2] "%s" is of an invalid format.', $value));
return null;
}
@@ -278,11 +278,11 @@ trait ConvertsDataTypes
try {
$carbon = Carbon::parse($value);
} catch (InvalidDateException $e) { // @phpstan-ignore-line
app('log')->error(sprintf('[3] "%s" is not a valid date or time: %s', $value, $e->getMessage()));
Log::error(sprintf('[3] "%s" is not a valid date or time: %s', $value, $e->getMessage()));
return null;
} catch (InvalidFormatException $e) {
app('log')->error(sprintf('[4] "%s" is of an invalid format: %s', $value, $e->getMessage()));
Log::error(sprintf('[4] "%s" is of an invalid format: %s', $value, $e->getMessage()));
return null;
}
@@ -306,6 +306,7 @@ trait ConvertsDataTypes
protected function dateFromValue(?string $string): ?Carbon
{
if (null === $string) {
return null;
}
if ('' === $string) {
@@ -319,11 +320,11 @@ trait ConvertsDataTypes
// @ignoreException
}
if (!$carbon instanceof Carbon) {
app('log')->debug(sprintf('Invalid date: %s', $string));
Log::debug(sprintf('Invalid date: %s', $string));
return null;
}
app('log')->debug(sprintf('Date object: %s (%s)', $carbon->toW3cString(), $carbon->getTimezone()));
Log::debug(sprintf('Date object: %s (%s) from "%s"', $carbon->toW3cString(), $carbon->getTimezone(), $string));
return $carbon;
}
@@ -383,7 +384,7 @@ trait ConvertsDataTypes
Log::debug(sprintf('Exception when parsing date "%s".', $this->get($field)));
}
if (!$result instanceof Carbon) {
app('log')->debug(sprintf('Exception when parsing date "%s".', $this->get($field)));
Log::debug(sprintf('Exception when parsing date "%s".', $this->get($field)));
}
return $result;

File diff suppressed because it is too large Load Diff

View File

@@ -67,8 +67,8 @@ class AccountTransformer extends AbstractTransformer
}
// get account type:
$accountType = (string) config(sprintf('firefly.shortNamesByFullName.%s', $account->full_account_type));
$liabilityType = (string) config(sprintf('firefly.shortLiabilityNameByFullName.%s', $account->full_account_type));
$accountType = (string)config(sprintf('firefly.shortNamesByFullName.%s', $account->full_account_type));
$liabilityType = (string)config(sprintf('firefly.shortLiabilityNameByFullName.%s', $account->full_account_type));
$liabilityType = '' === $liabilityType ? null : strtolower($liabilityType);
$liabilityDirection = $account->meta['liability_direction'] ?? null;
@@ -89,10 +89,10 @@ class AccountTransformer extends AbstractTransformer
$native = null;
}
$decimalPlaces = (int) $account->meta['currency']?->decimal_places;
$decimalPlaces = (int)$account->meta['currency']?->decimal_places;
$decimalPlaces = 0 === $decimalPlaces ? 2 : $decimalPlaces;
$openingBalance = Steam::bcround($openingBalance, $decimalPlaces);
$includeNetWorth = 1 === (int) ($account->meta['include_net_worth'] ?? 0);
$openingBalanceRounded = Steam::bcround($openingBalance, $decimalPlaces);
$includeNetWorth = 1 === (int)($account->meta['include_net_worth'] ?? 0);
$longitude = $account->meta['location']['longitude'] ?? null;
$latitude = $account->meta['location']['latitude'] ?? null;
$zoomLevel = $account->meta['location']['zoom_level'] ?? null;
@@ -112,8 +112,55 @@ class AccountTransformer extends AbstractTransformer
$currentBalance = Steam::bcround($finalBalance['balance'] ?? '0', $decimalPlaces);
$nativeCurrentBalance = $this->convertToNative ? Steam::bcround($finalBalance['native_balance'] ?? '0', $native->decimal_places) : null;
// set up balances array:
$balances = [];
$balances[]
= [
'type' => 'current',
'amount' => $currentBalance,
'currency_id' => $account->meta['currency_id'] ?? null,
'currency_code' => $account->meta['currency']?->code,
'currency_symbol' => $account->meta['currency']?->symbol,
'currency_decimal_places' => $account->meta['currency']?->decimal_places,
'date' => $date->toAtomString(),
];
if (null !== $nativeCurrentBalance) {
$balances[] = [
'type' => 'native_current',
'amount' => $nativeCurrentBalance,
'currency_id' => $native instanceof TransactionCurrency ? (string)$native->id : null,
'currency_code' => $native?->code,
'currency_symbol' => $native?->symbol,
'ccurrency_decimal_places' => $native?->decimal_places,
'date' => $date->toAtomString(),
];
}
if (null !== $openingBalance) {
$balances[] = [
'type' => 'opening',
'amount' => $openingBalanceRounded,
'currency_id' => $account->meta['currency_id'] ?? null,
'currency_code' => $account->meta['currency']?->code,
'currency_symbol' => $account->meta['currency']?->symbol,
'currency_decimal_places' => $account->meta['currency']?->decimal_places,
'date' => $openingBalanceDate,
];
}
if (null !== $account->virtual_balance) {
$balances[] = [
'type' => 'virtual',
'amount' => Steam::bcround($account->virtual_balance, $decimalPlaces),
'currency_id' => $account->meta['currency_id'] ?? null,
'currency_code' => $account->meta['currency']?->code,
'currency_symbol' => $account->meta['currency']?->symbol,
'currency_decimal_places' => $account->meta['currency']?->decimal_places,
'date' => $date->toAtomString(),
];
}
return [
'id' => (string) $account->id,
'id' => (string)$account->id,
'created_at' => $account->created_at->toAtomString(),
'updated_at' => $account->updated_at->toAtomString(),
'active' => $account->active,
@@ -125,7 +172,7 @@ class AccountTransformer extends AbstractTransformer
'currency_code' => $account->meta['currency']?->code,
'currency_symbol' => $account->meta['currency']?->symbol,
'currency_decimal_places' => $account->meta['currency']?->decimal_places,
'native_currency_id' => $native instanceof TransactionCurrency ? (string) $native->id : null,
'native_currency_id' => $native instanceof TransactionCurrency ? (string)$native->id : null,
'native_currency_code' => $native?->code,
'native_currency_symbol' => $native?->symbol,
'native_currency_decimal_places' => $native?->decimal_places,
@@ -140,7 +187,7 @@ class AccountTransformer extends AbstractTransformer
'bic' => $account->meta['BIC'] ?? null,
'virtual_balance' => Steam::bcround($account->virtual_balance, $decimalPlaces),
'native_virtual_balance' => $this->convertToNative ? Steam::bcround($account->native_virtual_balance, $native->decimal_places) : null,
'opening_balance' => $openingBalance,
'opening_balance' => $openingBalanceRounded,
'native_opening_balance' => $nativeOpeningBalance,
'opening_balance_date' => $openingBalanceDate,
'liability_type' => $liabilityType,
@@ -153,6 +200,7 @@ class AccountTransformer extends AbstractTransformer
'latitude' => $latitude,
'zoom_level' => $zoomLevel,
'last_activity' => array_key_exists('last_activity', $account->meta) ? $account->meta['last_activity']->toAtomString() : null,
'balances' => $balances,
'links' => [
[
'rel' => 'self',
@@ -165,7 +213,7 @@ class AccountTransformer extends AbstractTransformer
private function getAccountRole(Account $account, string $accountType): ?string
{
$accountRole = $account->meta['account_role'] ?? null;
if ('asset' !== $accountType || '' === (string) $accountRole) {
if ('asset' !== $accountType || '' === (string)$accountRole) {
return null;
}
@@ -201,7 +249,7 @@ class AccountTransformer extends AbstractTransformer
}
$monthlyPaymentDate = $object->toAtomString();
}
if (10 !== strlen((string) $monthlyPaymentDate)) {
if (10 !== strlen((string)$monthlyPaymentDate)) {
$monthlyPaymentDate = Carbon::parse($monthlyPaymentDate, config('app.timezone'))->toAtomString();
}
}

View File

@@ -32,8 +32,10 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Models\BillDateCalculator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
/**
* Class BillTransformer
@@ -150,11 +152,11 @@ class BillTransformer extends AbstractTransformer
'id' => $bill->id,
'created_at' => $bill->created_at->toAtomString(),
'updated_at' => $bill->updated_at->toAtomString(),
'currency_id' => (string) $bill->transaction_currency_id,
'currency_id' => (string)$bill->transaction_currency_id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
'native_currency_id' => null === $default ? null : (string) $default->id,
'native_currency_id' => null === $default ? null : (string)$default->id,
'native_currency_code' => $default?->code,
'native_currency_symbol' => $default?->symbol,
'native_currency_decimal_places' => $default?->decimal_places,
@@ -171,7 +173,7 @@ class BillTransformer extends AbstractTransformer
'active' => $bill->active,
'order' => $bill->order,
'notes' => $notes,
'object_group_id' => null !== $objectGroupId ? (string) $objectGroupId : null,
'object_group_id' => null !== $objectGroupId ? (string)$objectGroupId : null,
'object_group_order' => $objectGroupOrder,
'object_group_title' => $objectGroupTitle,
@@ -194,9 +196,9 @@ class BillTransformer extends AbstractTransformer
*/
protected function paidData(Bill $bill): array
{
app('log')->debug(sprintf('Now in paidData for bill #%d', $bill->id));
Log::debug(sprintf('Now in paidData for bill #%d', $bill->id));
if (null === $this->parameters->get('start') || null === $this->parameters->get('end')) {
app('log')->debug('parameters are NULL, return empty array');
Log::debug('parameters are NULL, return empty array');
return [];
}
@@ -217,27 +219,40 @@ class BillTransformer extends AbstractTransformer
$searchStart->startOfDay();
$searchEnd->endOfDay();
app('log')->debug(sprintf('Parameters are start: %s end: %s', $start->format('Y-m-d'), $end->format('Y-m-d')));
app('log')->debug(sprintf('Search parameters are: start: %s', $searchStart->format('Y-m-d')));
Log::debug(sprintf('Parameters are start: %s end: %s', $start->format('Y-m-d'), $end->format('Y-m-d')));
Log::debug(sprintf('Search parameters are: start: %s', $searchStart->format('Y-m-d')));
// Get from database when bill was paid.
$set = $this->repository->getPaidDatesInRange($bill, $searchStart, $searchEnd);
app('log')->debug(sprintf('Count %d entries in getPaidDatesInRange()', $set->count()));
Log::debug(sprintf('Count %d entries in getPaidDatesInRange()', $set->count()));
// Grab from array the most recent payment. If none exist, fall back to the start date and pretend *that* was the last paid date.
app('log')->debug(sprintf('Grab last paid date from function, return %s if it comes up with nothing.', $start->format('Y-m-d')));
Log::debug(sprintf('Grab last paid date from function, return %s if it comes up with nothing.', $start->format('Y-m-d')));
$lastPaidDate = $this->lastPaidDate($set, $start);
app('log')->debug(sprintf('Result of lastPaidDate is %s', $lastPaidDate->format('Y-m-d')));
Log::debug(sprintf('Result of lastPaidDate is %s', $lastPaidDate->format('Y-m-d')));
// At this point the "next match" is exactly after the last time the bill was paid.
$result = [];
foreach ($set as $entry) {
$result[] = [
'transaction_group_id' => (string) $entry->transaction_group_id,
'transaction_journal_id' => (string) $entry->id,
'date' => $entry->date->format('Y-m-d'),
'date_object' => $entry->date,
$array = [
'transaction_group_id' => (string)$entry->transaction_group_id,
'transaction_journal_id' => (string)$entry->id,
'date' => $entry->date->format('Y-m-d'),
'date_object' => $entry->date,
'currency_id' => $entry->transaction_currency_id,
'currency_code' => $entry->transaction_currency_code,
'currency_decimal_places' => $entry->transaction_currency_decimal_places,
'amount' => Steam::bcround($entry->amount, $entry->transaction_currency_decimal_places),
];
if (null !== $entry->foreign_amount && null !== $entry->foreign_currency_code) {
$array['foreign_currency_id'] = $entry->foreign_currency_id;
$array['foreign_currency_code'] = $entry->foreign_currency_code;
$array['foreign_currency_decimal_places'] = $entry->foreign_currency_decimal_places;
$array['foreign_amount'] = Steam::bcround($entry->foreign_amount, $entry->foreign_currency_decimal_places);
}
$result[] = $array;
}
return $result;
@@ -265,7 +280,7 @@ class BillTransformer extends AbstractTransformer
private function getLastPaidDate(array $paidData): ?Carbon
{
app('log')->debug('getLastPaidDate()');
Log::debug('getLastPaidDate()');
$return = null;
foreach ($paidData as $entry) {
if (null !== $return) {
@@ -274,15 +289,15 @@ class BillTransformer extends AbstractTransformer
if ($current->gt($return)) {
$return = clone $current;
}
app('log')->debug(sprintf('Last paid date is: %s', $return->format('Y-m-d')));
Log::debug(sprintf('Last paid date is: %s', $return->format('Y-m-d')));
}
if (null === $return) {
/** @var Carbon $return */
$return = $entry['date_object'];
app('log')->debug(sprintf('Last paid date is: %s', $return->format('Y-m-d')));
Log::debug(sprintf('Last paid date is: %s', $return->format('Y-m-d')));
}
}
app('log')->debug(sprintf('Last paid date is: "%s"', $return?->format('Y-m-d')));
Log::debug(sprintf('Last paid date is: "%s"', $return?->format('Y-m-d')));
return $return;
}

View File

@@ -220,12 +220,12 @@ class TransactionGroupTransformer extends AbstractTransformer
'sepa_ci' => $transaction['meta']['sepa_ci'] ?? null,
'sepa_batch_id' => $transaction['meta']['sepa_batch_id'] ?? null,
'interest_date' => $transaction['meta_date']['interest_date'] ?? null,
'book_date' => $transaction['meta_date']['book_date'] ?? null,
'process_date' => $transaction['meta_date']['process_date'] ?? null,
'due_date' => $transaction['meta_date']['due_date'] ?? null,
'payment_date' => $transaction['meta_date']['payment_date'] ?? null,
'invoice_date' => $transaction['meta_date']['invoice_date'] ?? null,
'interest_date' => array_key_exists('interest_date', $transaction['meta_date']) ? $transaction['meta_date']['interest_date']->toW3CString() : null,
'book_date' => array_key_exists('book_date', $transaction['meta_date']) ? $transaction['meta_date']['book_date']->toW3CString() : null,
'process_date' => array_key_exists('process_date', $transaction['meta_date']) ? $transaction['meta_date']['process_date']->toW3CString() : null,
'due_date' => array_key_exists('due_date', $transaction['meta_date']) ? $transaction['meta_date']['due_date']->toW3CString() : null,
'payment_date' => array_key_exists('payment_date', $transaction['meta_date']) ? $transaction['meta_date']['payment_date']->toW3CString() : null,
'invoice_date' => array_key_exists('invoice_date', $transaction['meta_date']) ? $transaction['meta_date']['invoice_date']->toW3CString() : null,
// location data
'longitude' => $transaction['location']['longitude'],
'latitude' => $transaction['location']['latitude'],

View File

@@ -3,6 +3,21 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## 6.2.21 - 2025-07-18
### Added
- Debug information to search engine.
### Changed
- Rename table field for postgres databases.
### Fixed
- [Issue 10581](https://github.com/firefly-iii/firefly-iii/issues/10581) (Epoch doesn't fit in a PHP integer error on 32-bit systems due to strict date validation) reported by @kksandr7
- [Discussion 10601](https://github.com/orgs/firefly-iii/discussions/10601) (Edit a transaction will result in an incorrect date) started by @MasterZhang007
## 6.2.20 - 2025-07-02
### Changed

201
composer.lock generated
View File

@@ -1879,16 +1879,16 @@
},
{
"name": "laravel/framework",
"version": "v12.19.3",
"version": "v12.21.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "4e6ec689ef704bb4bd282f29d9dd658dfb4fb262"
"reference": "ac8c4e73bf1b5387b709f7736d41427e6af1c93b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/4e6ec689ef704bb4bd282f29d9dd658dfb4fb262",
"reference": "4e6ec689ef704bb4bd282f29d9dd658dfb4fb262",
"url": "https://api.github.com/repos/laravel/framework/zipball/ac8c4e73bf1b5387b709f7736d41427e6af1c93b",
"reference": "ac8c4e73bf1b5387b709f7736d41427e6af1c93b",
"shasum": ""
},
"require": {
@@ -2090,7 +2090,7 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2025-06-18T12:56:23+00:00"
"time": "2025-07-22T15:41:55+00:00"
},
{
"name": "laravel/passport",
@@ -2170,16 +2170,16 @@
},
{
"name": "laravel/prompts",
"version": "v0.3.5",
"version": "v0.3.6",
"source": {
"type": "git",
"url": "https://github.com/laravel/prompts.git",
"reference": "57b8f7efe40333cdb925700891c7d7465325d3b1"
"reference": "86a8b692e8661d0fb308cec64f3d176821323077"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/prompts/zipball/57b8f7efe40333cdb925700891c7d7465325d3b1",
"reference": "57b8f7efe40333cdb925700891c7d7465325d3b1",
"url": "https://api.github.com/repos/laravel/prompts/zipball/86a8b692e8661d0fb308cec64f3d176821323077",
"reference": "86a8b692e8661d0fb308cec64f3d176821323077",
"shasum": ""
},
"require": {
@@ -2223,22 +2223,22 @@
"description": "Add beautiful and user-friendly forms to your command-line applications.",
"support": {
"issues": "https://github.com/laravel/prompts/issues",
"source": "https://github.com/laravel/prompts/tree/v0.3.5"
"source": "https://github.com/laravel/prompts/tree/v0.3.6"
},
"time": "2025-02-11T13:34:40+00:00"
"time": "2025-07-07T14:17:42+00:00"
},
{
"name": "laravel/sanctum",
"version": "v4.1.1",
"version": "v4.2.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/sanctum.git",
"reference": "a360a6a1fd2400ead4eb9b6a9c1bb272939194f5"
"reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/sanctum/zipball/a360a6a1fd2400ead4eb9b6a9c1bb272939194f5",
"reference": "a360a6a1fd2400ead4eb9b6a9c1bb272939194f5",
"url": "https://api.github.com/repos/laravel/sanctum/zipball/fd6df4f79f48a72992e8d29a9c0ee25422a0d677",
"reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677",
"shasum": ""
},
"require": {
@@ -2289,7 +2289,7 @@
"issues": "https://github.com/laravel/sanctum/issues",
"source": "https://github.com/laravel/sanctum"
},
"time": "2025-04-23T13:03:38+00:00"
"time": "2025-07-09T19:45:24+00:00"
},
{
"name": "laravel/serializable-closure",
@@ -2354,16 +2354,16 @@
},
{
"name": "laravel/slack-notification-channel",
"version": "v3.5.0",
"version": "v3.6.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/slack-notification-channel.git",
"reference": "b9448136c2e93f51f0d603d05d6bf64412e5727c"
"reference": "642677a57490eebccb7e9fb666f5a5379c6e3459"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/b9448136c2e93f51f0d603d05d6bf64412e5727c",
"reference": "b9448136c2e93f51f0d603d05d6bf64412e5727c",
"url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/642677a57490eebccb7e9fb666f5a5379c6e3459",
"reference": "642677a57490eebccb7e9fb666f5a5379c6e3459",
"shasum": ""
},
"require": {
@@ -2413,9 +2413,9 @@
],
"support": {
"issues": "https://github.com/laravel/slack-notification-channel/issues",
"source": "https://github.com/laravel/slack-notification-channel/tree/v3.5.0"
"source": "https://github.com/laravel/slack-notification-channel/tree/v3.6.0"
},
"time": "2025-02-23T14:43:55+00:00"
"time": "2025-06-26T16:51:38+00:00"
},
{
"name": "laravel/ui",
@@ -2619,16 +2619,16 @@
},
{
"name": "league/commonmark",
"version": "2.7.0",
"version": "2.7.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
"reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405"
"reference": "10732241927d3971d28e7ea7b5712721fa2296ca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/6fbb36d44824ed4091adbcf4c7d4a3923cdb3405",
"reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/10732241927d3971d28e7ea7b5712721fa2296ca",
"reference": "10732241927d3971d28e7ea7b5712721fa2296ca",
"shasum": ""
},
"require": {
@@ -2657,7 +2657,7 @@
"symfony/process": "^5.4 | ^6.0 | ^7.0",
"symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0",
"unleashedtech/php-coding-standard": "^3.1.1",
"vimeo/psalm": "^4.24.0 || ^5.0.0"
"vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0"
},
"suggest": {
"symfony/yaml": "v2.3+ required if using the Front Matter extension"
@@ -2722,7 +2722,7 @@
"type": "tidelift"
}
],
"time": "2025-05-05T12:20:28+00:00"
"time": "2025-07-20T12:47:49+00:00"
},
{
"name": "league/config",
@@ -5101,16 +5101,16 @@
},
{
"name": "predis/predis",
"version": "v3.0.1",
"version": "v3.1.0",
"source": {
"type": "git",
"url": "https://github.com/predis/predis.git",
"reference": "34fb0a7da0330df1bab4280fcac4afdeeccc3edf"
"reference": "202e0c5322b906ec4c761c0cefebad6d0959a699"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/predis/predis/zipball/34fb0a7da0330df1bab4280fcac4afdeeccc3edf",
"reference": "34fb0a7da0330df1bab4280fcac4afdeeccc3edf",
"url": "https://api.github.com/repos/predis/predis/zipball/202e0c5322b906ec4c761c0cefebad6d0959a699",
"reference": "202e0c5322b906ec4c761c0cefebad6d0959a699",
"shasum": ""
},
"require": {
@@ -5152,7 +5152,7 @@
],
"support": {
"issues": "https://github.com/predis/predis/issues",
"source": "https://github.com/predis/predis/tree/v3.0.1"
"source": "https://github.com/predis/predis/tree/v3.1.0"
},
"funding": [
{
@@ -5160,7 +5160,7 @@
"type": "github"
}
],
"time": "2025-05-16T18:30:32+00:00"
"time": "2025-07-22T15:37:44+00:00"
},
{
"name": "psr/cache",
@@ -9840,16 +9840,16 @@
"packages-dev": [
{
"name": "barryvdh/laravel-debugbar",
"version": "v3.15.4",
"version": "v3.16.0",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-debugbar.git",
"reference": "c0667ea91f7185f1e074402c5788195e96bf8106"
"reference": "f265cf5e38577d42311f1a90d619bcd3740bea23"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/c0667ea91f7185f1e074402c5788195e96bf8106",
"reference": "c0667ea91f7185f1e074402c5788195e96bf8106",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/f265cf5e38577d42311f1a90d619bcd3740bea23",
"reference": "f265cf5e38577d42311f1a90d619bcd3740bea23",
"shasum": ""
},
"require": {
@@ -9857,7 +9857,7 @@
"illuminate/session": "^9|^10|^11|^12",
"illuminate/support": "^9|^10|^11|^12",
"php": "^8.1",
"php-debugbar/php-debugbar": "~2.1.1",
"php-debugbar/php-debugbar": "~2.2.0",
"symfony/finder": "^6|^7"
},
"require-dev": {
@@ -9877,7 +9877,7 @@
]
},
"branch-alias": {
"dev-master": "3.15-dev"
"dev-master": "3.16-dev"
}
},
"autoload": {
@@ -9909,7 +9909,7 @@
],
"support": {
"issues": "https://github.com/barryvdh/laravel-debugbar/issues",
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.15.4"
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.16.0"
},
"funding": [
{
@@ -9921,24 +9921,24 @@
"type": "github"
}
],
"time": "2025-04-16T06:32:06+00:00"
"time": "2025-07-14T11:56:43+00:00"
},
{
"name": "barryvdh/laravel-ide-helper",
"version": "v3.5.5",
"version": "v3.6.0",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-ide-helper.git",
"reference": "8d441ec99f8612b942b55f5183151d91591b618a"
"reference": "8d00250cba25728373e92c1d8dcebcbf64623d29"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/8d441ec99f8612b942b55f5183151d91591b618a",
"reference": "8d441ec99f8612b942b55f5183151d91591b618a",
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/8d00250cba25728373e92c1d8dcebcbf64623d29",
"reference": "8d00250cba25728373e92c1d8dcebcbf64623d29",
"shasum": ""
},
"require": {
"barryvdh/reflection-docblock": "^2.3",
"barryvdh/reflection-docblock": "^2.4",
"composer/class-map-generator": "^1.0",
"ext-json": "*",
"illuminate/console": "^11.15 || ^12",
@@ -10003,7 +10003,7 @@
],
"support": {
"issues": "https://github.com/barryvdh/laravel-ide-helper/issues",
"source": "https://github.com/barryvdh/laravel-ide-helper/tree/v3.5.5"
"source": "https://github.com/barryvdh/laravel-ide-helper/tree/v3.6.0"
},
"funding": [
{
@@ -10015,20 +10015,20 @@
"type": "github"
}
],
"time": "2025-02-11T13:59:46+00:00"
"time": "2025-07-17T20:11:57+00:00"
},
{
"name": "barryvdh/reflection-docblock",
"version": "v2.3.1",
"version": "v2.4.0",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/ReflectionDocBlock.git",
"reference": "b6ff9f93603561f50e53b64310495d20b8dff5d8"
"reference": "d103774cbe7e94ddee7e4870f97f727b43fe7201"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/b6ff9f93603561f50e53b64310495d20b8dff5d8",
"reference": "b6ff9f93603561f50e53b64310495d20b8dff5d8",
"url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/d103774cbe7e94ddee7e4870f97f727b43fe7201",
"reference": "d103774cbe7e94ddee7e4870f97f727b43fe7201",
"shasum": ""
},
"require": {
@@ -10065,9 +10065,9 @@
}
],
"support": {
"source": "https://github.com/barryvdh/ReflectionDocBlock/tree/v2.3.1"
"source": "https://github.com/barryvdh/ReflectionDocBlock/tree/v2.4.0"
},
"time": "2025-01-18T19:26:32+00:00"
"time": "2025-07-17T06:07:30+00:00"
},
{
"name": "cloudcreativity/json-api-testing",
@@ -10471,16 +10471,16 @@
},
{
"name": "larastan/larastan",
"version": "v3.5.0",
"version": "v3.6.0",
"source": {
"type": "git",
"url": "https://github.com/larastan/larastan.git",
"reference": "e8ccd73008487ba91da9877b373f8c447743f1ce"
"reference": "6431d010dd383a9279eb8874a76ddb571738564a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/larastan/larastan/zipball/e8ccd73008487ba91da9877b373f8c447743f1ce",
"reference": "e8ccd73008487ba91da9877b373f8c447743f1ce",
"url": "https://api.github.com/repos/larastan/larastan/zipball/6431d010dd383a9279eb8874a76ddb571738564a",
"reference": "6431d010dd383a9279eb8874a76ddb571738564a",
"shasum": ""
},
"require": {
@@ -10548,7 +10548,7 @@
],
"support": {
"issues": "https://github.com/larastan/larastan/issues",
"source": "https://github.com/larastan/larastan/tree/v3.5.0"
"source": "https://github.com/larastan/larastan/tree/v3.6.0"
},
"funding": [
{
@@ -10556,7 +10556,7 @@
"type": "github"
}
],
"time": "2025-06-19T22:41:50+00:00"
"time": "2025-07-11T06:52:52+00:00"
},
{
"name": "laravel-json-api/testing",
@@ -10708,16 +10708,16 @@
},
{
"name": "myclabs/deep-copy",
"version": "1.13.1",
"version": "1.13.3",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c"
"reference": "faed855a7b5f4d4637717c2b3863e277116beb36"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c",
"reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/faed855a7b5f4d4637717c2b3863e277116beb36",
"reference": "faed855a7b5f4d4637717c2b3863e277116beb36",
"shasum": ""
},
"require": {
@@ -10756,7 +10756,7 @@
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.1"
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.3"
},
"funding": [
{
@@ -10764,7 +10764,7 @@
"type": "tidelift"
}
],
"time": "2025-04-29T12:36:36+00:00"
"time": "2025-07-05T12:25:42+00:00"
},
{
"name": "nikic/php-parser",
@@ -10944,16 +10944,16 @@
},
{
"name": "php-debugbar/php-debugbar",
"version": "v2.1.6",
"version": "v2.2.4",
"source": {
"type": "git",
"url": "https://github.com/php-debugbar/php-debugbar.git",
"reference": "16fa68da5617220594aa5e33fa9de415f94784a0"
"reference": "3146d04671f51f69ffec2a4207ac3bdcf13a9f35"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/16fa68da5617220594aa5e33fa9de415f94784a0",
"reference": "16fa68da5617220594aa5e33fa9de415f94784a0",
"url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/3146d04671f51f69ffec2a4207ac3bdcf13a9f35",
"reference": "3146d04671f51f69ffec2a4207ac3bdcf13a9f35",
"shasum": ""
},
"require": {
@@ -10961,6 +10961,9 @@
"psr/log": "^1|^2|^3",
"symfony/var-dumper": "^4|^5|^6|^7"
},
"replace": {
"maximebf/debugbar": "self.version"
},
"require-dev": {
"dbrekelmans/bdi": "^1",
"phpunit/phpunit": "^8|^9",
@@ -10975,7 +10978,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
"dev-master": "2.1-dev"
}
},
"autoload": {
@@ -11008,9 +11011,9 @@
],
"support": {
"issues": "https://github.com/php-debugbar/php-debugbar/issues",
"source": "https://github.com/php-debugbar/php-debugbar/tree/v2.1.6"
"source": "https://github.com/php-debugbar/php-debugbar/tree/v2.2.4"
},
"time": "2025-02-21T17:47:03+00:00"
"time": "2025-07-22T14:01:30+00:00"
},
{
"name": "phpstan/extension-installer",
@@ -11062,16 +11065,16 @@
},
{
"name": "phpstan/phpstan",
"version": "2.1.17",
"version": "2.1.19",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "89b5ef665716fa2a52ecd2633f21007a6a349053"
"reference": "473a8c30e450d87099f76313edcbb90852f9afdf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/89b5ef665716fa2a52ecd2633f21007a6a349053",
"reference": "89b5ef665716fa2a52ecd2633f21007a6a349053",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/473a8c30e450d87099f76313edcbb90852f9afdf",
"reference": "473a8c30e450d87099f76313edcbb90852f9afdf",
"shasum": ""
},
"require": {
@@ -11116,7 +11119,7 @@
"type": "github"
}
],
"time": "2025-05-21T20:55:28+00:00"
"time": "2025-07-21T19:58:24+00:00"
},
{
"name": "phpstan/phpstan-deprecation-rules",
@@ -11167,16 +11170,16 @@
},
{
"name": "phpstan/phpstan-strict-rules",
"version": "2.0.4",
"version": "2.0.6",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-strict-rules.git",
"reference": "3e139cbe67fafa3588e1dbe27ca50f31fdb6236a"
"reference": "f9f77efa9de31992a832ff77ea52eb42d675b094"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/3e139cbe67fafa3588e1dbe27ca50f31fdb6236a",
"reference": "3e139cbe67fafa3588e1dbe27ca50f31fdb6236a",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/f9f77efa9de31992a832ff77ea52eb42d675b094",
"reference": "f9f77efa9de31992a832ff77ea52eb42d675b094",
"shasum": ""
},
"require": {
@@ -11209,9 +11212,9 @@
"description": "Extra strict and opinionated rules for PHPStan",
"support": {
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.4"
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.6"
},
"time": "2025-03-18T11:42:40+00:00"
"time": "2025-07-21T12:19:29+00:00"
},
{
"name": "phpunit/php-code-coverage",
@@ -11549,16 +11552,16 @@
},
{
"name": "phpunit/phpunit",
"version": "12.2.5",
"version": "12.2.7",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "b71849b29f7a8d7574e4401873cb8b539896613f"
"reference": "8b1348b254e5959acaf1539c6bd790515fb49414"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b71849b29f7a8d7574e4401873cb8b539896613f",
"reference": "b71849b29f7a8d7574e4401873cb8b539896613f",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8b1348b254e5959acaf1539c6bd790515fb49414",
"reference": "8b1348b254e5959acaf1539c6bd790515fb49414",
"shasum": ""
},
"require": {
@@ -11568,7 +11571,7 @@
"ext-mbstring": "*",
"ext-xml": "*",
"ext-xmlwriter": "*",
"myclabs/deep-copy": "^1.13.1",
"myclabs/deep-copy": "^1.13.3",
"phar-io/manifest": "^2.0.4",
"phar-io/version": "^3.2.1",
"php": ">=8.3",
@@ -11626,7 +11629,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.2.5"
"source": "https://github.com/sebastianbergmann/phpunit/tree/12.2.7"
},
"funding": [
{
@@ -11650,25 +11653,25 @@
"type": "tidelift"
}
],
"time": "2025-06-27T04:37:55+00:00"
"time": "2025-07-11T04:11:13+00:00"
},
{
"name": "rector/rector",
"version": "2.1.0",
"version": "2.1.2",
"source": {
"type": "git",
"url": "https://github.com/rectorphp/rector.git",
"reference": "d513dea45a94394b660e15c155d1fa27826f8e30"
"reference": "40a71441dd73fa150a66102f5ca1364c44fc8fff"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rectorphp/rector/zipball/d513dea45a94394b660e15c155d1fa27826f8e30",
"reference": "d513dea45a94394b660e15c155d1fa27826f8e30",
"url": "https://api.github.com/repos/rectorphp/rector/zipball/40a71441dd73fa150a66102f5ca1364c44fc8fff",
"reference": "40a71441dd73fa150a66102f5ca1364c44fc8fff",
"shasum": ""
},
"require": {
"php": "^7.4|^8.0",
"phpstan/phpstan": "^2.1.17"
"phpstan/phpstan": "^2.1.18"
},
"conflict": {
"rector/rector-doctrine": "*",
@@ -11702,7 +11705,7 @@
],
"support": {
"issues": "https://github.com/rectorphp/rector/issues",
"source": "https://github.com/rectorphp/rector/tree/2.1.0"
"source": "https://github.com/rectorphp/rector/tree/2.1.2"
},
"funding": [
{
@@ -11710,7 +11713,7 @@
"type": "github"
}
],
"time": "2025-06-24T20:26:57+00:00"
"time": "2025-07-17T19:30:06+00:00"
},
{
"name": "sebastian/cli-parser",

View File

@@ -78,9 +78,10 @@ return [
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
// see cer.php for exchange rates feature flag.
],
'version' => '6.2.20',
'version' => 'develop/2025-07-24',
'build_time' => 1753333121,
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 25,
'db_version' => 26,
// generic settings
'maxUploadSize' => 1073741824, // 1 GB

View File

@@ -0,0 +1,47 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
try {
// normal case
Schema::table('tags', static function (Blueprint $table): void {
if (Schema::hasColumn('tags', 'tagMode') && !Schema::hasColumn('piggy_banks', 'tag_mode')) {
$table->renameColumn('tagMode', 'tag_mode');
}
});
// lower case just in case (haha)
Schema::table('tags', static function (Blueprint $table): void {
if (Schema::hasColumn('tags', 'tagmode') && !Schema::hasColumn('piggy_banks', 'tag_mode')) {
$table->renameColumn('tagmode', 'tag_mode');
}
});
} catch (RuntimeException $e) {
Log::error(sprintf('Could not rename column: %s', $e->getMessage()));
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
try {
Schema::table('tags', static function (Blueprint $table): void {
if (Schema::hasColumn('tags', 'tag_mode') && !Schema::hasColumn('piggy_banks', 'tagMode')) {
$table->renameColumn('tag_mode', 'tagMode');
}
});
} catch (RuntimeException $e) {
Log::error(sprintf('Could not rename column: %s', $e->getMessage()));
}
}
};

814
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,7 @@
"devDependencies": {
"@johmun/vue-tags-input": "^2",
"@vue/compiler-sfc": "^3.5.11",
"axios": "^1.8",
"axios": "^1.11",
"bootstrap-sass": "^3",
"cross-env": "^7.0",
"font-awesome": "^4.7.0",

View File

@@ -4,7 +4,7 @@
"administrations_index_menu": "Administracions financeres",
"expires_at": "Caduca a les",
"temp_administrations_introduction": "Firefly III aviat podr\u00e0 gestionar diverses administracions financeres. Ara mateix, nom\u00e9s en teniu una. Podeu definir el t\u00edtol d'aquesta administraci\u00f3 i la seva moneda nativa. Aix\u00f2 substitueix la configuraci\u00f3 anterior on definiu la vostra \"moneda predeterminada\". Aquesta configuraci\u00f3 ara est\u00e0 vinculada a l'administraci\u00f3 financera i pot ser diferent per a cada administraci\u00f3.",
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
"administration_currency_form_help": "La p\u00e0gina pot trigar molt a carregar-se si canvieu la moneda nativa, ja que pot ser que la transacci\u00f3 s'hagi de convertir a la vostra (nova) moneda nativa.",
"administrations_page_edit_sub_title_js": "Edita l'administraci\u00f3 financera \"{title}\"",
"table": "Taula",
"welcome_back": "Qu\u00e8 est\u00e0 passant?",
@@ -16,10 +16,10 @@
"select_source_account": "Per favor, selecciona o escriu un nom de compte d'origen v\u00e0lid",
"split_transaction_title": "Descripci\u00f3 de la transacci\u00f3 dividida",
"errors_submission": "Hi ha hagut un error amb el teu enviament. Per favor, revisa els errors de sota.",
"is_reconciled": "Is reconciled",
"is_reconciled": "Est\u00e0 reconciliat",
"split": "Dividir",
"single_split": "Divisi\u00f3",
"not_enough_currencies": "Not enough currencies",
"not_enough_currencies": "No hi ha prou monedes",
"not_enough_currencies_enabled": "Si tens nom\u00e9s una divisa habilitada, no cal afegir tipus de canvi.",
"transaction_stored_link": "La <a href=\"transactions\/show\/{ID}\">Transacci\u00f3 #{ID} (\"{title}\")<\/a> s'ha desat.",
"webhook_stored_link": "S'ha desat <a href=\"webhooks\/show\/{ID}\">el Webook #{ID} (\"{title}\")<\/a> correctament.",
@@ -43,7 +43,7 @@
"submit": "Enviar",
"amount": "Import",
"date": "Data",
"is_reconciled_fields_dropped": "Because this transaction is reconciled, you will not be able to update the accounts, nor the amount(s) unless you remove the reconciliation flag.",
"is_reconciled_fields_dropped": "Com que aquesta transacci\u00f3 est\u00e0 reconciliada, no podreu actualitzar els comptes ni l'import o imports tret que elimineu el senyalador de reconciliaci\u00f3.",
"tags": "Etiquetes",
"no_budget": "(cap pressupost)",
"no_bill": "(cap subscripci\u00f3)",
@@ -141,9 +141,9 @@
"visit_webhook_url": "Visitar l'URL del webhook",
"reset_webhook_secret": "Reiniciar el secret del webhook",
"header_exchange_rates": "Tipus de canvi",
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">the documentation<\/a>.",
"exchange_rates_intro": "Firefly III permet descarregar i utilitzar tipus de canvi. M\u00e9s informaci\u00f3 sobre aix\u00f2 a la <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">documentaci\u00f3<\/a>.",
"exchange_rates_from_to": "Entre {from} i {to} (i a la inversa)",
"exchange_rates_intro_rates": "Firefly III uses the following exchange rates. The inverse is automatically calculated when it is not provided. If no exchange rate exists for the date of the transaction, Firefly III will go back in time to find one. If none are present, the rate \"1\" will be used.",
"exchange_rates_intro_rates": "Firefly III utilitza els tipus de canvi seg\u00fcents. L'invers es calcula autom\u00e0ticament quan no es proporciona. Si no existeix cap tipus de canvi per a la data de la transacci\u00f3, Firefly III tornar\u00e0 enrere en el temps per trobar-ne un. Si no n'hi ha cap, s'utilitzar\u00e0 el tipus \"1\".",
"header_exchange_rates_rates": "Tipus de canvi",
"header_exchange_rates_table": "Taula amb els tipus de canvi",
"help_rate_form": "El dia d'avui, quants {to} obtindr\u00e0s amb un {from}?",

View File

@@ -1,11 +1,11 @@
{
"firefly": {
"administrations_page_title": "Financial administrations",
"administrations_index_menu": "Financial administrations",
"administrations_page_title": "Spr\u00e1va financ\u00ed",
"administrations_index_menu": "Spr\u00e1va financ\u00ed",
"expires_at": "Expires at",
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
"temp_administrations_introduction": "Firefly III brzy z\u00edsk\u00e1 mo\u017enost spravovat v\u00edce spr\u00e1v financ\u00ed. Moment\u00e1ln\u011b m\u00e1te pouze jednu. M\u016f\u017eete nastavit n\u00e1zev t\u00e9to spr\u00e1vy a jej\u00ed m\u00edstn\u00ed m\u011bnu. Toto nahrazuje p\u0159edchoz\u00ed nastaven\u00ed, kde jste nastavovali \u201ev\u00fdchoz\u00ed m\u011bnu\u201c. Toto nastaven\u00ed je nyn\u00ed v\u00e1z\u00e1no na spr\u00e1vu financ\u00ed a m\u016f\u017ee se li\u0161it pro ka\u017edou spr\u00e1vu.",
"administration_currency_form_help": "Pokud zm\u011bn\u00edte m\u00edstn\u00ed m\u011bnu, m\u016f\u017ee na\u010dten\u00ed str\u00e1nky trvat d\u00e9le, proto\u017ee transakce mo\u017en\u00e1 bude pot\u0159eba p\u0159ev\u00e9st na va\u0161i (novou) m\u00edstn\u00ed m\u011bnu.",
"administrations_page_edit_sub_title_js": "Upravit spr\u00e1vu financ\u00ed \u201e{title}\u201c",
"table": "Tabulka",
"welcome_back": "Jak to jde?",
"flash_error": "Chyba!",
@@ -20,14 +20,14 @@
"split": "Rozd\u011blit",
"single_split": "Rozd\u011blit",
"not_enough_currencies": "Not enough currencies",
"not_enough_currencies_enabled": "If you have just one currency enabled, there is no need to add exchange rates.",
"not_enough_currencies_enabled": "Pokud m\u00e1te povolenou pouze jednu m\u011bnu, nemus\u00edte p\u0159id\u00e1vat sm\u011bnn\u00e9 kurzy.",
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Transakce #{ID} (\"{title}\")<\/a> byla ulo\u017eena.",
"webhook_stored_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID} (\"{title}\")<\/a> byl ulo\u017een.",
"webhook_updated_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID}<\/a> (\"{title}\") byl aktualizov\u00e1n.",
"transaction_updated_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID}<\/a> (\"{title}\") has been updated.",
"transaction_new_stored_link": "<a href=\"transactions\/show\/{ID}\">Transakce #{ID}<\/a> byla ulo\u017eena.",
"transaction_journal_information": "Informace o transakci",
"submission_options": "Submission options",
"submission_options": "Mo\u017enosti polo\u017eky",
"apply_rules_checkbox": "Aplikovat pravidla",
"fire_webhooks_checkbox": "Spustit webhooky",
"no_budget_pointer": "<a href=\"budgets\">Zde<\/a> si m\u016f\u017eete spravovat rozpo\u010dty, kter\u00e9 v\u00e1m mohou pomoci sledovat v\u00fddaje.",
@@ -36,17 +36,17 @@
"hidden_fields_preferences": "Dal\u0161\u00ed vlastnosti transakc\u00ed m\u016f\u017eete zaznamenat kdy\u017e je zapnete v <a href=\"preferences\">nastaven\u00ed<\/a>.",
"destination_account": "C\u00edlov\u00fd \u00fa\u010det",
"add_another_split": "P\u0159idat dal\u0161\u00ed roz\u00fa\u010dtov\u00e1n\u00ed",
"submission": "Submission",
"submission": "Polo\u017eka",
"stored_journal": "\u00dasp\u011b\u0161n\u011b vytvo\u0159ena nov\u00e1 transakce \u201e:description\u201c",
"create_another": "Po ulo\u017een\u00ed se vr\u00e1tit sem pro vytvo\u0159en\u00ed dal\u0161\u00ed.",
"reset_after": "Po odesl\u00e1n\u00ed vymazat obsah formul\u00e1\u0159e",
"submit": "Odeslat",
"submit": "Potvrdit",
"amount": "\u010c\u00e1stka",
"date": "Datum",
"is_reconciled_fields_dropped": "Because this transaction is reconciled, you will not be able to update the accounts, nor the amount(s) unless you remove the reconciliation flag.",
"tags": "\u0160t\u00edtky",
"no_budget": "(\u017e\u00e1dn\u00fd rozpo\u010det)",
"no_bill": "(no subscription)",
"no_bill": "(bez pravideln\u00e9 platby)",
"category": "Kategorie",
"attachments": "P\u0159\u00edlohy",
"notes": "Pozn\u00e1mky",
@@ -62,7 +62,7 @@
"destination_account_reconciliation": "C\u00edlov\u00fd \u00fa\u010det odsouhlasen\u00e9 transakce nelze upravit.",
"source_account_reconciliation": "Nem\u016f\u017eete upravovat zdrojov\u00fd \u00fa\u010det srovn\u00e1vac\u00ed transakce.",
"budget": "Rozpo\u010det",
"bill": "Subscription",
"bill": "Pravideln\u00e1 platba",
"you_create_withdrawal": "Vytv\u00e1\u0159\u00edte v\u00fdb\u011br.",
"you_create_transfer": "Vytv\u00e1\u0159\u00edte p\u0159evod.",
"you_create_deposit": "Vytv\u00e1\u0159\u00edte vklad.",
@@ -72,27 +72,27 @@
"profile_whoops": "Omlouv\u00e1me se, tohle n\u011bjak nefunguje",
"profile_something_wrong": "Something went wrong!",
"profile_try_again": "Something went wrong. Please try again.",
"profile_oauth_clients": "OAuth Clients",
"profile_oauth_clients": "Klienti OAuth",
"profile_oauth_no_clients": "Zat\u00edm jste nevytvo\u0159ili OAuth klienty.",
"profile_oauth_clients_header": "Klienti",
"profile_oauth_client_id": "ID z\u00e1kazn\u00edka",
"profile_oauth_client_id": "ID klienta",
"profile_oauth_client_name": "Jm\u00e9no",
"profile_oauth_client_secret": "Tajn\u00fd kl\u00ed\u010d",
"profile_oauth_client_secret": "Tajn\u00e9",
"profile_oauth_create_new_client": "Vytvo\u0159it nov\u00e9ho klienta",
"profile_oauth_create_client": "Vytvo\u0159it klienta",
"profile_oauth_edit_client": "Upravit klienta",
"profile_oauth_name_help": "N\u011bco \u010demu va\u0161i u\u017eivatel\u00e9 budou d\u016fv\u011b\u0159ovat.",
"profile_oauth_redirect_url": "P\u0159esm\u011brovat URL adresu",
"profile_oauth_clients_external_auth": "Pokud pro ov\u011b\u0159ov\u00e1n\u00ed pou\u017e\u00edv\u00e1te extern\u00ed slu\u017ebu, nap\u0159\u00edklad Authelia, OAuth klienti nemus\u00ed fungovat spr\u00e1vn\u011b. M\u00edsto toho m\u016f\u017eete pou\u017e\u00edt Personal Access Token.",
"profile_oauth_clients_external_auth": "Pokud pro ov\u011b\u0159ov\u00e1n\u00ed pou\u017e\u00edv\u00e1te extern\u00ed slu\u017ebu, nap\u0159\u00edklad Authelia, OAuth klienti nemus\u00ed fungovat spr\u00e1vn\u011b. M\u00edsto toho m\u016f\u017eete pou\u017e\u00edt osobn\u00ed p\u0159\u00edstupov\u00fd token.",
"profile_oauth_redirect_url_help": "Callback URL va\u0161\u00ed aplikace.",
"profile_authorized_apps": "Authorized applications",
"profile_authorized_clients": "Autorizovan\u00ed klienti",
"profile_scopes": "Scopes",
"profile_revoke": "Revoke",
"profile_personal_access_tokens": "Personal Access Token",
"profile_personal_access_token": "Personal Access Token",
"profile_personal_access_token_explanation": "Tohle je v\u00e1\u0161 nov\u00fd p\u0159\u00edstupov\u00fd token. Tohle je naposled kdy ho vid\u00edte, tak\u017ee ho neztra\u0165te! M\u016f\u017eete ho pou\u017e\u00edt pro vol\u00e1n\u00ed API.",
"profile_no_personal_access_token": "Je\u0161t\u011b jste nevytvo\u0159ili \u017e\u00e1dn\u00e9 p\u0159\u00edstupov\u00e9 tokeny.",
"profile_personal_access_tokens": "Osobn\u00ed p\u0159\u00edstupov\u00fd token",
"profile_personal_access_token": "Osobn\u00ed p\u0159\u00edstupov\u00e9 tokeny",
"profile_personal_access_token_explanation": "Zde je v\u00e1\u0161 nov\u00fd osobn\u00ed p\u0159\u00edstupov\u00fd token. Toto je jedin\u00fd okam\u017eik, kdy jej uvid\u00edte, tak\u017ee ho neztra\u0165te! Nyn\u00ed m\u016f\u017eete tento token pou\u017e\u00edt k odes\u00edl\u00e1n\u00ed po\u017eadavk\u016f na API.",
"profile_no_personal_access_token": "Zat\u00edm jste nevytvo\u0159ili \u017e\u00e1dn\u00e9 osobn\u00ed p\u0159\u00edstupov\u00e9 tokeny.",
"profile_create_new_token": "Vytvo\u0159it nov\u00fd token",
"profile_create_token": "Vytvo\u0159it token",
"profile_create": "Vytvo\u0159it",
@@ -123,7 +123,7 @@
"create_new_webhook": "Vytvo\u0159it nov\u00fd webhook",
"webhooks": "Webhooky",
"webhook_trigger_form_help": "Ur\u010dit, na kterou ud\u00e1lost se spust\u00ed webhook",
"webhook_response_form_help": "Ur\u010dit, co mus\u00ed webhook odeslat do URL.",
"webhook_response_form_help": "Ur\u010dete, co mus\u00ed webhook odeslat do URL.",
"webhook_delivery_form_help": "V jak\u00e9m form\u00e1tu mus\u00ed webhook pos\u00edlat data.",
"webhook_active_form_help": "Webhook mus\u00ed b\u00fdt aktivn\u00ed, nebo nebude zavol\u00e1n.",
"edit_webhook_js": "Upravit webhook \"{title}\"",
@@ -140,12 +140,12 @@
"response": "Odpov\u011b\u010f",
"visit_webhook_url": "Nav\u0161t\u00edvit URL webhooku",
"reset_webhook_secret": "Restartovat tajn\u00fd kl\u00ed\u010d webhooku",
"header_exchange_rates": "Exchange rates",
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">the documentation<\/a>.",
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
"exchange_rates_intro_rates": "Firefly III uses the following exchange rates. The inverse is automatically calculated when it is not provided. If no exchange rate exists for the date of the transaction, Firefly III will go back in time to find one. If none are present, the rate \"1\" will be used.",
"header_exchange_rates_rates": "Exchange rates",
"header_exchange_rates_table": "Table with exchange rates",
"header_exchange_rates": "Sm\u011bnn\u00e9 kurzy",
"exchange_rates_intro": "Firefly III podporuje stahov\u00e1n\u00ed a pou\u017e\u00edv\u00e1n\u00ed sm\u011bnn\u00fdch kurz\u016f. V\u00edce informac\u00ed o t\u00e9to funkci najdete <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">v dokumentaci<\/a>.",
"exchange_rates_from_to": "Mezi {from} a {to} (a opa\u010dn\u011b)",
"exchange_rates_intro_rates": "Firefly III pou\u017e\u00edv\u00e1 n\u00e1sleduj\u00edc\u00ed sm\u011bnn\u00e9 kurzy. Inverzn\u00ed kurz je automaticky vypo\u010d\u00edt\u00e1n, pokud nen\u00ed zad\u00e1n. Pokud pro datum transakce neexistuje sm\u011bnn\u00fd kurz, Firefly III se vr\u00e1t\u00ed zp\u011bt v \u010dase a pokus\u00ed se n\u011bjak\u00fd naj\u00edt. Pokud \u017e\u00e1dn\u00fd nenajde, pou\u017eije se kurz \u201e1\u201c.",
"header_exchange_rates_rates": "Sm\u011bnn\u00e9 kurzy",
"header_exchange_rates_table": "Tabulka se sm\u011bnn\u00fdmi kurzy",
"help_rate_form": "On this day, how many {to} will you get for one {from}?",
"add_new_rate": "Add a new exchange rate",
"save_new_rate": "Save new rate"
@@ -154,7 +154,7 @@
"url": "URL",
"active": "Aktivn\u00ed",
"interest_date": "\u00darokov\u00e9 datum",
"administration_currency": "Native currency",
"administration_currency": "M\u00edstn\u00ed m\u011bna",
"title": "N\u00e1zev",
"date": "Datum",
"book_date": "Datum rezervace",

View File

@@ -1,11 +1,11 @@
{
"firefly": {
"administrations_page_title": "Financial administrations",
"administrations_index_menu": "Financial administrations",
"expires_at": "Expires at",
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
"administrations_page_title": "Administraciones financieras",
"administrations_index_menu": "Administraciones financieras",
"expires_at": "Expira el",
"temp_administrations_introduction": "Firefly III pronto tendr\u00e1 la capacidad de gestionar m\u00faltiples administraciones financieras. Ahora mismo, solo tienes uno. Puedes establecer el t\u00edtulo de esta administraci\u00f3n y su moneda nativa. Esto reemplaza la configuraci\u00f3n anterior donde establecer\u00eda su \"moneda predeterminada\". Esta situaci\u00f3n est\u00e1 vinculada ahora a la administraci\u00f3n financiera y puede ser diferente por administraci\u00f3n.",
"administration_currency_form_help": "Puede tardar mucho tiempo en cargar la p\u00e1gina si cambia la moneda nativa porque la transacci\u00f3n puede necesitar ser convertida a su (nueva) moneda nativa.",
"administrations_page_edit_sub_title_js": "Editar administraci\u00f3n financiera \"{title}\"",
"table": "Mesa",
"welcome_back": "\u00bfQu\u00e9 est\u00e1 pasando?",
"flash_error": "\u00a1Error!",
@@ -16,11 +16,11 @@
"select_source_account": "Por favor, seleccione o escriba un nombre de cuenta de origen v\u00e1lido",
"split_transaction_title": "Descripci\u00f3n de la transacci\u00f3n dividida",
"errors_submission": "Hubo un problema con su env\u00edo. Por favor, compruebe los siguientes errores.",
"is_reconciled": "Is reconciled",
"is_reconciled": "Est\u00e1 reconciliado",
"split": "Separar",
"single_split": "Divisi\u00f3n",
"not_enough_currencies": "Not enough currencies",
"not_enough_currencies_enabled": "If you have just one currency enabled, there is no need to add exchange rates.",
"not_enough_currencies": "No hay suficientes monedas",
"not_enough_currencies_enabled": "Si solo tiene una divisa habilitada, no es necesario a\u00f1adir tipos de cambio.",
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">La transacci\u00f3n #{ID} (\"{title}\")<\/a> ha sido almacenada.",
"webhook_stored_link": "<a href=\"webhooks\/show\/{ID}\">El webhook #{ID} (\"{title}\")<\/a> ha sido almacenado.",
"webhook_updated_link": "<a href=\"webhooks\/show\/{ID}\">El webhook #{ID} (\"{title}\")<\/a> ha sido actualizado.",
@@ -43,10 +43,10 @@
"submit": "Enviar",
"amount": "Cantidad",
"date": "Fecha",
"is_reconciled_fields_dropped": "Because this transaction is reconciled, you will not be able to update the accounts, nor the amount(s) unless you remove the reconciliation flag.",
"is_reconciled_fields_dropped": "Debido a que esta transacci\u00f3n est\u00e1 reconciliada, no podr\u00e1 actualizar las cuentas, ni la cantidad(es) a menos que elimine la bandera de reconciliaci\u00f3n.",
"tags": "Etiquetas",
"no_budget": "(sin presupuesto)",
"no_bill": "(no subscription)",
"no_bill": "(sin suscripci\u00f3n)",
"category": "Categor\u00eda",
"attachments": "Archivos adjuntos",
"notes": "Notas",
@@ -62,7 +62,7 @@
"destination_account_reconciliation": "No puedes editar la cuenta de destino de una transacci\u00f3n de reconciliaci\u00f3n.",
"source_account_reconciliation": "No puedes editar la cuenta de origen de una transacci\u00f3n de reconciliaci\u00f3n.",
"budget": "Presupuesto",
"bill": "Subscription",
"bill": "Suscripci\u00f3n",
"you_create_withdrawal": "Est\u00e1 creando un gasto.",
"you_create_transfer": "Est\u00e1 creando una transferencia.",
"you_create_deposit": "Est\u00e1 creando un ingreso.",
@@ -140,11 +140,11 @@
"response": "Respuesta",
"visit_webhook_url": "Visita la URL del webhook",
"reset_webhook_secret": "Restablecer secreto del webhook",
"header_exchange_rates": "Exchange rates",
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">the documentation<\/a>.",
"header_exchange_rates": "Tipos de cambio",
"exchange_rates_intro": "Firefly III soporta la descarga y el uso de tipos de cambio. Lee m\u00e1s sobre esto en <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">la documentaci\u00f3n<\/a>.",
"exchange_rates_from_to": "Entre {from} y {to} (y viceversa)",
"exchange_rates_intro_rates": "Firefly III utiliza los siguientes tipos de cambio. El inverso se calcula autom\u00e1ticamente cuando no se proporciona. Si no existe un tipo de cambio para la fecha de la transacci\u00f3n, Firefly III retroceder\u00e1 en el tiempo para encontrar uno. Si no hay ninguno presente, se usar\u00e1 la tasa \"1\".",
"header_exchange_rates_rates": "Exchange rates",
"header_exchange_rates_rates": "Tipos de cambio",
"header_exchange_rates_table": "Tabla con tipos de cambio",
"help_rate_form": "En este d\u00eda, \u00bfcu\u00e1nto {to} conseguir\u00e1s por un {from}?",
"add_new_rate": "Agregar un nuevo tipo de cambio",
@@ -174,7 +174,7 @@
"list": {
"title": "T\u00edtulo",
"active": "\u00bfEst\u00e1 Activo?",
"native_currency": "Native currency",
"native_currency": "Moneda nativa",
"trigger": "Disparador",
"response": "Respuesta",
"delivery": "Entrega",

View File

@@ -9,16 +9,16 @@
},
"devDependencies": {
"axios": "^1",
"laravel-vite-plugin": "^1",
"laravel-vite-plugin": "^2",
"patch-package": "^8",
"sass": "^1",
"vite": "^6",
"vite": "^7",
"vite-plugin-manifest-sri": "^0.2.0"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^6.4.0",
"@popperjs/core": "^2.11.8",
"admin-lte": "^4.0.0-beta3",
"admin-lte": "^4.0.0-rc4",
"alpinejs": "^3.13.7",
"bootstrap": "^5",
"bootstrap5-autocomplete": "^1",

View File

@@ -48,6 +48,10 @@ window.bootstrap = bootstrap;
// always grab the preference "marker" from Firefly III.
getFreshVariable('lastActivity').then((serverValue) => {
if(null === serverValue) {
console.log('Server value is null in getFreshVariable.');
throw new Error('401 in getFreshVariable.');
}
const localValue = store.get('lastActivity');
store.set('cacheValid', localValue === serverValue);
store.set('lastActivity', serverValue);
@@ -78,6 +82,8 @@ getFreshVariable('lastActivity').then((serverValue) => {
window.bootstrapped = true;
});
});
}).catch((error) => {
console.error('Error while bootstrapping: ' + error);
});
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

View File

@@ -30,3 +30,4 @@
border:0;
}
.skip-links {display: none;}

View File

@@ -315,7 +315,7 @@ let index = function () {
// need to find the input thing
console.log('Clicked edit button for account on index #' + index + ' and field ' + fieldName);
const querySelector = 'input[data-field="' + fieldName + '"][data-index="' + index + '"]';
console.log(querySelector);
// console.log(querySelector);
const newValue = document.querySelectorAll(querySelector)[0].value ?? '';
if ('' === newValue) {
return;
@@ -352,12 +352,15 @@ let index = function () {
// filter instructions
let filters = {};
let type = this.filters.type;
let active = this.filters.active;
for (let k in this.filters) {
if (this.filters.hasOwnProperty(k) && null !== this.filters[k]) {
filters[k] = this.filters[k];
//filters.push({column: k, filter: this.filters[k]});
}
}
delete filters.type;
// get start and end from the store:
const start = new Date(window.store.get('start'));
@@ -367,24 +370,23 @@ let index = function () {
let params = {
sort: sorting,
filter: filters,
active: active,
currentMoment: today,
// type: type,
page: {number: this.page},
type: type,
page: this.page,
startPeriod: start,
endPeriod: end
};
if (!this.tableColumns.balance_difference.enabled) {
delete params.startPeriod;
delete params.enPeriod;
delete params.endPeriod;
}
this.accounts = [];
let groupedAccounts = {};
// one page only.o
(new Get()).index(params).then(response => {
console.log(response);
this.totalPages = response.meta.pagination.total_pages;
console.log('a');
for (let i = 0; i < response.data.length; i++) {
if (response.data.hasOwnProperty(i)) {
let current = response.data[i];
@@ -399,18 +401,14 @@ let index = function () {
account_number: null === current.attributes.account_number ? '' : current.attributes.account_number,
current_balance: current.attributes.current_balance,
currency_code: current.attributes.currency_code,
//native_current_balance: current.attributes.native_current_balance,
//native_currency_code: current.attributes.native_currency_code,
last_activity: null === current.attributes.last_activity ? '' : format(new Date(current.attributes.last_activity), i18next.t('config.month_and_day_fns')),
//balance_difference: current.attributes.balance_difference,
//native_balance_difference: current.attributes.native_balance_difference,
liability_type: current.attributes.liability_type,
liability_direction: current.attributes.liability_direction,
interest: current.attributes.interest,
interest_period: current.attributes.interest_period,
//current_debt: current.attributes.current_debt,
balance: current.attributes.balance,
native_balance: current.attributes.native_balance,
balances: current.attributes.balances,
};
// get group info:
let groupId = current.attributes.object_group_id;

View File

@@ -196,6 +196,14 @@ export default () => ({
(new Get).show(accountId, new Date(window.store.get('end'))).then((response) => {
let parent = response.data.data;
// apply function to each element of parent:
parent.attributes.balances = parent.attributes.balances.map((balance) => {
balance.amount_formatted = formatMoney(balance.amount, balance.currency_code);
return balance;
});
// console.log(parent);
// get groups for account:
const params = {
page: 1,
@@ -243,8 +251,7 @@ export default () => ({
name: parent.attributes.name,
order: parent.attributes.order,
id: parent.id,
balance: parent.attributes.balance,
//native_balance: parent.attributes.native_balance,
balances: parent.attributes.balances,
groups: groups,
});
// console.log(parent.attributes);

View File

@@ -76,7 +76,7 @@ export default () => ({
continue;
}
let key = current.key;
console.log('NOT NATIVE');
// console.log('NOT NATIVE');
if (key.startsWith('balance-in-')) {
this.balanceBox.amounts.push(formatMoney(current.monetary_value, current.currency_code));
continue;

View File

@@ -31,6 +31,99 @@ let afterPromises = false;
let apiData = [];
let subscriptionData = {};
function addObjectGroupInfo(data) {
let objectGroupId = parseInt(data.object_group_id);
if (!subscriptionData.hasOwnProperty(objectGroupId)) {
subscriptionData[objectGroupId] = {
id: objectGroupId,
title: null === data.object_group_title ? i18next.t('firefly.default_group_title_name_plain') : data.object_group_title,
order: parseInt(data.object_group_order),
payment_info: {},
bills: [],
};
}
}
function parsePayDates(list) {
let newList = [];
for(let i in list) {
if (list.hasOwnProperty(i)) {
let current = list[i];
// convert to date object:
newList.push(new Date(current));
}
}
return newList;
}
function parseBillInfo(data) {
let result = {
id: data.id,
name: data.attributes.name,
amount_min: data.attributes.amount_min,
amount_max: data.attributes.amount_max,
amount: (parseFloat(data.attributes.amount_max) + parseFloat(data.attributes.amount_min)) / 2,
currency_code: data.attributes.currency_code,
// paid transactions:
transactions: [],
// unpaid moments
pay_dates: parsePayDates(data.attributes.pay_dates),
paid: data.attributes.paid_dates.length > 0,
};
// set variables
result.expected_amount = formatMoney(result.amount, result.currency_code);
result.expected_times = i18next.t('firefly.subscr_expected_x_times', {
times: data.attributes.pay_dates.length,
amount: result.expected_amount
});
// console.log(result);
return result;
}
function parsePaidTransactions(paid_dates, bill) {
if( !paid_dates || paid_dates.length < 1) {
return [];
}
let result = [];
// add transactions (simpler version)
for (let i in paid_dates) {
if (paid_dates.hasOwnProperty(i)) {
const currentPayment = paid_dates[i];
// console.log(currentPayment);
// math: -100+(paid/expected)*100
let percentage = Math.round(-100 + ((parseFloat(currentPayment.amount) ) / parseFloat(bill.amount)) * 100);
let currentTransaction = {
amount: formatMoney(currentPayment.amount, currentPayment.currency_code),
percentage: percentage,
date: format(new Date(currentPayment.date), 'PP'),
foreign_amount: null,
};
if (null !== currentPayment.foreign_currency_code) {
currentTransaction.foreign_amount = currentPayment.foreign_amount;
currentTransaction.foreign_currency_code = currentPayment.foreign_currency_code;
}
result.push(currentTransaction);
}
}
return result;
}
function isInRange(bill) {
let start = new Date(window.store.get('start'));
let end = new Date(window.store.get('end'));
for(let i in bill.pay_dates) {
if (bill.pay_dates.hasOwnProperty(i)) {
let currentDate = bill.pay_dates[i];
//console.log(currentDate);
if (currentDate >= start && currentDate <= end) {
return true;
}
}
}
return false;
}
function downloadSubscriptions(params) {
const getter = new Get();
return getter.list(params)
@@ -41,83 +134,25 @@ function downloadSubscriptions(params) {
for (let i in data) {
if (data.hasOwnProperty(i)) {
let current = data[i];
//console.log(current);
if (current.attributes.active && current.attributes.pay_dates.length > 0) {
let objectGroupId = null === current.attributes.object_group_id ? 0 : current.attributes.object_group_id;
let objectGroupTitle = null === current.attributes.object_group_title ? i18next.t('firefly.default_group_title_name_plain') : current.attributes.object_group_title;
let objectGroupOrder = null === current.attributes.object_group_order ? 0 : current.attributes.object_group_order;
if (!subscriptionData.hasOwnProperty(objectGroupId)) {
subscriptionData[objectGroupId] = {
id: objectGroupId,
title: objectGroupTitle,
order: objectGroupOrder,
payment_info: {},
bills: [],
};
// create or update object group
let objectGroupId = parseInt(current.attributes.object_group_id);
addObjectGroupInfo(current.attributes);
// create and update the bill.
let bill = parseBillInfo(current);
// if not yet paid, and pay_dates is not in current rage, ignore it.
if (false === bill.paid && !isInRange(bill)) {
console.warn('Bill "'+bill.name+'" is not paid and not in range, ignoring: ');
continue;
}
// TODO this conversion needs to be inside some kind of a parsing class.
let bill = {
id: current.id,
name: current.attributes.name,
// amount
amount_min: current.attributes.amount_min,
amount_max: current.attributes.amount_max,
amount: (parseFloat(current.attributes.amount_max) + parseFloat(current.attributes.amount_min)) / 2,
currency_code: current.attributes.currency_code,
// native amount
// native_amount_min: current.attributes.native_amount_min,
// native_amount_max: current.attributes.native_amount_max,
// native_amount: (parseFloat(current.attributes.native_amount_max) + parseFloat(current.attributes.native_amount_min)) / 2,
// native_currency_code: current.attributes.native_currency_code,
// paid transactions:
transactions: [],
// unpaid moments
pay_dates: current.attributes.pay_dates,
paid: current.attributes.paid_dates.length > 0,
};
// set variables
bill.expected_amount = formatMoney(bill.amount, bill.currency_code);
bill.expected_times = i18next.t('firefly.subscr_expected_x_times', {
times: current.attributes.pay_dates.length,
amount: bill.expected_amount
});
// add transactions (simpler version)
for (let iii in current.attributes.paid_dates) {
if (current.attributes.paid_dates.hasOwnProperty(iii)) {
const currentPayment = current.attributes.paid_dates[iii];
let percentage = 100;
// math: -100+(paid/expected)*100
if (params.convertToNative) {
percentage = Math.round(-100 + ((parseFloat(currentPayment.native_amount) * -1) / parseFloat(bill.native_amount)) * 100);
}
if (!params.convertToNative) {
percentage = Math.round(-100 + ((parseFloat(currentPayment.amount) * -1) / parseFloat(bill.amount)) * 100);
}
// TODO fix me
currentPayment.currency_code = 'EUR';
console.log('Currency code: "'+currentPayment+'"');
console.log(currentPayment);
let currentTransaction = {
amount: formatMoney(currentPayment.amount, currentPayment.currency_code),
percentage: percentage,
date: format(new Date(currentPayment.date), 'PP'),
foreign_amount: null,
};
if (null !== currentPayment.foreign_currency_code) {
currentTransaction.foreign_amount = currentPayment.foreign_amount;
currentTransaction.foreign_currency_code = currentPayment.foreign_currency_code;
}
bill.transactions.push(currentTransaction);
}
}
bill.transactions = parsePaidTransactions(current.attributes.paid_dates, bill);
subscriptionData[objectGroupId].bills.push(bill);
if (0 === current.attributes.paid_dates.length) {
if (false === bill.paid) {
// bill is unpaid, count the "pay_dates" and multiply with the "amount".
// since bill is unpaid, this can only be in currency amount and native currency amount.
const totalAmount = current.attributes.pay_dates.length * bill.amount;
@@ -133,6 +168,7 @@ function downloadSubscriptions(params) {
//native_unpaid: 0,
};
}
subscriptionData[objectGroupId].payment_info[bill.currency_code].unpaid += totalAmount;
//subscriptionData[objectGroupId].payment_info[bill.currency_code].native_unpaid += totalNativeAmount;
}

View File

@@ -1,5 +1,5 @@
/*!
* adminlte-filteres.scss
* adminlte-filtered.scss
* Copyright (c) 2024 james@firefly-iii.org.
*
* This file is part of Firefly III (https://github.com/firefly-iii).
@@ -23,7 +23,7 @@
// copied from:
/*!
* AdminLTE v4.0.0-alpha2
* AdminLTE v4.0.0-rc3
* Author: Colorlib
* Website: AdminLTE.io <https://adminlte.io>
* License: Open source - MIT <https://opensource.org/licenses/MIT>
@@ -84,7 +84,6 @@
// Bootstrap Utilities
@import "bootstrap/scss/utilities/api";
// AdminLTE Configuration
// ---------------------------------------------------
@import "admin-lte/src/scss/variables";
@@ -97,9 +96,12 @@
@import "admin-lte/src/scss/parts/components";
@import "admin-lte/src/scss/parts/extra-components";
// @import "admin-lte/src/scss/parts/pages";
@import "admin-lte/src/scss/pages/login_and_register";
//
// Part: Pages
//
@import "admin-lte/src/scss/pages/login_and_register";
@import "admin-lte/src/scss/parts/miscellaneous";
// AdminLTE Accessibility Styles - WCAG 2.1 AA Compliance
@import "admin-lte/src/scss/accessibility";

View File

@@ -26,6 +26,9 @@ $danger: #CD5029 !default;
$primary: #1E6581 !default;
$success: #64B624 !default;
.skip-links {display: none;}
/*
Remove bottom margin from unstyled lists
*/

View File

@@ -26,13 +26,17 @@ export function getFreshVariable(name, defaultValue = null) {
return getter.getByName(name).then((response) => {
// console.log('Get from API');
return Promise.resolve(parseResponse(name, response));
}).catch(() => {
// preference does not exist (yet).
// POST it and then return it anyway.
let poster = (new Post);
poster.post(name, defaultValue).then((response) => {
return Promise.resolve(parseResponse(name, response));
});
}).catch((response) => {
if(response.status === 404) {
// preference does not exist (yet).
// POST it and then return it anyway.
let poster = (new Post);
poster.post(name, defaultValue).then((response) => {
return Promise.resolve(parseResponse(name, response));
});
return;
}
return Promise.resolve(null);
});
}

View File

@@ -21,5 +21,9 @@
export function showInternalsButton() {
// console.log('showInternalsButton');
document.querySelector('.toggle-page-internals').classList.remove('d-none');
let obj = document.querySelector('.toggle-page-internals');
if (obj === null) {
return;
}
obj.classList.remove('d-none');
}

View File

@@ -83,7 +83,8 @@ export default defineConfig(({command, mode, isSsrBuild, isPreview}) => {
server: {
cors: true,
origin: 'https://192.168.96.154:5173',
// make sure this IP matches the IP of the dev machine.
origin: 'https://192.168.96.162:5173',
watch: {
usePolling: true,
},

View File

@@ -1866,8 +1866,8 @@ return [
'skip_help_text' => 'Use the skip field to create bi-monthly (skip = 1) or other custom intervals.',
'subscription' => 'Subscription',
'not_expected_period' => 'Not expected this period',
'subscriptions_in_group' => 'Subscriptions in group "%{title}"',
'subscr_expected_x_times' => 'Expect to pay %{amount} %{times} times this period',
'subscriptions_in_group' => 'Subscriptions in group "{{title}}"',
'subscr_expected_x_times' => 'Expect to pay {{amount}} {{times}} times this period',
'not_or_not_yet' => 'Not (yet)',
'visit_bill' => 'Visit subscription ":name" at Firefly III',
'match_between_amounts' => 'Subscription matches transactions between :low and :high.',

View File

@@ -64,7 +64,7 @@ return [
'budget_id' => 'Budget',
'bill_id' => 'Subscription',
'opening_balance' => 'Opening balance',
'tagMode' => 'Tag mode',
'tag_mode' => 'Tag mode',
'virtual_balance' => 'Virtual balance',

View File

@@ -82,13 +82,13 @@
{% for tag in journal.tags %}
<h4 style="display: inline;"><a class="label label-success" href="{{ route('tags.show',tag) }}">
{% if tag.tagMode == 'nothing' %}
{% if tag.tag_mode == 'nothing' %}
<span class="fa fa-fw fa-tag"></span>
{% endif %}
{% if tag.tagMode == 'balancingAct' %}
{% if tag.tag_mode == 'balancingAct' %}
<span class="fa fa-fw fa-refresh"></span>
{% endif %}
{% if tag.tagMode == 'advancePayment' %}
{% if tag.tag_mode == 'advancePayment' %}
<span class="fa fa-fw fa-sort-numeric-desc"></span>
{% endif %}
{{ tag.tag }}</a>

View File

@@ -29,7 +29,7 @@
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="invite_code" value="{{ $inviteCode ?? '' }}">
<div class="input-group mb-3">
<input type="email" name="email" autofocus required value="{{ $email }}" class="form-control" "
<input type="email" name="email" autofocus required value="{{ $email }}" class="form-control"
placeholder="{{ trans('form.email') }}"/>
<div class="input-group-text"> <em class="fa-solid fa-envelope"></em> </div>
</div>

View File

@@ -13,13 +13,13 @@
x-text="account.name"></a>
<span class="small">
<template x-for="balance in account.balance">
<span>x</span>
<template x-for="balance in account.balances">
<template x-if="balance.type === 'current'">
<span class="text-muted">(<span x-text="balance.amount_formatted"></span>)
</span>
</template>
</template>
<template x-for="balance in account.native_balance">
<span>Y</span>
</template>
</span>
</span>
</h3>
</div>
<div class="card-body p-0">

View File

@@ -2,7 +2,7 @@
<div class="col-xl-3 col-lg-6 col-md-12 col-sm-12">
<div class="small-box text-bg-primary">
<div class="inner balance-box">
<h3 class="hover-expand">
<h4 class="hover-expand">
<template x-if="0 === balanceBox.amounts.length">
<span>&nbsp;</span>
</template>
@@ -12,7 +12,7 @@
:class="{ 'invisible': (balanceBox.amounts.length == index+1) }">, </span>
</span>
</template>
</h3>
</h4>
<template x-if="loading">
<p class="d-none d-xs-block">
<em class="fa-solid fa-spinner fa-spin"></em>
@@ -53,17 +53,17 @@
<div class="small-box text-bg-success">
<div class="inner">
<template x-if="0 === billBox.unpaid.length">
<h3>&nbsp;</h3>
<h4>&nbsp;</h4>
</template>
<template x-if="billBox.unpaid.length > 0">
<h3 class="hover-expand">
<h4 class="hover-expand">
<template x-for="(amount, index) in billBox.unpaid" :key="index">
<span>
<span x-text="amount"></span><span
:class="{ 'invisible': (billBox.unpaid.length == index+1) }">, </span>
</span>
</template>
</h3>
</h4>
</template>
<template x-if="loading">
<p class="d-none d-sm-block">
@@ -104,7 +104,7 @@
<!--begin::Small Box Widget 3-->
<div class="small-box text-bg-warning">
<div class="inner">
<h3 class="hover-expand">
<h4 class="hover-expand">
<template x-if="0 === leftBox.left.length">
<span>&nbsp;</span>
</template>
@@ -114,7 +114,7 @@
:class="{ 'invisible': (leftBox.left.length == index+1) }">, </span>
</span>
</template>
</h3>
</h4>
<template x-if="loading">
<p class="d-none d-sm-block">
@@ -153,14 +153,14 @@
<!--begin::Small Box Widget 4-->
<div class="small-box text-bg-danger">
<div class="inner">
<h3 class="hover-expand">
<h4 class="hover-expand">
<template x-for="(amount, index) in netBox.net" :key="index">
<span>
<span x-text="amount"></span><span
:class="{ 'invisible': (netBox.net.length == index+1) }">, </span>
</span>
</template>
</h3>
</h4>
<template x-if="loading">
<p class="d-none d-sm-block">

View File

@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace Tests\integration\Support\Models;
use Override;
use Iterator;
use Carbon\Carbon;
use FireflyIII\Support\Models\BillDateCalculator;
use PHPUnit\Framework\Attributes\DataProvider;
@@ -59,7 +58,7 @@ final class BillDateCalculatorTest extends TestCase
$this->assertSame($expected, $result);
}
public static function provideDates(): Iterator
public static function provideDates(): iterable
{
// Carbon $earliest, Carbon $latest, Carbon $billStart, string $period, int $skip, ?Carbon $lastPaid
// basic monthly bill.x

View File

@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace Tests\unit\Support;
use Override;
use Iterator;
use Carbon\Carbon;
use FireflyIII\Support\Calendar\Periodicity;
use FireflyIII\Support\Navigation;
@@ -111,7 +110,7 @@ final class NavigationAddPeriodTest extends TestCase
$this->assertSame($expected->toDateString(), $period->toDateString());
}
public static function providePeriods(): Iterator
public static function providePeriods(): iterable
{
yield '1D' => ['1D', Carbon::now(), Carbon::tomorrow()];
@@ -161,7 +160,7 @@ final class NavigationAddPeriodTest extends TestCase
$this->assertSame($expected->toDateString(), $period->toDateString());
}
public static function provideFrequencies(): Iterator
public static function provideFrequencies(): iterable
{
yield Periodicity::Daily->name => [Periodicity::Daily, Carbon::now(), Carbon::tomorrow()];
@@ -215,7 +214,7 @@ final class NavigationAddPeriodTest extends TestCase
$this->assertSame($expected->toDateString(), $period->toDateString());
}
public static function provideMonthPeriods(): Iterator
public static function provideMonthPeriods(): iterable
{
yield '1M' => ['1M', Carbon::parse('2023-06-25'), Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)];

View File

@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace Tests\unit\Support;
use Override;
use Iterator;
use Carbon\Carbon;
use FireflyIII\Support\Navigation;
use Illuminate\Support\Facades\Log;
@@ -58,7 +57,7 @@ final class NavigationEndOfPeriodTest extends TestCase
$this->assertSame($expected->toDateString(), $period->toDateString());
}
public static function provideDates(): Iterator
public static function provideDates(): iterable
{
yield '1D' => ['1D', Carbon::now(), Carbon::now()->endOfDay()];
@@ -122,7 +121,7 @@ final class NavigationEndOfPeriodTest extends TestCase
Log::shouldHaveReceived('error', [$expectedMessage]);
}
public static function provideUnknownFrequencies(): Iterator
public static function provideUnknownFrequencies(): iterable
{
yield '1day' => ['1day', Carbon::now(), Carbon::now()];

View File

@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace Tests\unit\Support;
use Override;
use Iterator;
use FireflyIII\Support\Navigation;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\integration\TestCase;
@@ -57,7 +56,7 @@ final class NavigationPreferredCarbonFormatByPeriodTest extends TestCase
$this->assertSame($expected, $formatPeriod);
}
public static function providePeriods(): Iterator
public static function providePeriods(): iterable
{
yield 'unknown' => ['1day', 'Y-m-d'];

View File

@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace Tests\unit\Support;
use Override;
use Iterator;
use Carbon\Carbon;
use FireflyIII\Support\Navigation;
use PHPUnit\Framework\Attributes\DataProvider;
@@ -58,7 +57,7 @@ final class NavigationPreferredCarbonFormatTest extends TestCase
$this->assertSame($expected, $carbonFormat);
}
public static function providePeriods(): Iterator
public static function providePeriods(): iterable
{
yield '1 week' => [Carbon::now(), Carbon::now()->addWeek(), 'Y-m-d'];

View File

@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace Tests\unit\Support;
use Override;
use Iterator;
use Carbon\Carbon;
use FireflyIII\Support\Navigation;
use PHPUnit\Framework\Attributes\DataProvider;
@@ -58,7 +57,7 @@ final class NavigationPreferredEndOfPeriodTest extends TestCase
$this->assertSame($expected, $formatPeriod);
}
public static function providePeriods(): Iterator
public static function providePeriods(): iterable
{
yield '1 week' => [Carbon::now(), Carbon::now()->addWeek(), 'endOfDay'];

View File

@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace Tests\unit\Support;
use Override;
use Iterator;
use Carbon\Carbon;
use FireflyIII\Support\Navigation;
use PHPUnit\Framework\Attributes\DataProvider;
@@ -58,7 +57,7 @@ final class NavigationPreferredRangeFormatTest extends TestCase
$this->assertSame($expected, $formatPeriod);
}
public static function providePeriods(): Iterator
public static function providePeriods(): iterable
{
yield '1 week' => [Carbon::now(), Carbon::now()->addWeek(), '1D'];

View File

@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace Tests\unit\Support;
use Override;
use Iterator;
use Carbon\Carbon;
use FireflyIII\Support\Navigation;
use PHPUnit\Framework\Attributes\DataProvider;
@@ -58,7 +57,7 @@ final class NavigationPreferredSqlFormatTest extends TestCase
$this->assertSame($expected, $formatPeriod);
}
public static function provideDates(): Iterator
public static function provideDates(): iterable
{
yield '1 week' => [Carbon::now(), Carbon::now()->addWeek(), '%Y-%m-%d'];

View File

@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace Tests\unit\Support;
use Override;
use Iterator;
use Carbon\Carbon;
use FireflyIII\Support\Navigation;
use Illuminate\Support\Facades\Log;
@@ -59,7 +58,7 @@ final class NavigationStartOfPeriodTest extends TestCase
$this->assertSame($expected->toDateString(), $period->toDateString());
}
public static function provideDates(): Iterator
public static function provideDates(): iterable
{
yield 'custom' => ['custom', Carbon::now(), Carbon::now()];
@@ -124,7 +123,7 @@ final class NavigationStartOfPeriodTest extends TestCase
$this->assertSame($expected->toDateString(), $period->toDateString());
}
public static function provideUnknownFrequencies(): Iterator
public static function provideUnknownFrequencies(): iterable
{
yield '1day' => ['1day', Carbon::now(), Carbon::now()];

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Tests\unit\Support\Search\QueryParser;
use Iterator;
use FireflyIII\Support\Search\QueryParser\FieldNode;
use FireflyIII\Support\Search\QueryParser\QueryParserInterface;
use FireflyIII\Support\Search\QueryParser\StringNode;
@@ -30,7 +29,7 @@ abstract class AbstractQueryParserInterfaceParseQueryTester extends TestCase
}
public static function queryDataProvider(): Iterator
public static function queryDataProvider(): iterable
{
yield 'empty query' => [
'',