Compare commits

...

42 Commits

Author SHA1 Message Date
github-actions
7d13263482 Auto commit for release 'develop' on 2024-03-18 2024-03-18 21:08:27 +01:00
James Cole
d9ff252915 Unignore files 2024-03-18 21:03:17 +01:00
James Cole
51ba550251 Ignore generated files. 2024-03-18 20:29:09 +01:00
James Cole
fd21c467ad Remove generated files. 2024-03-18 20:28:58 +01:00
github-actions
9aa90650b4 Auto commit for release 'develop' on 2024-03-18 2024-03-18 20:25:30 +01:00
James Cole
db0dbcfcf1 Disable exchange rates by default. 2024-03-18 06:20:33 +01:00
James Cole
f591996f04 Remove deferrable interface 2024-03-18 06:14:17 +01:00
James Cole
b08d385586 Merge pull request #8683 from firefly-iii/dependabot/npm_and_yarn/develop/axios-1.6.8 2024-03-18 05:45:38 +01:00
James Cole
20ef22f67e Merge pull request #8682 from firefly-iii/dependabot/npm_and_yarn/develop/sass-1.72.0 2024-03-18 05:45:31 +01:00
James Cole
c888baf542 Merge pull request #8681 from firefly-iii/dependabot/npm_and_yarn/develop/date-fns-3.6.0 2024-03-18 05:45:22 +01:00
dependabot[bot]
8b0af3f666 Bump axios from 1.6.7 to 1.6.8
Bumps [axios](https://github.com/axios/axios) from 1.6.7 to 1.6.8.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.6.7...v1.6.8)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-18 03:07:58 +00:00
dependabot[bot]
7043e1e7c0 Bump sass from 1.71.1 to 1.72.0
Bumps [sass](https://github.com/sass/dart-sass) from 1.71.1 to 1.72.0.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.71.1...1.72.0)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-18 03:07:43 +00:00
dependabot[bot]
c5854eba23 Bump date-fns from 3.3.1 to 3.6.0
Bumps [date-fns](https://github.com/date-fns/date-fns) from 3.3.1 to 3.6.0.
- [Release notes](https://github.com/date-fns/date-fns/releases)
- [Changelog](https://github.com/date-fns/date-fns/blob/main/CHANGELOG.md)
- [Commits](https://github.com/date-fns/date-fns/compare/v3.3.1...v3.6.0)

---
updated-dependencies:
- dependency-name: date-fns
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-18 03:07:29 +00:00
github-actions
ddf1a8cebb Auto commit for release 'develop' on 2024-03-18 2024-03-18 01:30:56 +01:00
James Cole
7dcaf167e9 Replace blade template with twig template 2024-03-17 15:54:18 +01:00
James Cole
b359d51d3a Fix code and tests. 2024-03-17 12:26:56 +01:00
James Cole
3913fa5086 Restore old behavior 2024-03-17 12:00:28 +01:00
James Cole
ab2772abe0 Remove deferrable. 2024-03-17 11:44:58 +01:00
James Cole
bc7875b17b Add stub component. 2024-03-17 09:30:26 +01:00
James Cole
4938fa9990 Add stub component. 2024-03-17 09:29:49 +01:00
James Cole
84df2c80ee Fix missing var 2024-03-17 09:27:04 +01:00
James Cole
dc17060754 Remove deferrable. 2024-03-17 09:24:50 +01:00
James Cole
e2fa81dddc Remove deferrable. 2024-03-17 09:24:25 +01:00
James Cole
182dfc95fe Remove deferrable. 2024-03-17 09:23:44 +01:00
James Cole
c8979b6c33 Remove deferrable. 2024-03-17 09:23:12 +01:00
James Cole
ab872e8912 Remove deferrable. 2024-03-17 09:22:45 +01:00
James Cole
d36b94fabf Remove deferrable. 2024-03-17 09:22:13 +01:00
James Cole
e3d4ceaecb Merge branch 'main' into develop 2024-03-17 09:19:26 +01:00
James Cole
e3a6e5b788 Upgrade to laravel 11 2024-03-17 09:19:01 +01:00
James Cole
57235c0e00 Merge pull request #8675 from firefly-iii/dependabot/npm_and_yarn/follow-redirects-1.15.6 2024-03-17 07:43:18 +01:00
dependabot[bot]
2298c3ddaf Bump follow-redirects from 1.15.5 to 1.15.6
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.5 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.5...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-16 23:39:53 +00:00
James Cole
7224f1be6f Small code cleanup. 2024-03-16 23:06:16 +01:00
James Cole
1bd3019c16 Small code cleanup. 2024-03-16 22:57:48 +01:00
James Cole
f0fa21dead First version of line edit. 2024-03-16 22:00:25 +01:00
James Cole
845eaed8d7 Code cleanup. 2024-03-16 11:27:07 +01:00
James Cole
b3649cd4d0 Add migration routine for https://github.com/firefly-iii/firefly-iii/pull/8650 2024-03-16 07:03:50 +01:00
James Cole
55f14c587b New funding file. 2024-03-16 06:33:31 +01:00
James Cole
441a8a8408 Some code cleanup 2024-03-16 06:28:21 +01:00
James Cole
060c9648f1 Fix https://github.com/firefly-iii/firefly-iii/issues/8668 2024-03-16 06:25:56 +01:00
James Cole
7680c8733f Expand. include discussions. 2024-03-16 06:09:10 +01:00
James Cole
5a0af5c93b Fix https://github.com/firefly-iii/firefly-iii/issues/8672 2024-03-15 06:13:40 +01:00
James Cole
f4b066add1 Fix https://github.com/firefly-iii/firefly-iii/issues/8671 2024-03-14 21:20:30 +01:00
219 changed files with 1986 additions and 1909 deletions

View File

@@ -226,16 +226,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.51.0",
"version": "v3.52.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "127fa74f010da99053e3f5b62672615b72dd6efd"
"reference": "a3564bd66f4bce9bc871ef18b690e2dc67a7f969"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/127fa74f010da99053e3f5b62672615b72dd6efd",
"reference": "127fa74f010da99053e3f5b62672615b72dd6efd",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a3564bd66f4bce9bc871ef18b690e2dc67a7f969",
"reference": "a3564bd66f4bce9bc871ef18b690e2dc67a7f969",
"shasum": ""
},
"require": {
@@ -306,7 +306,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.51.0"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.52.0"
},
"funding": [
{
@@ -314,7 +314,7 @@
"type": "github"
}
],
"time": "2024-02-28T19:50:06+00:00"
"time": "2024-03-18T18:40:11+00:00"
},
{
"name": "psr/container",

View File

@@ -184,6 +184,11 @@ SEND_REPORT_JOURNALS=true
# Since this involves an external service, it's optional and disabled by default.
ENABLE_EXTERNAL_MAP=false
#
# Enable or disable exchange rate conversion. This function isn't used yet by Firefly III
#
ENABLE_EXCHANGE_RATES=false
# Set this value to true if you want Firefly III to download currency exchange rates
# from the internet. These rates are hosted by the creator of Firefly III inside
# an Azure Storage Container.

4
.github/funding.yml vendored
View File

@@ -1,4 +1,6 @@
# These are supported funding model platforms
# Firefly III sponsor options
github: jc5
patreon: JC5
ko_fi: jamesc5
liberapay: JC5

View File

@@ -18,11 +18,12 @@ jobs:
permissions:
issues: write
pull-requests: write
discussions: write
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v5
with:
github-token: ${{ github.token }}
issue-inactive-days: 7
pr-inactive-days: 7
issue-inactive-days: 21
pr-inactive-days: 21
discussion-inactive-days: 21
log-output: true

3
.gitignore vendored
View File

@@ -7,3 +7,6 @@ yarn-error.log
.env
/.ci/php-cs-fixer/vendor
coverage.xml
# ignore generated files.
#public/build

View File

@@ -281,7 +281,7 @@ class BasicController extends Controller
$spentInCurrency = $row['sum'];
$leftToSpend = bcadd($amount, $spentInCurrency);
$days = $today->diffInDays($end) + 1;
$days = (int)$today->diffInDays($end, true) + 1;
$perDay = '0';
if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
$perDay = bcdiv($leftToSpend, (string)$days);

View File

@@ -46,7 +46,7 @@ class DateRequest extends FormRequest
{
$start = $this->getCarbonDate('start');
$end = $this->getCarbonDate('end');
if ($start->diffInYears($end) > 5) {
if ($start->diffInYears($end, true) > 5) {
throw new FireflyException('Date range out of range.');
}

View File

@@ -0,0 +1,79 @@
<?php
/*
* UpdateController.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\Account;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Model\Account\UpdateRequest;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
use FireflyIII\Transformers\V2\AccountTransformer;
use Illuminate\Http\JsonResponse;
class UpdateController extends Controller
{
public const string RESOURCE_KEY = 'accounts';
private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
// new way of user group validation
$userGroup = $this->validateUserGroup($request);
if (null !== $userGroup) {
$this->repository->setUserGroup($userGroup);
}
return $next($request);
}
);
}
/**
* TODO this endpoint is not yet reachable.
*/
public function update(UpdateRequest $request, Account $account): JsonResponse
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
$data = $request->getUpdateData();
$data['type'] = config('firefly.shortNamesByFullName.'.$account->accountType->type);
$account = $this->repository->update($account, $data);
$account->refresh();
app('preferences')->mark();
$transformer = new AccountTransformer();
$transformer->setParameters($this->parameters);
return response()
->api($this->jsonApiObject('accounts', $account, $transformer))
->header('Content-Type', self::CONTENT_TYPE)
;
}
}

View File

@@ -298,7 +298,7 @@ class BasicController extends Controller
app('log')->debug(sprintf('Amount left is %s', $left));
// how much left per day?
$days = $today->diffInDays($end) + 1;
$days = (int) $today->diffInDays($end, true) + 1;
$perDay = '0';
$perDayNative = '0';
if (0 !== $days && bccomp($left, '0') > -1) {

View File

@@ -0,0 +1,116 @@
<?php
/*
* UpdateRequest.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\Account;
use FireflyIII\Models\Account;
use FireflyIII\Models\Location;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\UniqueAccountNumber;
use FireflyIII\Rules\UniqueIban;
use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
class UpdateRequest extends FormRequest
{
use AppendsLocationData;
use ChecksLogin;
use ConvertsDataTypes;
/**
* TODO is a duplicate of the v1 update thing.
*/
public function getUpdateData(): array
{
$fields = [
'name' => ['name', 'convertString'],
'active' => ['active', 'boolean'],
'include_net_worth' => ['include_net_worth', 'boolean'],
'account_type_name' => ['type', 'convertString'],
'virtual_balance' => ['virtual_balance', 'convertString'],
'iban' => ['iban', 'convertString'],
'BIC' => ['bic', 'convertString'],
'account_number' => ['account_number', 'convertString'],
'account_role' => ['account_role', 'convertString'],
'liability_type' => ['liability_type', 'convertString'],
'opening_balance' => ['opening_balance', 'convertString'],
'opening_balance_date' => ['opening_balance_date', 'convertDateTime'],
'cc_type' => ['credit_card_type', 'convertString'],
'cc_monthly_payment_date' => ['monthly_payment_date', 'convertDateTime'],
'notes' => ['notes', 'stringWithNewlines'],
'interest' => ['interest', 'convertString'],
'interest_period' => ['interest_period', 'convertString'],
'order' => ['order', 'convertInteger'],
'currency_id' => ['currency_id', 'convertInteger'],
'currency_code' => ['currency_code', 'convertString'],
'liability_direction' => ['liability_direction', 'convertString'],
'liability_amount' => ['liability_amount', 'convertString'],
'liability_start_date' => ['liability_start_date', 'date'],
];
$data = $this->getAllData($fields);
return $this->appendLocationData($data, null);
}
/**
* TODO is a duplicate of the v1 UpdateRequest method.
*
* The rules that the incoming request must be matched against.
*/
public function rules(): array
{
/** @var Account $account */
$account = $this->route()->parameter('account');
$accountRoles = implode(',', config('firefly.accountRoles'));
$types = implode(',', array_keys(config('firefly.subTitlesByIdentifier')));
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
$rules = [
'name' => sprintf('min:1|max:1024|uniqueAccountForUser:%d', $account->id),
'type' => sprintf('in:%s', $types),
'iban' => ['iban', 'nullable', new UniqueIban($account, $this->convertString('type'))],
'bic' => 'bic|nullable',
'account_number' => ['min:1', 'max:255', 'nullable', new UniqueAccountNumber($account, $this->convertString('type'))],
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
'virtual_balance' => 'numeric|nullable',
'order' => 'numeric|nullable',
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'active' => [new IsBoolean()],
'include_net_worth' => [new IsBoolean()],
'account_role' => sprintf('in:%s|nullable|required_if:type,asset', $accountRoles),
'credit_card_type' => sprintf('in:%s|nullable|required_if:account_role,ccAsset', $ccPaymentTypes),
'monthly_payment_date' => 'date|nullable|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
'liability_type' => 'required_if:type,liability|in:loan,debt,mortgage',
'liability_direction' => 'required_if:type,liability|in:credit,debit',
'interest' => 'required_if:type,liability|min:0|max:100|numeric',
'interest_period' => 'required_if:type,liability|in:daily,monthly,yearly',
'notes' => 'min:0|max:32768',
];
return Location::requestRules($rules);
}
}

View File

@@ -53,40 +53,40 @@ class ForceDecimalSize extends Command
{
use ShowsFriendlyMessages;
protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).';
protected $signature = 'firefly-iii:force-decimal-size';
protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).';
protected $signature = 'firefly-iii:force-decimal-size';
private string $cast;
private array $classes
= [
'accounts' => Account::class,
'auto_budgets' => AutoBudget::class,
'available_budgets' => AvailableBudget::class,
'bills' => Bill::class,
'budget_limits' => BudgetLimit::class,
'piggy_bank_events' => PiggyBankEvent::class,
'piggy_bank_repetitions' => PiggyBankRepetition::class,
'piggy_banks' => PiggyBank::class,
'recurrences_transactions' => RecurrenceTransaction::class,
'transactions' => Transaction::class,
];
= [
'accounts' => Account::class,
'auto_budgets' => AutoBudget::class,
'available_budgets' => AvailableBudget::class,
'bills' => Bill::class,
'budget_limits' => BudgetLimit::class,
'piggy_bank_events' => PiggyBankEvent::class,
'piggy_bank_repetitions' => PiggyBankRepetition::class,
'piggy_banks' => PiggyBank::class,
'recurrences_transactions' => RecurrenceTransaction::class,
'transactions' => Transaction::class,
];
private string $operator;
private string $regularExpression;
private array $tables
= [
'accounts' => ['virtual_balance'],
'auto_budgets' => ['amount'],
'available_budgets' => ['amount'],
'bills' => ['amount_min', 'amount_max'],
'budget_limits' => ['amount'],
'currency_exchange_rates' => ['rate', 'user_rate'],
'limit_repetitions' => ['amount'],
'piggy_bank_events' => ['amount'],
'piggy_bank_repetitions' => ['currentamount'],
'piggy_banks' => ['targetamount'],
'recurrences_transactions' => ['amount', 'foreign_amount'],
'transactions' => ['amount', 'foreign_amount'],
];
= [
'accounts' => ['virtual_balance'],
'auto_budgets' => ['amount'],
'available_budgets' => ['amount'],
'bills' => ['amount_min', 'amount_max'],
'budget_limits' => ['amount'],
'currency_exchange_rates' => ['rate', 'user_rate'],
'limit_repetitions' => ['amount'],
'piggy_bank_events' => ['amount'],
'piggy_bank_repetitions' => ['currentamount'],
'piggy_banks' => ['targetamount'],
'recurrences_transactions' => ['amount', 'foreign_amount'],
'transactions' => ['amount', 'foreign_amount'],
];
/**
* Execute the console command.

View File

@@ -110,7 +110,7 @@ class AppendBudgetLimitPeriods extends Command
return 'daily';
}
// is weekly
if ('1' === $limit->start_date->format('N') && '7' === $limit->end_date->format('N') && 6 === $limit->end_date->diffInDays($limit->start_date)) {
if ('1' === $limit->start_date->format('N') && '7' === $limit->end_date->format('N') && 6 === (int)$limit->end_date->diffInDays($limit->start_date, true)) {
return 'weekly';
}
@@ -129,7 +129,7 @@ class AppendBudgetLimitPeriods extends Command
if (
in_array($limit->start_date->format('j-n'), $start, true) // start of quarter
&& in_array($limit->end_date->format('j-n'), $end, true) // end of quarter
&& 2 === $limit->start_date->diffInMonths($limit->end_date)
&& 2 === (int)$limit->start_date->diffInMonths($limit->end_date, true)
) {
return 'quarterly';
}
@@ -139,7 +139,7 @@ class AppendBudgetLimitPeriods extends Command
if (
in_array($limit->start_date->format('j-n'), $start, true) // start of quarter
&& in_array($limit->end_date->format('j-n'), $end, true) // end of quarter
&& 5 === $limit->start_date->diffInMonths($limit->end_date)
&& 5 === (int)$limit->start_date->diffInMonths($limit->end_date, true)
) {
return 'half_year';
}

View File

@@ -0,0 +1,182 @@
<?php
declare(strict_types=1);
/*
* MigrateRuleActions.php
* Copyright (c) 2024 james@firefly-iii.org.
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
namespace FireflyIII\Console\Commands\Upgrade;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\RuleAction;
use Illuminate\Console\Command;
class MigrateRuleActions extends Command
{
use ShowsFriendlyMessages;
public const string CONFIG_NAME = '610_migrate_rule_actions';
protected $description = 'Migrate rule actions away from expression engine';
protected $signature = 'firefly-iii:migrate-rule-actions {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
*/
public function handle(): int
{
if ($this->isExecuted() && true !== $this->option('force')) {
$this->friendlyInfo('This command has already been executed.');
return 0;
}
if (false === config('firefly.feature_flags.expression_engine')) {
$this->friendlyInfo('Expression engine is not enabled. Nothing to do.');
return 0;
}
$this->replaceEqualSign();
$this->replaceObsoleteActions();
return 0;
}
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
}
return false;
}
private function replaceEqualSign(): void
{
$count = 0;
$actions = RuleAction::get();
/** @var RuleAction $action */
foreach ($actions as $action) {
if (str_starts_with($action->action_value, '=')) {
$action->action_value = sprintf('%s%s', '\=', substr($action->action_value, 1));
$action->save();
++$count;
}
}
if ($count > 0) {
$this->friendlyInfo(sprintf('Upgrading %d rule action(s) for the new expression engine.', $count));
}
if (0 === $count) {
$this->friendlyInfo('All rule actions are up to date.');
}
}
private function replaceObsoleteActions(): void
{
$obsolete = [
'append_description',
'prepend_description',
'append_notes',
'prepend_notes',
'append_descr_to_notes',
'append_notes_to_descr',
'move_descr_to_notes',
'move_notes_to_descr',
];
$actions = RuleAction::whereIn('action_type', $obsolete)->get();
/** @var RuleAction $action */
foreach ($actions as $action) {
$oldType = $action->action_type;
switch ($action->action_type) {
default:
$this->friendlyError(sprintf('Cannot deal with action type "%s", skip it.', $action->action_type));
break;
case 'append_description':
$action->action_type = 'set_description';
$action->action_value = sprintf('=description~"%s"', str_replace('"', '\"', $action->action_value));
$action->save();
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
break;
case 'prepend_description':
$action->action_type = 'set_description';
$action->action_value = sprintf('="%s"~description', str_replace('"', '\"', $action->action_value));
$action->save();
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
break;
case 'append_notes':
$action->action_type = 'set_notes';
$action->action_value = sprintf('=notes~"%s"', str_replace('"', '\"', $action->action_value));
$action->save();
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
break;
case 'prepend_notes':
$action->action_type = 'set_notes';
$action->action_value = sprintf('="%s"~notes', str_replace('"', '\"', $action->action_value));
$action->save();
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
break;
case 'append_descr_to_notes':
$action->action_type = 'set_notes';
$action->action_value = '=notes~" "~description';
$action->save();
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
break;
case 'append_notes_to_descr':
$action->action_type = 'set_description';
$action->action_value = '=description~" "~notes';
$action->save();
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
break;
case 'move_descr_to_notes':
$action->action_type = 'set_notes';
$action->action_value = '=description';
$action->save();
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
break;
case 'move_notes_to_descr':
$action->action_type = 'set_description';
$action->action_value = '=notes';
$action->save();
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
break;
}
}
}
}

View File

@@ -63,6 +63,7 @@ class UpgradeDatabase extends Command
'firefly-iii:upgrade-liabilities',
'firefly-iii:liabilities-600',
'firefly-iii:budget-limit-periods',
'firefly-iii:migrate-rule-actions',
'firefly-iii:restore-oauth-keys',
// also just in case, some integrity commands:
'firefly-iii:create-group-memberships',

View File

@@ -26,11 +26,11 @@ class UpgradeSkeleton extends Command
{
$start = microtime(true);
if ($this->isExecuted() && true !== $this->option('force')) {
$this->info('FRIENDLY This command has already been executed.');
$this->friendlyInfo('This command has already been executed.');
return 0;
}
$this->warn('Congrats, you found the skeleton command. Boo!');
$this->friendlyWarning('Congrats, you found the skeleton command. Boo!');
//$this->markAsExecuted();

View File

@@ -40,12 +40,12 @@ class ReportGeneratorFactory
{
$period = 'Month';
// more than two months date difference means year report.
if ($start->diffInMonths($end) > 1) {
if ($start->diffInMonths($end, true) > 1) {
$period = 'Year';
}
// more than one year date difference means multi year report.
if ($start->diffInMonths($end) > 12) {
// more than one year date difference means multi-year report.
if ($start->diffInMonths($end, true) > 12) {
$period = 'MultiYear';
}

View File

@@ -405,7 +405,7 @@ class UserEventHandler
}
// clean up old entries (6 months)
$carbon = Carbon::createFromFormat('Y-m-d H:i:s', $preference[$index]['time']);
if (false !== $carbon && $carbon->diffInMonths(today()) > 6) {
if (false !== $carbon && $carbon->diffInMonths(today(), true) > 6) {
app('log')->debug(sprintf('Entry for %s is very old, remove it.', $row['ip']));
unset($preference[$index]);
}

View File

@@ -236,7 +236,9 @@ class AttachmentHelper implements AttachmentHelperInterface
$fileObject->rewind();
if (0 === $file->getSize()) {
throw new FireflyException('Cannot upload empty or non-existent file.');
$this->errors->add('attachments', trans('validation.file_zero_length'));
return null;
}
$content = (string)$fileObject->fread($file->getSize());

View File

@@ -75,7 +75,7 @@ class ReconcileController extends Controller
*
* @throws FireflyException
* */
public function reconcile(Account $account, Carbon $start = null, Carbon $end = null)
public function reconcile(Account $account, ?Carbon $start = null, ?Carbon $end = null)
{
if (!$this->isEditableAccount($account)) {
return $this->redirectAccountToAccount($account);

View File

@@ -75,7 +75,7 @@ class ShowController extends Controller
*
* @throws FireflyException
* */
public function show(Request $request, Account $account, Carbon $start = null, Carbon $end = null)
public function show(Request $request, Account $account, ?Carbon $start = null, ?Carbon $end = null)
{
$objectType = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type));

View File

@@ -85,7 +85,7 @@ class IndexController extends Controller
*
* @throws FireflyException
* */
public function index(Carbon $start = null, Carbon $end = null)
public function index(?Carbon $start = null, ?Carbon $end = null)
{
$this->abRepository->cleanup();
app('log')->debug(sprintf('Start of IndexController::index("%s", "%s")', $start?->format('Y-m-d'), $end?->format('Y-m-d')));

View File

@@ -75,7 +75,7 @@ class ShowController extends Controller
*
* @throws FireflyException
*/
public function noBudget(Request $request, Carbon $start = null, Carbon $end = null)
public function noBudget(Request $request, ?Carbon $start = null, ?Carbon $end = null)
{
// @var Carbon $start
$start ??= session('start');

View File

@@ -70,7 +70,7 @@ class NoCategoryController extends Controller
*
* @throws FireflyException
*/
public function show(Request $request, Carbon $start = null, Carbon $end = null)
public function show(Request $request, ?Carbon $start = null, ?Carbon $end = null)
{
app('log')->debug('Start of noCategory()');
// @var Carbon $start

View File

@@ -71,7 +71,7 @@ class ShowController extends Controller
*
* @throws FireflyException
*/
public function show(Request $request, Category $category, Carbon $start = null, Carbon $end = null)
public function show(Request $request, Category $category, ?Carbon $start = null, ?Carbon $end = null)
{
// @var Carbon $start
$start ??= session('start', today(config('app.timezone'))->startOfMonth());

View File

@@ -97,10 +97,10 @@ class HomeController extends Controller
app('log')->debug('Range is now marked as "custom".');
}
$diff = $start->diffInDays($end) + 1;
$diff = $start->diffInDays($end, true) + 1;
if ($diff > 50) {
$request->session()->flash('warning', (string)trans('firefly.warning_much_data', ['days' => $diff]));
$request->session()->flash('warning', (string)trans('firefly.warning_much_data', ['days' => (int)$diff]));
}
$request->session()->put('is_custom_range', $isCustomRange);

View File

@@ -113,7 +113,7 @@ class BoxController extends Controller
$spentAmount = $spent[$currency->id]['sum'] ?? '0';
app('log')->debug(sprintf('Spent for default currency for all budgets in this period: %s', $spentAmount));
$days = $today->between($start, $end) ? $today->diffInDays($start) + 1 : $end->diffInDays($start) + 1;
$days = (int)($today->between($start, $end) ? $today->diffInDays($start, true) + 1 : $end->diffInDays($start, true) + 1);
app('log')->debug(sprintf('Number of days left: %d', $days));
$spentPerDay = bcdiv($spentAmount, (string)$days);
app('log')->debug(sprintf('Available to spend per day: %s', $spentPerDay));

View File

@@ -38,7 +38,7 @@ class IntroController extends Controller
/**
* Returns the introduction wizard for a page.
*/
public function getIntroSteps(string $route, string $specificPage = null): JsonResponse
public function getIntroSteps(string $route, ?string $specificPage = null): JsonResponse
{
app('log')->debug(sprintf('getIntroSteps for route "%s" and page "%s"', $route, $specificPage));
$specificPage ??= '';
@@ -91,7 +91,7 @@ class IntroController extends Controller
*
* @throws FireflyException
*/
public function postEnable(string $route, string $specialPage = null): JsonResponse
public function postEnable(string $route, ?string $specialPage = null): JsonResponse
{
$specialPage ??= '';
$route = str_replace('.', '_', $route);
@@ -111,7 +111,7 @@ class IntroController extends Controller
*
* @throws FireflyException
*/
public function postFinished(string $route, string $specialPage = null): JsonResponse
public function postFinished(string $route, ?string $specialPage = null): JsonResponse
{
$specialPage ??= '';
$key = 'shown_demo_'.$route;

View File

@@ -67,7 +67,7 @@ class ReconcileController extends Controller
*
* @throws FireflyException
*/
public function overview(Request $request, Account $account = null, Carbon $start = null, Carbon $end = null): JsonResponse
public function overview(Request $request, ?Account $account = null, ?Carbon $start = null, ?Carbon $end = null): JsonResponse
{
$startBalance = $request->get('startBalance');
$endBalance = $request->get('endBalance');
@@ -177,7 +177,7 @@ class ReconcileController extends Controller
*
* @throws FireflyException
*/
public function transactions(Account $account, Carbon $start = null, Carbon $end = null)
public function transactions(Account $account, ?Carbon $start = null, ?Carbon $end = null)
{
if (null === $start || null === $end) {
throw new FireflyException('Invalid dates submitted.');

View File

@@ -76,7 +76,7 @@ class CreateController extends Controller
*
* @throws FireflyException
*/
public function create(Request $request, RuleGroup $ruleGroup = null)
public function create(Request $request, ?RuleGroup $ruleGroup = null)
{
$this->createDefaultRuleGroup();
$preFilled = [

View File

@@ -215,7 +215,7 @@ class TagController extends Controller
*
* @throws FireflyException
*/
public function show(Request $request, Tag $tag, Carbon $start = null, Carbon $end = null)
public function show(Request $request, Tag $tag, ?Carbon $start = null, ?Carbon $end = null)
{
// default values:
$subTitleIcon = 'fa-tag';
@@ -312,6 +312,9 @@ class TagController extends Controller
if (count($this->attachmentsHelper->getMessages()->get('attachments')) > 0) {
$request->session()->flash('info', $this->attachmentsHelper->getMessages()->get('attachments'));
}
if (count($this->attachmentsHelper->getErrors()->get('attachments')) > 0) {
$request->session()->flash('error', $this->attachmentsHelper->getErrors()->get('attachments'));
}
$redirect = redirect($this->getPreviousUrl('tags.create.url'));
if (1 === (int)$request->get('create_another')) {
session()->put('tags.create.fromStore', true);
@@ -347,6 +350,9 @@ class TagController extends Controller
if (count($this->attachmentsHelper->getMessages()->get('attachments')) > 0) {
$request->session()->flash('info', $this->attachmentsHelper->getMessages()->get('attachments'));
}
if (count($this->attachmentsHelper->getErrors()->get('attachments')) > 0) {
$request->session()->flash('error', $this->attachmentsHelper->getErrors()->get('attachments'));
}
$redirect = redirect($this->getPreviousUrl('tags.edit.url'));
if (1 === (int)$request->get('return_to_edit')) {
session()->put('tags.edit.fromUpdate', true);

View File

@@ -69,7 +69,7 @@ class IndexController extends Controller
*
* @throws FireflyException
*/
public function index(Request $request, string $objectType, Carbon $start = null, Carbon $end = null)
public function index(Request $request, string $objectType, ?Carbon $start = null, ?Carbon $end = null)
{
if ('transfers' === $objectType) {
$objectType = 'transfer';

View File

@@ -34,10 +34,10 @@ class TrustProxies extends Middleware
// After...
protected $headers
= Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB;
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB;
/**
* TrustProxies constructor.

View File

@@ -128,7 +128,7 @@ class WarnAboutBills implements ShouldQueue
$today = clone $this->date;
$carbon = clone $bill->{$field};
return $today->diffInDays($carbon, false);
return (int) $today->diffInDays($carbon);
}
private function sendWarning(Bill $bill, string $field): void

View File

@@ -122,13 +122,13 @@ class Account extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'user_id' => 'integer',
'deleted_at' => 'datetime',
'active' => 'boolean',
'encrypted' => 'boolean',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'user_id' => 'integer',
'deleted_at' => 'datetime',
'active' => 'boolean',
'encrypted' => 'boolean',
];
protected $fillable = ['user_id', 'user_group_id', 'account_type_id', 'name', 'active', 'virtual_balance', 'iban'];

View File

@@ -59,9 +59,9 @@ class AccountMeta extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
protected $fillable = ['account_id', 'name', 'data'];

View File

@@ -72,9 +72,9 @@ class AccountType extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
protected $fillable = ['type'];

View File

@@ -97,11 +97,11 @@ class Attachment extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'uploaded' => 'boolean',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'uploaded' => 'boolean',
];
protected $fillable = ['attachable_id', 'attachable_type', 'user_id', 'md5', 'filename', 'mime', 'title', 'description', 'size', 'uploaded'];

View File

@@ -80,13 +80,13 @@ class AvailableBudget extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'start_date' => 'date',
'end_date' => 'date',
'transaction_currency_id' => 'int',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'start_date' => 'date',
'end_date' => 'date',
'transaction_currency_id' => 'int',
];
protected $fillable = ['user_id', 'user_group_id', 'transaction_currency_id', 'amount', 'start_date', 'end_date'];

View File

@@ -114,36 +114,36 @@ class Bill extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'date' => 'date',
'end_date' => 'date',
'extension_date' => 'date',
'skip' => 'int',
'automatch' => 'boolean',
'active' => 'boolean',
'name_encrypted' => 'boolean',
'match_encrypted' => 'boolean',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'date' => 'date',
'end_date' => 'date',
'extension_date' => 'date',
'skip' => 'int',
'automatch' => 'boolean',
'active' => 'boolean',
'name_encrypted' => 'boolean',
'match_encrypted' => 'boolean',
];
protected $fillable
= [
'name',
'match',
'amount_min',
'user_id',
'user_group_id',
'amount_max',
'date',
'repeat_freq',
'skip',
'automatch',
'active',
'transaction_currency_id',
'end_date',
'extension_date',
];
'name',
'match',
'amount_min',
'user_id',
'user_group_id',
'amount_max',
'date',
'repeat_freq',
'skip',
'automatch',
'active',
'transaction_currency_id',
'end_date',
'extension_date',
];
protected $hidden = ['amount_min_encrypted', 'amount_max_encrypted', 'name_encrypted', 'match_encrypted'];

View File

@@ -97,12 +97,12 @@ class Budget extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'active' => 'boolean',
'encrypted' => 'boolean',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'active' => 'boolean',
'encrypted' => 'boolean',
];
protected $fillable = ['user_id', 'name', 'active', 'order', 'user_group_id'];

View File

@@ -74,18 +74,18 @@ class BudgetLimit extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'start_date' => 'date',
'end_date' => 'date',
'auto_budget' => 'boolean',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'start_date' => 'date',
'end_date' => 'date',
'auto_budget' => 'boolean',
];
protected $dispatchesEvents
= [
'created' => Created::class,
'updated' => Updated::class,
'deleted' => Deleted::class,
];
'created' => Created::class,
'updated' => Updated::class,
'deleted' => Deleted::class,
];
protected $fillable = ['budget_id', 'start_date', 'end_date', 'amount', 'transaction_currency_id'];

View File

@@ -86,11 +86,11 @@ class Category extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'encrypted' => 'boolean',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'encrypted' => 'boolean',
];
protected $fillable = ['user_id', 'user_group_id', 'name'];

View File

@@ -62,10 +62,10 @@ class Configuration extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
/** @var string The table to store the data in */
protected $table = 'configuration';

View File

@@ -82,13 +82,13 @@ class CurrencyExchangeRate extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'user_id' => 'int',
'from_currency_id' => 'int',
'to_currency_id' => 'int',
'date' => 'datetime',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'user_id' => 'int',
'from_currency_id' => 'int',
'to_currency_id' => 'int',
'date' => 'datetime',
];
protected $fillable = ['user_id', 'from_currency_id', 'to_currency_id', 'date', 'rate'];
public function fromCurrency(): BelongsTo

View File

@@ -70,9 +70,9 @@ class InvitedUser extends Model
protected $casts
= [
'expires' => 'datetime',
'redeemed' => 'boolean',
];
'expires' => 'datetime',
'redeemed' => 'boolean',
];
protected $fillable = ['user_id', 'email', 'invite_code', 'expires', 'redeemed'];
/**

View File

@@ -72,11 +72,11 @@ class LinkType extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'editable' => 'boolean',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'editable' => 'boolean',
];
protected $fillable = ['name', 'inward', 'outward', 'editable'];

View File

@@ -74,13 +74,13 @@ class Location extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'zoomLevel' => 'int',
'latitude' => 'float',
'longitude' => 'float',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'zoomLevel' => 'int',
'latitude' => 'float',
'longitude' => 'float',
];
protected $fillable = ['locatable_id', 'locatable_type', 'latitude', 'longitude', 'zoom_level'];

View File

@@ -69,10 +69,10 @@ class Note extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
protected $fillable = ['title', 'text', 'noteable_id', 'noteable_type'];

View File

@@ -79,11 +79,11 @@ class ObjectGroup extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'user_id' => 'integer',
'deleted_at' => 'datetime',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'user_id' => 'integer',
'deleted_at' => 'datetime',
];
protected $fillable = ['title', 'order', 'user_id', 'user_group_id'];
/**

View File

@@ -92,15 +92,15 @@ class PiggyBank extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'startdate' => 'date',
'targetdate' => 'date',
'order' => 'int',
'active' => 'boolean',
'encrypted' => 'boolean',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'startdate' => 'date',
'targetdate' => 'date',
'order' => 'int',
'active' => 'boolean',
'encrypted' => 'boolean',
];
protected $fillable = ['name', 'account_id', 'order', 'targetamount', 'startdate', 'targetdate', 'active'];

View File

@@ -63,10 +63,10 @@ class PiggyBankEvent extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'date' => 'date',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'date' => 'date',
];
protected $fillable = ['piggy_bank_id', 'transaction_journal_id', 'date', 'amount'];

View File

@@ -64,11 +64,11 @@ class PiggyBankRepetition extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'startdate' => 'date',
'targetdate' => 'date',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'startdate' => 'date',
'targetdate' => 'date',
];
protected $fillable = ['piggy_bank_id', 'startdate', 'targetdate', 'currentamount'];

View File

@@ -63,10 +63,10 @@ class Preference extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'data' => 'array',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'data' => 'array',
];
protected $fillable = ['user_id', 'data', 'name'];

View File

@@ -104,19 +104,19 @@ class Recurrence extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'title' => 'string',
'id' => 'int',
'description' => 'string',
'first_date' => 'date',
'repeat_until' => 'date',
'latest_date' => 'date',
'repetitions' => 'int',
'active' => 'bool',
'apply_rules' => 'bool',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'title' => 'string',
'id' => 'int',
'description' => 'string',
'first_date' => 'date',
'repeat_until' => 'date',
'latest_date' => 'date',
'repetitions' => 'int',
'active' => 'bool',
'apply_rules' => 'bool',
];
protected $fillable
= ['user_id', 'transaction_type_id', 'title', 'description', 'first_date', 'repeat_until', 'latest_date', 'repetitions', 'apply_rules', 'active'];

View File

@@ -67,12 +67,12 @@ class RecurrenceMeta extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'name' => 'string',
'value' => 'string',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'name' => 'string',
'value' => 'string',
];
protected $fillable = ['recurrence_id', 'name', 'value'];

View File

@@ -76,14 +76,14 @@ class RecurrenceRepetition extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'repetition_type' => 'string',
'repetition_moment' => 'string',
'repetition_skip' => 'int',
'weekend' => 'int',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'repetition_type' => 'string',
'repetition_moment' => 'string',
'repetition_skip' => 'int',
'weekend' => 'int',
];
protected $fillable = ['recurrence_id', 'weekend', 'repetition_type', 'repetition_moment', 'repetition_skip'];

View File

@@ -91,25 +91,25 @@ class RecurrenceTransaction extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'amount' => 'string',
'foreign_amount' => 'string',
'description' => 'string',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'amount' => 'string',
'foreign_amount' => 'string',
'description' => 'string',
];
protected $fillable
= [
'recurrence_id',
'transaction_currency_id',
'foreign_currency_id',
'source_id',
'destination_id',
'amount',
'foreign_amount',
'description',
];
'recurrence_id',
'transaction_currency_id',
'foreign_currency_id',
'source_id',
'destination_id',
'amount',
'foreign_amount',
'description',
];
/** @var string The table to store the data in */
protected $table = 'recurrences_transactions';

View File

@@ -67,12 +67,12 @@ class RecurrenceTransactionMeta extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'name' => 'string',
'value' => 'string',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'name' => 'string',
'value' => 'string',
];
protected $fillable = ['rt_id', 'name', 'value'];

View File

@@ -62,9 +62,9 @@ class Role extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
protected $fillable = ['name', 'display_name', 'description'];

View File

@@ -95,15 +95,15 @@ class Rule extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'active' => 'boolean',
'order' => 'int',
'stop_processing' => 'boolean',
'id' => 'int',
'strict' => 'boolean',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'active' => 'boolean',
'order' => 'int',
'stop_processing' => 'boolean',
'id' => 'int',
'strict' => 'boolean',
];
protected $fillable = ['rule_group_id', 'order', 'active', 'title', 'description', 'user_id', 'strict'];

View File

@@ -69,12 +69,12 @@ class RuleAction extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'active' => 'boolean',
'order' => 'int',
'stop_processing' => 'boolean',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'active' => 'boolean',
'order' => 'int',
'stop_processing' => 'boolean',
];
protected $fillable = ['rule_id', 'action_type', 'action_value', 'order', 'active', 'stop_processing'];
@@ -85,6 +85,10 @@ class RuleAction extends Model
return (string)$this->action_value;
}
if (true === config('firefly.feature_flags.expression_engine') && str_starts_with($this->action_value, '\=')) {
// return literal string.
return substr($this->action_value, 1);
}
$expr = new ActionExpression($this->action_value);
try {

View File

@@ -85,13 +85,13 @@ class RuleGroup extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'active' => 'boolean',
'stop_processing' => 'boolean',
'order' => 'int',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'active' => 'boolean',
'stop_processing' => 'boolean',
'order' => 'int',
];
protected $fillable = ['user_id', 'user_group_id', 'stop_processing', 'order', 'title', 'description', 'active'];

View File

@@ -66,12 +66,12 @@ class RuleTrigger extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'active' => 'boolean',
'order' => 'int',
'stop_processing' => 'boolean',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'active' => 'boolean',
'order' => 'int',
'stop_processing' => 'boolean',
];
protected $fillable = ['rule_id', 'trigger_type', 'trigger_value', 'order', 'active', 'stop_processing'];

View File

@@ -93,14 +93,14 @@ class Tag extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'date' => 'date',
'zoomLevel' => 'int',
'latitude' => 'float',
'longitude' => 'float',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'date' => 'date',
'zoomLevel' => 'int',
'latitude' => 'float',
'longitude' => 'float',
];
protected $fillable = ['user_id', 'user_group_id', 'tag', 'date', 'description', 'tagMode'];

View File

@@ -99,28 +99,28 @@ class Transaction extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'identifier' => 'int',
'encrypted' => 'boolean', // model does not have these fields though
'bill_name_encrypted' => 'boolean',
'reconciled' => 'boolean',
'date' => 'datetime',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'identifier' => 'int',
'encrypted' => 'boolean', // model does not have these fields though
'bill_name_encrypted' => 'boolean',
'reconciled' => 'boolean',
'date' => 'datetime',
];
protected $fillable
= [
'account_id',
'transaction_journal_id',
'description',
'amount',
'identifier',
'transaction_currency_id',
'foreign_currency_id',
'foreign_amount',
'reconciled',
];
'account_id',
'transaction_journal_id',
'description',
'amount',
'identifier',
'transaction_currency_id',
'foreign_currency_id',
'foreign_amount',
'reconciled',
];
protected $hidden = ['encrypted'];

View File

@@ -89,12 +89,12 @@ class TransactionCurrency extends Model
public ?bool $userGroupEnabled;
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'decimal_places' => 'int',
'enabled' => 'bool',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'decimal_places' => 'int',
'enabled' => 'bool',
];
protected $fillable = ['name', 'code', 'symbol', 'decimal_places', 'enabled'];

View File

@@ -78,13 +78,13 @@ class TransactionGroup extends Model
protected $casts
= [
'id' => 'integer',
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'title' => 'string',
'date' => 'datetime',
];
'id' => 'integer',
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'title' => 'string',
'date' => 'datetime',
];
protected $fillable = ['user_id', 'user_group_id', 'title'];

View File

@@ -138,32 +138,32 @@ class TransactionJournal extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'date' => 'datetime',
'interest_date' => 'date',
'book_date' => 'date',
'process_date' => 'date',
'order' => 'int',
'tag_count' => 'int',
'encrypted' => 'boolean',
'completed' => 'boolean',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'date' => 'datetime',
'interest_date' => 'date',
'book_date' => 'date',
'process_date' => 'date',
'order' => 'int',
'tag_count' => 'int',
'encrypted' => 'boolean',
'completed' => 'boolean',
];
protected $fillable
= [
'user_id',
'user_group_id',
'transaction_type_id',
'bill_id',
'tag_count',
'transaction_currency_id',
'description',
'completed',
'order',
'date',
];
'user_id',
'user_group_id',
'transaction_type_id',
'bill_id',
'tag_count',
'transaction_currency_id',
'description',
'completed',
'order',
'date',
];
protected $hidden = ['encrypted'];

View File

@@ -71,9 +71,9 @@ class TransactionJournalLink extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
/** @var string The table to store the data in */
protected $table = 'journal_links';

View File

@@ -69,10 +69,10 @@ class TransactionJournalMeta extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
protected $fillable = ['transaction_journal_id', 'name', 'data', 'hash'];

View File

@@ -73,10 +73,10 @@ class TransactionType extends Model
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
protected $fillable = ['type'];
/**

View File

@@ -93,11 +93,11 @@ class Webhook extends Model
protected $casts
= [
'active' => 'boolean',
'trigger' => 'integer',
'response' => 'integer',
'delivery' => 'integer',
];
'active' => 'boolean',
'trigger' => 'integer',
'response' => 'integer',
'delivery' => 'integer',
];
protected $fillable = ['active', 'trigger', 'response', 'delivery', 'user_id', 'user_group_id', 'url', 'title', 'secret'];
public static function getDeliveries(): array

View File

@@ -80,7 +80,7 @@ class AppServiceProvider extends ServiceProvider
*/
public function register(): void
{
Passport::ignoreMigrations();
Sanctum::ignoreMigrations();
// Passport::ignoreMigrations();
// Sanctum::ignoreMigrations();
}
}

View File

@@ -122,7 +122,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
$budgetLimit->delete();
}
public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, Carbon $start = null, Carbon $end = null): Collection
public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, ?Carbon $start = null, ?Carbon $end = null): Collection
{
return $this->getAllBudgetLimits($start, $end)->filter(
static function (BudgetLimit $budgetLimit) use ($currency) {
@@ -131,7 +131,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
);
}
public function getAllBudgetLimits(Carbon $start = null, Carbon $end = null): Collection
public function getAllBudgetLimits(?Carbon $start = null, ?Carbon $end = null): Collection
{
// both are NULL:
if (null === $start && null === $end) {
@@ -198,7 +198,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
;
}
public function getBudgetLimits(Budget $budget, Carbon $start = null, Carbon $end = null): Collection
public function getBudgetLimits(Budget $budget, ?Carbon $start = null, ?Carbon $end = null): Collection
{
if (null === $end && null === $start) {
return $budget->budgetlimits()->with(['transactionCurrency'])->orderBy('budget_limits.start_date', 'DESC')->get(['budget_limits.*']);

View File

@@ -57,11 +57,11 @@ interface BudgetLimitRepositoryInterface
/**
* TODO this method is not multi currency aware.
*/
public function getAllBudgetLimits(Carbon $start = null, Carbon $end = null): Collection;
public function getAllBudgetLimits(?Carbon $start = null, ?Carbon $end = null): Collection;
public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, Carbon $start = null, Carbon $end = null): Collection;
public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, ?Carbon $start = null, ?Carbon $end = null): Collection;
public function getBudgetLimits(Budget $budget, Carbon $start = null, Carbon $end = null): Collection;
public function getBudgetLimits(Budget $budget, ?Carbon $start = null, ?Carbon $end = null): Collection;
public function setUser(null|Authenticatable|User $user): void;

View File

@@ -132,7 +132,7 @@ class BudgetRepository implements BudgetRepositoryInterface
continue;
}
$total = $limit->start_date->diffInDays($limit->end_date) + 1; // include the day itself.
$total = $limit->start_date->diffInDays($limit->end_date, true) + 1; // include the day itself.
$days = $this->daysInOverlap($limit, $start, $end);
$amount = bcmul(bcdiv($limit->amount, (string)$total), (string)$days);
$return[$currencyCode]['sum'] = bcadd($return[$currencyCode]['sum'], $amount);
@@ -183,21 +183,21 @@ class BudgetRepository implements BudgetRepositoryInterface
// |-----------|
// |----------------|
if ($start->gte($limit->start_date) && $end->lte($limit->end_date)) {
return $start->diffInDays($end) + 1; // add one day
return (int) $start->diffInDays($end, true) + 1; // add one day
}
// limit starts earlier and limit ends first:
// |-----------|
// |-------|
if ($limit->start_date->lte($start) && $limit->end_date->lte($end)) {
// return days in the range $start-$limit_end
return $start->diffInDays($limit->end_date) + 1; // add one day, the day itself
return (int) $start->diffInDays($limit->end_date, true) + 1; // add one day, the day itself
}
// limit starts later and limit ends earlier
// |-----------|
// |-------|
if ($limit->start_date->gte($start) && $limit->end_date->gte($end)) {
// return days in the range $limit_start - $end
return $limit->start_date->diffInDays($end) + 1; // add one day, the day itself
return (int) $limit->start_date->diffInDays($end, true) + 1; // add one day, the day itself
}
return 0;
@@ -438,7 +438,7 @@ class BudgetRepository implements BudgetRepositoryInterface
*
* @param null|int $budgetId |null
*/
public function find(int $budgetId = null): ?Budget
public function find(?int $budgetId = null): ?Budget
{
return $this->user->budgets()->find($budgetId);
}

View File

@@ -61,7 +61,7 @@ interface BudgetRepositoryInterface
public function destroyAutoBudget(Budget $budget): void;
public function find(int $budgetId = null): ?Budget;
public function find(?int $budgetId = null): ?Budget;
public function findBudget(?int $budgetId, ?string $budgetName): ?Budget;

View File

@@ -51,7 +51,7 @@ class OperationsRepository implements OperationsRepositoryInterface
$total = '0';
$count = 0;
foreach ($budget->budgetlimits as $limit) {
$diff = $limit->start_date->diffInDays($limit->end_date);
$diff = (int) $limit->start_date->diffInDays($limit->end_date, true);
$diff = 0 === $diff ? 1 : $diff;
$amount = $limit->amount;
$perDay = bcdiv($amount, (string)$diff);

View File

@@ -44,7 +44,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return $linkType->transactionJournalLinks()->count();
}
public function destroy(LinkType $linkType, LinkType $moveTo = null): bool
public function destroy(LinkType $linkType, ?LinkType $moveTo = null): bool
{
if (null !== $moveTo) {
TransactionJournalLink::where('link_type_id', $linkType->id)->update(['link_type_id' => $moveTo->id]);
@@ -113,7 +113,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
/**
* Returns all the journal links (of a specific type).
*/
public function getJournalLinks(LinkType $linkType = null): Collection
public function getJournalLinks(?LinkType $linkType = null): Collection
{
$query = TransactionJournalLink::with(['source', 'destination'])
->leftJoin('transaction_journals as source_journals', 'journal_links.source_id', '=', 'source_journals.id')
@@ -225,7 +225,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return LinkType::find($linkTypeId);
}
public function findByName(string $name = null): ?LinkType
public function findByName(?string $name = null): ?LinkType
{
if (null === $name) {
return null;

View File

@@ -37,7 +37,7 @@ interface LinkTypeRepositoryInterface
{
public function countJournals(LinkType $linkType): int;
public function destroy(LinkType $linkType, LinkType $moveTo = null): bool;
public function destroy(LinkType $linkType, ?LinkType $moveTo = null): bool;
public function destroyLink(TransactionJournalLink $link): bool;
@@ -46,7 +46,7 @@ interface LinkTypeRepositoryInterface
/**
* Find link type by name.
*/
public function findByName(string $name = null): ?LinkType;
public function findByName(?string $name = null): ?LinkType;
/**
* Check if link exists between journals.
@@ -65,7 +65,7 @@ interface LinkTypeRepositoryInterface
*/
public function getJournalIds(LinkType $linkType): array;
public function getJournalLinks(LinkType $linkType = null): Collection;
public function getJournalLinks(?LinkType $linkType = null): Collection;
/**
* Return list of existing connections.

View File

@@ -301,7 +301,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
if (null !== $piggyBank->targetdate && $repetition->currentamount < $piggyBank->targetamount) {
$now = today(config('app.timezone'));
$startDate = null !== $piggyBank->startdate && $piggyBank->startdate->gte($now) ? $piggyBank->startdate : $now;
$diffInMonths = $startDate->diffInMonths($piggyBank->targetdate, false);
$diffInMonths = (int) $startDate->diffInMonths($piggyBank->targetdate);
$remainingAmount = bcsub($piggyBank->targetamount, $repetition->currentamount);
// more than 1 month to go and still need money to save:

View File

@@ -202,7 +202,7 @@ class RecurringRepository implements RecurringRepositoryInterface
/**
* Returns the journals created for this recurrence, possibly limited by time.
*/
public function getJournalCount(Recurrence $recurrence, Carbon $start = null, Carbon $end = null): int
public function getJournalCount(Recurrence $recurrence, ?Carbon $start = null, ?Carbon $end = null): int
{
$query = TransactionJournal::leftJoin('journal_meta', 'journal_meta.transaction_journal_id', '=', 'transaction_journals.id')
->where('transaction_journals.user_id', $recurrence->user_id)
@@ -476,7 +476,7 @@ class RecurringRepository implements RecurringRepositoryInterface
if (false === $repDate) {
$repDate = clone $today;
}
$diffInYears = $today->diffInYears($repDate);
$diffInYears = (int) $today->diffInYears($repDate, true);
$repDate->addYears($diffInYears); // technically not necessary.
$string = $repDate->isoFormat((string)trans('config.month_and_day_no_year_js'));

View File

@@ -83,7 +83,7 @@ interface RecurringRepositoryInterface
/**
* Returns the count of journals created for this recurrence, possibly limited by time.
*/
public function getJournalCount(Recurrence $recurrence, Carbon $start = null, Carbon $end = null): int;
public function getJournalCount(Recurrence $recurrence, ?Carbon $start = null, ?Carbon $end = null): int;
/**
* Get journal ID's for journals created by this recurring transaction.

View File

@@ -28,6 +28,7 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Services\Internal\Update\AccountUpdateService;
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Support\Collection;
@@ -291,4 +292,13 @@ class AccountRepository implements AccountRepositoryInterface
return $dbQuery->take($limit)->get(['accounts.*']);
}
#[\Override]
public function update(Account $account, array $data): Account
{
/** @var AccountUpdateService $service */
$service = app(AccountUpdateService::class);
return $service->update($account, $data);
}
}

View File

@@ -73,4 +73,6 @@ interface AccountRepositoryInterface
public function setUser(User $user): void;
public function setUserGroup(UserGroup $userGroup): void;
public function update(Account $account, array $data): Account;
}

View File

@@ -40,7 +40,7 @@ class Amount
*
* @throws FireflyException
*/
public function formatAnything(TransactionCurrency $format, string $amount, bool $coloured = null): string
public function formatAnything(TransactionCurrency $format, string $amount, ?bool $coloured = null): string
{
return $this->formatFlat($format->symbol, $format->decimal_places, $amount, $coloured);
}
@@ -53,7 +53,7 @@ class Amount
*
* @SuppressWarnings(PHPMD.MissingImport)
*/
public function formatFlat(string $symbol, int $decimalPlaces, string $amount, bool $coloured = null): string
public function formatFlat(string $symbol, int $decimalPlaces, string $amount, ?bool $coloured = null): string
{
$locale = app('steam')->getLocale();
$rounded = app('steam')->bcround($amount, $decimalPlaces);

View File

@@ -120,4 +120,12 @@ class RemoteUserProvider implements UserProvider
throw new FireflyException(sprintf('C) Did not implement %s', __METHOD__));
}
#[\Override]
public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false): void
{
app('log')->debug(sprintf('Now at %s', __METHOD__));
throw new FireflyException(sprintf('Did not implement %s', __METHOD__));
}
}

View File

@@ -113,7 +113,7 @@ class WholePeriodChartGenerator
protected function calculateStep(Carbon $start, Carbon $end): string
{
$step = '1D';
$months = $start->diffInMonths($end);
$months = $start->diffInMonths($end, true);
if ($months > 3) {
$step = '1W';
}

View File

@@ -40,7 +40,7 @@ class ExpandedForm
*
* @throws FireflyException
*/
public function amountNoCurrency(string $name, $value = null, array $options = null): string
public function amountNoCurrency(string $name, $value = null, ?array $options = null): string
{
$options ??= [];
$label = $this->label($name, $options);
@@ -71,7 +71,7 @@ class ExpandedForm
*
* @throws FireflyException
*/
public function checkbox(string $name, int $value = null, $checked = null, array $options = null): string
public function checkbox(string $name, ?int $value = null, $checked = null, ?array $options = null): string
{
$options ??= [];
$value ??= 1;
@@ -106,7 +106,7 @@ class ExpandedForm
*
* @throws FireflyException
*/
public function date(string $name, $value = null, array $options = null): string
public function date(string $name, $value = null, ?array $options = null): string
{
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
@@ -129,7 +129,7 @@ class ExpandedForm
/**
* @throws FireflyException
*/
public function file(string $name, array $options = null): string
public function file(string $name, ?array $options = null): string
{
$options ??= [];
$label = $this->label($name, $options);
@@ -153,7 +153,7 @@ class ExpandedForm
*
* @throws FireflyException
*/
public function integer(string $name, $value = null, array $options = null): string
public function integer(string $name, $value = null, ?array $options = null): string
{
$options ??= [];
$label = $this->label($name, $options);
@@ -179,7 +179,7 @@ class ExpandedForm
*
* @throws FireflyException
*/
public function location(string $name, $value = null, array $options = null): string
public function location(string $name, $value = null, ?array $options = null): string
{
$options ??= [];
$label = $this->label($name, $options);
@@ -227,7 +227,7 @@ class ExpandedForm
*
* @throws FireflyException
*/
public function objectGroup($value = null, array $options = null): string
public function objectGroup($value = null, ?array $options = null): string
{
$name = 'object_group';
$label = $this->label($name, $options);
@@ -272,7 +272,7 @@ class ExpandedForm
/**
* @throws FireflyException
*/
public function password(string $name, array $options = null): string
public function password(string $name, ?array $options = null): string
{
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
@@ -297,7 +297,7 @@ class ExpandedForm
*
* @throws FireflyException
*/
public function percentage(string $name, $value = null, array $options = null): string
public function percentage(string $name, $value = null, ?array $options = null): string
{
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
@@ -323,7 +323,7 @@ class ExpandedForm
*
* @throws FireflyException
*/
public function staticText(string $name, $value, array $options = null): string
public function staticText(string $name, $value, ?array $options = null): string
{
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
@@ -346,7 +346,7 @@ class ExpandedForm
*
* @throws FireflyException
*/
public function text(string $name, $value = null, array $options = null): string
public function text(string $name, $value = null, ?array $options = null): string
{
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
@@ -370,7 +370,7 @@ class ExpandedForm
*
* @throws FireflyException
*/
public function textarea(string $name, $value = null, array $options = null): string
public function textarea(string $name, $value = null, ?array $options = null): string
{
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);

View File

@@ -43,7 +43,7 @@ class AccountForm
/**
* Grouped dropdown list of all accounts that are valid as the destination of a withdrawal.
*/
public function activeDepositDestinations(string $name, mixed $value = null, array $options = null): string
public function activeDepositDestinations(string $name, mixed $value = null, ?array $options = null): string
{
$types = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN, AccountType::REVENUE];
$repository = $this->getAccountRepository();
@@ -55,7 +55,7 @@ class AccountForm
return $this->select($name, $grouped, $value, $options);
}
private function getAccountsGrouped(array $types, AccountRepositoryInterface $repository = null): array
private function getAccountsGrouped(array $types, ?AccountRepositoryInterface $repository = null): array
{
if (null === $repository) {
$repository = $this->getAccountRepository();
@@ -89,7 +89,7 @@ class AccountForm
/**
* Grouped dropdown list of all accounts that are valid as the destination of a withdrawal.
*/
public function activeWithdrawalDestinations(string $name, mixed $value = null, array $options = null): string
public function activeWithdrawalDestinations(string $name, mixed $value = null, ?array $options = null): string
{
$types = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN, AccountType::EXPENSE];
$repository = $this->getAccountRepository();
@@ -107,7 +107,7 @@ class AccountForm
*
* @throws FireflyException
*/
public function assetAccountCheckList(string $name, array $options = null): string
public function assetAccountCheckList(string $name, ?array $options = null): string
{
$options ??= [];
$label = $this->label($name, $options);
@@ -138,7 +138,7 @@ class AccountForm
*
* @param mixed $value
*/
public function assetAccountList(string $name, $value = null, array $options = null): string
public function assetAccountList(string $name, $value = null, ?array $options = null): string
{
$types = [AccountType::ASSET, AccountType::DEFAULT];
$grouped = $this->getAccountsGrouped($types);
@@ -151,7 +151,7 @@ class AccountForm
*
* @param mixed $value
*/
public function longAccountList(string $name, $value = null, array $options = null): string
public function longAccountList(string $name, $value = null, ?array $options = null): string
{
$types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN];
$grouped = $this->getAccountsGrouped($types);

View File

@@ -42,7 +42,7 @@ class CurrencyForm
*
* @throws FireflyException
*/
public function amount(string $name, $value = null, array $options = null): string
public function amount(string $name, $value = null, ?array $options = null): string
{
return $this->currencyField($name, 'amount', $value, $options);
}
@@ -50,7 +50,7 @@ class CurrencyForm
/**
* @throws FireflyException
*/
protected function currencyField(string $name, string $view, mixed $value = null, array $options = null): string
protected function currencyField(string $name, string $view, mixed $value = null, ?array $options = null): string
{
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
@@ -106,7 +106,7 @@ class CurrencyForm
*
* @throws FireflyException
*/
public function balanceAll(string $name, $value = null, array $options = null): string
public function balanceAll(string $name, $value = null, ?array $options = null): string
{
return $this->allCurrencyField($name, 'balance', $value, $options);
}
@@ -118,7 +118,7 @@ class CurrencyForm
*
* @throws FireflyException
*/
protected function allCurrencyField(string $name, string $view, $value = null, array $options = null): string
protected function allCurrencyField(string $name, string $view, $value = null, ?array $options = null): string
{
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
@@ -173,7 +173,7 @@ class CurrencyForm
*
* @param mixed $value
*/
public function currencyList(string $name, $value = null, array $options = null): string
public function currencyList(string $name, $value = null, ?array $options = null): string
{
/** @var CurrencyRepositoryInterface $currencyRepos */
$currencyRepos = app(CurrencyRepositoryInterface::class);
@@ -195,7 +195,7 @@ class CurrencyForm
*
* @param mixed $value
*/
public function currencyListEmpty(string $name, $value = null, array $options = null): string
public function currencyListEmpty(string $name, $value = null, ?array $options = null): string
{
/** @var CurrencyRepositoryInterface $currencyRepos */
$currencyRepos = app(CurrencyRepositoryInterface::class);

View File

@@ -36,7 +36,7 @@ trait FormSupport
/**
* @param mixed $selected
*/
public function select(string $name, array $list = null, $selected = null, array $options = null): string
public function select(string $name, ?array $list = null, $selected = null, ?array $options = null): string
{
$list ??= [];
$label = $this->label($name, $options);
@@ -55,7 +55,7 @@ trait FormSupport
return $html;
}
protected function label(string $name, array $options = null): string
protected function label(string $name, ?array $options = null): string
{
$options ??= [];
if (array_key_exists('label', $options)) {
@@ -69,7 +69,7 @@ trait FormSupport
/**
* @param mixed $label
*/
protected function expandOptionArray(string $name, $label, array $options = null): array
protected function expandOptionArray(string $name, $label, ?array $options = null): array
{
$options ??= [];
$name = str_replace('[]', '', $name);

View File

@@ -40,7 +40,7 @@ class PiggyBankForm
*
* @param mixed $value
*/
public function piggyBankList(string $name, $value = null, array $options = null): string
public function piggyBankList(string $name, $value = null, ?array $options = null): string
{
// make repositories
/** @var PiggyBankRepositoryInterface $repository */

View File

@@ -34,7 +34,7 @@ class RuleForm
{
use FormSupport;
public function ruleGroupList(string $name, mixed $value = null, array $options = null): string
public function ruleGroupList(string $name, mixed $value = null, ?array $options = null): string
{
/** @var RuleGroupRepositoryInterface $groupRepos */
$groupRepos = app(RuleGroupRepositoryInterface::class);
@@ -54,7 +54,7 @@ class RuleForm
/**
* @param null $value
*/
public function ruleGroupListWithEmpty(string $name, $value = null, array $options = null): string
public function ruleGroupListWithEmpty(string $name, $value = null, ?array $options = null): string
{
$options ??= [];
$options['class'] = 'form-control';

View File

@@ -39,14 +39,14 @@ trait DateCalculation
*/
public function activeDaysLeft(Carbon $start, Carbon $end): int
{
$difference = $start->diffInDays($end) + 1;
$difference = (int)($start->diffInDays($end, true) + 1);
$today = today(config('app.timezone'))->startOfDay();
if ($start->lte($today) && $end->gte($today)) {
$difference = $today->diffInDays($end);
}
return 0 === $difference ? 1 : $difference;
return (int) (0 === $difference ? 1 : $difference);
}
/**
@@ -56,20 +56,20 @@ trait DateCalculation
*/
protected function activeDaysPassed(Carbon $start, Carbon $end): int
{
$difference = $start->diffInDays($end) + 1;
$difference = $start->diffInDays($end, true) + 1;
$today = today(config('app.timezone'))->startOfDay();
if ($start->lte($today) && $end->gte($today)) {
$difference = $start->diffInDays($today) + 1;
$difference = $start->diffInDays($today, true) + 1;
}
return $difference;
return (int) $difference;
}
protected function calculateStep(Carbon $start, Carbon $end): string
{
$step = '1D';
$months = $start->diffInMonths($end);
$months = $start->diffInMonths($end, true);
if ($months > 3) {
$step = '1W';
}

View File

@@ -38,7 +38,7 @@ class Navigation
{
private Calculator $calculator;
public function __construct(Calculator $calculator = null)
public function __construct(?Calculator $calculator = null)
{
$this->calculator = $calculator instanceof Calculator ? $calculator : new Calculator();
}
@@ -160,9 +160,9 @@ class Navigation
public function startOfPeriod(Carbon $theDate, string $repeatFreq): Carbon
{
$date = clone $theDate;
$functionMap = [
$date = clone $theDate;
Log::debug(sprintf('Now in startOfPeriod("%s", "%s")', $date->toIso8601String(), $repeatFreq));
$functionMap = [
'1D' => 'startOfDay',
'daily' => 'startOfDay',
'1W' => 'startOfWeek',
@@ -178,20 +178,37 @@ class Navigation
'yearly' => 'startOfYear',
'1Y' => 'startOfYear',
];
$parameterMap = [
'startOfWeek' => [Carbon::MONDAY],
];
if (array_key_exists($repeatFreq, $functionMap)) {
$function = $functionMap[$repeatFreq];
Log::debug(sprintf('Function is ->%s()', $function));
if (array_key_exists($function, $parameterMap)) {
Log::debug(sprintf('Parameter map, function becomes ->%s(%s)', $function, implode(', ', $parameterMap[$function])));
$date->{$function}($parameterMap[$function][0]);
Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
return $date;
}
$date->{$function}(); // @phpstan-ignore-line
Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
return $date;
}
if ('half-year' === $repeatFreq || '6M' === $repeatFreq) {
$skipTo = $date->month > 7 ? 6 : 0;
$date->startOfYear()->addMonths($skipTo);
Log::debug(sprintf('Custom call for "%s": addMonths(%d)', $repeatFreq, $skipTo));
Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
return $date;
}
$result = match ($repeatFreq) {
$result = match ($repeatFreq) {
'last7' => $date->subDays(7)->startOfDay(),
'last30' => $date->subDays(30)->startOfDay(),
'last90' => $date->subDays(90)->startOfDay(),
@@ -202,10 +219,14 @@ class Navigation
default => null,
};
if (null !== $result) {
Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
return $result;
}
if ('custom' === $repeatFreq) {
Log::debug(sprintf('Custom, result is "%s"', $date->toIso8601String()));
return $date; // the date is already at the start.
}
Log::error(sprintf('Cannot do startOfPeriod for $repeat_freq "%s"', $repeatFreq));
@@ -216,6 +237,7 @@ class Navigation
public function endOfPeriod(Carbon $end, string $repeatFreq): Carbon
{
$currentEnd = clone $end;
Log::debug(sprintf('Now in endOfPeriod("%s", "%s").', $currentEnd->toIso8601String(), $repeatFreq));
$functionMap = [
'1D' => 'endOfDay',
@@ -252,7 +274,7 @@ class Navigation
/** @var Carbon $tEnd */
$tEnd = session('end', today(config('app.timezone'))->endOfMonth());
$diffInDays = $tStart->diffInDays($tEnd);
$diffInDays = (int) $tStart->diffInDays($tEnd, true);
}
Log::debug(sprintf('Diff in days is %d', $diffInDays));
$currentEnd->addDays($diffInDays);
@@ -296,6 +318,7 @@ class Navigation
if (in_array($repeatFreq, $subDay, true)) {
$currentEnd->subDay();
}
Log::debug(sprintf('Final result: %s', $currentEnd->toIso8601String()));
return $currentEnd;
}
@@ -304,7 +327,7 @@ class Navigation
{
$endOfMonth = $date->copy()->endOfMonth();
return $date->diffInDays($endOfMonth);
return (int) $date->diffInDays($endOfMonth, true);
}
public function diffInPeriods(string $period, int $skip, Carbon $beginning, Carbon $end): int
@@ -317,12 +340,12 @@ class Navigation
$end->format('Y-m-d')
));
$map = [
'daily' => 'floatDiffInDays',
'weekly' => 'floatDiffInWeeks',
'monthly' => 'floatDiffInMonths',
'quarterly' => 'floatDiffInMonths',
'half-year' => 'floatDiffInMonths',
'yearly' => 'floatDiffInYears',
'daily' => 'diffInDays',
'weekly' => 'diffInWeeks',
'monthly' => 'diffInMonths',
'quarterly' => 'diffInMonths',
'half-year' => 'diffInMonths',
'yearly' => 'diffInYears',
];
if (!array_key_exists($period, $map)) {
Log::warning(sprintf('No diffInPeriods for period "%s"', $period));
@@ -331,7 +354,7 @@ class Navigation
}
$func = $map[$period];
// first do the diff
$floatDiff = $beginning->{$func}($end); // @phpstan-ignore-line
$floatDiff = $beginning->{$func}($end, true); // @phpstan-ignore-line
// then correct for quarterly or half-year
if ('quarterly' === $period) {
@@ -442,13 +465,13 @@ class Navigation
$format = $this->preferredCarbonFormat($start, $end);
$displayFormat = (string)trans('config.month_and_day_js', [], $locale);
// increment by month (for year)
if ($start->diffInMonths($end) > 1) {
if ($start->diffInMonths($end, true) > 1) {
$increment = 'addMonth';
$displayFormat = (string)trans('config.month_js');
}
// increment by year (for multi year)
if ($start->diffInMonths($end) > 12) {
// increment by year (for multi-year)
if ($start->diffInMonths($end, true) > 12) {
$increment = 'addYear';
$displayFormat = (string)trans('config.year_js');
}
@@ -471,11 +494,11 @@ class Navigation
public function preferredCarbonFormat(Carbon $start, Carbon $end): string
{
$format = 'Y-m-d';
if ($start->diffInMonths($end) > 1) {
if ((int)$start->diffInMonths($end, true) > 1) {
$format = 'Y-m';
}
if ($start->diffInMonths($end) > 12) {
if ((int)$start->diffInMonths($end, true) > 12) {
$format = 'Y';
}
@@ -540,11 +563,11 @@ class Navigation
{
$locale = app('steam')->getLocale();
$format = (string)trans('config.month_and_day_js', [], $locale);
if ($start->diffInMonths($end) > 1) {
if ($start->diffInMonths($end, true) > 1) {
$format = (string)trans('config.month_js', [], $locale);
}
if ($start->diffInMonths($end) > 12) {
if ($start->diffInMonths($end, true) > 12) {
$format = (string)trans('config.year_js', [], $locale);
}
@@ -558,11 +581,11 @@ class Navigation
public function preferredEndOfPeriod(Carbon $start, Carbon $end): string
{
$format = 'endOfDay';
if ($start->diffInMonths($end) > 1) {
if ((int)$start->diffInMonths($end, true) > 1) {
$format = 'endOfMonth';
}
if ($start->diffInMonths($end) > 12) {
if ((int)$start->diffInMonths($end, true) > 12) {
$format = 'endOfYear';
}
@@ -576,11 +599,11 @@ class Navigation
public function preferredRangeFormat(Carbon $start, Carbon $end): string
{
$format = '1D';
if ($start->diffInMonths($end) > 1) {
if ((int)$start->diffInMonths($end, true) > 1) {
$format = '1M';
}
if ($start->diffInMonths($end) > 12) {
if ((int)$start->diffInMonths($end, true) > 12) {
$format = '1Y';
}
@@ -594,11 +617,11 @@ class Navigation
public function preferredSqlFormat(Carbon $start, Carbon $end): string
{
$format = '%Y-%m-%d';
if ($start->diffInMonths($end) > 1) {
if ((int)$start->diffInMonths($end, true) > 1) {
$format = '%Y-%m';
}
if ($start->diffInMonths($end) > 12) {
if ((int)$start->diffInMonths($end, true) > 12) {
$format = '%Y';
}
@@ -608,7 +631,7 @@ class Navigation
/**
* @throws FireflyException
*/
public function subtractPeriod(Carbon $theDate, string $repeatFreq, int $subtract = null): Carbon
public function subtractPeriod(Carbon $theDate, string $repeatFreq, ?int $subtract = null): Carbon
{
$subtract ??= 1;
$date = clone $theDate;
@@ -654,7 +677,7 @@ class Navigation
/** @var Carbon $tEnd */
$tEnd = session('end', today(config('app.timezone'))->endOfMonth());
$diffInDays = $tStart->diffInDays($tEnd);
$diffInDays = (int) $tStart->diffInDays($tEnd, true);
$date->subDays($diffInDays * $subtract);
return $date;

View File

@@ -126,8 +126,8 @@ class ParseDateString
default => $today,
'yesterday' => $today->subDay(),
'tomorrow' => $today->addDay(),
'start of this week' => $today->startOfWeek(),
'end of this week' => $today->endOfWeek(),
'start of this week' => $today->startOfWeek(Carbon::MONDAY),
'end of this week' => $today->endOfWeek(Carbon::SUNDAY),
'start of this month' => $today->startOfMonth(),
'end of this month' => $today->endOfMonth(),
'start of this quarter' => $today->startOfQuarter(),

View File

@@ -851,7 +851,7 @@ class Steam
return number_format((float)$value, 0, '.', '');
}
public function opposite(string $amount = null): ?string
public function opposite(?string $amount = null): ?string
{
if (null === $amount) {
return null;

View File

@@ -87,7 +87,7 @@ class AmountFormat extends AbstractExtension
{
return new TwigFunction(
'formatAmountByAccount',
static function (AccountModel $account, string $amount, bool $coloured = null): string {
static function (AccountModel $account, string $amount, ?bool $coloured = null): string {
$coloured ??= true;
/** @var AccountRepositoryInterface $accountRepos */
@@ -107,7 +107,7 @@ class AmountFormat extends AbstractExtension
{
return new TwigFunction(
'formatAmountBySymbol',
static function (string $amount, string $symbol, int $decimalPlaces = null, bool $coloured = null): string {
static function (string $amount, string $symbol, ?int $decimalPlaces = null, ?bool $coloured = null): string {
$decimalPlaces ??= 2;
$coloured ??= true;
$currency = new TransactionCurrency();
@@ -127,7 +127,7 @@ class AmountFormat extends AbstractExtension
{
return new TwigFunction(
'formatAmountByCurrency',
static function (TransactionCurrency $currency, string $amount, bool $coloured = null): string {
static function (TransactionCurrency $currency, string $amount, ?bool $coloured = null): string {
$coloured ??= true;
return app('amount')->formatAnything($currency, $amount, $coloured);

View File

@@ -35,6 +35,7 @@ use FireflyIII\TransactionRules\Traits\RefreshNotesTrait;
class AppendDescription implements ActionInterface
{
use RefreshNotesTrait;
private RuleAction $action;
/**

Some files were not shown because too many files have changed in this diff Show More