mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'develop'
This commit is contained in:
commit
31722477d4
@ -29,7 +29,7 @@ $paths = [
|
|||||||
$current . '/../../database',
|
$current . '/../../database',
|
||||||
$current . '/../../routes',
|
$current . '/../../routes',
|
||||||
$current . '/../../tests',
|
$current . '/../../tests',
|
||||||
$current . '/../../resources/lang',
|
$current . '/../../resources/lang/en_US',
|
||||||
];
|
];
|
||||||
|
|
||||||
$finder = PhpCsFixer\Finder::create()
|
$finder = PhpCsFixer\Finder::create()
|
||||||
|
56
.ci/php-cs-fixer/composer.lock
generated
56
.ci/php-cs-fixer/composer.lock
generated
@ -97,13 +97,13 @@
|
|||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
|
||||||
"dev-main": "3.x-dev"
|
|
||||||
},
|
|
||||||
"phpstan": {
|
"phpstan": {
|
||||||
"includes": [
|
"includes": [
|
||||||
"extension.neon"
|
"extension.neon"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "3.x-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@ -406,16 +406,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "friendsofphp/php-cs-fixer",
|
"name": "friendsofphp/php-cs-fixer",
|
||||||
"version": "v3.65.0",
|
"version": "v3.66.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||||
"reference": "79d4f3e77b250a7d8043d76c6af8f0695e8a469f"
|
"reference": "5f5f2a142ff36b93c41885bca29cc5f861c013e6"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/79d4f3e77b250a7d8043d76c6af8f0695e8a469f",
|
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/5f5f2a142ff36b93c41885bca29cc5f861c013e6",
|
||||||
"reference": "79d4f3e77b250a7d8043d76c6af8f0695e8a469f",
|
"reference": "5f5f2a142ff36b93c41885bca29cc5f861c013e6",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -441,7 +441,7 @@
|
|||||||
"symfony/polyfill-mbstring": "^1.28",
|
"symfony/polyfill-mbstring": "^1.28",
|
||||||
"symfony/polyfill-php80": "^1.28",
|
"symfony/polyfill-php80": "^1.28",
|
||||||
"symfony/polyfill-php81": "^1.28",
|
"symfony/polyfill-php81": "^1.28",
|
||||||
"symfony/process": "^5.4 || ^6.0 || ^7.0",
|
"symfony/process": "^5.4 || ^6.0 || ^7.0 <7.2",
|
||||||
"symfony/stopwatch": "^5.4 || ^6.0 || ^7.0"
|
"symfony/stopwatch": "^5.4 || ^6.0 || ^7.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
@ -497,7 +497,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.65.0"
|
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.66.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -505,7 +505,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-11-25T00:39:24+00:00"
|
"time": "2024-12-29T13:46:23+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/container",
|
"name": "psr/container",
|
||||||
@ -1369,12 +1369,12 @@
|
|||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/contracts",
|
||||||
|
"name": "symfony/contracts"
|
||||||
|
},
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-main": "3.5-dev"
|
"dev-main": "3.5-dev"
|
||||||
},
|
|
||||||
"thanks": {
|
|
||||||
"name": "symfony/contracts",
|
|
||||||
"url": "https://github.com/symfony/contracts"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@ -1517,12 +1517,12 @@
|
|||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/contracts",
|
||||||
|
"name": "symfony/contracts"
|
||||||
|
},
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-main": "3.5-dev"
|
"dev-main": "3.5-dev"
|
||||||
},
|
|
||||||
"thanks": {
|
|
||||||
"name": "symfony/contracts",
|
|
||||||
"url": "https://github.com/symfony/contracts"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@ -2246,16 +2246,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/process",
|
"name": "symfony/process",
|
||||||
"version": "v7.2.0",
|
"version": "v7.1.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/process.git",
|
"url": "https://github.com/symfony/process.git",
|
||||||
"reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e"
|
"reference": "42783370fda6e538771f7c7a36e9fa2ee3a84892"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e",
|
"url": "https://api.github.com/repos/symfony/process/zipball/42783370fda6e538771f7c7a36e9fa2ee3a84892",
|
||||||
"reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e",
|
"reference": "42783370fda6e538771f7c7a36e9fa2ee3a84892",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -2287,7 +2287,7 @@
|
|||||||
"description": "Executes commands in sub-processes",
|
"description": "Executes commands in sub-processes",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/process/tree/v7.2.0"
|
"source": "https://github.com/symfony/process/tree/v7.1.8"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -2303,7 +2303,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-11-06T14:24:19+00:00"
|
"time": "2024-11-06T14:23:19+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/service-contracts",
|
"name": "symfony/service-contracts",
|
||||||
@ -2329,12 +2329,12 @@
|
|||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/contracts",
|
||||||
|
"name": "symfony/contracts"
|
||||||
|
},
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-main": "3.5-dev"
|
"dev-main": "3.5-dev"
|
||||||
},
|
|
||||||
"thanks": {
|
|
||||||
"name": "symfony/contracts",
|
|
||||||
"url": "https://github.com/symfony/contracts"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -26,8 +26,7 @@ SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
|||||||
cd $SCRIPT_DIR/php-cs-fixer
|
cd $SCRIPT_DIR/php-cs-fixer
|
||||||
composer update --quiet
|
composer update --quiet
|
||||||
rm -f .php-cs-fixer.cache
|
rm -f .php-cs-fixer.cache
|
||||||
PHP_CS_FIXER_IGNORE_ENV=true
|
PHP_CS_FIXER_IGNORE_ENV=true ./vendor/bin/php-cs-fixer fix \
|
||||||
./vendor/bin/php-cs-fixer fix \
|
|
||||||
--config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php \
|
--config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php \
|
||||||
--format=txt \
|
--format=txt \
|
||||||
--allow-risky=yes
|
--allow-risky=yes
|
||||||
|
2
.github/workflows/sonarcloud.yml
vendored
2
.github/workflows/sonarcloud.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
|||||||
- name: Setup PHP with Xdebug
|
- name: Setup PHP with Xdebug
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: '8.3'
|
php-version: '8.4'
|
||||||
coverage: xdebug
|
coverage: xdebug
|
||||||
extensions: >-
|
extensions: >-
|
||||||
bcmath
|
bcmath
|
||||||
|
@ -4,6 +4,7 @@ Over time, many people have contributed to Firefly III. Their efforts are not al
|
|||||||
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
|
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
|
||||||
|
|
||||||
## 2024
|
## 2024
|
||||||
|
- TasneemTantawy
|
||||||
- Antônio Franco
|
- Antônio Franco
|
||||||
- yparitcher
|
- yparitcher
|
||||||
- Jhon Pedroza
|
- Jhon Pedroza
|
||||||
|
@ -26,10 +26,11 @@ namespace FireflyIII\Api\V1\Controllers\Autocomplete;
|
|||||||
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest;
|
use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest;
|
||||||
|
use FireflyIII\Enums\AccountTypeEnum;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\AccountType;
|
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
@ -61,7 +62,7 @@ class AccountController extends Controller
|
|||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
$this->balanceTypes = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
|
$this->balanceTypes = [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,20 +81,20 @@ class AccountController extends Controller
|
|||||||
$return = [];
|
$return = [];
|
||||||
$result = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit'));
|
$result = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit'));
|
||||||
|
|
||||||
// TODO this code is duplicated in the V2 Autocomplete controller, which means this code is due to be deprecated.
|
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
|
||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($result as $account) {
|
foreach ($result as $account) {
|
||||||
$nameWithBalance = $account->name;
|
$nameWithBalance = $account->name;
|
||||||
$currency = $this->repository->getAccountCurrency($account) ?? $defaultCurrency;
|
$currency = $this->repository->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||||
|
$useCurrency = $currency;
|
||||||
if (in_array($account->accountType->type, $this->balanceTypes, true)) {
|
if (in_array($account->accountType->type, $this->balanceTypes, true)) {
|
||||||
$balance = app('steam')->balance($account, $date);
|
$balance = Steam::finalAccountBalance($account, $date);
|
||||||
|
$key = $this->convertToNative && $currency->id !== $this->defaultCurrency->id ? 'native_balance' : 'balance';
|
||||||
|
$useCurrency = $this->convertToNative && $currency->id !== $this->defaultCurrency->id ? $this->defaultCurrency : $currency;
|
||||||
|
$amount = $balance[$key] ?? '0';
|
||||||
$nameWithBalance = sprintf(
|
$nameWithBalance = sprintf(
|
||||||
'%s (%s)',
|
'%s (%s)',
|
||||||
$account->name,
|
$account->name,
|
||||||
app('amount')->formatAnything($currency, $balance, false)
|
app('amount')->formatAnything($useCurrency, $amount, false)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,11 +103,11 @@ class AccountController extends Controller
|
|||||||
'name' => $account->name,
|
'name' => $account->name,
|
||||||
'name_with_balance' => $nameWithBalance,
|
'name_with_balance' => $nameWithBalance,
|
||||||
'type' => $account->accountType->type,
|
'type' => $account->accountType->type,
|
||||||
'currency_id' => (string)$currency->id,
|
'currency_id' => (string) $useCurrency->id,
|
||||||
'currency_name' => $currency->name,
|
'currency_name' => $useCurrency->name,
|
||||||
'currency_code' => $currency->code,
|
'currency_code' => $useCurrency->code,
|
||||||
'currency_symbol' => $currency->symbol,
|
'currency_symbol' => $useCurrency->symbol,
|
||||||
'currency_decimal_places' => $currency->decimal_places,
|
'currency_decimal_places' => $useCurrency->decimal_places,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +115,7 @@ class AccountController extends Controller
|
|||||||
usort(
|
usort(
|
||||||
$return,
|
$return,
|
||||||
static function (array $left, array $right) {
|
static function (array $left, array $right) {
|
||||||
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
|
$order = [AccountTypeEnum::ASSET->value, AccountTypeEnum::REVENUE->value, AccountTypeEnum::EXPENSE->value];
|
||||||
$posA = (int) array_search($left['type'], $order, true);
|
$posA = (int) array_search($left['type'], $order, true);
|
||||||
$posB = (int) array_search($right['type'], $order, true);
|
$posB = (int) array_search($right['type'], $order, true);
|
||||||
|
|
||||||
|
@ -68,12 +68,11 @@ class PiggyBankController extends Controller
|
|||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
|
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
|
||||||
$response = [];
|
$response = [];
|
||||||
|
|
||||||
/** @var PiggyBank $piggy */
|
/** @var PiggyBank $piggy */
|
||||||
foreach ($piggies as $piggy) {
|
foreach ($piggies as $piggy) {
|
||||||
$currency = $this->accountRepository->getAccountCurrency($piggy->account) ?? $defaultCurrency;
|
$currency = $piggy->transactionCurrency;
|
||||||
$objectGroup = $piggy->objectGroups()->first();
|
$objectGroup = $piggy->objectGroups()->first();
|
||||||
$response[] = [
|
$response[] = [
|
||||||
'id' => (string) $piggy->id,
|
'id' => (string) $piggy->id,
|
||||||
@ -99,13 +98,12 @@ class PiggyBankController extends Controller
|
|||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
|
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
|
||||||
$response = [];
|
$response = [];
|
||||||
|
|
||||||
/** @var PiggyBank $piggy */
|
/** @var PiggyBank $piggy */
|
||||||
foreach ($piggies as $piggy) {
|
foreach ($piggies as $piggy) {
|
||||||
$currency = $this->accountRepository->getAccountCurrency($piggy->account) ?? $defaultCurrency;
|
$currency = $piggy->transactionCurrency;
|
||||||
$currentAmount = $this->piggyRepository->getRepetition($piggy)->currentamount ?? '0';
|
$currentAmount = $this->piggyRepository->getCurrentAmount($piggy);
|
||||||
$objectGroup = $piggy->objectGroups()->first();
|
$objectGroup = $piggy->objectGroups()->first();
|
||||||
$response[] = [
|
$response[] = [
|
||||||
'id' => (string) $piggy->id,
|
'id' => (string) $piggy->id,
|
||||||
@ -114,7 +112,7 @@ class PiggyBankController extends Controller
|
|||||||
'%s (%s / %s)',
|
'%s (%s / %s)',
|
||||||
$piggy->name,
|
$piggy->name,
|
||||||
app('amount')->formatAnything($currency, $currentAmount, false),
|
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_id' => (string) $currency->id,
|
||||||
'currency_name' => $currency->name,
|
'currency_name' => $currency->name,
|
||||||
|
@ -27,9 +27,9 @@ namespace FireflyIII\Api\V1\Controllers\Chart;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Data\DateRequest;
|
use FireflyIII\Api\V1\Requests\Data\DateRequest;
|
||||||
|
use FireflyIII\Enums\AccountTypeEnum;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\AccountType;
|
|
||||||
use FireflyIII\Models\Preference;
|
use FireflyIII\Models\Preference;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ApiSupport;
|
use FireflyIII\Support\Http\Api\ApiSupport;
|
||||||
@ -81,11 +81,10 @@ class AccountController extends Controller
|
|||||||
$end = $dates['end'];
|
$end = $dates['end'];
|
||||||
|
|
||||||
// user's preferences
|
// user's preferences
|
||||||
$defaultSet = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
|
$defaultSet = $this->repository->getAccountsByType([AccountTypeEnum::ASSET->value])->pluck('id')->toArray();
|
||||||
|
|
||||||
/** @var Preference $frontpage */
|
/** @var Preference $frontpage */
|
||||||
$frontpage = app('preferences')->get('frontpageAccounts', $defaultSet);
|
$frontpage = app('preferences')->get('frontpageAccounts', $defaultSet);
|
||||||
$default = app('amount')->getDefaultCurrency();
|
|
||||||
|
|
||||||
if (!(is_array($frontpage->data) && count($frontpage->data) > 0)) {
|
if (!(is_array($frontpage->data) && count($frontpage->data) > 0)) {
|
||||||
$frontpage->data = $defaultSet;
|
$frontpage->data = $defaultSet;
|
||||||
@ -98,10 +97,8 @@ class AccountController extends Controller
|
|||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($accounts as $account) {
|
foreach ($accounts as $account) {
|
||||||
$currency = $this->repository->getAccountCurrency($account);
|
$currency = $this->repository->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||||
if (null === $currency) {
|
$field = $this->convertToNative && $currency->id !== $this->defaultCurrency->id ? 'native_balance' : 'balance';
|
||||||
$currency = $default;
|
|
||||||
}
|
|
||||||
$currentSet = [
|
$currentSet = [
|
||||||
'label' => $account->name,
|
'label' => $account->name,
|
||||||
'currency_id' => (string) $currency->id,
|
'currency_id' => (string) $currency->id,
|
||||||
@ -116,13 +113,12 @@ class AccountController extends Controller
|
|||||||
];
|
];
|
||||||
// TODO this code is also present in the V2 chart account controller so this method is due to be deprecated.
|
// TODO this code is also present in the V2 chart account controller so this method is due to be deprecated.
|
||||||
$currentStart = clone $start;
|
$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][$field];
|
||||||
$previous = array_values($range)[0];
|
|
||||||
while ($currentStart <= $end) {
|
while ($currentStart <= $end) {
|
||||||
$format = $currentStart->format('Y-m-d');
|
$format = $currentStart->format('Y-m-d');
|
||||||
$label = $currentStart->toAtomString();
|
$label = $currentStart->toAtomString();
|
||||||
$balance = array_key_exists($format, $range) ? $range[$format] : $previous;
|
$balance = array_key_exists($format, $range) ? $range[$format][$field] : $previous;
|
||||||
$previous = $balance;
|
$previous = $balance;
|
||||||
$currentStart->addDay();
|
$currentStart->addDay();
|
||||||
$currentSet['entries'][$label] = $balance;
|
$currentSet['entries'][$label] = $balance;
|
||||||
|
@ -28,6 +28,9 @@ use Carbon\Carbon;
|
|||||||
use Carbon\Exceptions\InvalidDateException;
|
use Carbon\Exceptions\InvalidDateException;
|
||||||
use Carbon\Exceptions\InvalidFormatException;
|
use Carbon\Exceptions\InvalidFormatException;
|
||||||
use FireflyIII\Models\Preference;
|
use FireflyIII\Models\Preference;
|
||||||
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
@ -55,6 +58,8 @@ abstract class Controller extends BaseController
|
|||||||
/** @var array<int, string> */
|
/** @var array<int, string> */
|
||||||
protected array $allowedSort;
|
protected array $allowedSort;
|
||||||
protected ParameterBag $parameters;
|
protected ParameterBag $parameters;
|
||||||
|
protected bool $convertToNative = false;
|
||||||
|
protected TransactionCurrency $defaultCurrency;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller constructor.
|
* Controller constructor.
|
||||||
@ -67,8 +72,11 @@ abstract class Controller extends BaseController
|
|||||||
function ($request, $next) {
|
function ($request, $next) {
|
||||||
$this->parameters = $this->getParameters();
|
$this->parameters = $this->getParameters();
|
||||||
if (auth()->check()) {
|
if (auth()->check()) {
|
||||||
$language = app('steam')->getLanguage();
|
$language = Steam::getLanguage();
|
||||||
|
$this->convertToNative = Amount::convertToNative();
|
||||||
|
$this->defaultCurrency = Amount::getDefaultCurrency();
|
||||||
app()->setLocale($language);
|
app()->setLocale($language);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
|
@ -26,10 +26,10 @@ namespace FireflyIII\Api\V1\Controllers\Data;
|
|||||||
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Data\DestroyRequest;
|
use FireflyIII\Api\V1\Requests\Data\DestroyRequest;
|
||||||
|
use FireflyIII\Enums\AccountTypeEnum;
|
||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\AccountType;
|
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
@ -66,9 +66,9 @@ class DestroyController extends Controller
|
|||||||
$objects = $request->getObjects();
|
$objects = $request->getObjects();
|
||||||
$this->unused = $request->boolean('unused', false);
|
$this->unused = $request->boolean('unused', false);
|
||||||
|
|
||||||
$allExceptAssets = [AccountType::BENEFICIARY, AccountType::CASH, AccountType::CREDITCARD, AccountType::DEFAULT, AccountType::EXPENSE, AccountType::IMPORT, AccountType::INITIAL_BALANCE, AccountType::LIABILITY_CREDIT, AccountType::RECONCILIATION, AccountType::REVENUE];
|
$allExceptAssets = [AccountTypeEnum::BENEFICIARY->value, AccountTypeEnum::CASH->value, AccountTypeEnum::CREDITCARD->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::EXPENSE->value, AccountTypeEnum::IMPORT->value, AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::RECONCILIATION->value, AccountTypeEnum::REVENUE->value];
|
||||||
$all = [AccountType::ASSET, AccountType::BENEFICIARY, AccountType::CASH, AccountType::CREDITCARD, AccountType::DEBT, AccountType::DEFAULT, AccountType::EXPENSE, AccountType::IMPORT, AccountType::INITIAL_BALANCE, AccountType::LIABILITY_CREDIT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::RECONCILIATION];
|
$all = [AccountTypeEnum::ASSET->value, AccountTypeEnum::BENEFICIARY->value, AccountTypeEnum::CASH->value, AccountTypeEnum::CREDITCARD->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::EXPENSE->value, AccountTypeEnum::IMPORT->value, AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::RECONCILIATION->value];
|
||||||
$liabilities = [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD];
|
$liabilities = [AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::CREDITCARD->value];
|
||||||
$transactions = [TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value, TransactionTypeEnum::RECONCILIATION->value];
|
$transactions = [TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value, TransactionTypeEnum::RECONCILIATION->value];
|
||||||
|
|
||||||
match ($objects) {
|
match ($objects) {
|
||||||
@ -82,9 +82,9 @@ class DestroyController extends Controller
|
|||||||
'object_groups' => $this->destroyObjectGroups(),
|
'object_groups' => $this->destroyObjectGroups(),
|
||||||
'not_assets_liabilities' => $this->destroyAccounts($allExceptAssets),
|
'not_assets_liabilities' => $this->destroyAccounts($allExceptAssets),
|
||||||
'accounts' => $this->destroyAccounts($all),
|
'accounts' => $this->destroyAccounts($all),
|
||||||
'asset_accounts' => $this->destroyAccounts([AccountType::ASSET, AccountType::DEFAULT]),
|
'asset_accounts' => $this->destroyAccounts([AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value]),
|
||||||
'expense_accounts' => $this->destroyAccounts([AccountType::BENEFICIARY, AccountType::EXPENSE]),
|
'expense_accounts' => $this->destroyAccounts([AccountTypeEnum::BENEFICIARY->value, AccountTypeEnum::EXPENSE->value]),
|
||||||
'revenue_accounts' => $this->destroyAccounts([AccountType::REVENUE]),
|
'revenue_accounts' => $this->destroyAccounts([AccountTypeEnum::REVENUE->value]),
|
||||||
'liabilities' => $this->destroyAccounts($liabilities),
|
'liabilities' => $this->destroyAccounts($liabilities),
|
||||||
'transactions' => $this->destroyTransactions($transactions),
|
'transactions' => $this->destroyTransactions($transactions),
|
||||||
'withdrawals' => $this->destroyTransactions([TransactionTypeEnum::WITHDRAWAL->value]),
|
'withdrawals' => $this->destroyTransactions([TransactionTypeEnum::WITHDRAWAL->value]),
|
||||||
|
@ -29,13 +29,13 @@ use FireflyIII\Models\Account;
|
|||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
use FireflyIII\Models\Budget;
|
use FireflyIII\Models\Budget;
|
||||||
use FireflyIII\Models\Category;
|
use FireflyIII\Models\Category;
|
||||||
use FireflyIII\Models\PiggyBank;
|
|
||||||
use FireflyIII\Models\Recurrence;
|
use FireflyIII\Models\Recurrence;
|
||||||
use FireflyIII\Models\Rule;
|
use FireflyIII\Models\Rule;
|
||||||
use FireflyIII\Models\RuleGroup;
|
use FireflyIII\Models\RuleGroup;
|
||||||
use FireflyIII\Models\Tag;
|
use FireflyIII\Models\Tag;
|
||||||
use FireflyIII\Models\TransactionGroup;
|
use FireflyIII\Models\TransactionGroup;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
|
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
@ -63,14 +63,17 @@ class PurgeController extends Controller
|
|||||||
Bill::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
Bill::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
||||||
|
|
||||||
// piggies
|
// piggies
|
||||||
$set = PiggyBank::leftJoin('accounts', 'accounts.id', 'piggy_banks.account_id')
|
$repository = app(PiggyBankRepositoryInterface::class);
|
||||||
->where('accounts.user_id', $user->id)->onlyTrashed()->get(['piggy_banks.*'])
|
$repository->setUser($user);
|
||||||
;
|
$repository->purgeAll();
|
||||||
|
// $set = PiggyBank::leftJoin('accounts', 'accounts.id', 'piggy_banks.account_id')
|
||||||
/** @var PiggyBank $piggy */
|
// ->where('accounts.user_id', $user->id)->onlyTrashed()->get(['piggy_banks.*'])
|
||||||
foreach ($set as $piggy) {
|
// ;
|
||||||
$piggy->forceDelete();
|
//
|
||||||
}
|
// /** @var PiggyBank $piggy */
|
||||||
|
// foreach ($set as $piggy) {
|
||||||
|
// $piggy->forceDelete();
|
||||||
|
// }
|
||||||
|
|
||||||
// rule group
|
// rule group
|
||||||
RuleGroup::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
RuleGroup::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
||||||
|
@ -29,7 +29,9 @@ use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
|||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class BillController
|
* Class BillController
|
||||||
@ -67,6 +69,8 @@ class BillController extends Controller
|
|||||||
$bills = $request->getBills();
|
$bills = $request->getBills();
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getDefaultCurrency();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
|
||||||
// get all bills:
|
// get all bills:
|
||||||
@ -83,9 +87,22 @@ class BillController extends Controller
|
|||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$billId = (int) $journal['bill_id'];
|
$billId = (int) $journal['bill_id'];
|
||||||
$currencyId = (int) $journal['currency_id'];
|
$currencyId = (int) $journal['currency_id'];
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyCode = $journal['currency_code'];
|
||||||
|
$field = 'amount';
|
||||||
|
|
||||||
|
// use the native amount if the user wants to convert to native currency
|
||||||
|
if ($convertToNative && $currencyId !== $default->id) {
|
||||||
|
$currencyId = $default->id;
|
||||||
|
$currencyCode = $default->code;
|
||||||
|
$field = 'native_amount';
|
||||||
|
}
|
||||||
|
// use foreign amount when the foreign currency IS the default currency.
|
||||||
|
if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
|
||||||
|
$field = 'foreign_amount';
|
||||||
|
}
|
||||||
|
Log::debug(sprintf('Journal #%d in bill #%d will use %s (%s %s)', $journal['transaction_group_id'], $billId, $field, $currencyCode, $journal[$field] ?? '0'));
|
||||||
|
|
||||||
$key = sprintf('%d-%d', $billId, $currencyId);
|
$key = sprintf('%d-%d', $billId, $currencyId);
|
||||||
$foreignKey = sprintf('%d-%d', $billId, $foreignCurrencyId);
|
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
if (0 !== $currencyId) {
|
||||||
$response[$key] ??= [
|
$response[$key] ??= [
|
||||||
@ -94,21 +111,11 @@ class BillController extends Controller
|
|||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$key]['difference'] = bcadd($response[$key]['difference'], $journal['amount']);
|
$response[$key]['difference'] = bcadd($response[$key]['difference'], (string) ($journal[$field] ?? '0'));
|
||||||
$response[$key]['difference_float'] = (float) $response[$key]['difference']; // intentional float
|
$response[$key]['difference_float'] = (float) $response[$key]['difference']; // intentional float
|
||||||
}
|
}
|
||||||
if (0 !== $foreignCurrencyId) {
|
|
||||||
$response[$foreignKey] ??= [
|
|
||||||
'difference' => '0',
|
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignKey]['difference'] = bcadd($response[$foreignKey]['difference'], $journal['foreign_amount']);
|
|
||||||
$response[$foreignKey]['difference_float'] = (float)$response[$foreignKey]['difference']; // intentional float
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
@ -125,6 +132,8 @@ class BillController extends Controller
|
|||||||
$accounts = $request->getAssetAccounts();
|
$accounts = $request->getAssetAccounts();
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getDefaultCurrency();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||||
@ -136,28 +145,31 @@ class BillController extends Controller
|
|||||||
|
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int) $journal['currency_id'];
|
$currencyId = (int) $journal['currency_id'];
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyCode = $journal['currency_code'];
|
||||||
|
$field = 'amount';
|
||||||
|
|
||||||
|
// use the native amount if the user wants to convert to native currency
|
||||||
|
if ($convertToNative && $currencyId !== $default->id) {
|
||||||
|
$currencyId = $default->id;
|
||||||
|
$currencyCode = $default->code;
|
||||||
|
$field = 'native_amount';
|
||||||
|
}
|
||||||
|
// use foreign amount when the foreign currency IS the default currency.
|
||||||
|
if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
|
||||||
|
$field = 'foreign_amount';
|
||||||
|
}
|
||||||
|
Log::debug(sprintf('Journal #%d will use %s (%s %s)', $journal['transaction_group_id'], $field, $currencyCode, $journal[$field] ?? '0'));
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
if (0 !== $currencyId) {
|
||||||
$response[$currencyId] ??= [
|
$response[$currencyId] ??= [
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']);
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) ($journal[$field] ?? '0'));
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // intentional float
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // intentional float
|
||||||
}
|
}
|
||||||
if (0 !== $foreignCurrencyId) {
|
|
||||||
$response[$foreignCurrencyId] ??= [
|
|
||||||
'difference' => '0',
|
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // intentional float
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
|
@ -28,7 +28,9 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class PeriodController
|
* Class PeriodController
|
||||||
@ -45,36 +47,46 @@ class PeriodController extends Controller
|
|||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getDefaultCurrency();
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type)
|
// collect all expenses in this period (regardless of type)
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
|
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
|
// same code as many other sumExpense methods. I think this needs some kind of generic method.
|
||||||
|
$amount = '0';
|
||||||
$currencyId = (int) $journal['currency_id'];
|
$currencyId = (int) $journal['currency_id'];
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyCode = $journal['currency_code'];
|
||||||
|
if ($convertToNative) {
|
||||||
|
$amount = Amount::getAmountFromJournal($journal);
|
||||||
|
if ($default->id !== (int) $journal['currency_id'] && $default->id !== (int) $journal['foreign_currency_id']) {
|
||||||
|
$currencyId = $default->id;
|
||||||
|
$currencyCode = $default->code;
|
||||||
|
}
|
||||||
|
if ($default->id !== (int) $journal['currency_id'] && $default->id === (int) $journal['foreign_currency_id']) {
|
||||||
|
$currencyId = $journal['foreign_currency_id'];
|
||||||
|
$currencyCode = $journal['foreign_currency_code'];
|
||||||
|
}
|
||||||
|
Log::debug(sprintf('[a] Add amount %s %s', $currencyCode, $amount));
|
||||||
|
}
|
||||||
|
if (!$convertToNative) {
|
||||||
|
// ignore the amount in foreign currency.
|
||||||
|
Log::debug(sprintf('[b] Add amount %s %s', $currencyCode, $journal['amount']));
|
||||||
|
$amount = $journal['amount'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
|
||||||
$response[$currencyId] ??= [
|
$response[$currencyId] ??= [
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']);
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $amount);
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // intentional float
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // intentional float
|
||||||
}
|
}
|
||||||
if (0 !== $foreignCurrencyId) {
|
|
||||||
$response[$foreignCurrencyId] ??= [
|
|
||||||
'difference' => '0',
|
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // intentional float
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,9 @@ use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
|||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TagController
|
* Class TagController
|
||||||
@ -66,6 +68,8 @@ class TagController extends Controller
|
|||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getDefaultCurrency();
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
@ -75,30 +79,37 @@ class TagController extends Controller
|
|||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
|
// same code as many other sumExpense methods. I think this needs some kind of generic method.
|
||||||
|
$amount = '0';
|
||||||
$currencyId = (int) $journal['currency_id'];
|
$currencyId = (int) $journal['currency_id'];
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyCode = $journal['currency_code'];
|
||||||
|
if ($convertToNative) {
|
||||||
|
$amount = Amount::getAmountFromJournal($journal);
|
||||||
|
if ($default->id !== (int) $journal['currency_id'] && $default->id !== (int) $journal['foreign_currency_id']) {
|
||||||
|
$currencyId = $default->id;
|
||||||
|
$currencyCode = $default->code;
|
||||||
|
}
|
||||||
|
if ($default->id !== (int) $journal['currency_id'] && $default->id === (int) $journal['foreign_currency_id']) {
|
||||||
|
$currencyId = $journal['foreign_currency_id'];
|
||||||
|
$currencyCode = $journal['foreign_currency_code'];
|
||||||
|
}
|
||||||
|
Log::debug(sprintf('[a] Add amount %s %s', $currencyCode, $amount));
|
||||||
|
}
|
||||||
|
if (!$convertToNative) {
|
||||||
|
// ignore the amount in foreign currency.
|
||||||
|
Log::debug(sprintf('[b] Add amount %s %s', $currencyCode, $journal['amount']));
|
||||||
|
$amount = $journal['amount'];
|
||||||
|
}
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
|
||||||
$response[$currencyId] ??= [
|
$response[$currencyId] ??= [
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']);
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $amount);
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
|
||||||
}
|
}
|
||||||
if (0 !== $foreignCurrencyId) {
|
|
||||||
$response[$foreignCurrencyId] ??= [
|
|
||||||
'difference' => '0',
|
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // float but on purpose.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ class AccountController extends Controller
|
|||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$assetAccounts = $request->getAssetAccounts();
|
$assetAccounts = $request->getAssetAccounts();
|
||||||
|
|
||||||
$income = $this->opsRepository->sumIncomeByDestination($start, $end, $assetAccounts);
|
$income = $this->opsRepository->sumIncomeByDestination($start, $end, $assetAccounts);
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,39 +46,38 @@ class PeriodController extends Controller
|
|||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getDefaultCurrency();
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type)
|
// collect all expenses in this period (regardless of type)
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value])->setRange($start, $end)->setDestinationAccounts($accounts);
|
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
// currency
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyId = $journal['currency_id'];
|
||||||
|
$currencyCode = $journal['currency_code'];
|
||||||
|
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||||
|
|
||||||
|
// perhaps use default currency instead?
|
||||||
|
if ($convertToNative && $journal['currency_id'] !== $default->id) {
|
||||||
|
$currencyId = $default->id;
|
||||||
|
$currencyCode = $default->code;
|
||||||
|
}
|
||||||
|
// use foreign amount when the foreign currency IS the default currency.
|
||||||
|
if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
|
||||||
|
$field = 'foreign_amount';
|
||||||
|
}
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
|
||||||
$response[$currencyId] ??= [
|
$response[$currencyId] ??= [
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
|
||||||
}
|
}
|
||||||
if (0 !== $foreignCurrencyId) {
|
|
||||||
$response[$foreignCurrencyId] ??= [
|
|
||||||
'difference' => '0',
|
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd(
|
|
||||||
$response[$foreignCurrencyId]['difference'],
|
|
||||||
app('steam')->positive($journal['foreign_amount'])
|
|
||||||
);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // float but on purpose.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
|||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,6 +68,8 @@ class TagController extends Controller
|
|||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getDefaultCurrency();
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
@ -76,32 +79,30 @@ class TagController extends Controller
|
|||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
// currency
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyId = $journal['currency_id'];
|
||||||
|
$currencyCode = $journal['currency_code'];
|
||||||
|
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||||
|
|
||||||
|
// perhaps use default currency instead?
|
||||||
|
if ($convertToNative && $journal['currency_id'] !== $default->id) {
|
||||||
|
$currencyId = $default->id;
|
||||||
|
$currencyCode = $default->code;
|
||||||
|
}
|
||||||
|
// use foreign amount when the foreign currency IS the default currency.
|
||||||
|
if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
|
||||||
|
$field = 'foreign_amount';
|
||||||
|
}
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
|
||||||
$response[$currencyId] ??= [
|
$response[$currencyId] ??= [
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||||
}
|
|
||||||
if (0 !== $foreignCurrencyId) {
|
|
||||||
$response[$foreignCurrencyId] ??= [
|
|
||||||
'difference' => '0',
|
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd(
|
|
||||||
$response[$foreignCurrencyId]['difference'],
|
|
||||||
app('steam')->positive($journal['foreign_amount'])
|
|
||||||
);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
|
@ -28,6 +28,7 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
use FireflyIII\Models\TransactionType;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,38 +46,38 @@ class PeriodController extends Controller
|
|||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getDefaultCurrency();
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type)
|
// collect all expenses in this period (regardless of type)
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
|
$collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
// currency
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyId = $journal['currency_id'];
|
||||||
|
$currencyCode = $journal['currency_code'];
|
||||||
|
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||||
|
|
||||||
|
// perhaps use default currency instead?
|
||||||
|
if ($convertToNative && $journal['currency_id'] !== $default->id) {
|
||||||
|
$currencyId = $default->id;
|
||||||
|
$currencyCode = $default->code;
|
||||||
|
}
|
||||||
|
// use foreign amount when the foreign currency IS the default currency.
|
||||||
|
if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
|
||||||
|
$field = 'foreign_amount';
|
||||||
|
}
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
|
||||||
$response[$currencyId] ??= [
|
$response[$currencyId] ??= [
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||||
}
|
|
||||||
if (0 !== $foreignCurrencyId) {
|
|
||||||
$response[$foreignCurrencyId] ??= [
|
|
||||||
'difference' => '0',
|
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd(
|
|
||||||
$response[$foreignCurrencyId]['difference'],
|
|
||||||
app('steam')->positive($journal['foreign_amount'])
|
|
||||||
);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
|
@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
|||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
use FireflyIII\Models\TransactionType;
|
||||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,6 +66,9 @@ class TagController extends Controller
|
|||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getDefaultCurrency();
|
||||||
|
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
@ -74,32 +78,30 @@ class TagController extends Controller
|
|||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
// currency
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyId = $journal['currency_id'];
|
||||||
|
$currencyCode = $journal['currency_code'];
|
||||||
|
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||||
|
|
||||||
|
// perhaps use default currency instead?
|
||||||
|
if ($convertToNative && $journal['currency_id'] !== $default->id) {
|
||||||
|
$currencyId = $default->id;
|
||||||
|
$currencyCode = $default->code;
|
||||||
|
}
|
||||||
|
// use foreign amount when the foreign currency IS the default currency.
|
||||||
|
if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
|
||||||
|
$field = 'foreign_amount';
|
||||||
|
}
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
|
||||||
$response[$currencyId] ??= [
|
$response[$currencyId] ??= [
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||||
}
|
|
||||||
if (0 !== $foreignCurrencyId) {
|
|
||||||
$response[$foreignCurrencyId] ??= [
|
|
||||||
'difference' => '0',
|
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd(
|
|
||||||
$response[$foreignCurrencyId]['difference'],
|
|
||||||
app('steam')->positive($journal['foreign_amount'])
|
|
||||||
);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
|
@ -111,7 +111,7 @@ class ListController extends Controller
|
|||||||
// types to get, page size:
|
// types to get, page size:
|
||||||
$pageSize = $this->parameters->get('limit');
|
$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);
|
$collection = $this->repository->getPiggyBanks($account);
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
@ -69,6 +69,7 @@ class StoreController extends Controller
|
|||||||
$data = $request->getAll();
|
$data = $request->getAll();
|
||||||
$data['start_date'] = $data['start'];
|
$data['start_date'] = $data['start'];
|
||||||
$data['end_date'] = $data['end'];
|
$data['end_date'] = $data['end'];
|
||||||
|
$data['notes'] = $data['notes'];
|
||||||
$data['budget_id'] = $budget->id;
|
$data['budget_id'] = $budget->id;
|
||||||
|
|
||||||
$budgetLimit = $this->blRepository->store($data);
|
$budgetLimit = $this->blRepository->store($data);
|
||||||
|
@ -28,6 +28,7 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\PiggyBank;
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||||
|
use FireflyIII\Transformers\AccountTransformer;
|
||||||
use FireflyIII\Transformers\AttachmentTransformer;
|
use FireflyIII\Transformers\AttachmentTransformer;
|
||||||
use FireflyIII\Transformers\PiggyBankEventTransformer;
|
use FireflyIII\Transformers\PiggyBankEventTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
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:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listAttachmentByPiggyBank
|
* 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:
|
// types to get, page size:
|
||||||
$pageSize = $this->parameters->get('limit');
|
$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();
|
$collection = $this->repository->getPiggyBanks();
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
@ -107,8 +107,7 @@ class ShowController extends Controller
|
|||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($user->userGroup);
|
$this->parameters->set('defaultCurrency', $this->defaultCurrency);
|
||||||
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
|
||||||
|
|
||||||
// update fields with user info.
|
// update fields with user info.
|
||||||
$currency->refreshForUser($user);
|
$currency->refreshForUser($user);
|
||||||
@ -135,7 +134,7 @@ class ShowController extends Controller
|
|||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$currency = app('amount')->getDefaultCurrencyByUserGroup($user->userGroup);
|
$currency = $this->defaultCurrency;
|
||||||
|
|
||||||
// update fields with user info.
|
// update fields with user info.
|
||||||
$currency->refreshForUser($user);
|
$currency->refreshForUser($user);
|
||||||
|
@ -62,7 +62,6 @@ class AccountController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function search(Request $request): JsonResponse|Response
|
public function search(Request $request): JsonResponse|Response
|
||||||
{
|
{
|
||||||
app('log')->debug('Now in account search()');
|
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$query = trim((string) $request->get('query'));
|
$query = trim((string) $request->get('query'));
|
||||||
$field = trim((string) $request->get('field'));
|
$field = trim((string) $request->get('field'));
|
||||||
@ -70,6 +69,7 @@ class AccountController extends Controller
|
|||||||
if ('' === $query || !in_array($field, $this->validFields, true)) {
|
if ('' === $query || !in_array($field, $this->validFields, true)) {
|
||||||
return response(null, 422);
|
return response(null, 422);
|
||||||
}
|
}
|
||||||
|
app('log')->debug(sprintf('Now in account search("%s", "%s")', $field, $query));
|
||||||
$types = $this->mapAccountTypes($type);
|
$types = $this->mapAccountTypes($type);
|
||||||
|
|
||||||
/** @var AccountSearch $search */
|
/** @var AccountSearch $search */
|
||||||
|
@ -27,19 +27,21 @@ namespace FireflyIII\Api\V1\Controllers\Summary;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Data\DateRequest;
|
use FireflyIII\Api\V1\Requests\Data\DateRequest;
|
||||||
|
use FireflyIII\Enums\AccountTypeEnum;
|
||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Helpers\Report\NetWorthInterface;
|
use FireflyIII\Helpers\Report\NetWorthInterface;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\AccountType;
|
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class BasicController
|
* Class BasicController
|
||||||
@ -120,6 +122,9 @@ class BasicController extends Controller
|
|||||||
|
|
||||||
private function getBalanceInformation(Carbon $start, Carbon $end): array
|
private function getBalanceInformation(Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
|
// some config settings
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getDefaultCurrency();
|
||||||
// prep some arrays:
|
// prep some arrays:
|
||||||
$incomes = [];
|
$incomes = [];
|
||||||
$expenses = [];
|
$expenses = [];
|
||||||
@ -133,16 +138,17 @@ class BasicController extends Controller
|
|||||||
|
|
||||||
$set = $collector->getExtractedJournals();
|
$set = $collector->getExtractedJournals();
|
||||||
|
|
||||||
/** @var array $transactionJournal */
|
/** @var array $journal */
|
||||||
foreach ($set as $transactionJournal) {
|
foreach ($set as $journal) {
|
||||||
$currencyId = (int)$transactionJournal['currency_id'];
|
$currencyId = $convertToNative ? $default->id : (int) $journal['currency_id'];
|
||||||
|
$amount = Amount::getAmountFromJournal($journal);
|
||||||
$incomes[$currencyId] ??= '0';
|
$incomes[$currencyId] ??= '0';
|
||||||
$incomes[$currencyId] = bcadd(
|
$incomes[$currencyId] = bcadd(
|
||||||
$incomes[$currencyId],
|
$incomes[$currencyId],
|
||||||
bcmul($transactionJournal['amount'], '-1')
|
bcmul($amount, '-1')
|
||||||
);
|
);
|
||||||
$sums[$currencyId] ??= '0';
|
$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.
|
// 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]);
|
$collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||||
$set = $collector->getExtractedJournals();
|
$set = $collector->getExtractedJournals();
|
||||||
|
|
||||||
/** @var array $transactionJournal */
|
/** @var array $journal */
|
||||||
foreach ($set as $transactionJournal) {
|
foreach ($set as $journal) {
|
||||||
$currencyId = (int)$transactionJournal['currency_id'];
|
$currencyId = $convertToNative ? $default->id : (int) $journal['currency_id'];
|
||||||
|
$amount = Amount::getAmountFromJournal($journal);
|
||||||
$expenses[$currencyId] ??= '0';
|
$expenses[$currencyId] ??= '0';
|
||||||
$expenses[$currencyId] = bcadd($expenses[$currencyId], $transactionJournal['amount']);
|
$expenses[$currencyId] = bcadd($expenses[$currencyId], $amount);
|
||||||
$sums[$currencyId] ??= '0';
|
$sums[$currencyId] ??= '0';
|
||||||
$sums[$currencyId] = bcadd($sums[$currencyId], $transactionJournal['amount']);
|
$sums[$currencyId] = bcadd($sums[$currencyId], $amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// format amounts:
|
// format amounts:
|
||||||
@ -269,24 +276,27 @@ class BasicController extends Controller
|
|||||||
*/
|
*/
|
||||||
private function getLeftToSpendInfo(Carbon $start, Carbon $end): array
|
private function getLeftToSpendInfo(Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
|
Log::debug(sprintf('Now in getLeftToSpendInfo("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
|
||||||
$return = [];
|
$return = [];
|
||||||
$today = today(config('app.timezone'));
|
$today = today(config('app.timezone'));
|
||||||
$available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
|
$available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
|
||||||
$budgets = $this->budgetRepository->getActiveBudgets();
|
$budgets = $this->budgetRepository->getActiveBudgets();
|
||||||
$spent = $this->opsRepository->sumExpenses($start, $end, null, $budgets);
|
$spent = $this->opsRepository->sumExpenses($start, $end, null, $budgets);
|
||||||
|
$days = (int) $today->diffInDays($end, true) + 1;
|
||||||
|
|
||||||
foreach ($spent as $row) {
|
foreach ($spent as $row) {
|
||||||
// either an amount was budgeted or 0 is available.
|
// 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'];
|
$spentInCurrency = $row['sum'];
|
||||||
$leftToSpend = bcadd($amount, $spentInCurrency);
|
$leftToSpend = bcadd($amount, $spentInCurrency);
|
||||||
|
|
||||||
$days = (int)$today->diffInDays($end, true) + 1;
|
|
||||||
$perDay = '0';
|
$perDay = '0';
|
||||||
if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
|
if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
|
||||||
$perDay = bcdiv($leftToSpend, (string) $days);
|
$perDay = bcdiv($leftToSpend, (string) $days);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log::debug(sprintf('Spent %s %s', $row['currency_code'], $row['sum']));
|
||||||
|
|
||||||
$return[] = [
|
$return[] = [
|
||||||
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
|
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
|
||||||
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]),
|
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]),
|
||||||
@ -311,9 +321,11 @@ class BasicController extends Controller
|
|||||||
|
|
||||||
private function getNetWorthInfo(Carbon $start, Carbon $end): array
|
private function getNetWorthInfo(Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
|
Log::debug('getNetWorthInfo');
|
||||||
|
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
$date = today(config('app.timezone'))->startOfDay();
|
$date = now(config('app.timezone'));
|
||||||
// start and end in the future? use $end
|
// start and end in the future? use $end
|
||||||
if ($this->notInDateRange($date, $start, $end)) {
|
if ($this->notInDateRange($date, $start, $end)) {
|
||||||
/** @var Carbon $date */
|
/** @var Carbon $date */
|
||||||
@ -323,9 +335,7 @@ class BasicController extends Controller
|
|||||||
/** @var NetWorthInterface $netWorthHelper */
|
/** @var NetWorthInterface $netWorthHelper */
|
||||||
$netWorthHelper = app(NetWorthInterface::class);
|
$netWorthHelper = app(NetWorthInterface::class);
|
||||||
$netWorthHelper->setUser($user);
|
$netWorthHelper->setUser($user);
|
||||||
$allAccounts = $this->accountRepository->getActiveAccountsByType(
|
$allAccounts = $this->accountRepository->getActiveAccountsByType([AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::DEBT->value]);
|
||||||
[AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT]
|
|
||||||
);
|
|
||||||
|
|
||||||
// filter list on preference of being included.
|
// filter list on preference of being included.
|
||||||
$filtered = $allAccounts->filter(
|
$filtered = $allAccounts->filter(
|
||||||
@ -360,6 +370,7 @@ class BasicController extends Controller
|
|||||||
'sub_title' => '',
|
'sub_title' => '',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
Log::debug('End of getNetWorthInfo');
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ class StoreRequest extends FormRequest
|
|||||||
'amount' => $this->convertString('amount'),
|
'amount' => $this->convertString('amount'),
|
||||||
'currency_id' => $this->convertInteger('currency_id'),
|
'currency_id' => $this->convertInteger('currency_id'),
|
||||||
'currency_code' => $this->convertString('currency_code'),
|
'currency_code' => $this->convertString('currency_code'),
|
||||||
|
'notes' => $this->stringWithNewlines('notes'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,6 +63,7 @@ class StoreRequest extends FormRequest
|
|||||||
'amount' => ['required', new IsValidPositiveAmount()],
|
'amount' => ['required', new IsValidPositiveAmount()],
|
||||||
'currency_id' => 'numeric|exists:transaction_currencies,id',
|
'currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||||
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
|
'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'],
|
'amount' => ['amount', 'convertString'],
|
||||||
'currency_id' => ['currency_id', 'convertInteger'],
|
'currency_id' => ['currency_id', 'convertInteger'],
|
||||||
'currency_code' => ['currency_code', 'convertString'],
|
'currency_code' => ['currency_code', 'convertString'],
|
||||||
|
'notes' => ['notes', 'stringWithNewlines'],
|
||||||
];
|
];
|
||||||
|
if (false === $this->has('notes')) {
|
||||||
|
// ignore notes, not submitted.
|
||||||
|
unset($fields['notes']);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->getAllData($fields);
|
return $this->getAllData($fields);
|
||||||
}
|
}
|
||||||
@ -67,6 +72,7 @@ class UpdateRequest extends FormRequest
|
|||||||
'amount' => ['nullable', new IsValidPositiveAmount()],
|
'amount' => ['nullable', new IsValidPositiveAmount()],
|
||||||
'currency_id' => 'numeric|exists:transaction_currencies,id',
|
'currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||||
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
|
'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;
|
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\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Validation\Validator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class StoreRequest
|
* Class StoreRequest
|
||||||
@ -47,18 +52,38 @@ class StoreRequest extends FormRequest
|
|||||||
];
|
];
|
||||||
$data = $this->getAllData($fields);
|
$data = $this->getAllData($fields);
|
||||||
$data['name'] = $this->convertString('name');
|
$data['name'] = $this->convertString('name');
|
||||||
$data['account_id'] = $this->convertInteger('account_id');
|
$data['accounts'] = $this->parseAccounts($this->get('accounts'));
|
||||||
$data['targetamount'] = $this->convertString('target_amount');
|
$data['target_amount'] = $this->convertString('target_amount');
|
||||||
$data['current_amount'] = $this->convertString('current_amount');
|
$data['start_date'] = $this->getCarbonDate('start_date');
|
||||||
$data['startdate'] = $this->getCarbonDate('start_date');
|
$data['target_date'] = $this->getCarbonDate('target_date');
|
||||||
$data['targetdate'] = $this->getCarbonDate('target_date');
|
|
||||||
$data['notes'] = $this->stringWithNewlines('notes');
|
$data['notes'] = $this->stringWithNewlines('notes');
|
||||||
$data['object_group_id'] = $this->convertInteger('object_group_id');
|
$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');
|
$data['object_group_title'] = $this->convertString('object_group_title');
|
||||||
|
|
||||||
return $data;
|
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.
|
* The rules that the incoming request must be matched against.
|
||||||
*/
|
*/
|
||||||
@ -66,14 +91,79 @@ class StoreRequest extends FormRequest
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => 'required|min:1|max:255|uniquePiggyBankForUser',
|
'name' => 'required|min:1|max:255|uniquePiggyBankForUser',
|
||||||
'current_amount' => ['nullable', new IsValidPositiveAmount()],
|
'accounts' => 'required',
|
||||||
'account_id' => 'required|numeric|belongsToUser:accounts,id',
|
'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_id' => 'numeric|belongsToUser:object_groups,id',
|
||||||
'object_group_title' => ['min:1', 'max:255'],
|
'object_group_title' => ['min:1', 'max:255'],
|
||||||
'target_amount' => ['required', new IsValidPositiveAmount()],
|
'target_amount' => ['required', new IsValidZeroOrMoreAmount()],
|
||||||
'start_date' => 'date|nullable',
|
'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',
|
'target_date' => 'date|nullable|after:start_date',
|
||||||
'notes' => 'max:65000',
|
'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',
|
'description' => 'min:1|max:32768|nullable',
|
||||||
'rule_group_id' => 'belongsToUser:rule_groups|required_without:rule_group_title',
|
'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',
|
'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.*.type' => 'required|in:'.implode(',', $validTriggers),
|
||||||
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
|
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
|
||||||
'triggers.*.stop_processing' => [new IsBoolean()],
|
'triggers.*.stop_processing' => [new IsBoolean()],
|
||||||
|
@ -138,7 +138,7 @@ class UpdateRequest extends FormRequest
|
|||||||
'description' => 'min:1|max:32768|nullable',
|
'description' => 'min:1|max:32768|nullable',
|
||||||
'rule_group_id' => 'belongsToUser:rule_groups',
|
'rule_group_id' => 'belongsToUser:rule_groups',
|
||||||
'rule_group_title' => 'nullable|min:1|max:255|belongsToUser:rule_groups,title',
|
'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.*.type' => 'required|in:'.implode(',', $validTriggers),
|
||||||
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
|
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
|
||||||
'triggers.*.stop_processing' => [new IsBoolean()],
|
'triggers.*.stop_processing' => [new IsBoolean()],
|
||||||
|
@ -40,9 +40,9 @@ use Illuminate\Support\Facades\Log;
|
|||||||
*/
|
*/
|
||||||
class AccountController extends Controller
|
class AccountController extends Controller
|
||||||
{
|
{
|
||||||
private AccountRepositoryInterface $repository;
|
|
||||||
private TransactionCurrency $default;
|
|
||||||
private ExchangeRateConverter $converter;
|
private ExchangeRateConverter $converter;
|
||||||
|
private TransactionCurrency $default;
|
||||||
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
|
@ -45,9 +45,9 @@ class AccountController extends Controller
|
|||||||
use CollectsAccountsFromFilter;
|
use CollectsAccountsFromFilter;
|
||||||
use ValidatesUserGroupTrait;
|
use ValidatesUserGroupTrait;
|
||||||
|
|
||||||
private AccountRepositoryInterface $repository;
|
|
||||||
private ChartData $chartData;
|
private ChartData $chartData;
|
||||||
private TransactionCurrency $default;
|
private TransactionCurrency $default;
|
||||||
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@ -118,22 +118,21 @@ class AccountController extends Controller
|
|||||||
'native_entries' => [],
|
'native_entries' => [],
|
||||||
];
|
];
|
||||||
$currentStart = clone $params['start'];
|
$currentStart = clone $params['start'];
|
||||||
$range = app('steam')->balanceInRange($account, $params['start'], clone $params['end'], $currency);
|
$range = app('steam')->finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative);
|
||||||
$rangeConverted = app('steam')->balanceInRangeConverted($account, $params['start'], clone $params['end'], $this->default);
|
|
||||||
|
|
||||||
$previous = array_values($range)[0];
|
$previous = array_values($range)[0]['balance'];
|
||||||
$previousConverted = array_values($rangeConverted)[0];
|
$previousNative = array_values($range)[0]['native_balance'];
|
||||||
while ($currentStart <= $params['end']) {
|
while ($currentStart <= $params['end']) {
|
||||||
$format = $currentStart->format('Y-m-d');
|
$format = $currentStart->format('Y-m-d');
|
||||||
$label = $currentStart->toAtomString();
|
$label = $currentStart->toAtomString();
|
||||||
$balance = array_key_exists($format, $range) ? $range[$format] : $previous;
|
$balance = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous;
|
||||||
$balanceConverted = array_key_exists($format, $rangeConverted) ? $rangeConverted[$format] : $previousConverted;
|
$balanceNative = array_key_exists($format, $range) ? $range[$format]['balance_native'] : $previousNative;
|
||||||
$previous = $balance;
|
$previous = $balance;
|
||||||
$previousConverted = $balanceConverted;
|
$previousNative = $balanceNative;
|
||||||
|
|
||||||
$currentStart->addDay();
|
$currentStart->addDay();
|
||||||
$currentSet['entries'][$label] = $balance;
|
$currentSet['entries'][$label] = $balance;
|
||||||
$currentSet['native_entries'][$label] = $balanceConverted;
|
$currentSet['native_entries'][$label] = $balanceNative;
|
||||||
}
|
}
|
||||||
$this->chartData->add($currentSet);
|
$this->chartData->add($currentSet);
|
||||||
}
|
}
|
||||||
|
@ -45,9 +45,10 @@ class BalanceController extends Controller
|
|||||||
use CleansChartData;
|
use CleansChartData;
|
||||||
use CollectsAccountsFromFilter;
|
use CollectsAccountsFromFilter;
|
||||||
|
|
||||||
private AccountRepositoryInterface $repository;
|
|
||||||
private GroupCollectorInterface $collector;
|
|
||||||
private ChartData $chartData;
|
private ChartData $chartData;
|
||||||
|
private GroupCollectorInterface $collector;
|
||||||
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
// private TransactionCurrency $default;
|
// private TransactionCurrency $default;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
|
@ -55,8 +55,9 @@ class Controller extends BaseController
|
|||||||
use ValidatesUserGroupTrait;
|
use ValidatesUserGroupTrait;
|
||||||
|
|
||||||
protected const string CONTENT_TYPE = 'application/vnd.api+json';
|
protected const string CONTENT_TYPE = 'application/vnd.api+json';
|
||||||
protected ParameterBag $parameters;
|
|
||||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||||
|
protected ParameterBag $parameters;
|
||||||
|
protected bool $convertToNative = false;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@ -92,8 +93,8 @@ class Controller extends BaseController
|
|||||||
if ($page < 1) {
|
if ($page < 1) {
|
||||||
$page = 1;
|
$page = 1;
|
||||||
}
|
}
|
||||||
if ($page > (2 ^ 16)) {
|
if ($page > 2 ** 16) {
|
||||||
$page = (2 ^ 16);
|
$page = 2 ** 16;
|
||||||
}
|
}
|
||||||
$bag->set('page', $page);
|
$bag->set('page', $page);
|
||||||
|
|
||||||
|
@ -1,112 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AccountController.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\JsonApi;
|
|
||||||
|
|
||||||
use FireflyIII\Http\Controllers\Controller;
|
|
||||||
use FireflyIII\JsonApi\V2\Accounts\AccountCollectionQuery;
|
|
||||||
use FireflyIII\JsonApi\V2\Accounts\AccountSchema;
|
|
||||||
use FireflyIII\JsonApi\V2\Accounts\AccountSingleQuery;
|
|
||||||
use FireflyIII\Models\Account;
|
|
||||||
use Illuminate\Contracts\Support\Responsable;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use LaravelJsonApi\Core\Responses\DataResponse;
|
|
||||||
use LaravelJsonApi\Laravel\Http\Controllers\Actions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class AccountController
|
|
||||||
*
|
|
||||||
* This class handles api/v2 requests for accounts.
|
|
||||||
* Most stuff is default stuff.
|
|
||||||
*/
|
|
||||||
class AccountController extends Controller
|
|
||||||
{
|
|
||||||
use Actions\AttachRelationship;
|
|
||||||
use Actions\Destroy;
|
|
||||||
use Actions\DetachRelationship;
|
|
||||||
|
|
||||||
use Actions\FetchMany;
|
|
||||||
// use Actions\FetchOne;
|
|
||||||
use Actions\FetchRelated;
|
|
||||||
use Actions\FetchRelationship;
|
|
||||||
use Actions\Store;
|
|
||||||
use Actions\Update;
|
|
||||||
use Actions\UpdateRelationship;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch zero to many JSON API resources.
|
|
||||||
*
|
|
||||||
* @return Responsable|Response
|
|
||||||
*/
|
|
||||||
public function index(AccountSchema $schema, AccountCollectionQuery $request)
|
|
||||||
{
|
|
||||||
Log::debug(__METHOD__);
|
|
||||||
$models = $schema
|
|
||||||
->repository()
|
|
||||||
->queryAll()
|
|
||||||
->withRequest($request)
|
|
||||||
->get()
|
|
||||||
;
|
|
||||||
|
|
||||||
// do something custom...
|
|
||||||
|
|
||||||
return new DataResponse($models);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch zero to one JSON API resource by id.
|
|
||||||
*
|
|
||||||
* @return Responsable|Response
|
|
||||||
*/
|
|
||||||
public function show(AccountSchema $schema, AccountSingleQuery $request, Account $account)
|
|
||||||
{
|
|
||||||
Log::debug(__METHOD__);
|
|
||||||
$model = $schema->repository()
|
|
||||||
->queryOne($account)
|
|
||||||
->withRequest($request)
|
|
||||||
->first()
|
|
||||||
;
|
|
||||||
Log::debug(sprintf('%s again!', __METHOD__));
|
|
||||||
|
|
||||||
// do something custom...
|
|
||||||
|
|
||||||
return new DataResponse($model);
|
|
||||||
}
|
|
||||||
|
|
||||||
// public function readAccountBalances(AnonymousQuery $query, AccountBalanceSchema $schema, Account $account): Responsable
|
|
||||||
// {
|
|
||||||
// $schema = JsonApi::server()->schemas()->schemaFor('account-balances');
|
|
||||||
//
|
|
||||||
// $models = $schema
|
|
||||||
// ->repository()
|
|
||||||
// ->queryAll()
|
|
||||||
// ->withRequest($query)
|
|
||||||
// ->withAccount($account)
|
|
||||||
// ->get()
|
|
||||||
// ;
|
|
||||||
//
|
|
||||||
// return DataResponse::make($models);
|
|
||||||
// }
|
|
||||||
}
|
|
@ -36,9 +36,8 @@ use Illuminate\Support\Facades\Log;
|
|||||||
class IndexController extends Controller
|
class IndexController extends Controller
|
||||||
{
|
{
|
||||||
public const string RESOURCE_KEY = 'accounts';
|
public const string RESOURCE_KEY = 'accounts';
|
||||||
|
|
||||||
private AccountRepositoryInterface $repository;
|
|
||||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY, UserRoleEnum::MANAGE_TRANSACTIONS];
|
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY, UserRoleEnum::MANAGE_TRANSACTIONS];
|
||||||
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
|
@ -39,9 +39,8 @@ use Illuminate\Http\JsonResponse;
|
|||||||
class ShowController extends Controller
|
class ShowController extends Controller
|
||||||
{
|
{
|
||||||
public const string RESOURCE_KEY = 'accounts';
|
public const string RESOURCE_KEY = 'accounts';
|
||||||
|
|
||||||
private AccountRepositoryInterface $repository;
|
|
||||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY, UserRoleEnum::MANAGE_TRANSACTIONS];
|
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY, UserRoleEnum::MANAGE_TRANSACTIONS];
|
||||||
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* 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;
|
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
|
public function rules(): array
|
||||||
{
|
{
|
||||||
$valid = array_keys($this->types);
|
$valid = array_keys($this->types);
|
||||||
@ -86,14 +96,4 @@ class AutocompleteRequest extends FormRequest
|
|||||||
'transaction_types' => 'nullable|in:todo',
|
'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 ChecksLogin;
|
||||||
use ConvertsDataTypes;
|
use ConvertsDataTypes;
|
||||||
use ValidatesUserGroupTrait;
|
use ValidatesUserGroupTrait;
|
||||||
|
|
||||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AccountBalanceRepository.php
|
* DestroyRequest.php
|
||||||
* Copyright (c) 2024 james@firefly-iii.org.
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
*
|
*
|
||||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
@ -22,25 +22,30 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\JsonApi\V2\AccountBalances;
|
namespace FireflyIII\Api\V2\Request\Model\ExchangeRate;
|
||||||
|
|
||||||
use FireflyIII\Entities\AccountBalance;
|
use Carbon\Carbon;
|
||||||
use LaravelJsonApi\Contracts\Store\QueriesAll;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use LaravelJsonApi\NonEloquent\AbstractRepository;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
class AccountBalanceRepository extends AbstractRepository implements QueriesAll
|
class DestroyRequest extends FormRequest
|
||||||
{
|
{
|
||||||
#[\Override]
|
use ChecksLogin;
|
||||||
public function find(string $resourceId): ?object
|
use ConvertsDataTypes;
|
||||||
|
|
||||||
|
public function getDate(): Carbon
|
||||||
{
|
{
|
||||||
return AccountBalance::fromArray();
|
return $this->getCarbonDate('date');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function queryAll(): Capabilities\AccountBalanceQuery
|
/**
|
||||||
|
* The rules that the incoming request must be matched against.
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return Capabilities\AccountBalanceQuery::make()
|
return [
|
||||||
->withServer($this->server)
|
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
|
||||||
->withSchema($this->schema)
|
];
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
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',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AccountBalanceQuery.php
|
* DestroyRequest.php
|
||||||
* Copyright (c) 2024 james@firefly-iii.org.
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
*
|
*
|
||||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
@ -22,38 +22,36 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\JsonApi\V2\AccountBalances\Capabilities;
|
namespace FireflyIII\Api\V2\Request\Model\ExchangeRate;
|
||||||
|
|
||||||
use FireflyIII\Entities\AccountBalance;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use LaravelJsonApi\NonEloquent\Capabilities\QueryAll;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
class AccountBalanceQuery extends QueryAll
|
class UpdateRequest extends FormRequest
|
||||||
{
|
{
|
||||||
private Account $account;
|
use ChecksLogin;
|
||||||
|
use ConvertsDataTypes;
|
||||||
|
|
||||||
|
public function getDate(): ?Carbon
|
||||||
|
{
|
||||||
|
return $this->getCarbonDate('date');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRate(): string
|
||||||
|
{
|
||||||
|
return (string) $this->get('rate');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QuerySites constructor.
|
* The rules that the incoming request must be matched against.
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function rules(): array
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get(): iterable
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
AccountBalance::fromArray(),
|
'date' => 'date|after:1900-01-01|before:2099-12-31',
|
||||||
AccountBalance::fromArray(),
|
'rate' => 'required|numeric|gt:0',
|
||||||
AccountBalance::fromArray(),
|
|
||||||
AccountBalance::fromArray(),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function withAccount(Account $account): self
|
|
||||||
{
|
|
||||||
$this->account = $account;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -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
|
<?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);
|
declare(strict_types=1);
|
||||||
/*
|
/*
|
||||||
* ConvertDatesToUTC.php
|
* ConvertDatesToUTC.php
|
||||||
@ -21,7 +41,7 @@ declare(strict_types=1);
|
|||||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
* 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 Carbon\Carbon;
|
||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
@ -31,17 +51,10 @@ use Illuminate\Database\QueryException;
|
|||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class ConvertDatesToUTC extends Command
|
class ConvertsDatesToUTC extends Command
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
/**
|
|
||||||
* The name and signature of the console command.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $signature = 'firefly-iii:migrate-to-utc';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The console command description.
|
* The console command description.
|
||||||
*
|
*
|
||||||
@ -49,11 +62,22 @@ class ConvertDatesToUTC extends Command
|
|||||||
*/
|
*/
|
||||||
protected $description = 'Convert stored dates to UTC.';
|
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.
|
* Execute the console command.
|
||||||
*/
|
*/
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
|
$this->friendlyWarning('Please do not use this command.');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string $model
|
* @var string $model
|
||||||
* @var array $fields
|
* @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));
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,12 +4,9 @@ namespace FireflyIII\Console\Commands\Correction;
|
|||||||
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class CorrectionSkeleton
|
|
||||||
* TODO DONT FORGET TO ADD THIS TO THE DOCKER BUILD
|
|
||||||
*/
|
|
||||||
class CorrectionSkeleton extends Command
|
class CorrectionSkeleton extends Command
|
||||||
{
|
{
|
||||||
|
use ShowsFriendlyMessages;
|
||||||
protected $description = 'DESCRIPTION HERE';
|
protected $description = 'DESCRIPTION HERE';
|
||||||
|
|
||||||
protected $signature = 'firefly-iii:CORR_COMMAND';
|
protected $signature = 'firefly-iii:CORR_COMMAND';
|
||||||
|
@ -29,15 +29,12 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
|||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class CorrectsAccountOrder extends Command
|
||||||
* Class FixAccountOrder
|
|
||||||
*/
|
|
||||||
class FixAccountOrder extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Make sure account order is correct.';
|
protected $description = 'Make sure account order is correct.';
|
||||||
protected $signature = 'firefly-iii:fix-account-order';
|
protected $signature = 'correction:account-order';
|
||||||
|
|
||||||
private AccountRepositoryInterface $repository;
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
@ -54,8 +51,6 @@ class FixAccountOrder extends Command
|
|||||||
$this->repository->resetAccountOrder();
|
$this->repository->resetAccountOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->friendlyPositive('All accounts are ordered correctly');
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -36,15 +36,12 @@ use Illuminate\Console\Command;
|
|||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Query\JoinClause;
|
use Illuminate\Database\Query\JoinClause;
|
||||||
|
|
||||||
/**
|
class CorrectsAccountTypes extends Command
|
||||||
* Class FixAccountTypes
|
|
||||||
*/
|
|
||||||
class FixAccountTypes extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Make sure all journals have the correct from/to account types.';
|
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 int $count;
|
||||||
private array $expected;
|
private array $expected;
|
||||||
private AccountFactory $factory;
|
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) {
|
if (0 !== $this->count) {
|
||||||
app('log')->debug(sprintf('%d journals had to be fixed.', $this->count));
|
app('log')->debug(sprintf('%d journals had to be fixed.', $this->count));
|
||||||
$this->friendlyInfo(sprintf('Acted on %d transaction(s)', $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 Illuminate\Support\Facades\Log;
|
||||||
use Symfony\Component\Console\Command\Command as CommandAlias;
|
use Symfony\Component\Console\Command\Command as CommandAlias;
|
||||||
|
|
||||||
/**
|
class CorrectsCurrencies extends Command
|
||||||
* Class EnableCurrencies
|
|
||||||
*/
|
|
||||||
class EnableCurrencies extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Enables all currencies in use.';
|
protected $description = 'Enables all currencies in use.';
|
||||||
protected $signature = 'firefly-iii:enable-currencies';
|
protected $signature = 'correction:currencies';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
@ -27,14 +27,11 @@ namespace FireflyIII\Console\Commands\Correction;
|
|||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class CorrectsDatabase extends Command
|
||||||
* Class CorrectDatabase
|
|
||||||
*/
|
|
||||||
class CorrectDatabase extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
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';
|
protected $signature = 'firefly-iii:correct-database';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,32 +46,36 @@ class CorrectDatabase extends Command
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
$commands = [
|
$commands = [
|
||||||
'firefly-iii:fix-piggies',
|
'correction:restore-oauth-keys',
|
||||||
'firefly-iii:create-link-types',
|
'correction:timezones',
|
||||||
'firefly-iii:create-access-tokens',
|
'correction:create-group-memberships',
|
||||||
'firefly-iii:remove-bills',
|
'correction:group-information',
|
||||||
'firefly-iii:fix-amount-pos-neg',
|
'correction:piggy-banks',
|
||||||
'firefly-iii:enable-currencies',
|
'correction:link-types',
|
||||||
'firefly-iii:fix-transfer-budgets',
|
'correction:access-tokens',
|
||||||
'firefly-iii:fix-uneven-amount',
|
'correction:bills',
|
||||||
'firefly-iii:delete-zero-amount',
|
'correction:amounts',
|
||||||
'firefly-iii:delete-orphaned-transactions',
|
'correction:currencies',
|
||||||
'firefly-iii:delete-empty-journals',
|
'correction:transfer-budgets',
|
||||||
'firefly-iii:delete-empty-groups',
|
'correction:uneven-amounts',
|
||||||
'firefly-iii:fix-account-types',
|
'correction:zero-amounts',
|
||||||
'firefly-iii:fix-ibans',
|
'correction:orphaned-transactions',
|
||||||
'firefly-iii:fix-account-order',
|
'correction:empty-journals',
|
||||||
'firefly-iii:rename-meta-fields',
|
'correction:empty-groups',
|
||||||
'firefly-iii:fix-ob-currencies',
|
'correction:account-types',
|
||||||
'firefly-iii:fix-long-descriptions',
|
'correction:ibans',
|
||||||
'firefly-iii:fix-recurring-transactions',
|
'correction:account-order',
|
||||||
'firefly-iii:upgrade-group-information',
|
'correction:meta-fields',
|
||||||
'firefly-iii:fix-transaction-types',
|
'correction:opening-balance-currencies',
|
||||||
'firefly-iii:fix-frontpage-accounts',
|
'correction:long-descriptions',
|
||||||
// new!
|
'correction:recurring-transactions',
|
||||||
'firefly-iii:unify-group-accounts',
|
'correction:frontpage-accounts',
|
||||||
'firefly-iii:trigger-credit-recalculation',
|
'correction:group-accounts',
|
||||||
'firefly-iii:migrate-preferences',
|
'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) {
|
foreach ($commands as $command) {
|
||||||
$this->friendlyLine(sprintf('Now executing command "%s"', $command));
|
$this->friendlyLine(sprintf('Now executing command "%s"', $command));
|
@ -31,15 +31,12 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
|||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class CorrectsFrontpageAccounts extends Command
|
||||||
* Class FixFrontpageAccounts
|
|
||||||
*/
|
|
||||||
class FixFrontpageAccounts extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Fixes a preference that may include deleted accounts or accounts of another type.';
|
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.
|
* Execute the console command.
|
||||||
@ -55,7 +52,6 @@ class FixFrontpageAccounts extends Command
|
|||||||
$this->fixPreference($preference);
|
$this->fixPreference($preference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->friendlyPositive('Account preferences are OK');
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -31,15 +31,12 @@ use FireflyIII\Models\TransactionGroup;
|
|||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class CorrectsGroupAccounts extends Command
|
||||||
* Class FixGroupAccounts
|
|
||||||
*/
|
|
||||||
class FixGroupAccounts extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Unify the source / destination accounts of split groups.';
|
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.
|
* Execute the console command.
|
||||||
@ -64,8 +61,6 @@ class FixGroupAccounts extends Command
|
|||||||
$handler->unifyAccounts($event);
|
$handler->unifyAccounts($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->friendlyPositive('Updated possible inconsistent transaction groups.');
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UpdateGroupInformation.php
|
* CorrectsGroupInformation.php
|
||||||
* Copyright (c) 2022 james@firefly-iii.org
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
*
|
*
|
||||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
*
|
*
|
||||||
@ -17,12 +17,12 @@
|
|||||||
* GNU Affero General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\Console\Commands\Integrity;
|
namespace FireflyIII\Console\Commands\Correction;
|
||||||
|
|
||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
@ -45,15 +45,12 @@ use FireflyIII\User;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Database\QueryException;
|
use Illuminate\Database\QueryException;
|
||||||
|
|
||||||
/**
|
class CorrectsGroupInformation extends Command
|
||||||
* Class UpdateGroupInformation
|
|
||||||
*/
|
|
||||||
class UpdateGroupInformation extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Makes sure that every object is linked to a group';
|
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.
|
* Execute the console command.
|
||||||
@ -79,7 +76,7 @@ class UpdateGroupInformation extends Command
|
|||||||
{
|
{
|
||||||
$group = $user->userGroup;
|
$group = $user->userGroup;
|
||||||
if (null === $group) {
|
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;
|
return;
|
||||||
}
|
}
|
@ -30,15 +30,12 @@ use FireflyIII\Models\AccountType;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
/**
|
class CorrectsIbans extends Command
|
||||||
* Class FixIbans
|
|
||||||
*/
|
|
||||||
class FixIbans extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Removes spaces from IBANs';
|
protected $description = 'Removes spaces from IBANs';
|
||||||
protected $signature = 'firefly-iii:fix-ibans';
|
protected $signature = 'correction:ibans';
|
||||||
private int $count = 0;
|
private int $count = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,9 +46,6 @@ class FixIbans extends Command
|
|||||||
$accounts = Account::whereNotNull('iban')->get();
|
$accounts = Account::whereNotNull('iban')->get();
|
||||||
$this->filterIbans($accounts);
|
$this->filterIbans($accounts);
|
||||||
$this->countAndCorrectIbans($accounts);
|
$this->countAndCorrectIbans($accounts);
|
||||||
if (0 === $this->count) {
|
|
||||||
$this->friendlyPositive('All IBANs are valid.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -28,24 +28,22 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
|||||||
use FireflyIII\Models\TransactionGroup;
|
use FireflyIII\Models\TransactionGroup;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
/**
|
class CorrectsLongDescriptions extends Command
|
||||||
* Class FixLongDescriptions
|
|
||||||
*/
|
|
||||||
class FixLongDescriptions extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
private const int MAX_LENGTH = 1000;
|
private const int MAX_LENGTH = 1000;
|
||||||
protected $description = 'Fixes long descriptions in journals and groups.';
|
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.
|
* Execute the console command.
|
||||||
*/
|
*/
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
$journals = TransactionJournal::get(['id', 'description']);
|
$journals = TransactionJournal::where(DB::raw('LENGTH(description)'), '>', self::MAX_LENGTH)->get(['id', 'description']);
|
||||||
$count = 0;
|
$count = 0;
|
||||||
|
|
||||||
/** @var TransactionJournal $journal */
|
/** @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 */
|
/** @var TransactionGroup $group */
|
||||||
foreach ($groups as $group) {
|
foreach ($groups as $group) {
|
||||||
@ -69,9 +67,6 @@ class FixLongDescriptions extends Command
|
|||||||
++$count;
|
++$count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (0 === $count) {
|
|
||||||
$this->friendlyPositive('All transaction group and journal title lengths are within bounds.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -26,16 +26,14 @@ namespace FireflyIII\Console\Commands\Correction;
|
|||||||
|
|
||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
/**
|
class CorrectsMetaDataFields extends Command
|
||||||
* Class RenameMetaFields
|
|
||||||
*/
|
|
||||||
class RenameMetaFields extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Rename changed meta fields.';
|
protected $description = 'Rename changed meta fields.';
|
||||||
protected $signature = 'firefly-iii:rename-meta-fields';
|
protected $signature = 'correction:meta-fields';
|
||||||
|
|
||||||
private int $count = 0;
|
private int $count = 0;
|
||||||
|
|
||||||
@ -61,9 +59,6 @@ class RenameMetaFields extends Command
|
|||||||
foreach ($changes as $original => $update) {
|
foreach ($changes as $original => $update) {
|
||||||
$this->rename($original, $update);
|
$this->rename($original, $update);
|
||||||
}
|
}
|
||||||
if (0 === $this->count) {
|
|
||||||
$this->friendlyPositive('All meta fields are correct.');
|
|
||||||
}
|
|
||||||
if (0 !== $this->count) {
|
if (0 !== $this->count) {
|
||||||
$this->friendlyInfo(sprintf('Renamed %d meta field(s).', $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
|
private function rename(string $original, string $update): void
|
||||||
{
|
{
|
||||||
$total = \DB::table('journal_meta')
|
$total = DB::table('journal_meta')
|
||||||
->where('name', '=', $original)
|
->where('name', '=', $original)
|
||||||
->update(['name' => $update])
|
->update(['name' => $update])
|
||||||
;
|
;
|
243
app/Console/Commands/Correction/CorrectsNativeAmounts.php
Normal file
243
app/Console/Commands/Correction/CorrectsNativeAmounts.php
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
<?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
|
||||||
|
{
|
||||||
|
if (!config('cer.enabled')) {
|
||||||
|
$this->friendlyInfo('This command will not run because currency exchange rates are disabled.');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
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 for user group #%d.', $set->count(), $userGroup->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
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((string) $account->pivot->current_amount, '0')) {
|
||||||
|
$account->pivot->native_current_amount = $converter->convert($piggyBank->transactionCurrency, $currency, today(), (string) $account->pivot->current_amount);
|
||||||
|
}
|
||||||
|
$account->pivot->save();
|
||||||
|
}
|
||||||
|
$this->recalculatePiggyBankEvents($piggyBank);
|
||||||
|
}
|
||||||
|
Log::debug(sprintf('Recalculated %d piggy banks for user group #%d.', $set->count(), $userGroup->id));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 for budget #%d.', $set->count(), $budget->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
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 for budget #%d.', $set->count(), $budget->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
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\Console\Command;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
/**
|
class CorrectsOpeningBalanceCurrencies extends Command
|
||||||
* Class CorrectOpeningBalanceCurrencies
|
|
||||||
*/
|
|
||||||
class CorrectOpeningBalanceCurrencies extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Will make sure that opening balance transaction currencies match the account they\'re for.';
|
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.
|
* Execute the console command.
|
||||||
@ -62,10 +59,6 @@ class CorrectOpeningBalanceCurrencies extends Command
|
|||||||
$message = sprintf('Corrected %d opening balance transaction(s).', $count);
|
$message = sprintf('Corrected %d opening balance transaction(s).', $count);
|
||||||
$this->friendlyInfo($message);
|
$this->friendlyInfo($message);
|
||||||
}
|
}
|
||||||
if (0 === $count) {
|
|
||||||
$message = 'There was nothing to fix in the opening balance transactions.';
|
|
||||||
$this->friendlyPositive($message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -29,17 +29,12 @@ use FireflyIII\Models\PiggyBankEvent;
|
|||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class CorrectsPiggyBanks extends Command
|
||||||
* Report (and fix) piggy banks.
|
|
||||||
*
|
|
||||||
* Class FixPiggies
|
|
||||||
*/
|
|
||||||
class FixPiggies extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Fixes common issues with piggy banks.';
|
protected $description = 'Fixes common issues with piggy banks.';
|
||||||
protected $signature = 'firefly-iii:fix-piggies';
|
protected $signature = 'correction:piggy-banks';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
@ -66,9 +61,6 @@ class FixPiggies extends Command
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (0 === $count) {
|
|
||||||
$this->friendlyPositive('All piggy bank events are OK.');
|
|
||||||
}
|
|
||||||
if (0 !== $count) {
|
if (0 !== $count) {
|
||||||
$this->friendlyInfo(sprintf('Fixed %d piggy bank event(s).', $count));
|
$this->friendlyInfo(sprintf('Fixed %d piggy bank event(s).', $count));
|
||||||
}
|
}
|
@ -28,11 +28,11 @@ use FireflyIII\User;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Symfony\Component\Console\Command\Command as CommandAlias;
|
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 $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.
|
* Execute the console command.
|
||||||
@ -50,7 +50,7 @@ class MigratePreferences extends Command
|
|||||||
if (null === $preference) {
|
if (null === $preference) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (null !== $preference->user_group_id) {
|
if (null === $preference->user_group_id) {
|
||||||
$preference->user_group_id = $user->user_group_id;
|
$preference->user_group_id = $user->user_group_id;
|
||||||
$preference->save();
|
$preference->save();
|
||||||
++$count;
|
++$count;
|
@ -33,15 +33,12 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
|
|||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class CorrectsRecurringTransactions extends Command
|
||||||
* Class FixRecurringTransactions
|
|
||||||
*/
|
|
||||||
class FixRecurringTransactions extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Fixes recurring transactions with the wrong transaction type.';
|
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 int $count = 0;
|
||||||
private RecurringRepositoryInterface $recurringRepos;
|
private RecurringRepositoryInterface $recurringRepos;
|
||||||
private UserRepositoryInterface $userRepos;
|
private UserRepositoryInterface $userRepos;
|
||||||
@ -53,9 +50,6 @@ class FixRecurringTransactions extends Command
|
|||||||
{
|
{
|
||||||
$this->stupidLaravel();
|
$this->stupidLaravel();
|
||||||
$this->correctTransactions();
|
$this->correctTransactions();
|
||||||
if (0 === $this->count) {
|
|
||||||
$this->friendlyPositive('All recurring transactions are OK.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -1,5 +1,25 @@
|
|||||||
<?php
|
<?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);
|
declare(strict_types=1);
|
||||||
/*
|
/*
|
||||||
* AddTimezonesToDates.php
|
* AddTimezonesToDates.php
|
||||||
@ -21,7 +41,7 @@ declare(strict_types=1);
|
|||||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
* 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\Console\Commands\ShowsFriendlyMessages;
|
||||||
use FireflyIII\Models\AccountBalance;
|
use FireflyIII\Models\AccountBalance;
|
||||||
@ -41,16 +61,25 @@ use Illuminate\Console\Command;
|
|||||||
use Illuminate\Database\QueryException;
|
use Illuminate\Database\QueryException;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class AddTimezonesToDates extends Command
|
class CorrectsTimezoneInformation extends Command
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
/**
|
public static array $models
|
||||||
* The name and signature of the console command.
|
= [
|
||||||
*
|
AccountBalance::class => ['date'], // done
|
||||||
* @var string
|
AvailableBudget::class => ['start_date', 'end_date'], // done
|
||||||
*/
|
Bill::class => ['date', 'end_date', 'extension_date'], // done
|
||||||
protected $signature = 'firefly-iii:add-timezones-to-dates';
|
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.
|
* The console command description.
|
||||||
@ -59,20 +88,12 @@ class AddTimezonesToDates extends Command
|
|||||||
*/
|
*/
|
||||||
protected $description = 'Make sure all dates have a timezone.';
|
protected $description = 'Make sure all dates have a timezone.';
|
||||||
|
|
||||||
public static array $models = [
|
/**
|
||||||
AccountBalance::class => ['date'], // done
|
* The name and signature of the console command.
|
||||||
AvailableBudget::class => ['start_date', 'end_date'], // done
|
*
|
||||||
Bill::class => ['date', 'end_date', 'extension_date'], // done
|
* @var string
|
||||||
BudgetLimit::class => ['start_date', 'end_date'], // done
|
*/
|
||||||
CurrencyExchangeRate::class => ['date'], // done
|
protected $signature = 'correction:timezones';
|
||||||
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'],
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
@ -106,8 +127,6 @@ class AddTimezonesToDates extends Command
|
|||||||
Log::error($e->getMessage());
|
Log::error($e->getMessage());
|
||||||
}
|
}
|
||||||
if (0 === $count) {
|
if (0 === $count) {
|
||||||
$this->friendlyPositive(sprintf('Timezone information is present in field "%s" of model "%s".', $field, $shortModel));
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->friendlyInfo(sprintf('Adding timezone information to field "%s" of model "%s".', $field, $shortModel));
|
$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 FireflyIII\Models\TransactionType;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
class CorrectsTransactionTypes extends Command
|
||||||
* Class FixTransactionTypes
|
|
||||||
*/
|
|
||||||
class FixTransactionTypes extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Make sure all transactions are of the correct type, based on source + dest.';
|
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.
|
* Execute the console command.
|
||||||
@ -50,6 +48,7 @@ class FixTransactionTypes extends Command
|
|||||||
{
|
{
|
||||||
$count = 0;
|
$count = 0;
|
||||||
$journals = $this->collectJournals();
|
$journals = $this->collectJournals();
|
||||||
|
Log::debug(sprintf('In FixTransactionTypes, found %d journals.', $journals->count()));
|
||||||
|
|
||||||
/** @var TransactionJournal $journal */
|
/** @var TransactionJournal $journal */
|
||||||
foreach ($journals as $journal) {
|
foreach ($journals as $journal) {
|
@ -29,15 +29,12 @@ use FireflyIII\Models\TransactionJournal;
|
|||||||
use FireflyIII\Models\TransactionType;
|
use FireflyIII\Models\TransactionType;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class CorrectsTransferBudgets extends Command
|
||||||
* Class TransferBudgets
|
|
||||||
*/
|
|
||||||
class TransferBudgets extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Removes budgets from transfers.';
|
protected $description = 'Removes budgets from transfers.';
|
||||||
protected $signature = 'firefly-iii:fix-transfer-budgets';
|
protected $signature = 'correction:transfer-budgets';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
@ -60,10 +57,6 @@ class TransferBudgets extends Command
|
|||||||
$entry->budgets()->sync([]);
|
$entry->budgets()->sync([]);
|
||||||
++$count;
|
++$count;
|
||||||
}
|
}
|
||||||
if (0 === $count) {
|
|
||||||
$message = 'No invalid budget/journal entries.';
|
|
||||||
$this->friendlyPositive($message);
|
|
||||||
}
|
|
||||||
if (0 !== $count) {
|
if (0 !== $count) {
|
||||||
$message = sprintf('Corrected %d invalid budget/journal entries (entry).', $count);
|
$message = sprintf('Corrected %d invalid budget/journal entries (entry).', $count);
|
||||||
app('log')->debug($message);
|
app('log')->debug($message);
|
@ -25,6 +25,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Console\Commands\Correction;
|
namespace FireflyIII\Console\Commands\Correction;
|
||||||
|
|
||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Models\Transaction;
|
use FireflyIII\Models\Transaction;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use FireflyIII\Models\TransactionType;
|
use FireflyIII\Models\TransactionType;
|
||||||
@ -32,15 +33,12 @@ use FireflyIII\Support\Models\AccountBalanceCalculator;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
class CorrectsUnevenAmount extends Command
|
||||||
* Class FixUnevenAmount
|
|
||||||
*/
|
|
||||||
class FixUnevenAmount extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Fix journals with uneven amounts.';
|
protected $description = 'Fix journals with uneven amounts.';
|
||||||
protected $signature = 'firefly-iii:fix-uneven-amount';
|
protected $signature = 'correction:uneven-amounts';
|
||||||
private int $count;
|
private int $count;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,13 +52,112 @@ class FixUnevenAmount extends Command
|
|||||||
$this->matchCurrencies();
|
$this->matchCurrencies();
|
||||||
if (config('firefly.feature_flags.running_balance_column')) {
|
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.');
|
$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.');
|
$this->friendlyInfo('Done recalculating transaction running balance columns.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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
|
private function fixJournal(int $param): void
|
||||||
{
|
{
|
||||||
// one of the transactions is bad.
|
// one of the transactions is bad.
|
||||||
@ -129,78 +226,6 @@ class FixUnevenAmount extends Command
|
|||||||
++$this->count;
|
++$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
|
private function isForeignCurrencyTransfer(TransactionJournal $journal): bool
|
||||||
{
|
{
|
||||||
if (TransactionType::TRANSFER !== $journal->transactionType->type) {
|
if (TransactionType::TRANSFER !== $journal->transactionType->type) {
|
||||||
@ -235,63 +260,29 @@ class FixUnevenAmount extends Command
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function convertOldStyleTransfers(): void
|
private function matchCurrencies(): void
|
||||||
{
|
{
|
||||||
Log::debug('convertOldStyleTransfers()');
|
$journals = TransactionJournal::leftJoin('transactions', 'transaction_journals.id', 'transactions.transaction_journal_id')
|
||||||
// select transactions with a foreign amount and a foreign currency. and it's a transfer. and they are different.
|
->where('transactions.transaction_currency_id', '!=', \DB::raw('transaction_journals.transaction_currency_id'))
|
||||||
$transactions = Transaction::distinct()
|
->get(['transaction_journals.*'])
|
||||||
->whereNotNull('foreign_currency_id')
|
|
||||||
->whereNotNull('foreign_amount')->get(['transactions.transaction_journal_id'])
|
|
||||||
;
|
;
|
||||||
|
|
||||||
$count = 0;
|
$count = 0;
|
||||||
|
|
||||||
Log::debug(sprintf('Found %d potential journal(s)', $transactions->count()));
|
/** @var TransactionJournal $journal */
|
||||||
|
foreach ($journals as $journal) {
|
||||||
/** @var Transaction $transaction */
|
if (!$this->isForeignCurrencyTransfer($journal)) {
|
||||||
foreach ($transactions as $transaction) {
|
Transaction::where('transaction_journal_id', $journal->id)->update(['transaction_currency_id' => $journal->transaction_currency_id]);
|
||||||
/** @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;
|
++$count;
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
Log::debug(sprintf('Can skip foreign currency transfer #%d.', $journal->id));
|
||||||
}
|
}
|
||||||
if (0 === $count) {
|
if (0 === $count) {
|
||||||
$this->friendlyPositive('No "old style" foreign currency transfers.');
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->friendlyPositive(sprintf('Fixed %d journal(s) with mismatched currencies.', $journals->count()));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -29,16 +29,13 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
|
|||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class CreatesAccessTokens extends Command
|
||||||
* Class CreateAccessTokens
|
|
||||||
*/
|
|
||||||
class CreateAccessTokens extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Creates user access tokens which are used for command line access to personal data.';
|
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.
|
* Execute the console command.
|
||||||
@ -64,9 +61,6 @@ class CreateAccessTokens extends Command
|
|||||||
++$count;
|
++$count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (0 === $count) {
|
|
||||||
$this->friendlyPositive('Verified access tokens.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CreateGroupMemberships.php
|
* CreatesGroupMemberships.php
|
||||||
* Copyright (c) 2023 james@firefly-iii.org
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
*
|
*
|
||||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
*
|
*
|
||||||
@ -17,12 +17,12 @@
|
|||||||
* GNU Affero General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\Console\Commands\Integrity;
|
namespace FireflyIII\Console\Commands\Correction;
|
||||||
|
|
||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
use FireflyIII\Enums\UserRoleEnum;
|
use FireflyIII\Enums\UserRoleEnum;
|
||||||
@ -33,16 +33,13 @@ use FireflyIII\Models\UserRole;
|
|||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class CreatesGroupMemberships extends Command
|
||||||
* Class CreateGroupMemberships
|
|
||||||
*/
|
|
||||||
class CreateGroupMemberships extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
public const string CONFIG_NAME = '560_create_group_memberships';
|
public const string CONFIG_NAME = '560_create_group_memberships';
|
||||||
protected $description = 'Update group memberships';
|
protected $description = 'Update group memberships';
|
||||||
protected $signature = 'firefly-iii:create-group-memberships';
|
protected $signature = 'correction:create-group-memberships';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
@ -52,7 +49,6 @@ class CreateGroupMemberships extends Command
|
|||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
$this->createGroupMemberships();
|
$this->createGroupMemberships();
|
||||||
$this->friendlyPositive('Validated group memberships');
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -28,16 +28,13 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
|||||||
use FireflyIII\Models\LinkType;
|
use FireflyIII\Models\LinkType;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class CreatesLinkTypes extends Command
|
||||||
* Class CreateLinkTypes. Created all link types in case a migration hasn't fired.
|
|
||||||
*/
|
|
||||||
class CreateLinkTypes extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Creates all link types.';
|
protected $description = 'Creates all link types.';
|
||||||
|
|
||||||
protected $signature = 'firefly-iii:create-link-types';
|
protected $signature = 'correction:link-types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
@ -66,9 +63,6 @@ class CreateLinkTypes extends Command
|
|||||||
$link->editable = false;
|
$link->editable = false;
|
||||||
$link->save();
|
$link->save();
|
||||||
}
|
}
|
||||||
if (0 === $count) {
|
|
||||||
$this->friendlyPositive('All link types are OK');
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -29,15 +29,12 @@ use FireflyIII\Models\TransactionJournal;
|
|||||||
use FireflyIII\Models\TransactionType;
|
use FireflyIII\Models\TransactionType;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class RemovesBills extends Command
|
||||||
* Class RemoveBills
|
|
||||||
*/
|
|
||||||
class RemoveBills extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Remove bills from transactions that shouldn\'t have one.';
|
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.
|
* Execute the console command.
|
||||||
@ -60,7 +57,6 @@ class RemoveBills extends Command
|
|||||||
if ($journals->count() > 0) {
|
if ($journals->count() > 0) {
|
||||||
$this->friendlyInfo('Fixed all transaction journals so they have correct bill information.');
|
$this->friendlyInfo('Fixed all transaction journals so they have correct bill information.');
|
||||||
}
|
}
|
||||||
$this->friendlyPositive('All bills and journals are OK');
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -29,15 +29,12 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
|||||||
use FireflyIII\Models\TransactionGroup;
|
use FireflyIII\Models\TransactionGroup;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class RemovesEmptyGroups extends Command
|
||||||
* Class DeleteEmptyGroups
|
|
||||||
*/
|
|
||||||
class DeleteEmptyGroups extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Delete empty transaction groups.';
|
protected $description = 'Delete empty transaction groups.';
|
||||||
protected $signature = 'firefly-iii:delete-empty-groups';
|
protected $signature = 'correction:empty-groups';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
@ -61,9 +58,6 @@ class DeleteEmptyGroups extends Command
|
|||||||
TransactionGroup::whereNull('deleted_at')->whereIn('id', $chunk)->delete();
|
TransactionGroup::whereNull('deleted_at')->whereIn('id', $chunk)->delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (0 === $total) {
|
|
||||||
$this->friendlyInfo('Verified there are no empty groups.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -30,16 +30,13 @@ use FireflyIII\Models\TransactionJournal;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Database\QueryException;
|
use Illuminate\Database\QueryException;
|
||||||
|
|
||||||
/**
|
class RemovesEmptyJournals extends Command
|
||||||
* Class DeleteEmptyJournals
|
|
||||||
*/
|
|
||||||
class DeleteEmptyJournals extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Delete empty and uneven transaction journals.';
|
protected $description = 'Delete empty and uneven transaction journals.';
|
||||||
|
|
||||||
protected $signature = 'firefly-iii:delete-empty-journals';
|
protected $signature = 'correction:empty-journals';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
@ -82,9 +79,6 @@ class DeleteEmptyJournals extends Command
|
|||||||
++$total;
|
++$total;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (0 === $total) {
|
|
||||||
$this->friendlyPositive('No uneven transaction journals.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function deleteEmptyJournals(): void
|
private function deleteEmptyJournals(): void
|
||||||
@ -107,8 +101,5 @@ class DeleteEmptyJournals extends Command
|
|||||||
$this->friendlyInfo(sprintf('Deleted empty transaction journal #%d', $entry->id));
|
$this->friendlyInfo(sprintf('Deleted empty transaction journal #%d', $entry->id));
|
||||||
++$count;
|
++$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.
|
* Deletes transactions where the journal has been deleted.
|
||||||
*/
|
*/
|
||||||
class DeleteOrphanedTransactions extends Command
|
class RemovesOrphanedTransactions extends Command
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Deletes orphaned transactions.';
|
protected $description = 'Deletes orphaned transactions.';
|
||||||
|
|
||||||
protected $signature = 'firefly-iii:delete-orphaned-transactions';
|
protected $signature = 'correction:orphaned-transactions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
@ -63,7 +63,7 @@ class DeleteOrphanedTransactions extends Command
|
|||||||
;
|
;
|
||||||
$count = $set->count();
|
$count = $set->count();
|
||||||
if (0 === $count) {
|
if (0 === $count) {
|
||||||
$this->friendlyPositive('No orphaned journals.');
|
// $this->friendlyPositive('No orphaned journals.');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -116,9 +116,6 @@ class DeleteOrphanedTransactions extends Command
|
|||||||
++$count;
|
++$count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (0 === $count) {
|
|
||||||
$this->friendlyPositive('No orphaned transactions.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function deleteFromOrphanedAccounts(): void
|
private function deleteFromOrphanedAccounts(): void
|
||||||
@ -147,8 +144,5 @@ class DeleteOrphanedTransactions extends Command
|
|||||||
);
|
);
|
||||||
++$count;
|
++$count;
|
||||||
}
|
}
|
||||||
if (0 === $count) {
|
|
||||||
$this->friendlyPositive('No orphaned accounts.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -29,16 +29,13 @@ use FireflyIII\Models\Transaction;
|
|||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class RemovesZeroAmount extends Command
|
||||||
* Class DeleteZeroAmount
|
|
||||||
*/
|
|
||||||
class DeleteZeroAmount extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Delete transactions with zero amount.';
|
protected $description = 'Delete transactions with zero amount.';
|
||||||
|
|
||||||
protected $signature = 'firefly-iii:delete-zero-amount';
|
protected $signature = 'correction:zero-amounts';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
@ -56,9 +53,6 @@ class DeleteZeroAmount extends Command
|
|||||||
|
|
||||||
Transaction::where('transaction_journal_id', $journal->id)->delete();
|
Transaction::where('transaction_journal_id', $journal->id)->delete();
|
||||||
}
|
}
|
||||||
if (0 === $journals->count()) {
|
|
||||||
$this->friendlyPositive('No zero-amount transaction journals.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* RestoreOAuthKeys.php
|
* RestoresOAuthKeys.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
*
|
*
|
||||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
*
|
*
|
||||||
@ -17,26 +17,23 @@
|
|||||||
* GNU Affero General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\Console\Commands\Integrity;
|
namespace FireflyIII\Console\Commands\Correction;
|
||||||
|
|
||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
use FireflyIII\Support\System\OAuthKeys;
|
use FireflyIII\Support\System\OAuthKeys;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class RestoresOAuthKeys extends Command
|
||||||
* Class RestoreOAuthKeys
|
|
||||||
*/
|
|
||||||
class RestoreOAuthKeys extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Will restore the OAuth keys generated for the system.';
|
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.
|
* Execute the console command.
|
||||||
@ -76,7 +73,6 @@ class RestoreOAuthKeys extends Command
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->friendlyPositive('OAuth keys are OK');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function keysInDatabase(): bool
|
private function keysInDatabase(): bool
|
@ -28,13 +28,10 @@ use FireflyIII\Models\Account;
|
|||||||
use FireflyIII\Services\Internal\Support\CreditRecalculateService;
|
use FireflyIII\Services\Internal\Support\CreditRecalculateService;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class TriggersCreditCalculation extends Command
|
||||||
* Class CorrectionSkeleton
|
|
||||||
*/
|
|
||||||
class TriggerCreditCalculation extends Command
|
|
||||||
{
|
{
|
||||||
protected $description = 'Triggers the credit recalculation service for liabilities.';
|
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.
|
* Execute the console command.
|
@ -36,10 +36,7 @@ use FireflyIII\Support\Export\ExportDataGenerator;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
/**
|
class ExportsData extends Command
|
||||||
* Class ExportData
|
|
||||||
*/
|
|
||||||
class ExportData extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
use VerifiesAccessToken;
|
use VerifiesAccessToken;
|
@ -4,10 +4,6 @@ namespace FireflyIII\Console\Commands\Integrity;
|
|||||||
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ReportSkeleton
|
|
||||||
* TODO DONT FORGET TO ADD THIS TO THE DOCKER BUILD
|
|
||||||
*/
|
|
||||||
class ReportSkeleton extends Command
|
class ReportSkeleton extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -31,16 +31,13 @@ use FireflyIII\Models\Category;
|
|||||||
use FireflyIII\Models\Tag;
|
use FireflyIII\Models\Tag;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class ReportsEmptyObjects extends Command
|
||||||
* Class ReportEmptyObjects
|
|
||||||
*/
|
|
||||||
class ReportEmptyObjects extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Reports on empty database objects.';
|
protected $description = 'Reports on empty database objects.';
|
||||||
|
|
||||||
protected $signature = 'firefly-iii:report-empty-objects';
|
protected $signature = 'integrity:empty-objects';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
@ -27,10 +27,7 @@ namespace FireflyIII\Console\Commands\Integrity;
|
|||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class ReportsIntegrity extends Command
|
||||||
* Class ReportIntegrity
|
|
||||||
*/
|
|
||||||
class ReportIntegrity extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
@ -48,11 +45,8 @@ class ReportIntegrity extends Command
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
$commands = [
|
$commands = [
|
||||||
'firefly-iii:add-timezones-to-dates',
|
'integrity:empty-objects',
|
||||||
'firefly-iii:create-group-memberships',
|
'integrity:total-sums',
|
||||||
'firefly-iii:report-empty-objects',
|
|
||||||
'firefly-iii:report-sum',
|
|
||||||
'firefly-iii:upgrade-group-information',
|
|
||||||
];
|
];
|
||||||
foreach ($commands as $command) {
|
foreach ($commands as $command) {
|
||||||
$this->friendlyLine(sprintf('Now executing %s', $command));
|
$this->friendlyLine(sprintf('Now executing %s', $command));
|
@ -29,15 +29,12 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
|
|||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class ReportsSums extends Command
|
||||||
* Class ReportSkeleton
|
|
||||||
*/
|
|
||||||
class ReportSum extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Report on the total sum of transactions. Must be 0.';
|
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.
|
* Execute the console command.
|
||||||
@ -59,18 +56,22 @@ class ReportSum extends Command
|
|||||||
|
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
foreach ($userRepository->all() as $user) {
|
foreach ($userRepository->all() as $user) {
|
||||||
$sum = (string)$user->transactions()->selectRaw('SUM(amount) + SUM(foreign_amount) as total')->value('total');
|
$sum = (string) $user->transactions()->selectRaw('SUM(amount) as total')->value('total');
|
||||||
if (!is_numeric($sum)) {
|
$foreign = (string) $user->transactions()->selectRaw('SUM(foreign_amount) as total')->value('total');
|
||||||
$message = sprintf('Error: Transactions for user #%d (%s) have an invalid sum ("%s").', $user->id, $user->email, $sum);
|
$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);
|
$this->friendlyError($message);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (0 !== bccomp($sum, '0')) {
|
if (0 !== bccomp($total, '0')) {
|
||||||
$message = sprintf('Error: Transactions for user #%d (%s) are off by %s!', $user->id, $user->email, $sum);
|
$message = sprintf('Error: Transactions for user #%d (%s) are off by %s!', $user->id, $user->email, $total);
|
||||||
$this->friendlyError($message);
|
$this->friendlyError($message);
|
||||||
}
|
}
|
||||||
if (0 === bccomp($sum, '0')) {
|
if (0 === bccomp($total, '0')) {
|
||||||
$this->friendlyPositive(sprintf('Amount integrity OK for user #%d', $user->id));
|
$this->friendlyPositive(sprintf('Amount integrity OK for user #%d', $user->id));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -28,7 +28,7 @@ use Illuminate\Console\Command;
|
|||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use Symfony\Component\Console\Command\Command as CommandAlias;
|
use Symfony\Component\Console\Command\Command as CommandAlias;
|
||||||
|
|
||||||
class LaravelPassportKeys extends Command
|
class CallsLaravelPassportKeys extends Command
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
@ -28,10 +28,7 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use PDO;
|
use PDO;
|
||||||
|
|
||||||
/**
|
class CreatesDatabase extends Command
|
||||||
* Class CreateDatabase
|
|
||||||
*/
|
|
||||||
class CreateDatabase extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
@ -29,16 +29,13 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
|
||||||
/**
|
class CreatesFirstUser extends Command
|
||||||
* Class CreateFirstUser
|
|
||||||
*/
|
|
||||||
class CreateFirstUser extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'Creates a new user and gives admin rights. Outputs the password on the command line. Strictly for testing.';
|
protected $description = 'Creates a new user and gives admin rights. Outputs the password on the command line. Strictly for testing.';
|
||||||
|
|
||||||
protected $signature = 'firefly-iii:create-first-user {email}';
|
protected $signature = 'system:create-first-user {email}';
|
||||||
private UserRepositoryInterface $repository;
|
private UserRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
/**
|
@ -44,13 +44,11 @@ use Illuminate\Support\Collection;
|
|||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ForceDecimalSize
|
|
||||||
*
|
|
||||||
* This command was inspired by https://github.com/elliot-gh. It will check all amount fields
|
* This command was inspired by https://github.com/elliot-gh. It will check all amount fields
|
||||||
* and their values and correct them to the correct number of decimal places. This fixes issues where
|
* and their values and correct them to the correct number of decimal places. This fixes issues where
|
||||||
* Firefly III would store 0.01 as 0.01000000000000000020816681711721685132943093776702880859375.
|
* Firefly III would store 0.01 as 0.01000000000000000020816681711721685132943093776702880859375.
|
||||||
*/
|
*/
|
||||||
class ForceDecimalSize extends Command
|
class ForcesDecimalSize extends Command
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
@ -83,8 +81,8 @@ class ForceDecimalSize extends Command
|
|||||||
'currency_exchange_rates' => ['rate', 'user_rate'],
|
'currency_exchange_rates' => ['rate', 'user_rate'],
|
||||||
'limit_repetitions' => ['amount'],
|
'limit_repetitions' => ['amount'],
|
||||||
'piggy_bank_events' => ['amount'],
|
'piggy_bank_events' => ['amount'],
|
||||||
'piggy_bank_repetitions' => ['currentamount'],
|
'piggy_bank_repetitions' => ['current_amount'],
|
||||||
'piggy_banks' => ['targetamount'],
|
'piggy_banks' => ['target_amount'],
|
||||||
'recurrences_transactions' => ['amount', 'foreign_amount'],
|
'recurrences_transactions' => ['amount', 'foreign_amount'],
|
||||||
'transactions' => ['amount', 'foreign_amount'],
|
'transactions' => ['amount', 'foreign_amount'],
|
||||||
];
|
];
|
@ -33,10 +33,7 @@ use Illuminate\Support\Facades\DB;
|
|||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
/**
|
class ForcesMigrations extends Command
|
||||||
* Class ForceMigration
|
|
||||||
*/
|
|
||||||
class ForceMigration extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
use VerifiesAccessToken;
|
use VerifiesAccessToken;
|
@ -27,16 +27,13 @@ namespace FireflyIII\Console\Commands\System;
|
|||||||
use FireflyIII\Support\System\GeneratesInstallationId;
|
use FireflyIII\Support\System\GeneratesInstallationId;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class OutputsInstructions extends Command
|
||||||
* Class UpgradeFireflyInstructions.
|
|
||||||
*/
|
|
||||||
class UpgradeFireflyInstructions extends Command
|
|
||||||
{
|
{
|
||||||
use GeneratesInstallationId;
|
use GeneratesInstallationId;
|
||||||
|
|
||||||
protected $description = 'Instructions in case of upgrade trouble.';
|
protected $description = 'Instructions in case of upgrade trouble.';
|
||||||
|
|
||||||
protected $signature = 'firefly:instructions {task}';
|
protected $signature = 'firefly-iii:instructions {task=install}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
@ -79,7 +76,7 @@ class UpgradeFireflyInstructions extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
$prefix = 'v';
|
$prefix = 'v';
|
||||||
if (str_starts_with($version, 'develop')) {
|
if (str_starts_with($version, 'develop') || str_starts_with($version, 'branch')) {
|
||||||
$prefix = '';
|
$prefix = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +91,8 @@ class UpgradeFireflyInstructions extends Command
|
|||||||
$this->boxedInfo('There are no extra upgrade instructions.');
|
$this->boxedInfo('There are no extra upgrade instructions.');
|
||||||
$this->boxed('Firefly III should be ready for use.');
|
$this->boxed('Firefly III should be ready for use.');
|
||||||
$this->boxed('');
|
$this->boxed('');
|
||||||
|
$this->donationText();
|
||||||
|
$this->boxed('');
|
||||||
$this->showLine();
|
$this->showLine();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -102,6 +101,8 @@ class UpgradeFireflyInstructions extends Command
|
|||||||
$this->boxed(sprintf('Thank you for updating to Firefly III, %s%s!', $prefix, $version));
|
$this->boxed(sprintf('Thank you for updating to Firefly III, %s%s!', $prefix, $version));
|
||||||
$this->boxedInfo($text);
|
$this->boxedInfo($text);
|
||||||
$this->boxed('');
|
$this->boxed('');
|
||||||
|
$this->donationText();
|
||||||
|
$this->boxed('');
|
||||||
$this->showLine();
|
$this->showLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,6 +214,8 @@ class UpgradeFireflyInstructions extends Command
|
|||||||
$this->boxedInfo('There are no extra installation instructions.');
|
$this->boxedInfo('There are no extra installation instructions.');
|
||||||
$this->boxed('Firefly III should be ready for use.');
|
$this->boxed('Firefly III should be ready for use.');
|
||||||
$this->boxed('');
|
$this->boxed('');
|
||||||
|
$this->donationText();
|
||||||
|
$this->boxed('');
|
||||||
$this->showLine();
|
$this->showLine();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -221,6 +224,15 @@ class UpgradeFireflyInstructions extends Command
|
|||||||
$this->boxed(sprintf('Thank you for installing Firefly III, %s%s!', $prefix, $version));
|
$this->boxed(sprintf('Thank you for installing Firefly III, %s%s!', $prefix, $version));
|
||||||
$this->boxedInfo($text);
|
$this->boxedInfo($text);
|
||||||
$this->boxed('');
|
$this->boxed('');
|
||||||
|
$this->donationText();
|
||||||
|
$this->boxed('');
|
||||||
$this->showLine();
|
$this->showLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function donationText(): void
|
||||||
|
{
|
||||||
|
$this->boxed('Did you know you can support the development of Firefly III?');
|
||||||
|
$this->boxed('You can donate in many ways, like GitHub Sponsors or Patreon.');
|
||||||
|
$this->boxed('For more information, please visit https://bit.ly/donate-to-Firefly-III');
|
||||||
|
}
|
||||||
}
|
}
|
@ -26,10 +26,7 @@ namespace FireflyIII\Console\Commands\System;
|
|||||||
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class OutputsVersion extends Command
|
||||||
* Class OutputVersion
|
|
||||||
*/
|
|
||||||
class OutputVersion extends Command
|
|
||||||
{
|
{
|
||||||
protected $description = 'Outputs the Firefly III version';
|
protected $description = 'Outputs the Firefly III version';
|
||||||
|
|
@ -29,10 +29,7 @@ use FireflyIII\Models\Attachment;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Contracts\Encryption\DecryptException;
|
use Illuminate\Contracts\Encryption\DecryptException;
|
||||||
|
|
||||||
/**
|
class ScansAttachments extends Command
|
||||||
* Class ScanAttachments.
|
|
||||||
*/
|
|
||||||
class ScanAttachments extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
@ -27,10 +27,7 @@ namespace FireflyIII\Console\Commands\System;
|
|||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
class SetsLatestVersion extends Command
|
||||||
* Class SetLatestVersion
|
|
||||||
*/
|
|
||||||
class SetLatestVersion extends Command
|
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
@ -29,9 +29,6 @@ use Illuminate\Console\Command;
|
|||||||
use Illuminate\Database\QueryException;
|
use Illuminate\Database\QueryException;
|
||||||
use League\Flysystem\FilesystemException;
|
use League\Flysystem\FilesystemException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class VerifySecurityAlerts
|
|
||||||
*/
|
|
||||||
class VerifySecurityAlerts extends Command
|
class VerifySecurityAlerts extends Command
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
@ -40,9 +40,6 @@ use Illuminate\Console\Command;
|
|||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ApplyRules
|
|
||||||
*/
|
|
||||||
class ApplyRules extends Command
|
class ApplyRules extends Command
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
@ -128,7 +125,7 @@ class ApplyRules extends Command
|
|||||||
$ruleEngine->addOperator(['type' => 'account_id', 'value' => $list]);
|
$ruleEngine->addOperator(['type' => 'account_id', 'value' => $list]);
|
||||||
|
|
||||||
// add the date as a filter:
|
// 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')]);
|
$ruleEngine->addOperator(['type' => 'date_before', 'value' => $this->endDate->format('Y-m-d')]);
|
||||||
|
|
||||||
// start running rules.
|
// start running rules.
|
||||||
@ -296,7 +293,7 @@ class ApplyRules extends Command
|
|||||||
[$inputEnd, $inputStart] = [$inputStart, $inputEnd];
|
[$inputEnd, $inputStart] = [$inputStart, $inputEnd];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->startDate = $inputStart;
|
$this->start_date = $inputStart;
|
||||||
$this->endDate = $inputEnd;
|
$this->endDate = $inputEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user