mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-12-10 17:09:42 +00:00
Compare commits
153 Commits
develop-20
...
branch-v6.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32e5efec7c | ||
|
|
36457455ca | ||
|
|
062c148e43 | ||
|
|
2314ce8004 | ||
|
|
a3ff73903a | ||
|
|
7c8445707e | ||
|
|
291e73da4b | ||
|
|
286a29ca3e | ||
|
|
71cf6c6a5e | ||
|
|
1e8f0adaf8 | ||
|
|
33531244aa | ||
|
|
06049a9a28 | ||
|
|
d313f5fdf5 | ||
|
|
f4868126c1 | ||
|
|
00147e98dd | ||
|
|
6d22663ca2 | ||
|
|
756bb9cf5e | ||
|
|
399d7968f5 | ||
|
|
966b68f42e | ||
|
|
134c551c12 | ||
|
|
9aeca15355 | ||
|
|
6c6d31830b | ||
|
|
e8cc321898 | ||
|
|
e73fe06f7e | ||
|
|
98b579c042 | ||
|
|
7b3a5c1afd | ||
|
|
7e2e49e129 | ||
|
|
e8ef630424 | ||
|
|
8805bcf6f6 | ||
|
|
ff5c9a3aa0 | ||
|
|
3a274dcaa7 | ||
|
|
ddfededf02 | ||
|
|
e1785898ba | ||
|
|
ae09200f42 | ||
|
|
847984f678 | ||
|
|
42305672ac | ||
|
|
25a56d9f72 | ||
|
|
8f9f08b96f | ||
|
|
3c65b46aa5 | ||
|
|
1cf9c76329 | ||
|
|
c0499df4ec | ||
|
|
d90ac519f7 | ||
|
|
a0e92b6969 | ||
|
|
df49dd23e2 | ||
|
|
d4525da6bc | ||
|
|
25b11bd20b | ||
|
|
705aac419a | ||
|
|
f6e642f72e | ||
|
|
565bd87959 | ||
|
|
5751f7e5a3 | ||
|
|
f5a755d4fc | ||
|
|
a500de8ab1 | ||
|
|
303548a5fe | ||
|
|
68de905698 | ||
|
|
9240b9868b | ||
|
|
0e2e155cc6 | ||
|
|
bffa0088b4 | ||
|
|
2e993857e8 | ||
|
|
117a376fc3 | ||
|
|
1daffedde0 | ||
|
|
0e8fdd76a6 | ||
|
|
7ff4f29bcb | ||
|
|
9e4cff2b23 | ||
|
|
4aaea89f2c | ||
|
|
4fbf7b38fb | ||
|
|
76075401f9 | ||
|
|
e2a20dd63d | ||
|
|
b52a1f3eb1 | ||
|
|
7fd5a88122 | ||
|
|
1a1baa5cda | ||
|
|
577d671a0c | ||
|
|
380029ffd8 | ||
|
|
76cc27a267 | ||
|
|
e8a6f30e4e | ||
|
|
fe6021a3d6 | ||
|
|
563c54702b | ||
|
|
4d67d27ba0 | ||
|
|
edf3876a57 | ||
|
|
2d10f255c2 | ||
|
|
ee76cc6761 | ||
|
|
f197e6623b | ||
|
|
42a9809450 | ||
|
|
444f80a933 | ||
|
|
4b985c818a | ||
|
|
2e62fe7b72 | ||
|
|
ccd182aed9 | ||
|
|
615eef3fdd | ||
|
|
d4e4907363 | ||
|
|
c205e93876 | ||
|
|
3b24bb99bb | ||
|
|
2814cd1b2a | ||
|
|
5285e1ac14 | ||
|
|
48a999cf91 | ||
|
|
3117c8846e | ||
|
|
6bb297e76f | ||
|
|
bc698f67ea | ||
|
|
f1c859aaa3 | ||
|
|
2d0aa207d4 | ||
|
|
4a75e9c262 | ||
|
|
ee7c4b8863 | ||
|
|
f782979d6c | ||
|
|
53cce6510c | ||
|
|
53252b84fd | ||
|
|
8f3cf38f77 | ||
|
|
f33766a062 | ||
|
|
ac5e62c65d | ||
|
|
e2289ce1e6 | ||
|
|
f0e2913802 | ||
|
|
1fa928b98f | ||
|
|
1c691cca33 | ||
|
|
69e1eb3eff | ||
|
|
90794cb515 | ||
|
|
28d7e24d30 | ||
|
|
6a62f781e9 | ||
|
|
fb6c67fa04 | ||
|
|
03e9e3dbdb | ||
|
|
5520992861 | ||
|
|
5f1502eea7 | ||
|
|
b3560ff525 | ||
|
|
8030167ffc | ||
|
|
fd2c1615cf | ||
|
|
b976239580 | ||
|
|
7d8d773f8f | ||
|
|
b930ad4da7 | ||
|
|
abad7cdf16 | ||
|
|
0e5eb036b0 | ||
|
|
d995bfc081 | ||
|
|
c920070ce2 | ||
|
|
277f5e538f | ||
|
|
89f197b9d4 | ||
|
|
c35ff3174a | ||
|
|
94085ee940 | ||
|
|
c841fa3620 | ||
|
|
69b2c1f4d2 | ||
|
|
2f7a1c941e | ||
|
|
c06fb8daf6 | ||
|
|
26948a058a | ||
|
|
1220564f30 | ||
|
|
ea4be9dd0c | ||
|
|
1ccda0b598 | ||
|
|
eb3b67ffd6 | ||
|
|
4819b5ac5d | ||
|
|
591b795aa3 | ||
|
|
ac21ed7d18 | ||
|
|
d740814f88 | ||
|
|
cdf1ebf3f7 | ||
|
|
f2fab5d4ee | ||
|
|
21a6927279 | ||
|
|
92190bbc54 | ||
|
|
9ad005e31f | ||
|
|
f5c56e02da | ||
|
|
c25c0d37c5 | ||
|
|
4ba1c5bcfc |
42
.ci/php-cs-fixer/composer.lock
generated
42
.ci/php-cs-fixer/composer.lock
generated
@@ -97,13 +97,13 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
},
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon"
|
||||
]
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -1259,16 +1259,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.2.0",
|
||||
"version": "v7.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf"
|
||||
"reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/23c8aae6d764e2bae02d2a99f7532a7f6ed619cf",
|
||||
"reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3",
|
||||
"reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1332,7 +1332,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.2.0"
|
||||
"source": "https://github.com/symfony/console/tree/v7.2.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1348,7 +1348,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-06T14:24:19+00:00"
|
||||
"time": "2024-12-11T03:49:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
@@ -1796,8 +1796,8 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -1872,8 +1872,8 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -1950,8 +1950,8 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2034,8 +2034,8 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2108,8 +2108,8 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2188,8 +2188,8 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
||||
@@ -26,8 +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 \
|
||||
PHP_CS_FIXER_IGNORE_ENV=true ./vendor/bin/php-cs-fixer fix \
|
||||
--config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php \
|
||||
--format=txt \
|
||||
--allow-risky=yes
|
||||
|
||||
2
.github/workflows/close-duplicates.yml
vendored
2
.github/workflows/close-duplicates.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
close_duplicates:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: github/command@v1.2.2
|
||||
- uses: github/command@v1.3.0
|
||||
id: command
|
||||
with:
|
||||
allowed_contexts: "issue"
|
||||
|
||||
93
.github/workflows/release.yml
vendored
93
.github/workflows/release.yml
vendored
@@ -4,9 +4,13 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Release "v1.2.3" or "develop"'
|
||||
description: 'Release "v1.2.3" or "develop" or "branch-abc"'
|
||||
required: true
|
||||
default: 'develop'
|
||||
phpversion:
|
||||
description: 'PHP version'
|
||||
required: true
|
||||
default: '8.3'
|
||||
schedule:
|
||||
- cron: '0 3 * * MON'
|
||||
|
||||
@@ -23,6 +27,11 @@ jobs:
|
||||
if [[ "develop" == "$version" ]]; then
|
||||
git checkout --track origin/develop
|
||||
git pull
|
||||
elif [[ "$version" == branch* ]]; then
|
||||
PULLBRANCH=${version:7}
|
||||
echo "The branch is '$PULLBRANCH' ($version)"
|
||||
git checkout --track origin/$PULLBRANCH
|
||||
git pull
|
||||
else
|
||||
git config user.name github-actions
|
||||
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
||||
@@ -36,7 +45,7 @@ jobs:
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.3'
|
||||
php-version: ${{ github.event.inputs.phpversion }}
|
||||
extensions: mbstring, intl, zip, bcmath
|
||||
- name: crowdin action
|
||||
uses: crowdin/github-action@v2
|
||||
@@ -133,7 +142,7 @@ jobs:
|
||||
rm -rf vendor composer.lock
|
||||
composer update --no-dev --no-scripts --no-plugins -q
|
||||
sudo chown -R runner:docker resources/lang
|
||||
.ci/phpcs.sh
|
||||
.ci/phpcs.sh || true
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@v6
|
||||
with:
|
||||
@@ -166,6 +175,16 @@ jobs:
|
||||
tarName=FireflyIII-develop.tar.gz
|
||||
fi
|
||||
|
||||
# if this is a branch build, also slightly different variable names.
|
||||
if [[ "$version" == branch* ]]; then
|
||||
[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
|
||||
# branch builds overrule develop
|
||||
releaseName=$version-$(date +'%Y%m%d')
|
||||
originalName=$releaseName
|
||||
zipName=FireflyIII-$version.zip
|
||||
tarName=FireflyIII-$version.tar.gz
|
||||
fi
|
||||
|
||||
# in both cases, if the release or tag already exists, add ".1" until it no longer exists.
|
||||
tagFound=true
|
||||
tagCount=1
|
||||
@@ -207,12 +226,13 @@ jobs:
|
||||
gpg --armor --detach-sign $zipName
|
||||
gpg --armor --detach-sign $tarName
|
||||
|
||||
# create a development (nightly) release:
|
||||
# describe the development release.
|
||||
if [[ "develop" == "$version" ]]; then
|
||||
echo 'Develop release.'
|
||||
# add text to output.txt (instructions)
|
||||
rm output.txt
|
||||
echo "Bi-weekly development release of Firefly III with the latest fixes, translations and features. Docker users can find this release under the \`develop\` tag." >> output.txt
|
||||
touch output.txt
|
||||
sudo chown -R runner:docker output.txt
|
||||
echo "Weekly development release of Firefly III with the latest fixes, translations and features. Docker users can find this release under the \`develop\` tag." >> output.txt
|
||||
echo "" >> output.txt
|
||||
echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
echo "" >> output.txt
|
||||
@@ -220,15 +240,62 @@ jobs:
|
||||
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||
echo "" >> output.txt
|
||||
echo ":warning: Please be careful with this pre-release, as it may not work as expected." >> output.txt
|
||||
fi
|
||||
# describe a branch release
|
||||
if [[ "$version" == branch* ]]; then
|
||||
echo 'Branch release.'
|
||||
rm output.txt
|
||||
touch output.txt
|
||||
sudo chown -R runner:docker output.txt
|
||||
echo "Irregular BRANCH release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
|
||||
echo "" >> output.txt
|
||||
echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
echo "" >> output.txt
|
||||
echo "* Please read the installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||
echo "" >> output.txt
|
||||
echo ":warning: Please be careful with this branch pre-release, as it may not work as expected." >> output.txt
|
||||
fi
|
||||
# describe the main release
|
||||
if [[ "develop" != "$version" ]] && [[ "$version" != branch* ]]; then
|
||||
sudo chown -R runner:docker output.txt
|
||||
echo 'Main release.'
|
||||
echo '' >> output.txt
|
||||
echo '### Instructions' >> output.txt
|
||||
echo '' >> output.txt
|
||||
echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||
echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
|
||||
fi
|
||||
|
||||
# create a development release:
|
||||
if [[ "develop" == "$version" ]]; then
|
||||
# create the release:
|
||||
echo "Create nightly release."
|
||||
git tag -a $releaseName -m "Nightly development release '$version' on $(date +'%Y-%m-%d')"
|
||||
echo "Create develop release."
|
||||
git tag -a $releaseName -m "Development release '$version' on $(date +'%Y-%m-%d')"
|
||||
|
||||
git push origin $releaseName
|
||||
gh release create $releaseName -p --verify-tag \
|
||||
-t "Development release for $(date +'%Y-%m-%d')" \
|
||||
-F output.txt
|
||||
fi
|
||||
|
||||
# create a branch release:
|
||||
if [[ "$version" == branch* ]]; then
|
||||
|
||||
# create the release:
|
||||
echo "Create branch release."
|
||||
git tag -a $releaseName -m "Branch release '$version' on $(date +'%Y-%m-%d')"
|
||||
|
||||
git push origin $releaseName
|
||||
gh release create $releaseName -p --verify-tag \
|
||||
-t "Branch release for $(date +'%Y-%m-%d')" \
|
||||
-F output.txt
|
||||
fi
|
||||
|
||||
# create a development (nightly) release:
|
||||
if [[ "develop" == "$version" ]] || [[ "$version" == branch* ]]; then
|
||||
# add zip file to release.
|
||||
gh release upload $releaseName $zipName
|
||||
gh release upload $releaseName $tarName
|
||||
@@ -247,16 +314,6 @@ jobs:
|
||||
gh release upload $releaseName HEAD.txt
|
||||
else
|
||||
echo 'MAIN (real) release'
|
||||
sudo chown -R runner:docker output.txt
|
||||
# add text to output.txt (more instructions)
|
||||
echo '' >> output.txt
|
||||
echo '### Instructions' >> output.txt
|
||||
echo '' >> output.txt
|
||||
echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||
echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
|
||||
echo "Create default release."
|
||||
git tag -a $releaseName -m "Here be changelog"
|
||||
git push origin $releaseName
|
||||
gh release create $releaseName -F output.txt -t "$releaseName" --verify-tag
|
||||
|
||||
@@ -30,6 +30,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -89,11 +90,11 @@ class AccountController extends Controller
|
||||
$currency = $this->repository->getAccountCurrency($account) ?? $defaultCurrency;
|
||||
|
||||
if (in_array($account->accountType->type, $this->balanceTypes, true)) {
|
||||
$balance = app('steam')->balance($account, $date);
|
||||
$balance = Steam::finalAccountBalance($account, $date);
|
||||
$nameWithBalance = sprintf(
|
||||
'%s (%s)',
|
||||
$account->name,
|
||||
app('amount')->formatAnything($currency, $balance, false)
|
||||
app('amount')->formatAnything($currency, $balance['balance'], false)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,12 +68,11 @@ class PiggyBankController extends Controller
|
||||
{
|
||||
$data = $request->getData();
|
||||
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$response = [];
|
||||
|
||||
/** @var PiggyBank $piggy */
|
||||
foreach ($piggies as $piggy) {
|
||||
$currency = $this->accountRepository->getAccountCurrency($piggy->account) ?? $defaultCurrency;
|
||||
$currency = $piggy->transactionCurrency;
|
||||
$objectGroup = $piggy->objectGroups()->first();
|
||||
$response[] = [
|
||||
'id' => (string) $piggy->id,
|
||||
@@ -99,13 +98,12 @@ class PiggyBankController extends Controller
|
||||
{
|
||||
$data = $request->getData();
|
||||
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$response = [];
|
||||
|
||||
/** @var PiggyBank $piggy */
|
||||
foreach ($piggies as $piggy) {
|
||||
$currency = $this->accountRepository->getAccountCurrency($piggy->account) ?? $defaultCurrency;
|
||||
$currentAmount = $this->piggyRepository->getRepetition($piggy)->currentamount ?? '0';
|
||||
$currency = $piggy->transactionCurrency;
|
||||
$currentAmount = $this->piggyRepository->getCurrentAmount($piggy);
|
||||
$objectGroup = $piggy->objectGroups()->first();
|
||||
$response[] = [
|
||||
'id' => (string) $piggy->id,
|
||||
@@ -114,7 +112,7 @@ class PiggyBankController extends Controller
|
||||
'%s (%s / %s)',
|
||||
$piggy->name,
|
||||
app('amount')->formatAnything($currency, $currentAmount, false),
|
||||
app('amount')->formatAnything($currency, $piggy->targetamount, false),
|
||||
app('amount')->formatAnything($currency, $piggy->target_amount, false),
|
||||
),
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_name' => $currency->name,
|
||||
|
||||
@@ -116,13 +116,13 @@ class AccountController extends Controller
|
||||
];
|
||||
// TODO this code is also present in the V2 chart account controller so this method is due to be deprecated.
|
||||
$currentStart = clone $start;
|
||||
$range = app('steam')->balanceInRange($account, $start, clone $end);
|
||||
$range = app('steam')->finalAccountBalanceInRange($account, $start, clone $end, $this->convertToNative);
|
||||
// 2022-10-11 this method no longer converts to float.
|
||||
$previous = array_values($range)[0];
|
||||
while ($currentStart <= $end) {
|
||||
$format = $currentStart->format('Y-m-d');
|
||||
$label = $currentStart->toAtomString();
|
||||
$balance = array_key_exists($format, $range) ? $range[$format] : $previous;
|
||||
$balance = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous;
|
||||
$previous = $balance;
|
||||
$currentStart->addDay();
|
||||
$currentSet['entries'][$label] = $balance;
|
||||
|
||||
@@ -55,6 +55,7 @@ abstract class Controller extends BaseController
|
||||
/** @var array<int, string> */
|
||||
protected array $allowedSort;
|
||||
protected ParameterBag $parameters;
|
||||
protected bool $convertToNative = false;
|
||||
|
||||
/**
|
||||
* Controller constructor.
|
||||
@@ -68,7 +69,9 @@ abstract class Controller extends BaseController
|
||||
$this->parameters = $this->getParameters();
|
||||
if (auth()->check()) {
|
||||
$language = app('steam')->getLanguage();
|
||||
$this->convertToNative = app('preferences')->get('convert_to_native', false)->data;
|
||||
app()->setLocale($language);
|
||||
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
||||
@@ -29,13 +29,13 @@ use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
@@ -63,14 +63,17 @@ class PurgeController extends Controller
|
||||
Bill::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
||||
|
||||
// piggies
|
||||
$set = PiggyBank::leftJoin('accounts', 'accounts.id', 'piggy_banks.account_id')
|
||||
->where('accounts.user_id', $user->id)->onlyTrashed()->get(['piggy_banks.*'])
|
||||
;
|
||||
|
||||
/** @var PiggyBank $piggy */
|
||||
foreach ($set as $piggy) {
|
||||
$piggy->forceDelete();
|
||||
}
|
||||
$repository = app(PiggyBankRepositoryInterface::class);
|
||||
$repository->setUser($user);
|
||||
$repository->purgeAll();
|
||||
// $set = PiggyBank::leftJoin('accounts', 'accounts.id', 'piggy_banks.account_id')
|
||||
// ->where('accounts.user_id', $user->id)->onlyTrashed()->get(['piggy_banks.*'])
|
||||
// ;
|
||||
//
|
||||
// /** @var PiggyBank $piggy */
|
||||
// foreach ($set as $piggy) {
|
||||
// $piggy->forceDelete();
|
||||
// }
|
||||
|
||||
// rule group
|
||||
RuleGroup::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
||||
|
||||
@@ -111,7 +111,7 @@ class ListController extends Controller
|
||||
// types to get, page size:
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
|
||||
// get list of budgets. Count it and split it.
|
||||
// get list of piggy banks. Count it and split it.
|
||||
$collection = $this->repository->getPiggyBanks($account);
|
||||
$count = $collection->count();
|
||||
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
@@ -69,6 +69,7 @@ class StoreController extends Controller
|
||||
$data = $request->getAll();
|
||||
$data['start_date'] = $data['start'];
|
||||
$data['end_date'] = $data['end'];
|
||||
$data['notes'] = $data['notes'];
|
||||
$data['budget_id'] = $budget->id;
|
||||
|
||||
$budgetLimit = $this->blRepository->store($data);
|
||||
|
||||
@@ -28,6 +28,7 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Transformers\AccountTransformer;
|
||||
use FireflyIII\Transformers\AttachmentTransformer;
|
||||
use FireflyIII\Transformers\PiggyBankEventTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -58,6 +59,38 @@ class ListController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listAccountByPiggyBank
|
||||
*
|
||||
* List single resource.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function accounts(PiggyBank $piggyBank): JsonResponse
|
||||
{
|
||||
// types to get, page size:
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
$manager = $this->getManager();
|
||||
|
||||
$collection = $piggyBank->accounts;
|
||||
$count = $collection->count();
|
||||
$events = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($events, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.piggy-banks.accounts', [$piggyBank->id]).$this->buildParams());
|
||||
|
||||
/** @var AccountTransformer $transformer */
|
||||
$transformer = app(AccountTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new FractalCollection($events, $transformer, 'accounts');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listAttachmentByPiggyBank
|
||||
|
||||
@@ -72,7 +72,7 @@ class ShowController extends Controller
|
||||
// types to get, page size:
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
|
||||
// get list of budgets. Count it and split it.
|
||||
// get list of piggy banks. Count it and split it.
|
||||
$collection = $this->repository->getPiggyBanks();
|
||||
$count = $collection->count();
|
||||
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
@@ -62,7 +62,6 @@ class AccountController extends Controller
|
||||
*/
|
||||
public function search(Request $request): JsonResponse|Response
|
||||
{
|
||||
app('log')->debug('Now in account search()');
|
||||
$manager = $this->getManager();
|
||||
$query = trim((string) $request->get('query'));
|
||||
$field = trim((string) $request->get('field'));
|
||||
@@ -70,6 +69,7 @@ class AccountController extends Controller
|
||||
if ('' === $query || !in_array($field, $this->validFields, true)) {
|
||||
return response(null, 422);
|
||||
}
|
||||
app('log')->debug(sprintf('Now in account search("%s", "%s")', $field, $query));
|
||||
$types = $this->mapAccountTypes($type);
|
||||
|
||||
/** @var AccountSearch $search */
|
||||
|
||||
@@ -27,19 +27,21 @@ namespace FireflyIII\Api\V1\Controllers\Summary;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Requests\Data\DateRequest;
|
||||
use FireflyIII\Enums\AccountTypeEnum;
|
||||
use FireflyIII\Enums\TransactionTypeEnum;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Helpers\Report\NetWorthInterface;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class BasicController
|
||||
@@ -120,6 +122,9 @@ class BasicController extends Controller
|
||||
|
||||
private function getBalanceInformation(Carbon $start, Carbon $end): array
|
||||
{
|
||||
// some config settings
|
||||
$convertToNative = app('preferences')->get('convert_to_native', false)->data;
|
||||
$default = app('amount')->getDefaultCurrency();
|
||||
// prep some arrays:
|
||||
$incomes = [];
|
||||
$expenses = [];
|
||||
@@ -133,16 +138,17 @@ class BasicController extends Controller
|
||||
|
||||
$set = $collector->getExtractedJournals();
|
||||
|
||||
/** @var array $transactionJournal */
|
||||
foreach ($set as $transactionJournal) {
|
||||
$currencyId = (int)$transactionJournal['currency_id'];
|
||||
/** @var array $journal */
|
||||
foreach ($set as $journal) {
|
||||
$currencyId = $convertToNative ? $default->id : (int) $journal['currency_id'];
|
||||
$amount = Amount::getAmountFromJournal($journal);
|
||||
$incomes[$currencyId] ??= '0';
|
||||
$incomes[$currencyId] = bcadd(
|
||||
$incomes[$currencyId],
|
||||
bcmul($transactionJournal['amount'], '-1')
|
||||
bcmul($amount, '-1')
|
||||
);
|
||||
$sums[$currencyId] ??= '0';
|
||||
$sums[$currencyId] = bcadd($sums[$currencyId], bcmul($transactionJournal['amount'], '-1'));
|
||||
$sums[$currencyId] = bcadd($sums[$currencyId], bcmul($amount, '-1'));
|
||||
}
|
||||
|
||||
// collect expenses of user using the new group collector.
|
||||
@@ -151,13 +157,14 @@ class BasicController extends Controller
|
||||
$collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||
$set = $collector->getExtractedJournals();
|
||||
|
||||
/** @var array $transactionJournal */
|
||||
foreach ($set as $transactionJournal) {
|
||||
$currencyId = (int)$transactionJournal['currency_id'];
|
||||
/** @var array $journal */
|
||||
foreach ($set as $journal) {
|
||||
$currencyId = $convertToNative ? $default->id : (int) $journal['currency_id'];
|
||||
$amount = Amount::getAmountFromJournal($journal);
|
||||
$expenses[$currencyId] ??= '0';
|
||||
$expenses[$currencyId] = bcadd($expenses[$currencyId], $transactionJournal['amount']);
|
||||
$expenses[$currencyId] = bcadd($expenses[$currencyId], $amount);
|
||||
$sums[$currencyId] ??= '0';
|
||||
$sums[$currencyId] = bcadd($sums[$currencyId], $transactionJournal['amount']);
|
||||
$sums[$currencyId] = bcadd($sums[$currencyId], $amount);
|
||||
}
|
||||
|
||||
// format amounts:
|
||||
@@ -274,19 +281,22 @@ class BasicController extends Controller
|
||||
$available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
|
||||
$budgets = $this->budgetRepository->getActiveBudgets();
|
||||
$spent = $this->opsRepository->sumExpenses($start, $end, null, $budgets);
|
||||
$days = (int) $today->diffInDays($end, true) + 1;
|
||||
Log::debug(sprintf('Now in getLeftToSpendInfo("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
|
||||
|
||||
foreach ($spent as $row) {
|
||||
// either an amount was budgeted or 0 is available.
|
||||
$amount = (string)($available[$row['currency_id']] ?? '0');
|
||||
$currencyId = $row['currency_id'];
|
||||
$amount = (string) ($available[$currencyId] ?? '0');
|
||||
$spentInCurrency = $row['sum'];
|
||||
$leftToSpend = bcadd($amount, $spentInCurrency);
|
||||
|
||||
$days = (int)$today->diffInDays($end, true) + 1;
|
||||
$perDay = '0';
|
||||
if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
|
||||
$perDay = bcdiv($leftToSpend, (string) $days);
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Spent %s %s', $row['currency_code'], $row['sum']));
|
||||
|
||||
$return[] = [
|
||||
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
|
||||
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]),
|
||||
@@ -311,9 +321,11 @@ class BasicController extends Controller
|
||||
|
||||
private function getNetWorthInfo(Carbon $start, Carbon $end): array
|
||||
{
|
||||
Log::debug('getNetWorthInfo');
|
||||
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$date = today(config('app.timezone'))->startOfDay();
|
||||
$date = now(config('app.timezone'));
|
||||
// start and end in the future? use $end
|
||||
if ($this->notInDateRange($date, $start, $end)) {
|
||||
/** @var Carbon $date */
|
||||
@@ -323,9 +335,7 @@ class BasicController extends Controller
|
||||
/** @var NetWorthInterface $netWorthHelper */
|
||||
$netWorthHelper = app(NetWorthInterface::class);
|
||||
$netWorthHelper->setUser($user);
|
||||
$allAccounts = $this->accountRepository->getActiveAccountsByType(
|
||||
[AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT]
|
||||
);
|
||||
$allAccounts = $this->accountRepository->getActiveAccountsByType([AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::DEBT->value]);
|
||||
|
||||
// filter list on preference of being included.
|
||||
$filtered = $allAccounts->filter(
|
||||
@@ -360,6 +370,7 @@ class BasicController extends Controller
|
||||
'sub_title' => '',
|
||||
];
|
||||
}
|
||||
Log::debug('End of getNetWorthInfo');
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ class StoreRequest extends FormRequest
|
||||
'amount' => $this->convertString('amount'),
|
||||
'currency_id' => $this->convertInteger('currency_id'),
|
||||
'currency_code' => $this->convertString('currency_code'),
|
||||
'notes' => $this->stringWithNewlines('notes'),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -62,6 +63,7 @@ class StoreRequest extends FormRequest
|
||||
'amount' => ['required', new IsValidPositiveAmount()],
|
||||
'currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
|
||||
'notes' => 'nullable|min:0|max:32768',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,12 @@ class UpdateRequest extends FormRequest
|
||||
'amount' => ['amount', 'convertString'],
|
||||
'currency_id' => ['currency_id', 'convertInteger'],
|
||||
'currency_code' => ['currency_code', 'convertString'],
|
||||
'notes' => ['notes', 'stringWithNewlines'],
|
||||
];
|
||||
if (false === $this->has('notes')) {
|
||||
// ignore notes, not submitted.
|
||||
unset($fields['notes']);
|
||||
}
|
||||
|
||||
return $this->getAllData($fields);
|
||||
}
|
||||
@@ -67,6 +72,7 @@ class UpdateRequest extends FormRequest
|
||||
'amount' => ['nullable', new IsValidPositiveAmount()],
|
||||
'currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
|
||||
'notes' => 'nullable|min:0|max:32768',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests\Models\PiggyBank;
|
||||
|
||||
use FireflyIII\Rules\IsValidPositiveAmount;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Rules\IsValidZeroOrMoreAmount;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
/**
|
||||
* Class StoreRequest
|
||||
@@ -47,18 +52,38 @@ class StoreRequest extends FormRequest
|
||||
];
|
||||
$data = $this->getAllData($fields);
|
||||
$data['name'] = $this->convertString('name');
|
||||
$data['account_id'] = $this->convertInteger('account_id');
|
||||
$data['targetamount'] = $this->convertString('target_amount');
|
||||
$data['current_amount'] = $this->convertString('current_amount');
|
||||
$data['startdate'] = $this->getCarbonDate('start_date');
|
||||
$data['targetdate'] = $this->getCarbonDate('target_date');
|
||||
$data['accounts'] = $this->parseAccounts($this->get('accounts'));
|
||||
$data['target_amount'] = $this->convertString('target_amount');
|
||||
$data['start_date'] = $this->getCarbonDate('start_date');
|
||||
$data['target_date'] = $this->getCarbonDate('target_date');
|
||||
$data['notes'] = $this->stringWithNewlines('notes');
|
||||
$data['object_group_id'] = $this->convertInteger('object_group_id');
|
||||
$data['transaction_currency_id'] = $this->convertInteger('transaction_currency_id');
|
||||
$data['transaction_currency_code'] = $this->convertString('transaction_currency_code');
|
||||
$data['object_group_title'] = $this->convertString('object_group_title');
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function parseAccounts(mixed $array): array
|
||||
{
|
||||
if (!is_array($array)) {
|
||||
return [];
|
||||
}
|
||||
$return = [];
|
||||
foreach ($array as $entry) {
|
||||
if (!is_array($entry)) {
|
||||
continue;
|
||||
}
|
||||
$return[] = [
|
||||
'account_id' => $this->integerFromValue((string) ($entry['account_id'] ?? '0')),
|
||||
'current_amount' => $this->clearString((string) ($entry['current_amount'] ?? '0')),
|
||||
];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*/
|
||||
@@ -66,14 +91,79 @@ class StoreRequest extends FormRequest
|
||||
{
|
||||
return [
|
||||
'name' => 'required|min:1|max:255|uniquePiggyBankForUser',
|
||||
'current_amount' => ['nullable', new IsValidPositiveAmount()],
|
||||
'account_id' => 'required|numeric|belongsToUser:accounts,id',
|
||||
'accounts' => 'required',
|
||||
'accounts.*' => 'array|required',
|
||||
'accounts.*.account_id' => 'required|numeric|belongsToUser:accounts,id',
|
||||
'accounts.*.current_amount' => ['numeric', new IsValidZeroOrMoreAmount()],
|
||||
'object_group_id' => 'numeric|belongsToUser:object_groups,id',
|
||||
'object_group_title' => ['min:1', 'max:255'],
|
||||
'target_amount' => ['required', new IsValidPositiveAmount()],
|
||||
'target_amount' => ['required', new IsValidZeroOrMoreAmount()],
|
||||
'start_date' => 'date|nullable',
|
||||
'transaction_currency_id' => 'exists:transaction_currencies,id|required_without:transaction_currency_code',
|
||||
'transaction_currency_code' => 'exists:transaction_currencies,code|required_without:transaction_currency_id',
|
||||
'target_date' => 'date|nullable|after:start_date',
|
||||
'notes' => 'max:65000',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Can only store money on liabilities and asset accounts.
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(
|
||||
function (Validator $validator): void {
|
||||
// validate start before end only if both are there.
|
||||
$data = $validator->getData();
|
||||
$currency = $this->getCurrencyFromData($data);
|
||||
$targetAmount = (string) ($data['target_amount'] ?? '0');
|
||||
$currentAmount = '0';
|
||||
if (array_key_exists('accounts', $data) && is_array($data['accounts'])) {
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$types = config('firefly.piggy_bank_account_types');
|
||||
foreach ($data['accounts'] as $index => $array) {
|
||||
$accountId = (int) ($array['account_id'] ?? 0);
|
||||
$account = $repository->find($accountId);
|
||||
if (null !== $account) {
|
||||
// check currency here.
|
||||
$accountCurrency = $repository->getAccountCurrency($account);
|
||||
$isMultiCurrency = $repository->getMetaValue($account, 'is_multi_currency');
|
||||
$currentAmount = bcadd($currentAmount, (string) ($array['current_amount'] ?? '0'));
|
||||
if ($accountCurrency->id !== $currency->id && 'true' !== $isMultiCurrency) {
|
||||
$validator->errors()->add(sprintf('accounts.%d', $index), trans('validation.invalid_account_currency'));
|
||||
}
|
||||
$type = $account->accountType->type;
|
||||
if (!in_array($type, $types, true)) {
|
||||
$validator->errors()->add(sprintf('accounts.%d', $index), trans('validation.invalid_account_type'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (-1 === bccomp($targetAmount, $currentAmount) && 1 === bccomp($targetAmount, '0')) {
|
||||
$validator->errors()->add('target_amount', trans('validation.current_amount_too_much'));
|
||||
}
|
||||
}
|
||||
);
|
||||
if ($validator->fails()) {
|
||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
private function getCurrencyFromData(array $data): TransactionCurrency
|
||||
{
|
||||
if (array_key_exists('transaction_currency_code', $data) && '' !== (string) $data['transaction_currency_code']) {
|
||||
$currency = TransactionCurrency::whereCode($data['transaction_currency_code'])->first();
|
||||
if (null !== $currency) {
|
||||
return $currency;
|
||||
}
|
||||
}
|
||||
if (array_key_exists('transaction_currency_id', $data) && '' !== (string) $data['transaction_currency_id']) {
|
||||
$currency = TransactionCurrency::find((int) $data['transaction_currency_id']);
|
||||
if (null !== $currency) {
|
||||
return $currency;
|
||||
}
|
||||
}
|
||||
|
||||
throw new FireflyException('Unexpected empty currency.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ class StoreRequest extends FormRequest
|
||||
'description' => 'min:1|max:32768|nullable',
|
||||
'rule_group_id' => 'belongsToUser:rule_groups|required_without:rule_group_title',
|
||||
'rule_group_title' => 'nullable|min:1|max:255|required_without:rule_group_id|belongsToUser:rule_groups,title',
|
||||
'trigger' => 'required|in:store-journal,update-journal',
|
||||
'trigger' => 'required|in:store-journal,update-journal,manual-activation',
|
||||
'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
|
||||
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
|
||||
'triggers.*.stop_processing' => [new IsBoolean()],
|
||||
|
||||
@@ -138,7 +138,7 @@ class UpdateRequest extends FormRequest
|
||||
'description' => 'min:1|max:32768|nullable',
|
||||
'rule_group_id' => 'belongsToUser:rule_groups',
|
||||
'rule_group_title' => 'nullable|min:1|max:255|belongsToUser:rule_groups,title',
|
||||
'trigger' => 'in:store-journal,update-journal',
|
||||
'trigger' => 'in:store-journal,update-journal.manual-activation',
|
||||
'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
|
||||
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
|
||||
'triggers.*.stop_processing' => [new IsBoolean()],
|
||||
|
||||
@@ -40,9 +40,9 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class AccountController extends Controller
|
||||
{
|
||||
private AccountRepositoryInterface $repository;
|
||||
private TransactionCurrency $default;
|
||||
private ExchangeRateConverter $converter;
|
||||
private TransactionCurrency $default;
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
|
||||
@@ -45,9 +45,9 @@ class AccountController extends Controller
|
||||
use CollectsAccountsFromFilter;
|
||||
use ValidatesUserGroupTrait;
|
||||
|
||||
private AccountRepositoryInterface $repository;
|
||||
private ChartData $chartData;
|
||||
private TransactionCurrency $default;
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -118,22 +118,21 @@ class AccountController extends Controller
|
||||
'native_entries' => [],
|
||||
];
|
||||
$currentStart = clone $params['start'];
|
||||
$range = app('steam')->balanceInRange($account, $params['start'], clone $params['end'], $currency);
|
||||
$rangeConverted = app('steam')->balanceInRangeConverted($account, $params['start'], clone $params['end'], $this->default);
|
||||
$range = app('steam')->finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative);
|
||||
|
||||
$previous = array_values($range)[0];
|
||||
$previousConverted = array_values($rangeConverted)[0];
|
||||
$previous = array_values($range)[0]['balance'];
|
||||
$previousNative = array_values($range)[0]['native_balance'];
|
||||
while ($currentStart <= $params['end']) {
|
||||
$format = $currentStart->format('Y-m-d');
|
||||
$label = $currentStart->toAtomString();
|
||||
$balance = array_key_exists($format, $range) ? $range[$format] : $previous;
|
||||
$balanceConverted = array_key_exists($format, $rangeConverted) ? $rangeConverted[$format] : $previousConverted;
|
||||
$balance = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous;
|
||||
$balanceNative = array_key_exists($format, $range) ? $range[$format]['balance_native'] : $previousNative;
|
||||
$previous = $balance;
|
||||
$previousConverted = $balanceConverted;
|
||||
$previousNative = $balanceNative;
|
||||
|
||||
$currentStart->addDay();
|
||||
$currentSet['entries'][$label] = $balance;
|
||||
$currentSet['native_entries'][$label] = $balanceConverted;
|
||||
$currentSet['native_entries'][$label] = $balanceNative;
|
||||
}
|
||||
$this->chartData->add($currentSet);
|
||||
}
|
||||
|
||||
@@ -45,9 +45,10 @@ class BalanceController extends Controller
|
||||
use CleansChartData;
|
||||
use CollectsAccountsFromFilter;
|
||||
|
||||
private AccountRepositoryInterface $repository;
|
||||
private GroupCollectorInterface $collector;
|
||||
private ChartData $chartData;
|
||||
private GroupCollectorInterface $collector;
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
// private TransactionCurrency $default;
|
||||
|
||||
public function __construct()
|
||||
|
||||
@@ -55,8 +55,9 @@ class Controller extends BaseController
|
||||
use ValidatesUserGroupTrait;
|
||||
|
||||
protected const string CONTENT_TYPE = 'application/vnd.api+json';
|
||||
protected ParameterBag $parameters;
|
||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||
protected ParameterBag $parameters;
|
||||
protected bool $convertToNative = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -92,8 +93,8 @@ class Controller extends BaseController
|
||||
if ($page < 1) {
|
||||
$page = 1;
|
||||
}
|
||||
if ($page > (2 ^ 16)) {
|
||||
$page = (2 ^ 16);
|
||||
if ($page > 2 ** 16) {
|
||||
$page = 2 ** 16;
|
||||
}
|
||||
$bag->set('page', $page);
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ class AccountController extends Controller
|
||||
use Actions\DetachRelationship;
|
||||
|
||||
use Actions\FetchMany;
|
||||
|
||||
// use Actions\FetchOne;
|
||||
use Actions\FetchRelated;
|
||||
use Actions\FetchRelationship;
|
||||
|
||||
@@ -36,9 +36,8 @@ use Illuminate\Support\Facades\Log;
|
||||
class IndexController extends Controller
|
||||
{
|
||||
public const string RESOURCE_KEY = 'accounts';
|
||||
|
||||
private AccountRepositoryInterface $repository;
|
||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY, UserRoleEnum::MANAGE_TRANSACTIONS];
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
|
||||
@@ -39,9 +39,8 @@ use Illuminate\Http\JsonResponse;
|
||||
class ShowController extends Controller
|
||||
{
|
||||
public const string RESOURCE_KEY = 'accounts';
|
||||
|
||||
private AccountRepositoryInterface $repository;
|
||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY, UserRoleEnum::MANAGE_TRANSACTIONS];
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DestroyController.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\ExchangeRate;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Model\ExchangeRate\DestroyRequest;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class DestroyController extends Controller
|
||||
{
|
||||
use ValidatesUserGroupTrait;
|
||||
|
||||
public const string RESOURCE_KEY = 'exchange-rates';
|
||||
|
||||
private ExchangeRateRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(ExchangeRateRepositoryInterface::class);
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function destroy(DestroyRequest $request, TransactionCurrency $from, TransactionCurrency $to): JsonResponse
|
||||
{
|
||||
$date = $request->getDate();
|
||||
$rate = $this->repository->getSpecificRateOnDate($from, $to, $date);
|
||||
if (null === $rate) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
$this->repository->deleteRate($rate);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ShowController.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\ExchangeRate;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* Class ShowController
|
||||
*/
|
||||
class IndexController extends Controller
|
||||
{
|
||||
use ValidatesUserGroupTrait;
|
||||
|
||||
public const string RESOURCE_KEY = 'exchange-rates';
|
||||
|
||||
private ExchangeRateRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(ExchangeRateRepositoryInterface::class);
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
$piggies = $this->repository->getAll();
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
$count = $piggies->count();
|
||||
$piggies = $piggies->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
$paginator = new LengthAwarePaginator($piggies, $count, $pageSize, $this->parameters->get('page'));
|
||||
|
||||
var_dump('here we are');
|
||||
|
||||
$transformer = new ExchangeRateTransformer();
|
||||
$transformer->setParameters($this->parameters); // give params to transformer
|
||||
|
||||
return response()
|
||||
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
}
|
||||
76
app/Api/V2/Controllers/Model/ExchangeRate/ShowController.php
Normal file
76
app/Api/V2/Controllers/Model/ExchangeRate/ShowController.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ShowController.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\ExchangeRate;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* Class ShowController
|
||||
*/
|
||||
class ShowController extends Controller
|
||||
{
|
||||
use ValidatesUserGroupTrait;
|
||||
|
||||
public const string RESOURCE_KEY = 'exchange-rates';
|
||||
|
||||
private ExchangeRateRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(ExchangeRateRepositoryInterface::class);
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function show(TransactionCurrency $from, TransactionCurrency $to): JsonResponse
|
||||
{
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
$page = $this->parameters->get('page');
|
||||
$rates = $this->repository->getRates($from, $to);
|
||||
$count = $rates->count();
|
||||
$rates = $rates->slice(($page - 1) * $pageSize, $pageSize);
|
||||
$paginator = new LengthAwarePaginator($rates, $count, $pageSize, $page);
|
||||
|
||||
$transformer = new ExchangeRateTransformer();
|
||||
$transformer->setParameters($this->parameters); // give params to transformer
|
||||
|
||||
return response()
|
||||
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DestroyController.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\ExchangeRate;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Model\ExchangeRate\StoreRequest;
|
||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class StoreController extends Controller
|
||||
{
|
||||
use ValidatesUserGroupTrait;
|
||||
|
||||
public const string RESOURCE_KEY = 'exchange-rates';
|
||||
|
||||
private ExchangeRateRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(ExchangeRateRepositoryInterface::class);
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function store(StoreRequest $request): JsonResponse
|
||||
{
|
||||
$date = $request->getDate();
|
||||
$rate = $request->getRate();
|
||||
$from = $request->getFromCurrency();
|
||||
$to = $request->getToCurrency();
|
||||
|
||||
// already has rate?
|
||||
$object = $this->repository->getSpecificRateOnDate($from, $to, $date);
|
||||
if (null !== $object) {
|
||||
// just update it, no matter.
|
||||
$rate = $this->repository->updateExchangeRate($object, $rate, $date);
|
||||
}
|
||||
if (null === $object) {
|
||||
// store new
|
||||
$rate = $this->repository->storeExchangeRate($from, $to, $rate, $date);
|
||||
}
|
||||
|
||||
$transformer = new ExchangeRateTransformer();
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
return response()
|
||||
->api($this->jsonApiObject(self::RESOURCE_KEY, $rate, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DestroyController.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\ExchangeRate;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Model\ExchangeRate\UpdateRequest;
|
||||
use FireflyIII\Models\CurrencyExchangeRate;
|
||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class UpdateController extends Controller
|
||||
{
|
||||
use ValidatesUserGroupTrait;
|
||||
|
||||
public const string RESOURCE_KEY = 'exchange-rates';
|
||||
|
||||
private ExchangeRateRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(ExchangeRateRepositoryInterface::class);
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function update(UpdateRequest $request, CurrencyExchangeRate $exchangeRate): JsonResponse
|
||||
{
|
||||
$date = $request->getDate();
|
||||
$rate = $request->getRate();
|
||||
$exchangeRate = $this->repository->updateExchangeRate($exchangeRate, $rate, $date);
|
||||
$transformer = new ExchangeRateTransformer();
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
return response()
|
||||
->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* IndexController.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\TransactionCurrency;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Model\TransactionCurrency\IndexRequest;
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Transformers\V2\CurrencyTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
public const string RESOURCE_KEY = 'transaction-currencies';
|
||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||
private CurrencyRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
// new way of user group validation
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function index(IndexRequest $request): JsonResponse
|
||||
{
|
||||
$settings = $request->getAll();
|
||||
if (true === $settings['enabled']) {
|
||||
$currencies = $this->repository->get();
|
||||
}
|
||||
if (true !== $settings['enabled']) {
|
||||
$currencies = $this->repository->getAll();
|
||||
}
|
||||
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
$count = $currencies->count();
|
||||
|
||||
// depending on the sort parameters, this list must not be split, because the
|
||||
// order is calculated in the account transformer and by that time it's too late.
|
||||
$accounts = $currencies->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
$paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
|
||||
$transformer = new CurrencyTransformer();
|
||||
|
||||
$this->parameters->set('pageSize', $pageSize);
|
||||
$transformer->setParameters($this->parameters); // give params to transformer
|
||||
|
||||
return response()
|
||||
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ShowController.php
|
||||
* Copyright (c) 2021 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\TransactionCurrency;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Transformers\V2\CurrencyTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* Class ShowController
|
||||
*/
|
||||
class ShowController extends Controller
|
||||
{
|
||||
public const string RESOURCE_KEY = 'transaction-currencies';
|
||||
|
||||
private CurrencyRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
// new way of user group validation
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function show(TransactionCurrency $currency): JsonResponse
|
||||
{
|
||||
$groups = $currency->userGroups()->where('user_groups.id', $this->repository->getUserGroup()->id)->get();
|
||||
$enabled = $groups->count() > 0;
|
||||
$default = false;
|
||||
|
||||
/** @var UserGroup $group */
|
||||
foreach ($groups as $group) {
|
||||
$default = 1 === $group->pivot->group_default;
|
||||
}
|
||||
$currency->userGroupEnabled = $enabled;
|
||||
$currency->userGroupDefault = $default;
|
||||
|
||||
|
||||
$transformer = new CurrencyTransformer();
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
return response()
|
||||
->api($this->jsonApiObject(self::RESOURCE_KEY, $currency, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -73,6 +73,16 @@ class AutocompleteRequest extends FormRequest
|
||||
return $array;
|
||||
}
|
||||
|
||||
private function getAccountTypeParameter(array $types): array
|
||||
{
|
||||
$return = [];
|
||||
foreach ($types as $type) {
|
||||
$return = array_merge($return, $this->mapAccountTypes($type));
|
||||
}
|
||||
|
||||
return array_unique($return);
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
$valid = array_keys($this->types);
|
||||
@@ -86,14 +96,4 @@ class AutocompleteRequest extends FormRequest
|
||||
'transaction_types' => 'nullable|in:todo',
|
||||
];
|
||||
}
|
||||
|
||||
private function getAccountTypeParameter(array $types): array
|
||||
{
|
||||
$return = [];
|
||||
foreach ($types as $type) {
|
||||
$return = array_merge($return, $this->mapAccountTypes($type));
|
||||
}
|
||||
|
||||
return array_unique($return);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ class BalanceChartRequest extends FormRequest
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
use ValidatesUserGroupTrait;
|
||||
|
||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||
|
||||
/**
|
||||
|
||||
51
app/Api/V2/Request/Model/ExchangeRate/DestroyRequest.php
Normal file
51
app/Api/V2/Request/Model/ExchangeRate/DestroyRequest.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DestroyRequest.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Request\Model\ExchangeRate;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class DestroyRequest extends FormRequest
|
||||
{
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
|
||||
public function getDate(): Carbon
|
||||
{
|
||||
return $this->getCarbonDate('date');
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
|
||||
];
|
||||
}
|
||||
}
|
||||
70
app/Api/V2/Request/Model/ExchangeRate/StoreRequest.php
Normal file
70
app/Api/V2/Request/Model/ExchangeRate/StoreRequest.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DestroyRequest.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Request\Model\ExchangeRate;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreRequest extends FormRequest
|
||||
{
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
|
||||
public function getDate(): ?Carbon
|
||||
{
|
||||
return $this->getCarbonDate('date');
|
||||
}
|
||||
|
||||
public function getRate(): string
|
||||
{
|
||||
return (string) $this->get('rate');
|
||||
}
|
||||
|
||||
public function getFromCurrency(): TransactionCurrency
|
||||
{
|
||||
return TransactionCurrency::where('code', $this->get('from'))->first();
|
||||
}
|
||||
|
||||
public function getToCurrency(): TransactionCurrency
|
||||
{
|
||||
return TransactionCurrency::where('code', $this->get('to'))->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
|
||||
'rate' => 'required|numeric|gt:0',
|
||||
'from' => 'required|exists:transaction_currencies,code',
|
||||
'to' => 'required|exists:transaction_currencies,code',
|
||||
];
|
||||
}
|
||||
}
|
||||
57
app/Api/V2/Request/Model/ExchangeRate/UpdateRequest.php
Normal file
57
app/Api/V2/Request/Model/ExchangeRate/UpdateRequest.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DestroyRequest.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Request\Model\ExchangeRate;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateRequest extends FormRequest
|
||||
{
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
|
||||
public function getDate(): ?Carbon
|
||||
{
|
||||
return $this->getCarbonDate('date');
|
||||
}
|
||||
|
||||
public function getRate(): string
|
||||
{
|
||||
return (string) $this->get('rate');
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'rate' => 'required|numeric|gt:0',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* IndexRequest.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Request\Model\TransactionCurrency;
|
||||
|
||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use FireflyIII\Support\Request\GetFilterInstructions;
|
||||
use FireflyIII\Support\Request\GetSortInstructions;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
/**
|
||||
* Class IndexRequest
|
||||
*
|
||||
* Lots of code stolen from the SingleDateRequest.
|
||||
*/
|
||||
class IndexRequest extends FormRequest
|
||||
{
|
||||
use AccountFilter;
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
use GetFilterInstructions;
|
||||
use GetSortInstructions;
|
||||
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'enabled' => $this->convertBoolean($this->get('enabled')),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'enabled' => 'nullable|boolean',
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ConvertsDatesToUTC.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* ConvertDatesToUTC.php
|
||||
@@ -21,7 +41,7 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Console\Commands\Integrity;
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
@@ -31,17 +51,10 @@ use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ConvertDatesToUTC extends Command
|
||||
class ConvertsDatesToUTC extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:migrate-to-utc';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -49,11 +62,22 @@ class ConvertDatesToUTC extends Command
|
||||
*/
|
||||
protected $description = 'Convert stored dates to UTC.';
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'correction:convert-to-utc';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$this->friendlyWarning('Please do not use this command.');
|
||||
|
||||
return 0;
|
||||
|
||||
/**
|
||||
* @var string $model
|
||||
* @var array $fields
|
||||
@@ -1,253 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* CorrectAmounts.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\AutoBudget;
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\CurrencyExchangeRate;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\RecurrenceTransaction;
|
||||
use FireflyIII\Models\RuleTrigger;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class ReportSkeleton
|
||||
*/
|
||||
class CorrectAmounts extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'This command makes sure positive and negative amounts are recorded correctly.';
|
||||
protected $signature = 'firefly-iii:fix-amount-pos-neg';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
// auto budgets must be positive
|
||||
$this->fixAutoBudgets();
|
||||
// available budgets must be positive
|
||||
$this->fixAvailableBudgets();
|
||||
// bills must be positive (both amounts)
|
||||
$this->fixBills();
|
||||
// budget limits must be positive
|
||||
$this->fixBudgetLimits();
|
||||
// currency_exchange_rates must be positive
|
||||
$this->fixExchangeRates();
|
||||
// piggy_bank_repetitions must be positive
|
||||
$this->fixRepetitions();
|
||||
// piggy_banks must be positive
|
||||
$this->fixPiggyBanks();
|
||||
// recurrences_transactions amount must be positive
|
||||
$this->fixRecurrences();
|
||||
// rule_triggers must be positive or zero (amount_less, amount_more, amount_is)
|
||||
$this->fixRuleTriggers();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function fixAutoBudgets(): void
|
||||
{
|
||||
$set = AutoBudget::where('amount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All auto budget amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var AutoBudget $item */
|
||||
foreach ($set as $item) {
|
||||
$item->amount = app('steam')->positive($item->amount);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d auto budget amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixAvailableBudgets(): void
|
||||
{
|
||||
$set = AvailableBudget::where('amount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All available budget amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var AvailableBudget $item */
|
||||
foreach ($set as $item) {
|
||||
$item->amount = app('steam')->positive($item->amount);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d available budget amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixBills(): void
|
||||
{
|
||||
$set = Bill::where('amount_min', '<', 0)->orWhere('amount_max', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All bill amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var Bill $item */
|
||||
foreach ($set as $item) {
|
||||
$item->amount_min = app('steam')->positive($item->amount_min);
|
||||
$item->amount_max = app('steam')->positive($item->amount_max);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d bill amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixBudgetLimits(): void
|
||||
{
|
||||
$set = BudgetLimit::where('amount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All budget limit amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var BudgetLimit $item */
|
||||
foreach ($set as $item) {
|
||||
$item->amount = app('steam')->positive($item->amount);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d budget limit amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixExchangeRates(): void
|
||||
{
|
||||
$set = CurrencyExchangeRate::where('rate', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All currency exchange rates are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var CurrencyExchangeRate $item */
|
||||
foreach ($set as $item) {
|
||||
$item->rate = app('steam')->positive($item->rate);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d currency exchange rate(s).', $count));
|
||||
}
|
||||
|
||||
private function fixRepetitions(): void
|
||||
{
|
||||
$set = PiggyBankRepetition::where('currentamount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All piggy bank repetition amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var PiggyBankRepetition $item */
|
||||
foreach ($set as $item) {
|
||||
$item->currentamount = app('steam')->positive($item->currentamount);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d piggy bank repetition amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixPiggyBanks(): void
|
||||
{
|
||||
$set = PiggyBank::where('targetamount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All piggy bank amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var PiggyBank $item */
|
||||
foreach ($set as $item) {
|
||||
$item->targetamount = app('steam')->positive($item->targetamount);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d piggy bank amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixRecurrences(): void
|
||||
{
|
||||
$set = RecurrenceTransaction::where('amount', '<', 0)
|
||||
->orWhere('foreign_amount', '<', 0)
|
||||
->get()
|
||||
;
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All recurring transaction amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var RecurrenceTransaction $item */
|
||||
foreach ($set as $item) {
|
||||
$item->amount = app('steam')->positive($item->amount);
|
||||
$item->foreign_amount = app('steam')->positive($item->foreign_amount);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d recurring transaction amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixRuleTriggers(): void
|
||||
{
|
||||
$set = RuleTrigger::whereIn('trigger_type', ['amount_less', 'amount_more', 'amount_is'])->get();
|
||||
$fixed = 0;
|
||||
|
||||
/** @var RuleTrigger $item */
|
||||
foreach ($set as $item) {
|
||||
// basic check:
|
||||
$check = 0;
|
||||
|
||||
try {
|
||||
$check = bccomp((string)$item->trigger_value, '0');
|
||||
} catch (\ValueError $e) {
|
||||
$this->friendlyError(sprintf('Rule #%d contained invalid %s-trigger "%s". The trigger has been removed, and the rule is disabled.', $item->rule_id, $item->trigger_type, $item->trigger_value));
|
||||
$item->rule->active = false;
|
||||
$item->rule->save();
|
||||
$item->forceDelete();
|
||||
}
|
||||
if (-1 === $check) {
|
||||
++$fixed;
|
||||
$item->trigger_value = app('steam')->positive($item->trigger_value);
|
||||
$item->save();
|
||||
}
|
||||
}
|
||||
if (0 === $fixed) {
|
||||
$this->friendlyPositive('All rule trigger amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d rule trigger amount(s).', $fixed));
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class CorrectionSkeleton extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
protected $description = 'DESCRIPTION HERE';
|
||||
|
||||
protected $signature = 'firefly-iii:CORR_COMMAND';
|
||||
|
||||
@@ -29,15 +29,12 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class FixAccountOrder
|
||||
*/
|
||||
class FixAccountOrder extends Command
|
||||
class CorrectsAccountOrder extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Make sure account order is correct.';
|
||||
protected $signature = 'firefly-iii:fix-account-order';
|
||||
protected $signature = 'correction:account-order';
|
||||
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
@@ -54,8 +51,6 @@ class FixAccountOrder extends Command
|
||||
$this->repository->resetAccountOrder();
|
||||
}
|
||||
|
||||
$this->friendlyPositive('All accounts are ordered correctly');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -36,15 +36,12 @@ use Illuminate\Console\Command;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
|
||||
/**
|
||||
* Class FixAccountTypes
|
||||
*/
|
||||
class FixAccountTypes extends Command
|
||||
class CorrectsAccountTypes extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Make sure all journals have the correct from/to account types.';
|
||||
protected $signature = 'firefly-iii:fix-account-types';
|
||||
protected $signature = 'correction:account-types';
|
||||
private int $count;
|
||||
private array $expected;
|
||||
private AccountFactory $factory;
|
||||
@@ -120,9 +117,6 @@ class FixAccountTypes extends Command
|
||||
}
|
||||
}
|
||||
}
|
||||
if (0 === $this->count) {
|
||||
$this->friendlyPositive('All account types are OK');
|
||||
}
|
||||
if (0 !== $this->count) {
|
||||
app('log')->debug(sprintf('%d journals had to be fixed.', $this->count));
|
||||
$this->friendlyInfo(sprintf('Acted on %d transaction(s)', $this->count));
|
||||
185
app/Console/Commands/Correction/CorrectsAmounts.php
Normal file
185
app/Console/Commands/Correction/CorrectsAmounts.php
Normal file
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* CorrectAmounts.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\AutoBudget;
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\CurrencyExchangeRate;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\RecurrenceTransaction;
|
||||
use FireflyIII\Models\RuleTrigger;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CorrectsAmounts extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'This command makes sure positive and negative amounts are recorded correctly.';
|
||||
protected $signature = 'correction:amounts';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
// auto budgets must be positive
|
||||
$this->fixAutoBudgets();
|
||||
// available budgets must be positive
|
||||
$this->fixAvailableBudgets();
|
||||
// bills must be positive (both amounts)
|
||||
$this->fixBills();
|
||||
// budget limits must be positive
|
||||
$this->fixBudgetLimits();
|
||||
// currency_exchange_rates must be positive
|
||||
$this->fixExchangeRates();
|
||||
// piggy_banks must be positive
|
||||
$this->fixPiggyBanks();
|
||||
// recurrences_transactions amount must be positive
|
||||
$this->fixRecurrences();
|
||||
// rule_triggers must be positive or zero (amount_less, amount_more, amount_is)
|
||||
$this->fixRuleTriggers();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function fixAutoBudgets(): void
|
||||
{
|
||||
$count = AutoBudget::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
|
||||
if (0 === $count) {
|
||||
|
||||
return;
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d auto budget amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixAvailableBudgets(): void
|
||||
{
|
||||
$count = AvailableBudget::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
|
||||
if (0 === $count) {
|
||||
|
||||
return;
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d available budget amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixBills(): void
|
||||
{
|
||||
$count = 0;
|
||||
$count += Bill::where('amount_max', '<', 0)->update(['amount_max' => DB::raw('amount_max * -1')]);
|
||||
$count += Bill::where('amount_min', '<', 0)->update(['amount_min' => DB::raw('amount_min * -1')]);
|
||||
if (0 === $count) {
|
||||
|
||||
return;
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d bill amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixBudgetLimits(): void
|
||||
{
|
||||
$count = BudgetLimit::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
|
||||
if (0 === $count) {
|
||||
|
||||
return;
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d budget limit amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixExchangeRates(): void
|
||||
{
|
||||
$count = CurrencyExchangeRate::where('rate', '<', 0)->update(['rate' => DB::raw('rate * -1')]);
|
||||
if (0 === $count) {
|
||||
|
||||
return;
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d currency exchange rate(s).', $count));
|
||||
}
|
||||
|
||||
private function fixPiggyBanks(): void
|
||||
{
|
||||
$count = PiggyBank::where('target_amount', '<', 0)->update(['target_amount' => DB::raw('target_amount * -1')]);
|
||||
if (0 === $count) {
|
||||
|
||||
return;
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d piggy bank amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixRecurrences(): void
|
||||
{
|
||||
$count = 0;
|
||||
$count += RecurrenceTransaction::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
|
||||
$count += RecurrenceTransaction::where('foreign_amount', '<', 0)->update(['foreign_amount' => DB::raw('foreign_amount * -1')]);
|
||||
if (0 === $count) {
|
||||
|
||||
return;
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d recurring transaction amount(s).', $count));
|
||||
}
|
||||
|
||||
/**
|
||||
* Foreach loop is unavoidable here.
|
||||
*/
|
||||
private function fixRuleTriggers(): void
|
||||
{
|
||||
$set = RuleTrigger::whereIn('trigger_type', ['amount_less', 'amount_more', 'amount_is'])->get();
|
||||
$fixed = 0;
|
||||
|
||||
/** @var RuleTrigger $item */
|
||||
foreach ($set as $item) {
|
||||
$result = $this->fixRuleTrigger($item);
|
||||
if (true === $result) {
|
||||
++$fixed;
|
||||
}
|
||||
}
|
||||
if (0 === $fixed) {
|
||||
|
||||
return;
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d rule trigger amount(s).', $fixed));
|
||||
}
|
||||
|
||||
private function fixRuleTrigger(RuleTrigger $item): bool
|
||||
{
|
||||
try {
|
||||
$check = bccomp((string) $item->trigger_value, '0');
|
||||
} catch (\ValueError $e) {
|
||||
$this->friendlyError(sprintf('Rule #%d contained invalid %s-trigger "%s". The trigger has been removed, and the rule is disabled.', $item->rule_id, $item->trigger_type, $item->trigger_value));
|
||||
$item->rule->active = false;
|
||||
$item->rule->save();
|
||||
$item->forceDelete();
|
||||
|
||||
return false;
|
||||
}
|
||||
if (-1 === $check) {
|
||||
$item->trigger_value = app('steam')->positive($item->trigger_value);
|
||||
$item->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -37,15 +37,12 @@ use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Symfony\Component\Console\Command\Command as CommandAlias;
|
||||
|
||||
/**
|
||||
* Class EnableCurrencies
|
||||
*/
|
||||
class EnableCurrencies extends Command
|
||||
class CorrectsCurrencies extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Enables all currencies in use.';
|
||||
protected $signature = 'firefly-iii:enable-currencies';
|
||||
protected $signature = 'correction:currencies';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -27,14 +27,11 @@ namespace FireflyIII\Console\Commands\Correction;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class CorrectDatabase
|
||||
*/
|
||||
class CorrectDatabase extends Command
|
||||
class CorrectsDatabase extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Will correct the integrity of your database, if necessary.';
|
||||
protected $description = 'Will validate and correct the integrity of your database, if necessary.';
|
||||
protected $signature = 'firefly-iii:correct-database';
|
||||
|
||||
/**
|
||||
@@ -49,32 +46,36 @@ class CorrectDatabase extends Command
|
||||
return 1;
|
||||
}
|
||||
$commands = [
|
||||
'firefly-iii:fix-piggies',
|
||||
'firefly-iii:create-link-types',
|
||||
'firefly-iii:create-access-tokens',
|
||||
'firefly-iii:remove-bills',
|
||||
'firefly-iii:fix-amount-pos-neg',
|
||||
'firefly-iii:enable-currencies',
|
||||
'firefly-iii:fix-transfer-budgets',
|
||||
'firefly-iii:fix-uneven-amount',
|
||||
'firefly-iii:delete-zero-amount',
|
||||
'firefly-iii:delete-orphaned-transactions',
|
||||
'firefly-iii:delete-empty-journals',
|
||||
'firefly-iii:delete-empty-groups',
|
||||
'firefly-iii:fix-account-types',
|
||||
'firefly-iii:fix-ibans',
|
||||
'firefly-iii:fix-account-order',
|
||||
'firefly-iii:rename-meta-fields',
|
||||
'firefly-iii:fix-ob-currencies',
|
||||
'firefly-iii:fix-long-descriptions',
|
||||
'firefly-iii:fix-recurring-transactions',
|
||||
'firefly-iii:upgrade-group-information',
|
||||
'firefly-iii:fix-transaction-types',
|
||||
'firefly-iii:fix-frontpage-accounts',
|
||||
// new!
|
||||
'firefly-iii:unify-group-accounts',
|
||||
'firefly-iii:trigger-credit-recalculation',
|
||||
'firefly-iii:migrate-preferences',
|
||||
'correction:restore-oauth-keys',
|
||||
'correction:timezones',
|
||||
'correction:create-group-memberships',
|
||||
'correction:group-information',
|
||||
'correction:piggy-banks',
|
||||
'correction:link-types',
|
||||
'correction:access-tokens',
|
||||
'correction:bills',
|
||||
'correction:amounts',
|
||||
'correction:currencies',
|
||||
'correction:transfer-budgets',
|
||||
'correction:uneven-amounts',
|
||||
'correction:zero-amounts',
|
||||
'correction:orphaned-transactions',
|
||||
'correction:empty-journals',
|
||||
'correction:empty-groups',
|
||||
'correction:account-types',
|
||||
'correction:ibans',
|
||||
'correction:account-order',
|
||||
'correction:meta-fields',
|
||||
'correction:opening-balance-currencies',
|
||||
'correction:long-descriptions',
|
||||
'correction:recurring-transactions',
|
||||
'correction:frontpage-accounts',
|
||||
'correction:group-accounts',
|
||||
'correction:recalculates-liabilities',
|
||||
'correction:preferences',
|
||||
// 'correction:transaction-types', // resource heavy, disabled.
|
||||
// 'correction:recalculate-native-amounts', // not necessary, disabled.
|
||||
'firefly-iii:report-integrity',
|
||||
];
|
||||
foreach ($commands as $command) {
|
||||
$this->friendlyLine(sprintf('Now executing command "%s"', $command));
|
||||
@@ -31,15 +31,12 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class FixFrontpageAccounts
|
||||
*/
|
||||
class FixFrontpageAccounts extends Command
|
||||
class CorrectsFrontpageAccounts extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Fixes a preference that may include deleted accounts or accounts of another type.';
|
||||
protected $signature = 'firefly-iii:fix-frontpage-accounts';
|
||||
protected $signature = 'correction:frontpage-accounts';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -55,7 +52,6 @@ class FixFrontpageAccounts extends Command
|
||||
$this->fixPreference($preference);
|
||||
}
|
||||
}
|
||||
$this->friendlyPositive('Account preferences are OK');
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -34,12 +34,12 @@ use Illuminate\Console\Command;
|
||||
/**
|
||||
* Class FixGroupAccounts
|
||||
*/
|
||||
class FixGroupAccounts extends Command
|
||||
class CorrectsGroupAccounts extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Unify the source / destination accounts of split groups.';
|
||||
protected $signature = 'firefly-iii:unify-group-accounts';
|
||||
protected $signature = 'correction:group-accounts';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -64,8 +64,6 @@ class FixGroupAccounts extends Command
|
||||
$handler->unifyAccounts($event);
|
||||
}
|
||||
|
||||
$this->friendlyPositive('Updated possible inconsistent transaction groups.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* UpdateGroupInformation.php
|
||||
* Copyright (c) 2022 james@firefly-iii.org
|
||||
* CorrectsGroupInformation.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
@@ -17,12 +17,12 @@
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Integrity;
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\Account;
|
||||
@@ -45,15 +45,12 @@ use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\QueryException;
|
||||
|
||||
/**
|
||||
* Class UpdateGroupInformation
|
||||
*/
|
||||
class UpdateGroupInformation extends Command
|
||||
class CorrectsGroupInformation extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Makes sure that every object is linked to a group';
|
||||
protected $signature = 'firefly-iii:upgrade-group-information';
|
||||
protected $signature = 'correction:group-information';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -79,7 +76,7 @@ class UpdateGroupInformation extends Command
|
||||
{
|
||||
$group = $user->userGroup;
|
||||
if (null === $group) {
|
||||
$this->friendlyWarning(sprintf('User "%s" has no group.', $user->email));
|
||||
$this->friendlyWarning(sprintf('User "%s" has no group. Please run "php artisan firefly-iii:create-group-memberships"', $user->email));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -30,15 +30,12 @@ use FireflyIII\Models\AccountType;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class FixIbans
|
||||
*/
|
||||
class FixIbans extends Command
|
||||
class CorrectsIbans extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Removes spaces from IBANs';
|
||||
protected $signature = 'firefly-iii:fix-ibans';
|
||||
protected $signature = 'correction:ibans';
|
||||
private int $count = 0;
|
||||
|
||||
/**
|
||||
@@ -49,9 +46,6 @@ class FixIbans extends Command
|
||||
$accounts = Account::whereNotNull('iban')->get();
|
||||
$this->filterIbans($accounts);
|
||||
$this->countAndCorrectIbans($accounts);
|
||||
if (0 === $this->count) {
|
||||
$this->friendlyPositive('All IBANs are valid.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -28,24 +28,22 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* Class FixLongDescriptions
|
||||
*/
|
||||
class FixLongDescriptions extends Command
|
||||
class CorrectsLongDescriptions extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
private const int MAX_LENGTH = 1000;
|
||||
protected $description = 'Fixes long descriptions in journals and groups.';
|
||||
protected $signature = 'firefly-iii:fix-long-descriptions';
|
||||
protected $signature = 'correction:long-descriptions';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$journals = TransactionJournal::get(['id', 'description']);
|
||||
$journals = TransactionJournal::where(DB::raw('LENGTH(description)'), '>', self::MAX_LENGTH)->get(['id', 'description']);
|
||||
$count = 0;
|
||||
|
||||
/** @var TransactionJournal $journal */
|
||||
@@ -58,7 +56,7 @@ class FixLongDescriptions extends Command
|
||||
}
|
||||
}
|
||||
|
||||
$groups = TransactionGroup::get(['id', 'title']);
|
||||
$groups = TransactionGroup::where(DB::raw('LENGTH(title)'), '>', self::MAX_LENGTH)->get(['id', 'title']);
|
||||
|
||||
/** @var TransactionGroup $group */
|
||||
foreach ($groups as $group) {
|
||||
@@ -69,9 +67,6 @@ class FixLongDescriptions extends Command
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All transaction group and journal title lengths are within bounds.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -26,16 +26,14 @@ namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* Class RenameMetaFields
|
||||
*/
|
||||
class RenameMetaFields extends Command
|
||||
class CorrectsMetaDataFields extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Rename changed meta fields.';
|
||||
protected $signature = 'firefly-iii:rename-meta-fields';
|
||||
protected $signature = 'correction:meta-fields';
|
||||
|
||||
private int $count = 0;
|
||||
|
||||
@@ -61,9 +59,6 @@ class RenameMetaFields extends Command
|
||||
foreach ($changes as $original => $update) {
|
||||
$this->rename($original, $update);
|
||||
}
|
||||
if (0 === $this->count) {
|
||||
$this->friendlyPositive('All meta fields are correct.');
|
||||
}
|
||||
if (0 !== $this->count) {
|
||||
$this->friendlyInfo(sprintf('Renamed %d meta field(s).', $this->count));
|
||||
}
|
||||
@@ -73,7 +68,7 @@ class RenameMetaFields extends Command
|
||||
|
||||
private function rename(string $original, string $update): void
|
||||
{
|
||||
$total = \DB::table('journal_meta')
|
||||
$total = DB::table('journal_meta')
|
||||
->where('name', '=', $original)
|
||||
->update(['name' => $update])
|
||||
;
|
||||
238
app/Console/Commands/Correction/CorrectsNativeAmounts.php
Normal file
238
app/Console/Commands/Correction/CorrectsNativeAmounts.php
Normal file
@@ -0,0 +1,238 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* RecalculateNativeAmounts.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Handlers\Observer\TransactionObserver;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AutoBudget;
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Support\Facades\Preferences;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder as DatabaseBuilder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CorrectsNativeAmounts extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Recalculate native amounts for all objects.';
|
||||
|
||||
protected $signature = 'correction:recalculate-native-amounts';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
Log::debug('Will update all native amounts. This may take some time.');
|
||||
$this->friendlyWarning('Recalculating native amounts for all objects. This may take some time!');
|
||||
|
||||
/** @var UserGroupRepositoryInterface $repository */
|
||||
$repository = app(UserGroupRepositoryInterface::class);
|
||||
|
||||
/** @var UserGroup $userGroup */
|
||||
foreach ($repository->getAll() as $userGroup) {
|
||||
$this->recalculateForGroup($userGroup);
|
||||
}
|
||||
$this->friendlyInfo('Recalculated all native amounts.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function recalculateForGroup(UserGroup $userGroup): void
|
||||
{
|
||||
Log::debug(sprintf('Now recalculating for user group #%d', $userGroup->id));
|
||||
$this->recalculateAccounts($userGroup);
|
||||
|
||||
// do a check with the group's currency so we can skip some stuff.
|
||||
Preferences::mark();
|
||||
$currency = app('amount')->getDefaultCurrencyByUserGroup($userGroup);
|
||||
|
||||
$this->recalculatePiggyBanks($userGroup, $currency);
|
||||
$this->recalculateBudgets($userGroup, $currency);
|
||||
$this->recalculateAvailableBudgets($userGroup, $currency);
|
||||
$this->recalculateBills($userGroup, $currency);
|
||||
$this->calculateTransactions($userGroup, $currency);
|
||||
|
||||
}
|
||||
|
||||
private function recalculateAccounts(UserGroup $userGroup): void
|
||||
{
|
||||
$set = $userGroup->accounts()->where(function (EloquentBuilder $q): void {
|
||||
$q->whereNotNull('virtual_balance');
|
||||
$q->orWhere('virtual_balance', '!=', '');
|
||||
})->get();
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($set as $account) {
|
||||
$account->touch();
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d accounts', $set->count()));
|
||||
}
|
||||
|
||||
private function recalculatePiggyBanks(UserGroup $userGroup, TransactionCurrency $currency): void
|
||||
{
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter->setUserGroup($userGroup);
|
||||
$converter->setIgnoreSettings(true);
|
||||
$repository = app(PiggyBankRepositoryInterface::class);
|
||||
$repository->setUserGroup($userGroup);
|
||||
$set = $repository->getPiggyBanks();
|
||||
$set = $set->filter(
|
||||
static function (PiggyBank $piggyBank) use ($currency) {
|
||||
return $currency->id !== $piggyBank->transaction_currency_id;
|
||||
}
|
||||
);
|
||||
foreach ($set as $piggyBank) {
|
||||
$piggyBank->encrypted = false;
|
||||
$piggyBank->save();
|
||||
|
||||
foreach ($piggyBank->accounts as $account) {
|
||||
$account->pivot->native_current_amount = null;
|
||||
if (0 !== bccomp($account->pivot->current_amount, '0')) {
|
||||
$account->pivot->native_current_amount = $converter->convert($piggyBank->transactionCurrency, $currency, today(), $account->pivot->current_amount);
|
||||
}
|
||||
$account->pivot->save();
|
||||
}
|
||||
$this->recalculatePiggyBankEvents($piggyBank);
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d piggy banks.', $set->count()));
|
||||
|
||||
}
|
||||
|
||||
private function recalculatePiggyBankEvents(PiggyBank $piggyBank): void
|
||||
{
|
||||
$set = $piggyBank->piggyBankEvents()->get();
|
||||
$set->each(
|
||||
static function (PiggyBankEvent $event): void {
|
||||
$event->touch();
|
||||
}
|
||||
);
|
||||
Log::debug(sprintf('Recalculated %d piggy bank events.', $set->count()));
|
||||
}
|
||||
|
||||
private function recalculateBudgets(UserGroup $userGroup, TransactionCurrency $currency): void
|
||||
{
|
||||
$set = $userGroup->budgets()->get();
|
||||
|
||||
/** @var Budget $budget */
|
||||
foreach ($set as $budget) {
|
||||
$this->recalculateBudgetLimits($budget, $currency);
|
||||
$this->recalculateAutoBudgets($budget, $currency);
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d budgets.', $set->count()));
|
||||
}
|
||||
|
||||
private function recalculateBudgetLimits(Budget $budget, TransactionCurrency $currency): void
|
||||
{
|
||||
$set = $budget->budgetlimits()->where('transaction_currency_id', '!=', $currency->id)->get();
|
||||
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($set as $limit) {
|
||||
Log::debug(sprintf('Will now touch BL #%d', $limit->id));
|
||||
$limit->touch();
|
||||
Log::debug(sprintf('Done with touch BL #%d', $limit->id));
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d budget limits.', $set->count()));
|
||||
}
|
||||
|
||||
private function recalculateAutoBudgets(Budget $budget, TransactionCurrency $currency): void
|
||||
{
|
||||
$set = $budget->autoBudgets()->where('transaction_currency_id', '!=', $currency->id)->get();
|
||||
|
||||
/** @var AutoBudget $autoBudget */
|
||||
foreach ($set as $autoBudget) {
|
||||
$autoBudget->touch();
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d auto budgets.', $set->count()));
|
||||
}
|
||||
|
||||
private function recalculateAvailableBudgets(UserGroup $userGroup, TransactionCurrency $currency): void
|
||||
{
|
||||
Log::debug('Start with available budgets.');
|
||||
$set = $userGroup->availableBudgets()->where('transaction_currency_id', '!=', $currency->id)->get();
|
||||
|
||||
/** @var AvailableBudget $budget */
|
||||
foreach ($set as $budget) {
|
||||
$budget->touch();
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d available budgets.', $set->count()));
|
||||
}
|
||||
|
||||
private function recalculateBills(UserGroup $userGroup, TransactionCurrency $currency): void
|
||||
{
|
||||
$set = $userGroup->bills()->where('transaction_currency_id', '!=', $currency->id)->get();
|
||||
|
||||
/** @var Bill $bill */
|
||||
foreach ($set as $bill) {
|
||||
$bill->touch();
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d bills.', $set->count()));
|
||||
}
|
||||
|
||||
private function calculateTransactions(UserGroup $userGroup, TransactionCurrency $currency): void
|
||||
{
|
||||
// custom query because of the potential size of this update.
|
||||
$set = DB::table('transactions')
|
||||
->join('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.user_group_id', $userGroup->id)
|
||||
|
||||
->where(function (DatabaseBuilder $q1) use ($currency): void {
|
||||
$q1->where(function (DatabaseBuilder $q2) use ($currency): void {
|
||||
$q2->whereNot('transactions.transaction_currency_id', $currency->id)->whereNull('transactions.foreign_currency_id');
|
||||
})->orWhere(function (DatabaseBuilder $q3) use ($currency): void {
|
||||
$q3->whereNot('transactions.transaction_currency_id', $currency->id)->whereNot('transactions.foreign_currency_id', $currency->id);
|
||||
});
|
||||
})
|
||||
// ->where(static function (DatabaseBuilder $q) use ($currency): void {
|
||||
// $q->whereNot('transactions.transaction_currency_id', $currency->id)
|
||||
// ->whereNot('transactions.foreign_currency_id', $currency->id)
|
||||
// ;
|
||||
// })
|
||||
->get(['transactions.id'])
|
||||
;
|
||||
TransactionObserver::$recalculate = false;
|
||||
foreach ($set as $item) {
|
||||
// here we are.
|
||||
$transaction = Transaction::find($item->id);
|
||||
$transaction->touch();
|
||||
}
|
||||
TransactionObserver::$recalculate = true;
|
||||
Log::debug(sprintf('Recalculated %d transactions.', $set->count()));
|
||||
}
|
||||
}
|
||||
@@ -35,15 +35,12 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class CorrectOpeningBalanceCurrencies
|
||||
*/
|
||||
class CorrectOpeningBalanceCurrencies extends Command
|
||||
class CorrectsOpeningBalanceCurrencies extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Will make sure that opening balance transaction currencies match the account they\'re for.';
|
||||
protected $signature = 'firefly-iii:fix-ob-currencies';
|
||||
protected $signature = 'correction:opening-balance-currencies';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -62,10 +59,6 @@ class CorrectOpeningBalanceCurrencies extends Command
|
||||
$message = sprintf('Corrected %d opening balance transaction(s).', $count);
|
||||
$this->friendlyInfo($message);
|
||||
}
|
||||
if (0 === $count) {
|
||||
$message = 'There was nothing to fix in the opening balance transactions.';
|
||||
$this->friendlyPositive($message);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -34,12 +34,12 @@ use Illuminate\Console\Command;
|
||||
*
|
||||
* Class FixPiggies
|
||||
*/
|
||||
class FixPiggies extends Command
|
||||
class CorrectsPiggyBanks extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Fixes common issues with piggy banks.';
|
||||
protected $signature = 'firefly-iii:fix-piggies';
|
||||
protected $signature = 'correction:piggy-banks';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -66,9 +66,6 @@ class FixPiggies extends Command
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All piggy bank events are OK.');
|
||||
}
|
||||
if (0 !== $count) {
|
||||
$this->friendlyInfo(sprintf('Fixed %d piggy bank event(s).', $count));
|
||||
}
|
||||
@@ -28,11 +28,11 @@ use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Symfony\Component\Console\Command\Command as CommandAlias;
|
||||
|
||||
class MigratePreferences extends Command
|
||||
class CorrectsPreferences extends Command
|
||||
{
|
||||
protected $description = 'Give Firefly III preferences a user group ID so they can be made administration specific.';
|
||||
|
||||
protected $signature = 'firefly-iii:migrate-preferences';
|
||||
protected $signature = 'correction:preferences';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -50,7 +50,7 @@ class MigratePreferences extends Command
|
||||
if (null === $preference) {
|
||||
continue;
|
||||
}
|
||||
if (null !== $preference->user_group_id) {
|
||||
if (null === $preference->user_group_id) {
|
||||
$preference->user_group_id = $user->user_group_id;
|
||||
$preference->save();
|
||||
++$count;
|
||||
@@ -33,15 +33,12 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class FixRecurringTransactions
|
||||
*/
|
||||
class FixRecurringTransactions extends Command
|
||||
class CorrectsRecurringTransactions extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Fixes recurring transactions with the wrong transaction type.';
|
||||
protected $signature = 'firefly-iii:fix-recurring-transactions';
|
||||
protected $signature = 'correction:recurring-transactions';
|
||||
private int $count = 0;
|
||||
private RecurringRepositoryInterface $recurringRepos;
|
||||
private UserRepositoryInterface $userRepos;
|
||||
@@ -53,9 +50,6 @@ class FixRecurringTransactions extends Command
|
||||
{
|
||||
$this->stupidLaravel();
|
||||
$this->correctTransactions();
|
||||
if (0 === $this->count) {
|
||||
$this->friendlyPositive('All recurring transactions are OK.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,5 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* CorrectsTimezoneInformation.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* AddTimezonesToDates.php
|
||||
@@ -21,7 +41,7 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Console\Commands\Integrity;
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\AccountBalance;
|
||||
@@ -41,16 +61,25 @@ use Illuminate\Console\Command;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class AddTimezonesToDates extends Command
|
||||
class CorrectsTimezoneInformation extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:add-timezones-to-dates';
|
||||
public static array $models
|
||||
= [
|
||||
AccountBalance::class => ['date'], // done
|
||||
AvailableBudget::class => ['start_date', 'end_date'], // done
|
||||
Bill::class => ['date', 'end_date', 'extension_date'], // done
|
||||
BudgetLimit::class => ['start_date', 'end_date'], // done
|
||||
CurrencyExchangeRate::class => ['date'], // done
|
||||
InvitedUser::class => ['expires'],
|
||||
PiggyBankEvent::class => ['date'],
|
||||
PiggyBankRepetition::class => ['start_date', 'target_date'],
|
||||
PiggyBank::class => ['start_date', 'target_date'], // done
|
||||
Recurrence::class => ['first_date', 'repeat_until', 'latest_date'],
|
||||
Tag::class => ['date'],
|
||||
TransactionJournal::class => ['date'],
|
||||
];
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
@@ -59,20 +88,12 @@ class AddTimezonesToDates extends Command
|
||||
*/
|
||||
protected $description = 'Make sure all dates have a timezone.';
|
||||
|
||||
public static array $models = [
|
||||
AccountBalance::class => ['date'], // done
|
||||
AvailableBudget::class => ['start_date', 'end_date'], // done
|
||||
Bill::class => ['date', 'end_date', 'extension_date'], // done
|
||||
BudgetLimit::class => ['start_date', 'end_date'], // done
|
||||
CurrencyExchangeRate::class => ['date'], // done
|
||||
InvitedUser::class => ['expires'],
|
||||
PiggyBankEvent::class => ['date'],
|
||||
PiggyBankRepetition::class => ['startdate', 'targetdate'],
|
||||
PiggyBank::class => ['startdate', 'targetdate'], // done
|
||||
Recurrence::class => ['first_date', 'repeat_until', 'latest_date'],
|
||||
Tag::class => ['date'],
|
||||
TransactionJournal::class => ['date'],
|
||||
];
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'correction:timezones';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -106,8 +127,6 @@ class AddTimezonesToDates extends Command
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive(sprintf('Timezone information is present in field "%s" of model "%s".', $field, $shortModel));
|
||||
|
||||
return;
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Adding timezone information to field "%s" of model "%s".', $field, $shortModel));
|
||||
@@ -32,16 +32,14 @@ use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class FixTransactionTypes
|
||||
*/
|
||||
class FixTransactionTypes extends Command
|
||||
class CorrectsTransactionTypes extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Make sure all transactions are of the correct type, based on source + dest.';
|
||||
protected $signature = 'firefly-iii:fix-transaction-types';
|
||||
protected $signature = 'correction:transaction-types';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -50,6 +48,7 @@ class FixTransactionTypes extends Command
|
||||
{
|
||||
$count = 0;
|
||||
$journals = $this->collectJournals();
|
||||
Log::debug(sprintf('In FixTransactionTypes, found %d journals.', $journals->count()));
|
||||
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
@@ -32,12 +32,12 @@ use Illuminate\Console\Command;
|
||||
/**
|
||||
* Class TransferBudgets
|
||||
*/
|
||||
class TransferBudgets extends Command
|
||||
class CorrectsTransferBudgets extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Removes budgets from transfers.';
|
||||
protected $signature = 'firefly-iii:fix-transfer-budgets';
|
||||
protected $signature = 'correction:transfer-budgets';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -60,10 +60,6 @@ class TransferBudgets extends Command
|
||||
$entry->budgets()->sync([]);
|
||||
++$count;
|
||||
}
|
||||
if (0 === $count) {
|
||||
$message = 'No invalid budget/journal entries.';
|
||||
$this->friendlyPositive($message);
|
||||
}
|
||||
if (0 !== $count) {
|
||||
$message = sprintf('Corrected %d invalid budget/journal entries (entry).', $count);
|
||||
app('log')->debug($message);
|
||||
@@ -25,6 +25,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Enums\TransactionTypeEnum;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
@@ -35,12 +36,12 @@ use Illuminate\Support\Facades\Log;
|
||||
/**
|
||||
* Class FixUnevenAmount
|
||||
*/
|
||||
class FixUnevenAmount extends Command
|
||||
class CorrectsUnevenAmount extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Fix journals with uneven amounts.';
|
||||
protected $signature = 'firefly-iii:fix-uneven-amount';
|
||||
protected $signature = 'correction:uneven-amounts';
|
||||
private int $count;
|
||||
|
||||
/**
|
||||
@@ -54,13 +55,112 @@ class FixUnevenAmount extends Command
|
||||
$this->matchCurrencies();
|
||||
if (config('firefly.feature_flags.running_balance_column')) {
|
||||
$this->friendlyInfo('Will recalculate transaction running balance columns. This may take a LONG time. Please be patient.');
|
||||
AccountBalanceCalculator::recalculateAll(true);
|
||||
AccountBalanceCalculator::recalculateAll(false);
|
||||
$this->friendlyInfo('Done recalculating transaction running balance columns.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function convertOldStyleTransfers(): void
|
||||
{
|
||||
Log::debug('convertOldStyleTransfers()');
|
||||
// select transactions with a foreign amount and a foreign currency. and it's a transfer. and they are different.
|
||||
$transactions = Transaction::distinct()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', 'transactions.transaction_journal_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', 'transaction_journals.transaction_type_id')
|
||||
->where('transaction_types.type', TransactionTypeEnum::TRANSFER->value)
|
||||
->whereNotNull('foreign_currency_id')
|
||||
->whereNotNull('foreign_amount')->get(['transactions.transaction_journal_id'])
|
||||
;
|
||||
$count = 0;
|
||||
|
||||
Log::debug(sprintf('Found %d potential journal(s)', $transactions->count()));
|
||||
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
/** @var null|TransactionJournal $journal */
|
||||
$journal = TransactionJournal::find($transaction->transaction_journal_id);
|
||||
if (null === $journal) {
|
||||
Log::debug('Found no journal, continue.');
|
||||
|
||||
continue;
|
||||
}
|
||||
// needs to be a transfer.
|
||||
if (TransactionType::TRANSFER !== $journal->transactionType->type) {
|
||||
Log::debug('Must be a transfer, continue.');
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @var null|Transaction $destination */
|
||||
$destination = $journal->transactions()->where('amount', '>', 0)->first();
|
||||
|
||||
/** @var null|Transaction $source */
|
||||
$source = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
if (null === $destination || null === $source) {
|
||||
Log::debug('Source or destination transaction is NULL, continue.');
|
||||
|
||||
// will be picked up later.
|
||||
continue;
|
||||
}
|
||||
if ($source->transaction_currency_id === $destination->transaction_currency_id) {
|
||||
Log::debug('Ready to swap data between transactions.');
|
||||
$destination->foreign_currency_id = $source->transaction_currency_id;
|
||||
$destination->foreign_amount = app('steam')->positive($source->amount);
|
||||
$destination->transaction_currency_id = $source->foreign_currency_id;
|
||||
$destination->amount = app('steam')->positive($source->foreign_amount);
|
||||
$destination->balance_dirty = true;
|
||||
$source->balance_dirty = true;
|
||||
$destination->save();
|
||||
$source->save();
|
||||
$this->friendlyWarning(sprintf('Corrected foreign amounts of transfer #%d.', $journal->id));
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function fixUnevenAmounts(): void
|
||||
{
|
||||
$journals = \DB::table('transactions')
|
||||
->groupBy('transaction_journal_id')
|
||||
->whereNull('deleted_at')
|
||||
->get(['transaction_journal_id', \DB::raw('SUM(amount) AS the_sum')])
|
||||
;
|
||||
|
||||
/** @var \stdClass $entry */
|
||||
foreach ($journals as $entry) {
|
||||
$sum = (string) $entry->the_sum;
|
||||
if (!is_numeric($sum)
|
||||
|| '' === $sum // @phpstan-ignore-line
|
||||
|| str_contains($sum, 'e')
|
||||
|| str_contains($sum, ',')) {
|
||||
$message = sprintf(
|
||||
'Journal #%d has an invalid sum ("%s"). No sure what to do.',
|
||||
$entry->transaction_journal_id,
|
||||
$entry->the_sum
|
||||
);
|
||||
$this->friendlyWarning($message);
|
||||
app('log')->warning($message);
|
||||
++$this->count;
|
||||
|
||||
continue;
|
||||
}
|
||||
$res = -1;
|
||||
|
||||
try {
|
||||
$res = bccomp($sum, '0');
|
||||
} catch (\ValueError $e) {
|
||||
$this->friendlyError(sprintf('Could not bccomp("%s", "0").', $sum));
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
if (0 !== $res) {
|
||||
$this->fixJournal($entry->transaction_journal_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function fixJournal(int $param): void
|
||||
{
|
||||
// one of the transactions is bad.
|
||||
@@ -129,78 +229,6 @@ class FixUnevenAmount extends Command
|
||||
++$this->count;
|
||||
}
|
||||
|
||||
private function fixUnevenAmounts(): void
|
||||
{
|
||||
$journals = \DB::table('transactions')
|
||||
->groupBy('transaction_journal_id')
|
||||
->whereNull('deleted_at')
|
||||
->get(['transaction_journal_id', \DB::raw('SUM(amount) AS the_sum')])
|
||||
;
|
||||
|
||||
/** @var \stdClass $entry */
|
||||
foreach ($journals as $entry) {
|
||||
$sum = (string) $entry->the_sum;
|
||||
if (!is_numeric($sum)
|
||||
|| '' === $sum // @phpstan-ignore-line
|
||||
|| str_contains($sum, 'e')
|
||||
|| str_contains($sum, ',')) {
|
||||
$message = sprintf(
|
||||
'Journal #%d has an invalid sum ("%s"). No sure what to do.',
|
||||
$entry->transaction_journal_id,
|
||||
$entry->the_sum
|
||||
);
|
||||
$this->friendlyWarning($message);
|
||||
app('log')->warning($message);
|
||||
++$this->count;
|
||||
|
||||
continue;
|
||||
}
|
||||
$res = -1;
|
||||
|
||||
try {
|
||||
$res = bccomp($sum, '0');
|
||||
} catch (\ValueError $e) {
|
||||
$this->friendlyError(sprintf('Could not bccomp("%s", "0").', $sum));
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
if (0 !== $res) {
|
||||
$this->fixJournal($entry->transaction_journal_id);
|
||||
}
|
||||
}
|
||||
if (0 === $this->count) {
|
||||
$this->friendlyPositive('Database amount integrity is OK');
|
||||
}
|
||||
}
|
||||
|
||||
private function matchCurrencies(): void
|
||||
{
|
||||
$journals = TransactionJournal::leftJoin('transactions', 'transaction_journals.id', 'transactions.transaction_journal_id')
|
||||
->where('transactions.transaction_currency_id', '!=', \DB::raw('transaction_journals.transaction_currency_id'))
|
||||
->get(['transaction_journals.*'])
|
||||
;
|
||||
|
||||
$count = 0;
|
||||
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
if (!$this->isForeignCurrencyTransfer($journal)) {
|
||||
Transaction::where('transaction_journal_id', $journal->id)->update(['transaction_currency_id' => $journal->transaction_currency_id]);
|
||||
++$count;
|
||||
|
||||
continue;
|
||||
}
|
||||
Log::debug(sprintf('Can skip foreign currency transfer #%d.', $journal->id));
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('Journal currency integrity is OK');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->friendlyPositive(sprintf('Fixed %d journal(s) with mismatched currencies.', $journals->count()));
|
||||
}
|
||||
|
||||
private function isForeignCurrencyTransfer(TransactionJournal $journal): bool
|
||||
{
|
||||
if (TransactionType::TRANSFER !== $journal->transactionType->type) {
|
||||
@@ -235,63 +263,29 @@ class FixUnevenAmount extends Command
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertOldStyleTransfers(): void
|
||||
private function matchCurrencies(): void
|
||||
{
|
||||
Log::debug('convertOldStyleTransfers()');
|
||||
// select transactions with a foreign amount and a foreign currency. and it's a transfer. and they are different.
|
||||
$transactions = Transaction::distinct()
|
||||
->whereNotNull('foreign_currency_id')
|
||||
->whereNotNull('foreign_amount')->get(['transactions.transaction_journal_id'])
|
||||
$journals = TransactionJournal::leftJoin('transactions', 'transaction_journals.id', 'transactions.transaction_journal_id')
|
||||
->where('transactions.transaction_currency_id', '!=', \DB::raw('transaction_journals.transaction_currency_id'))
|
||||
->get(['transaction_journals.*'])
|
||||
;
|
||||
|
||||
$count = 0;
|
||||
|
||||
Log::debug(sprintf('Found %d potential journal(s)', $transactions->count()));
|
||||
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
/** @var null|TransactionJournal $journal */
|
||||
$journal = TransactionJournal::find($transaction->transaction_journal_id);
|
||||
if (null === $journal) {
|
||||
Log::debug('Found no journal, continue.');
|
||||
|
||||
continue;
|
||||
}
|
||||
// needs to be a transfer.
|
||||
if (TransactionType::TRANSFER !== $journal->transactionType->type) {
|
||||
Log::debug('Must be a transfer, continue.');
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @var null|Transaction $destination */
|
||||
$destination = $journal->transactions()->where('amount', '>', 0)->first();
|
||||
|
||||
/** @var null|Transaction $source */
|
||||
$source = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
if (null === $destination || null === $source) {
|
||||
Log::debug('Source or destination transaction is NULL, continue.');
|
||||
|
||||
// will be picked up later.
|
||||
continue;
|
||||
}
|
||||
if ($source->transaction_currency_id === $destination->transaction_currency_id) {
|
||||
Log::debug('Ready to swap data between transactions.');
|
||||
$destination->foreign_currency_id = $source->transaction_currency_id;
|
||||
$destination->foreign_amount = app('steam')->positive($source->amount);
|
||||
$destination->transaction_currency_id = $source->foreign_currency_id;
|
||||
$destination->amount = app('steam')->positive($source->foreign_amount);
|
||||
$destination->balance_dirty = true;
|
||||
$source->balance_dirty = true;
|
||||
$destination->save();
|
||||
$source->save();
|
||||
$this->friendlyWarning(sprintf('Corrected foreign amounts of transfer #%d.', $journal->id));
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
if (!$this->isForeignCurrencyTransfer($journal)) {
|
||||
Transaction::where('transaction_journal_id', $journal->id)->update(['transaction_currency_id' => $journal->transaction_currency_id]);
|
||||
++$count;
|
||||
|
||||
continue;
|
||||
}
|
||||
Log::debug(sprintf('Can skip foreign currency transfer #%d.', $journal->id));
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('No "old style" foreign currency transfers.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->friendlyPositive(sprintf('Fixed %d journal(s) with mismatched currencies.', $journals->count()));
|
||||
}
|
||||
}
|
||||
@@ -32,13 +32,13 @@ use Illuminate\Console\Command;
|
||||
/**
|
||||
* Class CreateAccessTokens
|
||||
*/
|
||||
class CreateAccessTokens extends Command
|
||||
class CreatesAccessTokens extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Creates user access tokens which are used for command line access to personal data.';
|
||||
|
||||
protected $signature = 'firefly-iii:create-access-tokens';
|
||||
protected $signature = 'correction:access-tokens';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -64,9 +64,6 @@ class CreateAccessTokens extends Command
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('Verified access tokens.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* CreateGroupMemberships.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
* CreatesGroupMemberships.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
@@ -17,12 +17,12 @@
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Integrity;
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
@@ -33,16 +33,13 @@ use FireflyIII\Models\UserRole;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class CreateGroupMemberships
|
||||
*/
|
||||
class CreateGroupMemberships extends Command
|
||||
class CreatesGroupMemberships extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
public const string CONFIG_NAME = '560_create_group_memberships';
|
||||
protected $description = 'Update group memberships';
|
||||
protected $signature = 'firefly-iii:create-group-memberships';
|
||||
protected $signature = 'correction:create-group-memberships';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -52,7 +49,6 @@ class CreateGroupMemberships extends Command
|
||||
public function handle(): int
|
||||
{
|
||||
$this->createGroupMemberships();
|
||||
$this->friendlyPositive('Validated group memberships');
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -31,13 +31,13 @@ use Illuminate\Console\Command;
|
||||
/**
|
||||
* Class CreateLinkTypes. Created all link types in case a migration hasn't fired.
|
||||
*/
|
||||
class CreateLinkTypes extends Command
|
||||
class CreatesLinkTypes extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Creates all link types.';
|
||||
|
||||
protected $signature = 'firefly-iii:create-link-types';
|
||||
protected $signature = 'correction:link-types';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -66,9 +66,6 @@ class CreateLinkTypes extends Command
|
||||
$link->editable = false;
|
||||
$link->save();
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All link types are OK');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -32,12 +32,12 @@ use Illuminate\Console\Command;
|
||||
/**
|
||||
* Class RemoveBills
|
||||
*/
|
||||
class RemoveBills extends Command
|
||||
class RemovesBills extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Remove bills from transactions that shouldn\'t have one.';
|
||||
protected $signature = 'firefly-iii:remove-bills';
|
||||
protected $signature = 'correction:bills';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -60,7 +60,6 @@ class RemoveBills extends Command
|
||||
if ($journals->count() > 0) {
|
||||
$this->friendlyInfo('Fixed all transaction journals so they have correct bill information.');
|
||||
}
|
||||
$this->friendlyPositive('All bills and journals are OK');
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -32,12 +32,12 @@ use Illuminate\Console\Command;
|
||||
/**
|
||||
* Class DeleteEmptyGroups
|
||||
*/
|
||||
class DeleteEmptyGroups extends Command
|
||||
class RemovesEmptyGroups extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Delete empty transaction groups.';
|
||||
protected $signature = 'firefly-iii:delete-empty-groups';
|
||||
protected $signature = 'correction:empty-groups';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -61,9 +61,6 @@ class DeleteEmptyGroups extends Command
|
||||
TransactionGroup::whereNull('deleted_at')->whereIn('id', $chunk)->delete();
|
||||
}
|
||||
}
|
||||
if (0 === $total) {
|
||||
$this->friendlyInfo('Verified there are no empty groups.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -33,13 +33,13 @@ use Illuminate\Database\QueryException;
|
||||
/**
|
||||
* Class DeleteEmptyJournals
|
||||
*/
|
||||
class DeleteEmptyJournals extends Command
|
||||
class RemovesEmptyJournals extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Delete empty and uneven transaction journals.';
|
||||
|
||||
protected $signature = 'firefly-iii:delete-empty-journals';
|
||||
protected $signature = 'correction:empty-journals';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -82,9 +82,6 @@ class DeleteEmptyJournals extends Command
|
||||
++$total;
|
||||
}
|
||||
}
|
||||
if (0 === $total) {
|
||||
$this->friendlyPositive('No uneven transaction journals.');
|
||||
}
|
||||
}
|
||||
|
||||
private function deleteEmptyJournals(): void
|
||||
@@ -107,8 +104,5 @@ class DeleteEmptyJournals extends Command
|
||||
$this->friendlyInfo(sprintf('Deleted empty transaction journal #%d', $entry->id));
|
||||
++$count;
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('No empty transaction journals.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,13 +32,13 @@ use Illuminate\Console\Command;
|
||||
/**
|
||||
* Deletes transactions where the journal has been deleted.
|
||||
*/
|
||||
class DeleteOrphanedTransactions extends Command
|
||||
class RemovesOrphanedTransactions extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Deletes orphaned transactions.';
|
||||
|
||||
protected $signature = 'firefly-iii:delete-orphaned-transactions';
|
||||
protected $signature = 'correction:orphaned-transactions';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -63,7 +63,7 @@ class DeleteOrphanedTransactions extends Command
|
||||
;
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('No orphaned journals.');
|
||||
// $this->friendlyPositive('No orphaned journals.');
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -116,9 +116,6 @@ class DeleteOrphanedTransactions extends Command
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('No orphaned transactions.');
|
||||
}
|
||||
}
|
||||
|
||||
private function deleteFromOrphanedAccounts(): void
|
||||
@@ -147,8 +144,5 @@ class DeleteOrphanedTransactions extends Command
|
||||
);
|
||||
++$count;
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('No orphaned accounts.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,16 +29,13 @@ use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class DeleteZeroAmount
|
||||
*/
|
||||
class DeleteZeroAmount extends Command
|
||||
class RemovesZeroAmount extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Delete transactions with zero amount.';
|
||||
|
||||
protected $signature = 'firefly-iii:delete-zero-amount';
|
||||
protected $signature = 'correction:zero-amounts';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -56,9 +53,6 @@ class DeleteZeroAmount extends Command
|
||||
|
||||
Transaction::where('transaction_journal_id', $journal->id)->delete();
|
||||
}
|
||||
if (0 === $journals->count()) {
|
||||
$this->friendlyPositive('No zero-amount transaction journals.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RestoreOAuthKeys.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
/*
|
||||
* RestoresOAuthKeys.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
@@ -17,12 +17,12 @@
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Integrity;
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Support\System\OAuthKeys;
|
||||
@@ -31,12 +31,12 @@ use Illuminate\Console\Command;
|
||||
/**
|
||||
* Class RestoreOAuthKeys
|
||||
*/
|
||||
class RestoreOAuthKeys extends Command
|
||||
class RestoresOAuthKeys extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Will restore the OAuth keys generated for the system.';
|
||||
protected $signature = 'firefly-iii:restore-oauth-keys';
|
||||
protected $signature = 'correction:restore-oauth-keys';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -76,7 +76,6 @@ class RestoreOAuthKeys extends Command
|
||||
|
||||
return;
|
||||
}
|
||||
$this->friendlyPositive('OAuth keys are OK');
|
||||
}
|
||||
|
||||
private function keysInDatabase(): bool
|
||||
@@ -28,13 +28,10 @@ use FireflyIII\Models\Account;
|
||||
use FireflyIII\Services\Internal\Support\CreditRecalculateService;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class CorrectionSkeleton
|
||||
*/
|
||||
class TriggerCreditCalculation extends Command
|
||||
class TriggersCreditCalculation extends Command
|
||||
{
|
||||
protected $description = 'Triggers the credit recalculation service for liabilities.';
|
||||
protected $signature = 'firefly-iii:trigger-credit-recalculation';
|
||||
protected $signature = 'correction:recalculates-liabilities';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -34,13 +34,13 @@ use Illuminate\Console\Command;
|
||||
/**
|
||||
* Class ReportEmptyObjects
|
||||
*/
|
||||
class ReportEmptyObjects extends Command
|
||||
class ReportsEmptyObjects extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Reports on empty database objects.';
|
||||
|
||||
protected $signature = 'firefly-iii:report-empty-objects';
|
||||
protected $signature = 'integrity:empty-objects';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -30,7 +30,7 @@ use Illuminate\Console\Command;
|
||||
/**
|
||||
* Class ReportIntegrity
|
||||
*/
|
||||
class ReportIntegrity extends Command
|
||||
class ReportsIntegrity extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
@@ -48,11 +48,9 @@ class ReportIntegrity extends Command
|
||||
return 1;
|
||||
}
|
||||
$commands = [
|
||||
'firefly-iii:add-timezones-to-dates',
|
||||
'firefly-iii:create-group-memberships',
|
||||
'firefly-iii:report-empty-objects',
|
||||
'firefly-iii:report-sum',
|
||||
'firefly-iii:upgrade-group-information',
|
||||
// 'firefly-iii:add-timezones-to-dates',
|
||||
'integrity:empty-objects',
|
||||
'integrity:total-sums',
|
||||
];
|
||||
foreach ($commands as $command) {
|
||||
$this->friendlyLine(sprintf('Now executing %s', $command));
|
||||
@@ -32,12 +32,12 @@ use Illuminate\Console\Command;
|
||||
/**
|
||||
* Class ReportSkeleton
|
||||
*/
|
||||
class ReportSum extends Command
|
||||
class ReportsSums extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Report on the total sum of transactions. Must be 0.';
|
||||
protected $signature = 'firefly-iii:report-sum';
|
||||
protected $signature = 'integrity:total-sums';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -59,18 +59,22 @@ class ReportSum extends Command
|
||||
|
||||
/** @var User $user */
|
||||
foreach ($userRepository->all() as $user) {
|
||||
$sum = (string)$user->transactions()->selectRaw('SUM(amount) + SUM(foreign_amount) as total')->value('total');
|
||||
if (!is_numeric($sum)) {
|
||||
$message = sprintf('Error: Transactions for user #%d (%s) have an invalid sum ("%s").', $user->id, $user->email, $sum);
|
||||
$sum = (string) $user->transactions()->selectRaw('SUM(amount) as total')->value('total');
|
||||
$foreign = (string) $user->transactions()->selectRaw('SUM(foreign_amount) as total')->value('total');
|
||||
$sum = '' === $sum ? '0' : $sum;
|
||||
$foreign = '' === $foreign ? '0' : $foreign;
|
||||
$total = bcadd($sum, $foreign);
|
||||
if (!is_numeric($total)) {
|
||||
$message = sprintf('Error: Transactions for user #%d (%s) have an invalid sum ("%s").', $user->id, $user->email, $total);
|
||||
$this->friendlyError($message);
|
||||
|
||||
continue;
|
||||
}
|
||||
if (0 !== bccomp($sum, '0')) {
|
||||
$message = sprintf('Error: Transactions for user #%d (%s) are off by %s!', $user->id, $user->email, $sum);
|
||||
if (0 !== bccomp($total, '0')) {
|
||||
$message = sprintf('Error: Transactions for user #%d (%s) are off by %s!', $user->id, $user->email, $total);
|
||||
$this->friendlyError($message);
|
||||
}
|
||||
if (0 === bccomp($sum, '0')) {
|
||||
if (0 === bccomp($total, '0')) {
|
||||
$this->friendlyPositive(sprintf('Amount integrity OK for user #%d', $user->id));
|
||||
}
|
||||
}
|
||||
@@ -83,8 +83,8 @@ class ForceDecimalSize extends Command
|
||||
'currency_exchange_rates' => ['rate', 'user_rate'],
|
||||
'limit_repetitions' => ['amount'],
|
||||
'piggy_bank_events' => ['amount'],
|
||||
'piggy_bank_repetitions' => ['currentamount'],
|
||||
'piggy_banks' => ['targetamount'],
|
||||
'piggy_bank_repetitions' => ['current_amount'],
|
||||
'piggy_banks' => ['target_amount'],
|
||||
'recurrences_transactions' => ['amount', 'foreign_amount'],
|
||||
'transactions' => ['amount', 'foreign_amount'],
|
||||
];
|
||||
|
||||
@@ -128,7 +128,7 @@ class ApplyRules extends Command
|
||||
$ruleEngine->addOperator(['type' => 'account_id', 'value' => $list]);
|
||||
|
||||
// add the date as a filter:
|
||||
$ruleEngine->addOperator(['type' => 'date_after', 'value' => $this->startDate->format('Y-m-d')]);
|
||||
$ruleEngine->addOperator(['type' => 'date_after', 'value' => $this->start_date->format('Y-m-d')]);
|
||||
$ruleEngine->addOperator(['type' => 'date_before', 'value' => $this->endDate->format('Y-m-d')]);
|
||||
|
||||
// start running rules.
|
||||
@@ -296,7 +296,7 @@ class ApplyRules extends Command
|
||||
[$inputEnd, $inputStart] = [$inputStart, $inputEnd];
|
||||
}
|
||||
|
||||
$this->startDate = $inputStart;
|
||||
$this->start_date = $inputStart;
|
||||
$this->endDate = $inputEnd;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,16 +32,13 @@ use FireflyIII\Repositories\Journal\JournalCLIRepositoryInterface;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\QueryException;
|
||||
|
||||
/**
|
||||
* Class TransactionIdentifier
|
||||
*/
|
||||
class TransactionIdentifier extends Command
|
||||
class AddsTransactionIdentifiers extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
public const string CONFIG_NAME = '480_transaction_identifier';
|
||||
protected $description = 'Fixes transaction identifiers.';
|
||||
protected $signature = 'firefly-iii:transaction-identifiers {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:480-transaction-identifiers {--F|force : Force the execution of this command.}';
|
||||
private JournalCLIRepositoryInterface $cliRepository;
|
||||
private int $count;
|
||||
|
||||
@@ -30,15 +30,12 @@ use FireflyIII\Models\Preference;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
|
||||
/**
|
||||
* Class DecryptDatabase
|
||||
*/
|
||||
class DecryptDatabase extends Command
|
||||
class RemovesDatabaseDecryption extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Decrypts the database.';
|
||||
protected $signature = 'firefly-iii:decrypt-all';
|
||||
protected $signature = 'upgrade:480-decrypt-all';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -28,16 +28,13 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Support\Models\AccountBalanceCalculator;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class CorrectionSkeleton
|
||||
*/
|
||||
class CorrectAccountBalance extends Command
|
||||
class RepairsAccountBalances extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
public const string CONFIG_NAME = '610_correct_balances';
|
||||
protected $description = 'Recalculate all account balance amounts';
|
||||
protected $signature = 'firefly-iii:correct-account-balance {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:610-account-balances {--F|force : Force the execution of this command.}';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
@@ -59,12 +56,6 @@ class CorrectAccountBalance extends Command
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function correctBalanceAmounts(): void
|
||||
{
|
||||
return;
|
||||
AccountBalanceCalculator::recalculateAll(true);
|
||||
}
|
||||
|
||||
private function isExecuted(): bool
|
||||
{
|
||||
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
|
||||
@@ -76,4 +67,10 @@ class CorrectAccountBalance extends Command
|
||||
{
|
||||
app('fireflyconfig')->set(self::CONFIG_NAME, true);
|
||||
}
|
||||
|
||||
private function correctBalanceAmounts(): void
|
||||
{
|
||||
return;
|
||||
AccountBalanceCalculator::recalculateAll(true);
|
||||
}
|
||||
}
|
||||
@@ -27,16 +27,13 @@ namespace FireflyIII\Console\Commands\Upgrade;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class FixPostgresSequences
|
||||
*/
|
||||
class FixPostgresSequences extends Command
|
||||
class RepairsPostgresSequences extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Fixes issues with PostgreSQL sequences.';
|
||||
|
||||
protected $signature = 'firefly-iii:fix-pgsql-sequences';
|
||||
protected $signature = 'upgrade:600-pgsql-sequences';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -6,7 +6,6 @@ use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class UpgradeSkeleton.
|
||||
* TODO DONT FORGET TO ADD THIS TO THE DOCKER BUILD
|
||||
*/
|
||||
class UpgradeSkeleton extends Command
|
||||
{
|
||||
@@ -15,7 +14,7 @@ class UpgradeSkeleton extends Command
|
||||
|
||||
protected $description = 'SOME DESCRIPTION';
|
||||
|
||||
protected $signature = 'firefly-iii:UPGRSKELETON {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:UPGRSKELETON {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
|
||||
@@ -36,17 +36,14 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class AccountCurrencies
|
||||
*/
|
||||
class AccountCurrencies extends Command
|
||||
class UpgradesAccountCurrencies extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
public const string CONFIG_NAME = '480_account_currencies';
|
||||
|
||||
protected $description = 'Give all accounts proper currency info.';
|
||||
protected $signature = 'firefly-iii:account-currencies {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:480-account-currencies {--F|force : Force the execution of this command.}';
|
||||
private AccountRepositoryInterface $accountRepos;
|
||||
private int $count;
|
||||
private UserRepositoryInterface $userRepos;
|
||||
@@ -29,10 +29,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class RenameAccountMeta
|
||||
*/
|
||||
class RenameAccountMeta extends Command
|
||||
class UpgradesAccountMetaData extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
@@ -40,7 +37,7 @@ class RenameAccountMeta extends Command
|
||||
|
||||
protected $description = 'Rename account meta-data to new format.';
|
||||
|
||||
protected $signature = 'firefly-iii:rename-account-meta {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:480-account-meta {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -30,10 +30,7 @@ use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\Note;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class MigrateAttachments
|
||||
*/
|
||||
class MigrateAttachments extends Command
|
||||
class UpgradesAttachments extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
@@ -41,7 +38,7 @@ class MigrateAttachments extends Command
|
||||
|
||||
protected $description = 'Migrates attachment meta-data.';
|
||||
|
||||
protected $signature = 'firefly-iii:migrate-attachments {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:480-attachments {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -36,10 +36,7 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class MigrateToRules
|
||||
*/
|
||||
class MigrateToRules extends Command
|
||||
class UpgradesBillsToRules extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
@@ -47,7 +44,7 @@ class MigrateToRules extends Command
|
||||
|
||||
protected $description = 'Migrate bills to rules.';
|
||||
|
||||
protected $signature = 'firefly-iii:bills-to-rules {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:480-bills-to-rules {--F|force : Force the execution of this command.}';
|
||||
private BillRepositoryInterface $billRepository;
|
||||
private int $count;
|
||||
private RuleGroupRepositoryInterface $ruleGroupRepository;
|
||||
@@ -28,10 +28,7 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class AppendBudgetLimitPeriods
|
||||
*/
|
||||
class AppendBudgetLimitPeriods extends Command
|
||||
class UpgradesBudgetLimitPeriods extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
@@ -39,7 +36,7 @@ class AppendBudgetLimitPeriods extends Command
|
||||
|
||||
protected $description = 'Append budget limits with their (estimated) timeframe.';
|
||||
|
||||
protected $signature = 'firefly-iii:budget-limit-periods {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:550-budget-limit-periods {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -31,10 +31,7 @@ use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class BudgetLimitCurrency
|
||||
*/
|
||||
class BudgetLimitCurrency extends Command
|
||||
class UpgradesBudgetLimits extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
@@ -42,7 +39,7 @@ class BudgetLimitCurrency extends Command
|
||||
|
||||
protected $description = 'Give budget limits a currency';
|
||||
|
||||
protected $signature = 'firefly-iii:bl-currency {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:480-budget-limit-currencies {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -31,16 +31,13 @@ use FireflyIII\Models\AccountType;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class CCLiabilities
|
||||
*/
|
||||
class CCLiabilities extends Command
|
||||
class UpgradesCreditCardLiabilities extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
public const string CONFIG_NAME = '480_cc_liabilities';
|
||||
protected $description = 'Convert old credit card liabilities.';
|
||||
protected $signature = 'firefly-iii:cc-liabilities {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:480-cc-liabilities {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -32,10 +32,7 @@ use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class UpgradeCurrencyPreferences
|
||||
*/
|
||||
class UpgradeCurrencyPreferences extends Command
|
||||
class UpgradesCurrencyPreferences extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
@@ -43,7 +40,7 @@ class UpgradeCurrencyPreferences extends Command
|
||||
|
||||
protected $description = 'Upgrade user currency preferences';
|
||||
|
||||
protected $signature = 'firefly-iii:upgrade-currency-preferences {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:610-currency-preferences {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -29,10 +29,7 @@ set_time_limit(0);
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class UpgradeDatabase
|
||||
*/
|
||||
class UpgradeDatabase extends Command
|
||||
class UpgradesDatabase extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
@@ -46,32 +43,30 @@ class UpgradeDatabase extends Command
|
||||
{
|
||||
$this->callInitialCommands();
|
||||
$commands = [
|
||||
'firefly-iii:transaction-identifiers',
|
||||
'firefly-iii:migrate-to-groups',
|
||||
'firefly-iii:account-currencies',
|
||||
'firefly-iii:transfer-currencies',
|
||||
'firefly-iii:other-currencies',
|
||||
'firefly-iii:migrate-notes',
|
||||
'firefly-iii:migrate-attachments',
|
||||
'firefly-iii:bills-to-rules',
|
||||
'firefly-iii:bl-currency',
|
||||
'firefly-iii:cc-liabilities',
|
||||
'firefly-iii:back-to-journals',
|
||||
'firefly-iii:rename-account-meta',
|
||||
'firefly-iii:migrate-recurrence-meta',
|
||||
'firefly-iii:migrate-tag-locations',
|
||||
'firefly-iii:migrate-recurrence-type',
|
||||
'firefly-iii:upgrade-liabilities',
|
||||
'firefly-iii:liabilities-600',
|
||||
'firefly-iii:budget-limit-periods',
|
||||
'firefly-iii:migrate-rule-actions',
|
||||
'firefly-iii:restore-oauth-keys',
|
||||
'firefly-iii:correct-account-balance',
|
||||
// also just in case, some integrity commands:
|
||||
'firefly-iii:add-timezones-to-dates',
|
||||
'firefly-iii:create-group-memberships',
|
||||
'firefly-iii:upgrade-group-information',
|
||||
'firefly-iii:upgrade-currency-preferences',
|
||||
'upgrade:480-transaction-identifiers',
|
||||
'upgrade:480-migrate-to-groups',
|
||||
'upgrade:480-account-currencies',
|
||||
'upgrade:480-transfer-currencies',
|
||||
'upgrade:480-currency-information',
|
||||
'upgrade:480-notes',
|
||||
'upgrade:480-attachments',
|
||||
'upgrade:480-bills-to-rules',
|
||||
'upgrade:480-budget-limit-currencies',
|
||||
'upgrade:480-cc-liabilities',
|
||||
'upgrade:480-journal-meta-data',
|
||||
'upgrade:480-account-meta',
|
||||
'upgrade:481-recurrence-meta',
|
||||
'upgrade:500-tag-locations',
|
||||
'upgrade:550-recurrence-type',
|
||||
'upgrade:560-liabilities',
|
||||
'upgrade:600-liabilities',
|
||||
'upgrade:550-budget-limit-periods',
|
||||
'upgrade:600-rule-actions',
|
||||
'upgrade:610-account-balance',
|
||||
'upgrade:610-currency-preferences',
|
||||
'upgrade:610-currency-preferences',
|
||||
'upgrade:620-piggy-banks',
|
||||
'upgrade:620-native-amounts',
|
||||
'firefly-iii:correct-database',
|
||||
];
|
||||
$args = [];
|
||||
@@ -93,7 +88,7 @@ class UpgradeDatabase extends Command
|
||||
private function callInitialCommands(): void
|
||||
{
|
||||
$this->call('migrate', ['--seed' => true, '--force' => true, '--no-interaction' => true]);
|
||||
$this->call('firefly-iii:fix-pgsql-sequences');
|
||||
$this->call('firefly-iii:decrypt-all');
|
||||
$this->call('upgrade:600-pgsql-sequences');
|
||||
$this->call('upgrade:480-decrypt-all');
|
||||
}
|
||||
}
|
||||
@@ -32,10 +32,7 @@ use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class BackToJournals
|
||||
*/
|
||||
class BackToJournals extends Command
|
||||
class UpgradesJournalMetaData extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
@@ -43,7 +40,7 @@ class BackToJournals extends Command
|
||||
|
||||
protected $description = 'Move meta data back to journals, not individual transactions.';
|
||||
|
||||
protected $signature = 'firefly-iii:back-to-journals {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:480-journal-meta-data {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -71,7 +68,7 @@ class BackToJournals extends Command
|
||||
|
||||
private function isMigrated(): bool
|
||||
{
|
||||
$configVar = app('fireflyconfig')->get(MigrateToGroups::CONFIG_NAME, false);
|
||||
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
|
||||
|
||||
return (bool) $configVar->data;
|
||||
}
|
||||
@@ -29,10 +29,7 @@ use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\TransactionJournalMeta;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class MigrateJournalNotes
|
||||
*/
|
||||
class MigrateJournalNotes extends Command
|
||||
class UpgradesJournalNotes extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
@@ -40,7 +37,7 @@ class MigrateJournalNotes extends Command
|
||||
|
||||
protected $description = 'Migrate notes for transaction journals.';
|
||||
|
||||
protected $signature = 'firefly-iii:migrate-notes {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:480-notes {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -34,16 +34,13 @@ use FireflyIII\Services\Internal\Support\CreditRecalculateService;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class UpgradeLiabilities
|
||||
*/
|
||||
class UpgradeLiabilities extends Command
|
||||
class UpgradesLiabilities extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
public const string CONFIG_NAME = '560_upgrade_liabilities';
|
||||
protected $description = 'Upgrade liabilities to new 5.6.0 structure.';
|
||||
protected $signature = 'firefly-iii:upgrade-liabilities {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:560-liabilities {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -35,16 +35,13 @@ use FireflyIII\Services\Internal\Support\CreditRecalculateService;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class UpgradeLiabilitiesEight
|
||||
*/
|
||||
class UpgradeLiabilitiesEight extends Command
|
||||
class UpgradesLiabilitiesEight extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
public const string CONFIG_NAME = '600_upgrade_liabilities';
|
||||
protected $description = 'Upgrade liabilities to new 6.0.0 structure.';
|
||||
protected $signature = 'firefly-iii:liabilities-600 {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:600-liabilities {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -201,32 +198,9 @@ class UpgradeLiabilitiesEight extends Command
|
||||
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
// $delete = false;
|
||||
// /** @var Transaction $source */
|
||||
// $source = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
// /** @var Transaction $dest */
|
||||
// $dest = $journal->transactions()->where('amount', '>', 0)->first();
|
||||
|
||||
/**
|
||||
* // if source is this liability and destination is expense, remove transaction.
|
||||
* // if source is revenue and destination is liability, remove transaction.
|
||||
* if ($source->account_id === $account->id && $dest->account->accountType->type === AccountType::EXPENSE) {
|
||||
* $delete = true;
|
||||
* }
|
||||
* if ($dest->account_id === $account->id && $source->account->accountType->type === AccountType::REVENUE) {
|
||||
* $delete = true;
|
||||
* }
|
||||
*
|
||||
* // overruled. No transaction will be deleted, ever.
|
||||
* // code is kept in place, so I can revisit my reasoning.
|
||||
* $delete = false;
|
||||
*/
|
||||
|
||||
// if ($delete) {
|
||||
$service = app(TransactionGroupDestroyService::class);
|
||||
$service->destroy($journal->transactionGroup);
|
||||
++$count;
|
||||
// }
|
||||
}
|
||||
|
||||
return $count;
|
||||
111
app/Console/Commands/Upgrade/UpgradesMultiPiggyBanks.php
Normal file
111
app/Console/Commands/Upgrade/UpgradesMultiPiggyBanks.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* UpgradeMultiPiggyBanks.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UpgradesMultiPiggyBanks extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
public const string CONFIG_NAME = '620_make_multi_piggies';
|
||||
|
||||
protected $description = 'Upgrade piggy banks so they can use multiple accounts.';
|
||||
|
||||
protected $signature = 'upgrade:620-piggy-banks {--F|force : Force the execution of this command.}';
|
||||
private AccountRepositoryInterface $accountRepository;
|
||||
private PiggyBankRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
if ($this->isExecuted() && true !== $this->option('force')) {
|
||||
$this->friendlyInfo('This command has already been executed.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
$this->upgradePiggyBanks();
|
||||
$this->friendlyInfo('Upgraded all piggy banks.');
|
||||
|
||||
$this->markAsExecuted();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function isExecuted(): bool
|
||||
{
|
||||
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
|
||||
if (null !== $configVar) {
|
||||
return (bool) $configVar->data;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function upgradePiggyBanks(): void
|
||||
{
|
||||
$this->repository = app(PiggyBankRepositoryInterface::class);
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$set = PiggyBank::whereNotNull('account_id')->get();
|
||||
Log::debug(sprintf('Will update %d piggy banks(s).', $set->count()));
|
||||
|
||||
/** @var PiggyBank $piggyBank */
|
||||
foreach ($set as $piggyBank) {
|
||||
$this->upgradePiggyBank($piggyBank);
|
||||
}
|
||||
}
|
||||
|
||||
private function upgradePiggyBank(PiggyBank $piggyBank): void
|
||||
{
|
||||
$this->repository->setUser($piggyBank->account->user);
|
||||
$this->accountRepository->setUser($piggyBank->account->user);
|
||||
$repetition = $this->repository->getRepetition($piggyBank, true);
|
||||
$currency = $this->accountRepository->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrencyByUserGroup($piggyBank->account->user->userGroup);
|
||||
|
||||
// update piggy bank to have a currency.
|
||||
$piggyBank->transaction_currency_id = $currency->id;
|
||||
$piggyBank->saveQuietly();
|
||||
|
||||
// store current amount in account association.
|
||||
$piggyBank->accounts()->sync([$piggyBank->account->id => ['current_amount' => $repetition->current_amount]]);
|
||||
$piggyBank->account_id = null;
|
||||
$piggyBank->saveQuietly();
|
||||
|
||||
// remove all repetitions (no longer used)
|
||||
$piggyBank->piggyBankRepetitions()->delete();
|
||||
|
||||
}
|
||||
|
||||
private function markAsExecuted(): void
|
||||
{
|
||||
app('fireflyconfig')->set(self::CONFIG_NAME, true);
|
||||
}
|
||||
}
|
||||
72
app/Console/Commands/Upgrade/UpgradesNativeAmounts.php
Normal file
72
app/Console/Commands/Upgrade/UpgradesNativeAmounts.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* UpgradesNativeAmounts.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
class UpgradesNativeAmounts extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
public const string CONFIG_NAME = '620_native_amounts';
|
||||
|
||||
protected $description = 'Runs the native amounts calculations.';
|
||||
|
||||
protected $signature = 'upgrade:620-native-amounts {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
if ($this->isExecuted() && true !== $this->option('force')) {
|
||||
$this->friendlyInfo('This command has already been executed.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Artisan::call('correction:recalculate-native-amounts');
|
||||
|
||||
$this->markAsExecuted();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function isExecuted(): bool
|
||||
{
|
||||
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
|
||||
if (null !== $configVar) {
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function markAsExecuted(): void
|
||||
{
|
||||
app('fireflyconfig')->set(self::CONFIG_NAME, true);
|
||||
}
|
||||
}
|
||||
@@ -30,10 +30,7 @@ use FireflyIII\Models\RecurrenceMeta;
|
||||
use FireflyIII\Models\RecurrenceTransactionMeta;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class MigrateRecurrenceMeta
|
||||
*/
|
||||
class MigrateRecurrenceMeta extends Command
|
||||
class UpgradesRecurrenceMetaData extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
@@ -41,7 +38,7 @@ class MigrateRecurrenceMeta extends Command
|
||||
|
||||
protected $description = 'Migrate recurrence meta data';
|
||||
|
||||
protected $signature = 'firefly-iii:migrate-recurrence-meta {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:481-recurrence-meta {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -27,10 +27,7 @@ namespace FireflyIII\Console\Commands\Upgrade;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class MigrateRecurrenceType
|
||||
*/
|
||||
class MigrateRecurrenceType extends Command
|
||||
class UpgradesRecurrenceType extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
@@ -38,7 +35,7 @@ class MigrateRecurrenceType extends Command
|
||||
|
||||
protected $description = 'Migrate transaction type of recurring transaction.';
|
||||
|
||||
protected $signature = 'firefly-iii:migrate-recurrence-type {--F|force : Force the execution of this command.}';
|
||||
protected $signature = 'upgrade:550-recurrence-type {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user