mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-08-16 19:04:36 +00:00
Compare commits
270 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
5085a384dc | ||
|
07abfd78e1 | ||
|
8b90d2297d | ||
|
28479ef2ed | ||
|
9b03ae160d | ||
|
5303321952 | ||
|
906fca7e9e | ||
|
f64e1f3c1b | ||
|
c8af3684c6 | ||
|
e3474bb075 | ||
|
8140613a29 | ||
|
00d5b4d29d | ||
|
251a347a42 | ||
|
7fb090392f | ||
|
13b96bb3b6 | ||
|
c318790bbf | ||
|
0d969dd42a | ||
|
4e70601d19 | ||
|
e4a6ff293a | ||
|
d0edae76f2 | ||
|
9eaacf30ad | ||
|
40111ed25e | ||
|
506f972c75 | ||
|
843f3c9b45 | ||
|
6c2c2ca41f | ||
|
8315734471 | ||
|
2d9b2ab379 | ||
|
45f20509f4 | ||
|
c5b9c79b82 | ||
|
6a196884e5 | ||
|
1d9431795b | ||
|
b3074b2f6a | ||
|
3be65ff806 | ||
|
8c0005e460 | ||
|
c7128dedf2 | ||
|
e5736c822d | ||
|
8f6655f85e | ||
|
dbe827e3c5 | ||
|
5a7f933a5c | ||
|
54d5f9a9c3 | ||
|
cc682485fc | ||
|
f8cb8967d9 | ||
|
0480db10ac | ||
|
f52c6f7b00 | ||
|
7d1f5f5257 | ||
|
ea0942b7fe | ||
|
3298f2d815 | ||
|
fae5cdae50 | ||
|
8ffe08bfb9 | ||
|
1c2b14868b | ||
|
7775a0141b | ||
|
831272d971 | ||
|
c8c4507d4b | ||
|
6a74cd21fb | ||
|
eb5eca9fa5 | ||
|
0e702fb334 | ||
|
626f97cd65 | ||
|
f03b0569cf | ||
|
82f3a37a3e | ||
|
112a27dbd9 | ||
|
366eca3173 | ||
|
fab0c5bfd9 | ||
|
dc3b923258 | ||
|
3622d3234a | ||
|
cf2c99d986 | ||
|
672add8668 | ||
|
d5826861a0 | ||
|
a8494bd6f0 | ||
|
7fa0c14f8c | ||
|
9bd22d4252 | ||
|
b78f5bd54a | ||
|
0949a264b8 | ||
|
97a0110931 | ||
|
83ec935ac3 | ||
|
e46da428eb | ||
|
26089f992e | ||
|
13233e0893 | ||
|
da934575a6 | ||
|
6feb04c800 | ||
|
d56f97e86d | ||
|
a78614f198 | ||
|
2b25631611 | ||
|
98613b5ea6 | ||
|
105ecc4452 | ||
|
418a682f7e | ||
|
215e5d42a7 | ||
|
21d71bd03c | ||
|
3184a8536e | ||
|
ddf9938c00 | ||
|
388d19b99c | ||
|
ec03017eca | ||
|
0b920b5c64 | ||
|
6e0be9a6a2 | ||
|
f1798a1c97 | ||
|
57cb428105 | ||
|
adc52f7b63 | ||
|
f8cf02bda1 | ||
|
4b14ad9770 | ||
|
2a630b0a50 | ||
|
1a311664e8 | ||
|
0a4e3edf43 | ||
|
9b0b80d1d4 | ||
|
dcd123a9ec | ||
|
e06452d97c | ||
|
e5b4e7afe0 | ||
|
0ea22269a0 | ||
|
577dcfa938 | ||
|
99f08da4df | ||
|
2f9724e7ca | ||
|
8cda89569c | ||
|
5421e30293 | ||
|
a2deff0f7a | ||
|
bff661fe69 | ||
|
f6b890e284 | ||
|
acb8fa522b | ||
|
b47614c965 | ||
|
9af458df49 | ||
|
a67e2b597d | ||
|
3c36eed461 | ||
|
5a7c3bd716 | ||
|
43476167d8 | ||
|
d357eaeb51 | ||
|
2e118c5f22 | ||
|
8e95530ca8 | ||
|
a04a6845f7 | ||
|
185e9b66d6 | ||
|
93a7c51dd1 | ||
|
f9ac40a811 | ||
|
b0027acf34 | ||
|
f5e5854479 | ||
|
95d72d065b | ||
|
56b2fa69bc | ||
|
e614427925 | ||
|
34dc1f9f53 | ||
|
94d9b78a33 | ||
|
b9d949d259 | ||
|
3376e1e663 | ||
|
ea98c2631f | ||
|
50b9fe649d | ||
|
56054531a3 | ||
|
1912e46113 | ||
|
075f951cfe | ||
|
26aad765ae | ||
|
73ba78d46d | ||
|
0d5dd40134 | ||
|
f0d84ad142 | ||
|
0b4ebf644d | ||
|
5b60db120f | ||
|
f2073a4494 | ||
|
3e12d26afd | ||
|
e458208966 | ||
|
e28a77dc87 | ||
|
a709596ccb | ||
|
849c7dfe02 | ||
|
e580093a34 | ||
|
4fa7a5c1bc | ||
|
d668007fee | ||
|
6cbccf3be6 | ||
|
9cd75dda1a | ||
|
56dff7ea67 | ||
|
6160f99e92 | ||
|
115639a004 | ||
|
a0c98c7d9f | ||
|
7842700bf1 | ||
|
4ecda4d4e0 | ||
|
c76d140d0b | ||
|
4f42eb1796 | ||
|
c67b10e38d | ||
|
614ceabd45 | ||
|
a94b2e8806 | ||
|
732616984b | ||
|
eddf0c1200 | ||
|
49013264d5 | ||
|
f12744ad8c | ||
|
4ddcb0c965 | ||
|
0846d4898f | ||
|
cb746200fa | ||
|
fe06a1f7a0 | ||
|
9c1cee738d | ||
|
7cc778673a | ||
|
38d0f0427f | ||
|
8572280b7b | ||
|
69b1769f22 | ||
|
5ceef2e9c3 | ||
|
d32446b171 | ||
|
d8ca39ffea | ||
|
d47bddde62 | ||
|
e4802ec958 | ||
|
6d855e119d | ||
|
7ab81e493a | ||
|
fa0397e431 | ||
|
aba3b361be | ||
|
1cf188ee08 | ||
|
f5983f08fd | ||
|
b812c2e09f | ||
|
d7466efbe1 | ||
|
dff30af9f2 | ||
|
25dcb73e27 | ||
|
63ed3d09d5 | ||
|
caf1e6010b | ||
|
2d97408c1f | ||
|
01c0d76c5a | ||
|
7c7032d951 | ||
|
6e722f5833 | ||
|
d3502c56d3 | ||
|
1b8eb3cd68 | ||
|
bc7bd84221 | ||
|
85b22341a4 | ||
|
f8c725e5b2 | ||
|
e6344e4f51 | ||
|
8eac10bf89 | ||
|
c1da0eeced | ||
|
0a6d5b1766 | ||
|
4035ac09ce | ||
|
f81a7cfac0 | ||
|
2b086879cc | ||
|
a3091f7509 | ||
|
70a6ac0038 | ||
|
468a53d587 | ||
|
51f3b17ad2 | ||
|
a864d3bd56 | ||
|
a4d5aa0d10 | ||
|
aff5ac2c0a | ||
|
effe92a05c | ||
|
a4ca6dfd38 | ||
|
e6012e1ca2 | ||
|
472497cafd | ||
|
34f4b16a63 | ||
|
7f55a870d9 | ||
|
6a37ad7c15 | ||
|
788981d170 | ||
|
f377c92d8a | ||
|
0dc3068f7f | ||
|
1ad8ec6dd1 | ||
|
18a80f3519 | ||
|
82f8b091c1 | ||
|
71785bae57 | ||
|
6d979a68f2 | ||
|
ef852ef963 | ||
|
00b0ce6c6e | ||
|
5750087d37 | ||
|
a2ae977550 | ||
|
b893651223 | ||
|
e221d37d2b | ||
|
f0acab21a3 | ||
|
93dc5fae09 | ||
|
40746db53e | ||
|
4404db650c | ||
|
ab968a56e6 | ||
|
246a3d000a | ||
|
cbcf251bb3 | ||
|
0756054690 | ||
|
b6109ca93e | ||
|
823ee2cea0 | ||
|
18f6052681 | ||
|
4f2ab72567 | ||
|
bc6a2c2cca | ||
|
7a6a911f7f | ||
|
abeff39829 | ||
|
4d18c1bf83 | ||
|
8a818059f2 | ||
|
3768262224 | ||
|
b790a0731e | ||
|
c38b9eeb08 | ||
|
22b376da71 | ||
|
fde53abb1a | ||
|
c32e09a2b3 | ||
|
a243f3d7c2 | ||
|
3586c76b95 | ||
|
10390953fe |
@@ -10,6 +10,19 @@ parameters:
|
||||
- '#is neither abstract nor final#'
|
||||
- '#Control structures using switch should not be used\.#'
|
||||
- '#has a nullable return type declaration#'
|
||||
- '#with a nullable type declaration#'
|
||||
- '#with null as default value#'
|
||||
- '#Constructor in [a-zA-Z0-9\\_]+ has parameter \$[a-zA-Z0-9\\_]+ with default value#'
|
||||
-
|
||||
message: '#Function compact\(\) should not be used.#'
|
||||
paths:
|
||||
- ../app/Http/Controllers
|
||||
- ../app/Support/Http/Controllers/RenderPartialViews.php
|
||||
- ../app/Support/Form/FormSupport.php
|
||||
- ../app/Support/Form/CurrencyForm.php
|
||||
- ../app/Support/Form/AccountForm.php
|
||||
- ../app/Support/ExpandedForm.php
|
||||
- ../app/Generator/Report
|
||||
paths:
|
||||
- ../app
|
||||
- ../database
|
||||
@@ -17,4 +30,4 @@ parameters:
|
||||
- ../bootstrap/app.php
|
||||
|
||||
# The level 8 is the highest level. original was 5
|
||||
level: 5
|
||||
level: 3
|
||||
|
@@ -21,12 +21,13 @@
|
||||
#
|
||||
|
||||
# Install composer packages
|
||||
composer install --no-scripts --no-ansi
|
||||
#composer install --no-scripts --no-ansi
|
||||
|
||||
# enable test .env file.
|
||||
cp .ci/.env.ci .env
|
||||
|
||||
# Do static code analysis.
|
||||
./vendor/bin/phpstan analyse -c .ci/phpstan.neon --no-progress
|
||||
# ./vendor/bin/phpstan analyse -c .ci/phpstan.neon --no-progress
|
||||
./vendor/bin/phpstan analyse -c .ci/phpstan.neon
|
||||
|
||||
exit 0
|
@@ -24,6 +24,7 @@
|
||||
cp .ci/.env.ci ../.env
|
||||
|
||||
# download test database
|
||||
# TODO no longer exists
|
||||
wget --quiet https://raw.githubusercontent.com/firefly-iii/test-data/main/test_db.sqlite -o storage/database/test_db.sqlite
|
||||
|
||||
# run phpunit
|
||||
|
15
.env.example
15
.env.example
@@ -64,7 +64,7 @@ AUDIT_LOG_LEVEL=info
|
||||
# Use "mysql" for MySQL and MariaDB.
|
||||
# Use "sqlite" for SQLite.
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=fireflyiiidb
|
||||
DB_HOST=db
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=firefly
|
||||
DB_USERNAME=firefly
|
||||
@@ -155,8 +155,16 @@ SEND_REPORT_JOURNALS=true
|
||||
|
||||
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
|
||||
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
# Take note: it is no longer necessary to set this value, and it will be removed in future versions.
|
||||
MAPBOX_API_KEY=
|
||||
|
||||
#
|
||||
# Instead of the mapbox API key, just set this value to true if you want to set the location
|
||||
# of certain things, like transactions. Since this involves an external service, it's optional
|
||||
# and disabled by default.
|
||||
#
|
||||
ENABLE_EXTERNAL_MAP=false
|
||||
|
||||
# The map will default to this location:
|
||||
MAP_DEFAULT_LAT=51.983333
|
||||
MAP_DEFAULT_LONG=5.916667
|
||||
@@ -167,6 +175,10 @@ MAP_DEFAULT_ZOOM=6
|
||||
# For full instructions on these settings please visit:
|
||||
# https://docs.firefly-iii.org/advanced-installation/authentication
|
||||
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
#
|
||||
# If you enable 'ldap' AND you run Docker, the Docker image will contact packagist.org
|
||||
# This is necessary to download the required packages.
|
||||
#
|
||||
LOGIN_PROVIDER=eloquent
|
||||
|
||||
# It's also possible to change the way users are authenticated. You could use Authelia for example.
|
||||
@@ -320,6 +332,7 @@ BROADCAST_DRIVER=log
|
||||
QUEUE_DRIVER=sync
|
||||
CACHE_PREFIX=firefly
|
||||
PUSHER_KEY=
|
||||
IPINFO_TOKEN=
|
||||
PUSHER_SECRET=
|
||||
PUSHER_ID=
|
||||
DEMO_USERNAME=
|
||||
|
35
.github/lock.yml
vendored
35
.github/lock.yml
vendored
@@ -1,35 +0,0 @@
|
||||
# Configuration for Lock Threads - https://github.com/dessant/lock-threads
|
||||
|
||||
# Number of days of inactivity before a closed issue or pull request is locked
|
||||
daysUntilLock: 90
|
||||
|
||||
# Skip issues and pull requests created before a given timestamp. Timestamp must
|
||||
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
|
||||
skipCreatedBefore: false
|
||||
|
||||
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
|
||||
exemptLabels: []
|
||||
|
||||
# Label to add before locking, such as `outdated`. Set to `false` to disable
|
||||
lockLabel: false
|
||||
|
||||
# Comment to post before locking. Set to `false` to disable
|
||||
lockComment: false
|
||||
|
||||
# Assign `resolved` as the reason for locking. Set to `false` to disable
|
||||
setLockReason: true
|
||||
|
||||
# Limit to only `issues` or `pulls`
|
||||
# only: issues
|
||||
|
||||
# Optionally, specify configuration settings just for `issues` or `pulls`
|
||||
# issues:
|
||||
# exemptLabels:
|
||||
# - help-wanted
|
||||
# lockLabel: outdated
|
||||
|
||||
# pulls:
|
||||
# daysUntilLock: 30
|
||||
|
||||
# Repository to extend settings from
|
||||
# _extends: repo
|
19
.github/workflows/lock.yml
vendored
Normal file
19
.github/workflows/lock.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: Lock old issues
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
jobs:
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v2
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-lock-inactive-days: '90'
|
||||
issue-lock-comment: >
|
||||
This issue has been automatically locked since there
|
||||
has not been any recent activity after it was closed.
|
||||
Please open a new issue for related bugs.
|
@@ -66,7 +66,7 @@ class ObjectGroupController extends Controller
|
||||
$return = [];
|
||||
$result = $this->repository->search($data['query'], $data['limit']);
|
||||
|
||||
/** @var ObjectGroup $account */
|
||||
/** @var ObjectGroup $objectGroup */
|
||||
foreach ($result as $objectGroup) {
|
||||
$return[] = [
|
||||
'id' => (string)$objectGroup->id,
|
||||
|
@@ -86,12 +86,12 @@ class AccountController extends Controller
|
||||
$defaultSet = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
|
||||
$frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
|
||||
$default = app('amount')->getDefaultCurrency();
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
if (0 === count($frontPage->data)) {
|
||||
$frontPage->data = $defaultSet;
|
||||
$frontPage->save();
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
|
||||
// get accounts:
|
||||
$accounts = $this->repository->getAccountsById($frontPage->data);
|
||||
@@ -100,7 +100,7 @@ class AccountController extends Controller
|
||||
foreach ($accounts as $account) {
|
||||
$currency = $this->repository->getAccountCurrency($account);
|
||||
if (null === $currency) {
|
||||
$currency = $default; // @codeCoverageIgnore
|
||||
$currency = $default;
|
||||
}
|
||||
$currentSet = [
|
||||
'label' => $account->name,
|
||||
@@ -108,8 +108,8 @@ class AccountController extends Controller
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'start_date' => $start->format('Y-m-d'),
|
||||
'end_date' => $end->format('Y-m-d'),
|
||||
'start_date' => $start->toAtomString(),
|
||||
'end_date' => $end->toAtomString(),
|
||||
'type' => 'line', // line, area or bar
|
||||
'yAxisID' => 0, // 0, 1, 2
|
||||
'entries' => [],
|
||||
@@ -120,7 +120,7 @@ class AccountController extends Controller
|
||||
$previous = round((float)array_values($range)[0], 12);
|
||||
while ($currentStart <= $end) {
|
||||
$format = $currentStart->format('Y-m-d');
|
||||
$label = $currentStart->format('Y-m-d');
|
||||
$label = $currentStart->toAtomString();
|
||||
$balance = array_key_exists($format, $range) ? round((float)$range[$format], 12) : $previous;
|
||||
$previous = $balance;
|
||||
$currentStart->addDay();
|
||||
|
52
app/Api/V1/Controllers/Data/Bulk/AccountController.php
Normal file
52
app/Api/V1/Controllers/Data/Bulk/AccountController.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers\Data\Bulk;
|
||||
|
||||
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Requests\Data\Bulk\MoveTransactionsRequest;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Services\Internal\Destroy\AccountDestroyService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* Class AccountController
|
||||
*/
|
||||
class AccountController extends Controller
|
||||
{
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MoveTransactionsRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function moveTransactions(MoveTransactionsRequest $request): JsonResponse
|
||||
{
|
||||
$accountIds = $request->getAll();
|
||||
$original = $this->repository->findNull($accountIds['original_account']);
|
||||
$destination = $this->repository->findNull($accountIds['destination_account']);
|
||||
|
||||
/** @var AccountDestroyService $service */
|
||||
$service = app(AccountDestroyService::class);
|
||||
$service->moveTransactions($original, $destination);
|
||||
|
||||
return response()->json([], 204);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* AccountController.php
|
||||
@@ -26,7 +25,6 @@ namespace FireflyIII\Api\V1\Controllers\Data\Export;
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Requests\Data\Export\ExportRequest;
|
||||
use FireflyIII\Support\Export\ExportDataGenerator;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\Response as LaravelResponse;
|
||||
use League\Csv\CannotInsertRecord;
|
||||
|
||||
@@ -45,11 +43,8 @@ class ExportController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
/** @var ExportDataGenerator $exporter */
|
||||
$this->exporter = app(ExportDataGenerator::class);
|
||||
$this->exporter->setUser($user);
|
||||
$this->exporter->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -93,7 +88,7 @@ class ExportController extends Controller
|
||||
->header('Expires', '0')
|
||||
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
|
||||
->header('Pragma', 'public')
|
||||
->header('Content-Length', strlen($data[$key]));
|
||||
->header('Content-Length', (string)strlen($data[$key]));
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
@@ -82,12 +82,14 @@ class AccountController extends Controller
|
||||
$start = $request->getStart();
|
||||
$end = $request->getEnd();
|
||||
$assetAccounts = $request->getAssetAccounts();
|
||||
$expenses = $this->opsRepository->sumExpenses($start, $end, $assetAccounts);
|
||||
$expenses = $this->opsRepository->sumExpensesBySource($start, $end, $assetAccounts);
|
||||
$result = [];
|
||||
|
||||
/** @var array $expense */
|
||||
foreach ($expenses as $expense) {
|
||||
$result[] = [
|
||||
'id' => (string)$expense['id'],
|
||||
'name' => $expense['name'],
|
||||
'difference' => $expense['sum'],
|
||||
'difference_float' => (float)$expense['sum'],
|
||||
'currency_id' => (string)$expense['currency_id'],
|
||||
@@ -109,12 +111,14 @@ class AccountController extends Controller
|
||||
$end = $request->getEnd();
|
||||
$assetAccounts = $request->getAssetAccounts();
|
||||
$expenseAccounts = $request->getExpenseAccounts();
|
||||
$expenses = $this->opsRepository->sumExpenses($start, $end, $assetAccounts, $expenseAccounts);
|
||||
$expenses = $this->opsRepository->sumExpensesByDestination($start, $end, $assetAccounts, $expenseAccounts);
|
||||
$result = [];
|
||||
|
||||
/** @var array $expense */
|
||||
foreach ($expenses as $expense) {
|
||||
$result[] = [
|
||||
'id' => (string)$expense['id'],
|
||||
'name' => $expense['name'],
|
||||
'difference' => $expense['sum'],
|
||||
'difference_float' => (float)$expense['sum'],
|
||||
'currency_id' => (string)$expense['currency_id'],
|
||||
|
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* PeriodController.php
|
||||
|
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* PeriodController.php
|
||||
@@ -45,9 +44,8 @@ class TagController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$user = auth()->user();
|
||||
$this->repository = app(TagRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -129,7 +127,7 @@ class TagController extends Controller
|
||||
$collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
|
||||
$collector->setTags($tags);
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
/** @var array $entry */
|
||||
/** @var array $journal */
|
||||
foreach ($genericSet as $journal) {
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
||||
|
@@ -75,7 +75,7 @@ class AccountController extends Controller
|
||||
|
||||
/**
|
||||
* TODO same code as Expense/AccountController.
|
||||
*
|
||||
* TODO does not actually include the name of the expense account.
|
||||
* @param GenericRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
@@ -85,11 +85,13 @@ class AccountController extends Controller
|
||||
$start = $request->getStart();
|
||||
$end = $request->getEnd();
|
||||
$assetAccounts = $request->getAssetAccounts();
|
||||
$income = $this->opsRepository->sumIncome($start, $end, $assetAccounts);
|
||||
$income = $this->opsRepository->sumIncomeByDestination($start, $end, $assetAccounts);
|
||||
$result = [];
|
||||
/** @var array $entry */
|
||||
foreach ($income as $entry) {
|
||||
$result[] = [
|
||||
'id' => (string)$entry['id'],
|
||||
'name' => $entry['name'],
|
||||
'difference' => $entry['sum'],
|
||||
'difference_float' => (float)$entry['sum'],
|
||||
'currency_id' => (string)$entry['currency_id'],
|
||||
@@ -101,7 +103,7 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* // TOOD same as
|
||||
* TODO does not actually include the name of the expense account.
|
||||
*
|
||||
* @param GenericRequest $request
|
||||
*
|
||||
@@ -113,12 +115,14 @@ class AccountController extends Controller
|
||||
$end = $request->getEnd();
|
||||
$assetAccounts = $request->getAssetAccounts();
|
||||
$revenueAccounts = $request->getRevenueAccounts();
|
||||
$income = $this->opsRepository->sumIncome($start, $end, $assetAccounts, $revenueAccounts);
|
||||
$income = $this->opsRepository->sumIncomeBySource($start, $end, $assetAccounts, $revenueAccounts);
|
||||
$result = [];
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($income as $entry) {
|
||||
$result[] = [
|
||||
'id' => (string)$entry['id'],
|
||||
'name' => $entry['name'],
|
||||
'difference' => $entry['sum'],
|
||||
'difference_float' => (float)$entry['sum'],
|
||||
'currency_id' => (string)$entry['currency_id'],
|
||||
|
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* PeriodController.php
|
||||
@@ -131,7 +130,7 @@ class TagController extends Controller
|
||||
$collector->setTypes([TransactionType::DEPOSIT])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||
$collector->setTags($tags);
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
/** @var array $entry */
|
||||
/** @var array $journal */
|
||||
foreach ($genericSet as $journal) {
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
||||
|
@@ -59,6 +59,7 @@ class AccountController extends Controller
|
||||
|
||||
/**
|
||||
* TODO same code as Expense/AccountController.
|
||||
* TODO does not actually include the name of the expense account.
|
||||
*
|
||||
* @param GenericRequest $request
|
||||
*
|
||||
@@ -69,18 +70,7 @@ class AccountController extends Controller
|
||||
$start = $request->getStart();
|
||||
$end = $request->getEnd();
|
||||
$assetAccounts = $request->getAssetAccounts();
|
||||
$income = $this->opsRepository->sumTransfers($start, $end, $assetAccounts);
|
||||
$result = [];
|
||||
/** @var array $entry */
|
||||
foreach ($income as $entry) {
|
||||
$result[] = [
|
||||
'difference' => $entry['sum'],
|
||||
'difference_float' => (float)$entry['sum'],
|
||||
'currency_id' => (string)$entry['currency_id'],
|
||||
'currency_code' => $entry['currency_code'],
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json($result);
|
||||
$transfers = $this->opsRepository->sumTransfers($start, $end, $assetAccounts);
|
||||
return response()->json($transfers);
|
||||
}
|
||||
}
|
||||
|
@@ -132,7 +132,7 @@ class TagController extends Controller
|
||||
$collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||
$collector->setTags($tags);
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
/** @var array $entry */
|
||||
/** @var array $journal */
|
||||
foreach ($genericSet as $journal) {
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
||||
|
@@ -100,7 +100,7 @@ class ShowController extends Controller
|
||||
->header('Expires', '0')
|
||||
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
|
||||
->header('Pragma', 'public')
|
||||
->header('Content-Length', strlen($content));
|
||||
->header('Content-Length', (string)strlen($content));
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
@@ -46,12 +46,8 @@ class DestroyController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var BillRepositoryInterface repository */
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -57,12 +57,8 @@ class ListController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var BillRepositoryInterface repository */
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -51,12 +51,8 @@ class ShowController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var BillRepositoryInterface repository */
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -52,12 +52,8 @@ class StoreController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var BillRepositoryInterface repository */
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -49,12 +49,8 @@ class UpdateController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var BillRepositoryInterface repository */
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -46,12 +46,8 @@ class DestroyController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var CategoryRepositoryInterface repository */
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -56,12 +56,8 @@ class ListController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var CategoryRepositoryInterface repository */
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -51,12 +51,8 @@ class ShowController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var CategoryRepositoryInterface repository */
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -49,12 +49,8 @@ class StoreController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var CategoryRepositoryInterface repository */
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -49,12 +49,8 @@ class UpdateController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var CategoryRepositoryInterface repository */
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -46,12 +46,8 @@ class DestroyController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
/** @var RecurringRepositoryInterface repository */
|
||||
$this->repository = app(RecurringRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -54,12 +54,8 @@ class ListController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
/** @var RecurringRepositoryInterface repository */
|
||||
$this->repository = app(RecurringRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -51,12 +51,8 @@ class ShowController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
/** @var RecurringRepositoryInterface repository */
|
||||
$this->repository = app(RecurringRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -49,12 +49,8 @@ class StoreController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
/** @var RecurringRepositoryInterface repository */
|
||||
$this->repository = app(RecurringRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* TriggerController.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\V1\Controllers\Models\Recurrence;
|
||||
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
|
||||
use FireflyIII\Support\Cronjobs\RecurringCronjob;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class TriggerController
|
||||
*/
|
||||
class TriggerController extends Controller
|
||||
{
|
||||
private RecurringRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* RecurrenceController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
/** @var RecurringRepositoryInterface repository */
|
||||
$this->repository = app(RecurringRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* TODO currently unused + unreachable.
|
||||
*/
|
||||
public function trigger(): JsonResponse
|
||||
{
|
||||
/** @var RecurringCronjob $recurring */
|
||||
$recurring = app(RecurringCronjob::class);
|
||||
try {
|
||||
$result = $recurring->fire();
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
throw new FireflyException('200022: Error in cron job.', 0, $e);
|
||||
}
|
||||
if (false === $result) {
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
return response()->json();
|
||||
}
|
||||
}
|
@@ -49,12 +49,8 @@ class UpdateController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
/** @var RecurringRepositoryInterface repository */
|
||||
$this->repository = app(RecurringRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -37,6 +37,7 @@ use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class TriggerController
|
||||
|
@@ -94,13 +94,13 @@ class StoreController extends Controller
|
||||
$validator = Validator::make(
|
||||
['transactions' => [['description' => $e->getMessage()]]], ['transactions.0.description' => new IsDuplicateTransaction]
|
||||
);
|
||||
throw new ValidationException($validator);
|
||||
throw new ValidationException($validator,0, $e);
|
||||
} catch (FireflyException $e) {
|
||||
Log::warning('Caught an exception. Return error message.');
|
||||
Log::error($e->getMessage());
|
||||
$message = sprintf('Internal exception: %s', $e->getMessage());
|
||||
$validator = Validator::make(['transactions' => [['description' => $message]]], ['transactions.0.description' => new IsDuplicateTransaction]);
|
||||
throw new ValidationException($validator);
|
||||
throw new ValidationException($validator,0, $e);
|
||||
}
|
||||
app('preferences')->mark();
|
||||
event(new StoredTransactionGroup($transactionGroup, $data['apply_rules'] ?? true));
|
||||
|
@@ -96,7 +96,7 @@ class UpdateController extends Controller
|
||||
|
||||
$selectedGroup = $collector->getGroups()->first();
|
||||
if (null === $selectedGroup) {
|
||||
throw new NotFoundHttpException(); // @codeCoverageIgnore
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
/** @var TransactionGroupTransformer $transformer */
|
||||
$transformer = app(TransactionGroupTransformer::class);
|
||||
|
@@ -50,13 +50,9 @@ class DestroyController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var CurrencyRepositoryInterface repository */
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
$this->userRepository = app(UserRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -79,13 +75,13 @@ class DestroyController extends Controller
|
||||
|
||||
if (!$this->userRepository->hasRole($admin, 'owner')) {
|
||||
// access denied:
|
||||
throw new FireflyException('200005: You need the "owner" role to do this.'); // @codeCoverageIgnore
|
||||
throw new FireflyException('200005: You need the "owner" role to do this.');
|
||||
}
|
||||
if ($this->repository->currencyInUse($currency)) {
|
||||
throw new FireflyException('200006: Currency in use.'); // @codeCoverageIgnore
|
||||
throw new FireflyException('200006: Currency in use.');
|
||||
}
|
||||
if ($this->repository->isFallbackCurrency($currency)) {
|
||||
throw new FireflyException('200026: Currency is fallback.'); // @codeCoverageIgnore
|
||||
throw new FireflyException('200026: Currency is fallback.');
|
||||
}
|
||||
|
||||
$this->repository->destroy($currency);
|
||||
|
@@ -77,13 +77,9 @@ class ListController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var CurrencyRepositoryInterface repository */
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
$this->userRepository = app(UserRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -56,12 +56,8 @@ class ShowController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var CurrencyRepositoryInterface repository */
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -56,13 +56,9 @@ class StoreController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var CurrencyRepositoryInterface repository */
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
$this->userRepository = app(UserRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -56,13 +56,9 @@ class UpdateController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var CurrencyRepositoryInterface repository */
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
$this->userRepository = app(UserRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -80,7 +80,7 @@ class StoreController extends Controller
|
||||
$admin = auth()->user();
|
||||
|
||||
if (!$this->userRepository->hasRole($admin, 'owner')) {
|
||||
throw new FireflyException('200005: You need the "owner" role to do this.'); // @codeCoverageIgnore
|
||||
throw new FireflyException('200005: You need the "owner" role to do this.');
|
||||
}
|
||||
$data = $request->getAll();
|
||||
// if currency ID is 0, find the currency by the code:
|
||||
|
@@ -86,7 +86,7 @@ class UpdateController extends Controller
|
||||
$admin = auth()->user();
|
||||
|
||||
if (!$this->userRepository->hasRole($admin, 'owner')) {
|
||||
throw new FireflyException('200005: You need the "owner" role to do this.'); // @codeCoverageIgnore
|
||||
throw new FireflyException('200005: You need the "owner" role to do this.');
|
||||
}
|
||||
|
||||
$data = $request->getAll();
|
||||
|
@@ -64,7 +64,7 @@ class ConfigurationController extends Controller
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
throw new FireflyException('200030: Could not load config variables.');
|
||||
throw new FireflyException('200030: Could not load config variables.', 0, $e);
|
||||
}
|
||||
$staticData = $this->getStaticConfiguration();
|
||||
$return = [];
|
||||
@@ -161,7 +161,7 @@ class ConfigurationController extends Controller
|
||||
public function update(UpdateRequest $request, string $name): JsonResponse
|
||||
{
|
||||
if (!$this->repository->hasRole(auth()->user(), 'owner')) {
|
||||
throw new FireflyException('200005: You need the "owner" role to do this.'); // @codeCoverageIgnore
|
||||
throw new FireflyException('200005: You need the "owner" role to do this.');
|
||||
}
|
||||
$data = $request->getAll();
|
||||
$shortName = str_replace('configuration.', '', $name);
|
||||
|
@@ -54,7 +54,6 @@ class UserController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var UserRepositoryInterface repository */
|
||||
$this->repository = app(UserRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
@@ -84,7 +83,7 @@ class UserController extends Controller
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
throw new FireflyException('200025: No access to function.'); // @codeCoverageIgnore
|
||||
throw new FireflyException('200025: No access to function.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -53,12 +53,8 @@ class AttemptController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var WebhookRepositoryInterface repository */
|
||||
$this->repository = app(WebhookRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -48,12 +48,8 @@ class DestroyController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var WebhookRepositoryInterface repository */
|
||||
$this->repository = app(WebhookRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -49,12 +49,8 @@ class MessageController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var WebhookRepositoryInterface repository */
|
||||
$this->repository = app(WebhookRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -50,12 +50,8 @@ class ShowController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var WebhookRepositoryInterface repository */
|
||||
$this->repository = app(WebhookRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -47,12 +47,8 @@ class StoreController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var WebhookRepositoryInterface repository */
|
||||
$this->repository = app(WebhookRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -27,7 +27,6 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Jobs\SendWebhookMessage;
|
||||
use FireflyIII\Models\Webhook;
|
||||
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
@@ -45,12 +44,8 @@ class SubmitController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var WebhookRepositoryInterface repository */
|
||||
$this->repository = app(WebhookRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -47,12 +47,8 @@ class UpdateController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var WebhookRepositoryInterface repository */
|
||||
$this->repository = app(WebhookRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -41,7 +41,7 @@ class ApiDemoUser
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
/** @var User $user */
|
||||
/** @var User|null $user */
|
||||
$user = $request->user();
|
||||
|
||||
if (null === $user) {
|
||||
|
86
app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php
Normal file
86
app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests\Data\Bulk;
|
||||
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
/**
|
||||
* Class MoveTransactionsRequest
|
||||
*/
|
||||
class MoveTransactionsRequest extends FormRequest
|
||||
{
|
||||
use ChecksLogin, ConvertsDataTypes;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'original_account' => $this->integer('original_account'),
|
||||
'destination_account' => $this->integer('destination_account'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'original_account' => 'required|different:destination_account|belongsToUser:accounts,id',
|
||||
'destination_account' => 'required|different:original_account|belongsToUser:accounts,id',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the validator instance with special rules for after the basic validation rules.
|
||||
*
|
||||
* @param Validator $validator
|
||||
* TODO duplicate code.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(
|
||||
function (Validator $validator) {
|
||||
// validate start before end only if both are there.
|
||||
$data = $validator->getData();
|
||||
if (array_key_exists('original_account', $data) && array_key_exists('destination_account', $data)) {
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$original = $repository->findNull((int)$data['original_account']);
|
||||
$destination = $repository->findNull((int)$data['destination_account']);
|
||||
if ($original->accountType->type !== $destination->accountType->type) {
|
||||
$validator->errors()->add('title', (string)trans('validation.same_account_type'));
|
||||
|
||||
return;
|
||||
}
|
||||
// get currency pref:
|
||||
$originalCurrency = $repository->getAccountCurrency($original);
|
||||
$destinationCurrency = $repository->getAccountCurrency($destination);
|
||||
if (null === $originalCurrency xor null === $destinationCurrency) {
|
||||
$validator->errors()->add('title', (string)trans('validation.same_account_currency'));
|
||||
|
||||
return;
|
||||
}
|
||||
if (null === $originalCurrency && null === $destinationCurrency) {
|
||||
// this is OK
|
||||
return;
|
||||
}
|
||||
if ($originalCurrency->code !== $destinationCurrency->code) {
|
||||
$validator->errors()->add('title', (string)trans('validation.same_account_currency'));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@@ -86,9 +86,6 @@ class GenericRequest extends FormRequest
|
||||
*/
|
||||
private function parseAccounts(): void
|
||||
{
|
||||
if (null === $this->accounts) {
|
||||
$this->accounts = new Collection;
|
||||
}
|
||||
if (0 !== $this->accounts->count()) {
|
||||
return;
|
||||
}
|
||||
@@ -121,9 +118,6 @@ class GenericRequest extends FormRequest
|
||||
*/
|
||||
private function parseBills(): void
|
||||
{
|
||||
if (null === $this->bills) {
|
||||
$this->bills = new Collection;
|
||||
}
|
||||
if (0 !== $this->bills->count()) {
|
||||
return;
|
||||
}
|
||||
@@ -156,9 +150,6 @@ class GenericRequest extends FormRequest
|
||||
*/
|
||||
private function parseBudgets(): void
|
||||
{
|
||||
if (null === $this->budgets) {
|
||||
$this->budgets = new Collection;
|
||||
}
|
||||
if (0 !== $this->budgets->count()) {
|
||||
return;
|
||||
}
|
||||
@@ -191,9 +182,6 @@ class GenericRequest extends FormRequest
|
||||
*/
|
||||
private function parseCategories(): void
|
||||
{
|
||||
if (null === $this->categories) {
|
||||
$this->categories = new Collection;
|
||||
}
|
||||
if (0 !== $this->categories->count()) {
|
||||
return;
|
||||
}
|
||||
@@ -284,9 +272,6 @@ class GenericRequest extends FormRequest
|
||||
*/
|
||||
private function parseTags(): void
|
||||
{
|
||||
if (null === $this->tags) {
|
||||
$this->tags = new Collection;
|
||||
}
|
||||
if (0 !== $this->tags->count()) {
|
||||
return;
|
||||
}
|
||||
@@ -311,7 +296,7 @@ class GenericRequest extends FormRequest
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
// this is cheating but it works:
|
||||
// this is cheating but it works to initialize the collections.
|
||||
$this->accounts = new Collection;
|
||||
$this->budgets = new Collection;
|
||||
$this->categories = new Collection;
|
||||
|
@@ -59,7 +59,7 @@ class StoreRequest extends FormRequest
|
||||
'name' => $this->string('name'),
|
||||
'active' => $active,
|
||||
'include_net_worth' => $includeNetWorth,
|
||||
'account_type' => $this->string('type'),
|
||||
'account_type_name' => $this->string('type'),
|
||||
'account_type_id' => null,
|
||||
'currency_id' => $this->integer('currency_id'),
|
||||
'order' => $this->integer('order'),
|
||||
@@ -73,17 +73,17 @@ class StoreRequest extends FormRequest
|
||||
'opening_balance_date' => $this->date('opening_balance_date'),
|
||||
'cc_type' => $this->string('credit_card_type'),
|
||||
'cc_monthly_payment_date' => $this->string('monthly_payment_date'),
|
||||
'notes' => $this->nlString('notes'),
|
||||
'notes' => $this->stringWithNewlines('notes'),
|
||||
'interest' => $this->string('interest'),
|
||||
'interest_period' => $this->string('interest_period'),
|
||||
];
|
||||
// append Location information.
|
||||
$data = $this->appendLocationData($data, null);
|
||||
|
||||
if ('liability' === $data['account_type'] || 'liabilities' === $data['account_type']) {
|
||||
if ('liability' === $data['account_type_name'] || 'liabilities' === $data['account_type_name']) {
|
||||
$data['opening_balance'] = bcmul($this->string('liability_amount'), '-1');
|
||||
$data['opening_balance_date'] = $this->date('liability_start_date');
|
||||
$data['account_type'] = $this->string('liability_type');
|
||||
$data['account_type_name'] = $this->string('liability_type');
|
||||
$data['account_type_id'] = null;
|
||||
}
|
||||
|
||||
|
@@ -51,7 +51,7 @@ class UpdateRequest extends FormRequest
|
||||
'name' => ['name', 'string'],
|
||||
'active' => ['active', 'boolean'],
|
||||
'include_net_worth' => ['include_net_worth', 'boolean'],
|
||||
'account_type' => ['type', 'string'],
|
||||
'account_type_name' => ['type', 'string'],
|
||||
'virtual_balance' => ['virtual_balance', 'string'],
|
||||
'iban' => ['iban', 'string'],
|
||||
'BIC' => ['bic', 'string'],
|
||||
@@ -62,7 +62,7 @@ class UpdateRequest extends FormRequest
|
||||
'opening_balance_date' => ['opening_balance_date', 'date'],
|
||||
'cc_type' => ['credit_card_type', 'string'],
|
||||
'cc_monthly_payment_date' => ['monthly_payment_date', 'string'],
|
||||
'notes' => ['notes', 'nlString'],
|
||||
'notes' => ['notes', 'stringWithNewlines'],
|
||||
'interest' => ['interest', 'string'],
|
||||
'interest_period' => ['interest_period', 'string'],
|
||||
'order' => ['order', 'integer'],
|
||||
@@ -72,10 +72,10 @@ class UpdateRequest extends FormRequest
|
||||
$data = $this->getAllData($fields);
|
||||
$data = $this->appendLocationData($data, null);
|
||||
|
||||
if (array_key_exists('account_type', $data) && 'liability' === $data['account_type']) {
|
||||
$data['opening_balance'] = bcmul($this->nullableString('liability_amount'), '-1');
|
||||
if (array_key_exists('account_type_name', $data) && 'liability' === $data['account_type_name']) {
|
||||
$data['opening_balance'] = bcmul($this->string('liability_amount'), '-1');
|
||||
$data['opening_balance_date'] = $this->date('liability_start_date');
|
||||
$data['account_type'] = $this->nullableString('liability_type');
|
||||
$data['account_type_name'] = $this->string('liability_type');
|
||||
$data['account_type_id'] = null;
|
||||
}
|
||||
|
||||
@@ -97,9 +97,9 @@ class UpdateRequest extends FormRequest
|
||||
$rules = [
|
||||
'name' => sprintf('min:1|uniqueAccountForUser:%d', $account->id),
|
||||
'type' => sprintf('in:%s', $types),
|
||||
'iban' => ['iban', 'nullable', new UniqueIban($account, $this->nullableString('type'))],
|
||||
'iban' => ['iban', 'nullable', new UniqueIban($account, $this->string('type'))],
|
||||
'bic' => 'bic|nullable',
|
||||
'account_number' => ['between:1,255', 'nullable', new UniqueAccountNumber($account, $this->nullableString('type'))],
|
||||
'account_number' => ['between:1,255', 'nullable', new UniqueAccountNumber($account, $this->string('type'))],
|
||||
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
|
||||
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
|
||||
'virtual_balance' => 'numeric|nullable',
|
||||
|
@@ -47,7 +47,7 @@ class StoreRequest extends FormRequest
|
||||
return [
|
||||
'filename' => $this->string('filename'),
|
||||
'title' => $this->string('title'),
|
||||
'notes' => $this->nlString('notes'),
|
||||
'notes' => $this->stringWithNewlines('notes'),
|
||||
'attachable_type' => $this->string('attachable_type'),
|
||||
'attachable_id' => $this->integer('attachable_id'),
|
||||
];
|
||||
|
@@ -47,7 +47,7 @@ class UpdateRequest extends FormRequest
|
||||
$fields = [
|
||||
'filename' => ['filename', 'string'],
|
||||
'title' => ['title', 'string'],
|
||||
'notes' => ['notes', 'nlString'],
|
||||
'notes' => ['notes', 'stringWithNewlines'],
|
||||
'attachable_type' => ['attachable_type', 'string'],
|
||||
'attachable_id' => ['attachable_id', 'integer'],
|
||||
];
|
||||
|
@@ -59,7 +59,7 @@ class StoreRequest extends FormRequest
|
||||
'skip' => ['skip', 'integer'],
|
||||
'active' => ['active', 'boolean'],
|
||||
'order' => ['order', 'integer'],
|
||||
'notes' => ['notes', 'nlString'],
|
||||
'notes' => ['notes', 'stringWithNewlines'],
|
||||
'object_group_id' => ['object_group_id', 'integer'],
|
||||
'object_group_title' => ['object_group_title', 'string'],
|
||||
];
|
||||
|
@@ -57,7 +57,7 @@ class UpdateRequest extends FormRequest
|
||||
'skip' => ['skip', 'integer'],
|
||||
'active' => ['active', 'boolean'],
|
||||
'order' => ['order', 'integer'],
|
||||
'notes' => ['notes', 'nlString'],
|
||||
'notes' => ['notes', 'stringWithNewlines'],
|
||||
'object_group_id' => ['object_group_id', 'integer'],
|
||||
'object_group_title' => ['object_group_title', 'string'],
|
||||
];
|
||||
|
@@ -76,8 +76,8 @@ class StoreRequest extends FormRequest
|
||||
'currency_code' => 'exists:transaction_currencies,code',
|
||||
// auto budget info
|
||||
'auto_budget_type' => 'in:reset,rollover,none',
|
||||
'auto_budget_amount' => 'min:0|max:1000000000',
|
||||
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly',
|
||||
'auto_budget_amount' => 'numeric|min:0|max:1000000000|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover',
|
||||
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover',
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -47,7 +47,7 @@ class UpdateRequest extends FormRequest
|
||||
public function getAll(): array
|
||||
{
|
||||
// this is the way:
|
||||
$fields = [
|
||||
$fields = [
|
||||
'name' => ['name', 'string'],
|
||||
'active' => ['active', 'boolean'],
|
||||
'order' => ['order', 'integer'],
|
||||
@@ -57,8 +57,17 @@ class UpdateRequest extends FormRequest
|
||||
'auto_budget_amount' => ['auto_budget_amount', 'string'],
|
||||
'auto_budget_period' => ['auto_budget_period', 'string'],
|
||||
];
|
||||
$allData = $this->getAllData($fields);
|
||||
if (array_key_exists('auto_budget_type', $allData)) {
|
||||
$types = [
|
||||
'none' => 0,
|
||||
'reset' => 1,
|
||||
'rollover' => 2,
|
||||
];
|
||||
$allData['auto_budget_type'] = $types[$allData['auto_budget_type']] ?? 0;
|
||||
}
|
||||
|
||||
return $this->getAllData($fields);
|
||||
return $allData;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,7 +78,6 @@ class UpdateRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
$budget = $this->route()->parameter('budget');
|
||||
|
||||
return [
|
||||
'name' => sprintf('between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id),
|
||||
'active' => [new IsBoolean],
|
||||
|
@@ -46,7 +46,7 @@ class StoreRequest extends FormRequest
|
||||
{
|
||||
return [
|
||||
'name' => $this->string('name'),
|
||||
'notes' => $this->nlString('notes'),
|
||||
'notes' => $this->stringWithNewlines('notes'),
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -45,7 +45,7 @@ class UpdateRequest extends FormRequest
|
||||
{
|
||||
$fields = [
|
||||
'name' => ['name', 'string'],
|
||||
'notes' => ['notes', 'nlString'],
|
||||
'notes' => ['notes', 'stringWithNewlines'],
|
||||
];
|
||||
|
||||
return $this->getAllData($fields);
|
||||
|
@@ -53,7 +53,7 @@ class StoreRequest extends FormRequest
|
||||
$data['current_amount'] = $this->string('current_amount');
|
||||
$data['startdate'] = $this->date('start_date');
|
||||
$data['targetdate'] = $this->date('target_date');
|
||||
$data['notes'] = $this->nlString('notes');
|
||||
$data['notes'] = $this->stringWithNewlines('notes');
|
||||
$data['object_group_id'] = $this->integer('object_group_id');
|
||||
$data['object_group_title'] = $this->string('object_group_title');
|
||||
|
||||
|
@@ -52,7 +52,7 @@ class UpdateRequest extends FormRequest
|
||||
'current_amount' => ['current_amount', 'string'],
|
||||
'startdate' => ['start_date', 'date'],
|
||||
'targetdate' => ['target_date', 'string'],
|
||||
'notes' => ['notes', 'nlString'],
|
||||
'notes' => ['notes', 'stringWithNewlines'],
|
||||
'order' => ['order', 'integer'],
|
||||
'object_group_title' => ['object_group_title', 'string'],
|
||||
'object_group_id' => ['object_group_id', 'integer'],
|
||||
|
@@ -58,7 +58,7 @@ class StoreRequest extends FormRequest
|
||||
'nr_of_repetitions' => ['nr_of_repetitions', 'integer'],
|
||||
'apply_rules' => ['apply_rules', 'boolean'],
|
||||
'active' => ['active', 'boolean'],
|
||||
'notes' => ['notes', 'nlString'],
|
||||
'notes' => ['notes', 'stringWithNewlines'],
|
||||
];
|
||||
$recurrence = $this->getAllData($fields);
|
||||
|
||||
@@ -79,7 +79,7 @@ class StoreRequest extends FormRequest
|
||||
{
|
||||
$return = [];
|
||||
// transaction data:
|
||||
/** @var array $transactions */
|
||||
/** @var array|null $transactions */
|
||||
$transactions = $this->get('transactions');
|
||||
if (null === $transactions) {
|
||||
return [];
|
||||
@@ -101,7 +101,7 @@ class StoreRequest extends FormRequest
|
||||
{
|
||||
$return = [];
|
||||
// repetition data:
|
||||
/** @var array $repetitions */
|
||||
/** @var array|null $repetitions */
|
||||
$repetitions = $this->get('repetitions');
|
||||
if (null === $repetitions) {
|
||||
return [];
|
||||
|
@@ -84,7 +84,7 @@ class UpdateRequest extends FormRequest
|
||||
{
|
||||
$return = [];
|
||||
// repetition data:
|
||||
/** @var array $repetitions */
|
||||
/** @var array|null $repetitions */
|
||||
$repetitions = $this->get('repetitions');
|
||||
if (null === $repetitions) {
|
||||
return null;
|
||||
@@ -126,7 +126,7 @@ class UpdateRequest extends FormRequest
|
||||
{
|
||||
$return = [];
|
||||
// transaction data:
|
||||
/** @var array $transactions */
|
||||
/** @var array|null $transactions */
|
||||
$transactions = $this->get('transactions');
|
||||
if (null === $transactions) {
|
||||
return null;
|
||||
|
@@ -47,7 +47,7 @@ class UpdateRequest extends FormRequest
|
||||
{
|
||||
$fields = [
|
||||
'title' => ['title', 'string'],
|
||||
'description' => ['description', 'nlString'],
|
||||
'description' => ['description', 'stringWithNewlines'],
|
||||
'rule_group_id' => ['rule_group_id', 'integer'],
|
||||
'trigger' => ['trigger', 'string'],
|
||||
'strict' => ['strict', 'boolean'],
|
||||
|
@@ -46,7 +46,7 @@ class UpdateRequest extends FormRequest
|
||||
// This is the way.
|
||||
$fields = [
|
||||
'title' => ['title', 'string'],
|
||||
'description' => ['description', 'nlString'],
|
||||
'description' => ['description', 'stringWithNewlines'],
|
||||
'active' => ['active', 'boolean'],
|
||||
'order' => ['order', 'integer'],
|
||||
];
|
||||
|
@@ -78,75 +78,75 @@ class StoreRequest extends FormRequest
|
||||
foreach ($this->get('transactions') as $transaction) {
|
||||
$object = new NullArrayObject($transaction);
|
||||
$return[] = [
|
||||
'type' => $this->stringFromValue($object['type']),
|
||||
'type' => $this->clearString($object['type'], false),
|
||||
'date' => $this->dateFromValue($object['date']),
|
||||
'order' => $this->integerFromValue((string)$object['order']),
|
||||
|
||||
'currency_id' => $this->integerFromValue((string)$object['currency_id']),
|
||||
'currency_code' => $this->stringFromValue($object['currency_code']),
|
||||
'currency_code' => $this->clearString((string)$object['currency_code'], false),
|
||||
|
||||
// foreign currency info:
|
||||
'foreign_currency_id' => $this->integerFromValue((string)$object['foreign_currency_id']),
|
||||
'foreign_currency_code' => $this->stringFromValue((string)$object['foreign_currency_code']),
|
||||
'foreign_currency_code' => $this->clearString((string)$object['foreign_currency_code'], false),
|
||||
|
||||
// amount and foreign amount. Cannot be 0.
|
||||
'amount' => $this->stringFromValue((string)$object['amount']),
|
||||
'foreign_amount' => $this->stringFromValue((string)$object['foreign_amount']),
|
||||
'amount' => $this->clearString((string)$object['amount'], false),
|
||||
'foreign_amount' => $this->clearString((string)$object['foreign_amount'], false),
|
||||
|
||||
// description.
|
||||
'description' => $this->stringFromValue($object['description']),
|
||||
'description' => $this->clearString($object['description'], false),
|
||||
|
||||
// source of transaction. If everything is null, assume cash account.
|
||||
'source_id' => $this->integerFromValue((string)$object['source_id']),
|
||||
'source_name' => $this->stringFromValue((string)$object['source_name']),
|
||||
'source_iban' => $this->stringFromValue((string)$object['source_iban']),
|
||||
'source_number' => $this->stringFromValue((string)$object['source_number']),
|
||||
'source_bic' => $this->stringFromValue((string)$object['source_bic']),
|
||||
'source_name' => $this->clearString($object['source_name'], false),
|
||||
'source_iban' => $this->clearString($object['source_iban'], false),
|
||||
'source_number' => $this->clearString($object['source_number'], false),
|
||||
'source_bic' => $this->clearString($object['source_bic'], false),
|
||||
|
||||
// destination of transaction. If everything is null, assume cash account.
|
||||
'destination_id' => $this->integerFromValue((string)$object['destination_id']),
|
||||
'destination_name' => $this->stringFromValue((string)$object['destination_name']),
|
||||
'destination_iban' => $this->stringFromValue((string)$object['destination_iban']),
|
||||
'destination_number' => $this->stringFromValue((string)$object['destination_number']),
|
||||
'destination_bic' => $this->stringFromValue((string)$object['destination_bic']),
|
||||
'destination_name' => $this->clearString($object['destination_name'], false),
|
||||
'destination_iban' => $this->clearString($object['destination_iban'], false),
|
||||
'destination_number' => $this->clearString($object['destination_number'], false),
|
||||
'destination_bic' => $this->clearString($object['destination_bic'], false),
|
||||
|
||||
// budget info
|
||||
'budget_id' => $this->integerFromValue((string)$object['budget_id']),
|
||||
'budget_name' => $this->stringFromValue((string)$object['budget_name']),
|
||||
'budget_name' => $this->clearString((string)$object['budget_name'], false),
|
||||
|
||||
// category info
|
||||
'category_id' => $this->integerFromValue((string)$object['category_id']),
|
||||
'category_name' => $this->stringFromValue((string)$object['category_name']),
|
||||
'category_name' => $this->clearString((string)$object['category_name'], false),
|
||||
|
||||
// journal bill reference. Optional. Will only work for withdrawals
|
||||
'bill_id' => $this->integerFromValue((string)$object['bill_id']),
|
||||
'bill_name' => $this->stringFromValue((string)$object['bill_name']),
|
||||
'bill_name' => $this->clearString((string)$object['bill_name'], false),
|
||||
|
||||
// piggy bank reference. Optional. Will only work for transfers
|
||||
'piggy_bank_id' => $this->integerFromValue((string)$object['piggy_bank_id']),
|
||||
'piggy_bank_name' => $this->stringFromValue((string)$object['piggy_bank_name']),
|
||||
'piggy_bank_name' => $this->clearString((string)$object['piggy_bank_name'], false),
|
||||
|
||||
// some other interesting properties
|
||||
'reconciled' => $this->convertBoolean((string)$object['reconciled']),
|
||||
'notes' => $this->nlStringFromValue((string)$object['notes']),
|
||||
'notes' => $this->clearString((string)$object['notes']),
|
||||
'tags' => $this->arrayFromValue($object['tags']),
|
||||
|
||||
// all custom fields:
|
||||
'internal_reference' => $this->stringFromValue((string)$object['internal_reference']),
|
||||
'external_id' => $this->stringFromValue((string)$object['external_id']),
|
||||
'internal_reference' => $this->clearString((string)$object['internal_reference'], false),
|
||||
'external_id' => $this->clearString((string)$object['external_id'], false),
|
||||
'original_source' => sprintf('ff3-v%s|api-v%s', config('firefly.version'), config('firefly.api_version')),
|
||||
'recurrence_id' => $this->integerFromValue($object['recurrence_id']),
|
||||
'bunq_payment_id' => $this->stringFromValue((string)$object['bunq_payment_id']),
|
||||
'external_uri' => $this->stringFromValue((string)$object['external_uri']),
|
||||
'bunq_payment_id' => $this->clearString((string)$object['bunq_payment_id'], false),
|
||||
'external_uri' => $this->clearString((string)$object['external_uri'], false),
|
||||
|
||||
'sepa_cc' => $this->stringFromValue($object['sepa_cc']),
|
||||
'sepa_ct_op' => $this->stringFromValue($object['sepa_ct_op']),
|
||||
'sepa_ct_id' => $this->stringFromValue($object['sepa_ct_id']),
|
||||
'sepa_db' => $this->stringFromValue($object['sepa_db']),
|
||||
'sepa_country' => $this->stringFromValue($object['sepa_country']),
|
||||
'sepa_ep' => $this->stringFromValue($object['sepa_ep']),
|
||||
'sepa_ci' => $this->stringFromValue($object['sepa_ci']),
|
||||
'sepa_batch_id' => $this->stringFromValue($object['sepa_batch_id']),
|
||||
'sepa_cc' => $this->clearString((string)$object['sepa_cc'], false),
|
||||
'sepa_ct_op' => $this->clearString((string)$object['sepa_ct_op'], false),
|
||||
'sepa_ct_id' => $this->clearString((string)$object['sepa_ct_id'], false),
|
||||
'sepa_db' => $this->clearString((string)$object['sepa_db'], false),
|
||||
'sepa_country' => $this->clearString((string)$object['sepa_country'], false),
|
||||
'sepa_ep' => $this->clearString((string)$object['sepa_ep'], false),
|
||||
'sepa_ci' => $this->clearString((string)$object['sepa_ci'], false),
|
||||
'sepa_batch_id' => $this->clearString((string)$object['sepa_batch_id'], false),
|
||||
// custom date fields. Must be Carbon objects. Presence is optional.
|
||||
'interest_date' => $this->dateFromValue($object['interest_date']),
|
||||
'book_date' => $this->dateFromValue($object['book_date']),
|
||||
|
@@ -150,10 +150,7 @@ class UpdateRequest extends FormRequest
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var int $index
|
||||
* @var array $transaction
|
||||
*/
|
||||
/** @var array $transaction */
|
||||
foreach ($this->get('transactions') as $transaction) {
|
||||
// default response is to update nothing in the transaction:
|
||||
$current = [];
|
||||
@@ -197,7 +194,7 @@ class UpdateRequest extends FormRequest
|
||||
{
|
||||
foreach ($this->stringFields as $fieldName) {
|
||||
if (array_key_exists($fieldName, $transaction)) {
|
||||
$current[$fieldName] = $this->stringFromValue((string)$transaction[$fieldName]);
|
||||
$current[$fieldName] = $this->clearString((string)$transaction[$fieldName], false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +211,7 @@ class UpdateRequest extends FormRequest
|
||||
{
|
||||
foreach ($this->textareaFields as $fieldName) {
|
||||
if (array_key_exists($fieldName, $transaction)) {
|
||||
$current[$fieldName] = $this->nlStringFromValue((string)$transaction[$fieldName]);
|
||||
$current[$fieldName] = $this->clearString((string)$transaction[$fieldName]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -50,7 +50,7 @@ class StoreRequest extends FormRequest
|
||||
'link_type_name' => $this->string('link_type_name'),
|
||||
'inward_id' => $this->integer('inward_id'),
|
||||
'outward_id' => $this->integer('outward_id'),
|
||||
'notes' => $this->nlString('notes'),
|
||||
'notes' => $this->stringWithNewlines('notes'),
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -50,7 +50,7 @@ class UpdateRequest extends FormRequest
|
||||
'link_type_name' => $this->string('link_type_name'),
|
||||
'inward_id' => $this->integer('inward_id'),
|
||||
'outward_id' => $this->integer('outward_id'),
|
||||
'notes' => $this->nullableNlString('notes'),
|
||||
'notes' => $this->stringWithNewlines('notes'),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -117,12 +117,6 @@ class UpdateRequest extends FormRequest
|
||||
$validator->errors()->add('outward_id', 'Inward ID must be different from outward ID.');
|
||||
}
|
||||
|
||||
if (null === $inward) {
|
||||
$validator->errors()->add('inward_id', 'This is not a valid inward journal.');
|
||||
}
|
||||
if (null === $outward) {
|
||||
$validator->errors()->add('inward_id', 'This is not a valid outward journal.');
|
||||
}
|
||||
$inDB = $repository->findSpecificLink($existing->linkType, $inward, $outward);
|
||||
if (null === $inDB) {
|
||||
return;
|
||||
|
@@ -57,7 +57,7 @@ class UpdateRequest extends FormRequest
|
||||
return ['value' => $this->integer('value')];
|
||||
}
|
||||
|
||||
return ['value' => $this->string('value')]; // @codeCoverageIgnore
|
||||
return ['value' => $this->string('value')];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,6 +80,6 @@ class UpdateRequest extends FormRequest
|
||||
return ['value' => 'required|numeric|min:464272080'];
|
||||
}
|
||||
|
||||
return ['value' => 'required']; // @codeCoverageIgnore
|
||||
return ['value' => 'required'];
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* PreferenceStoreRequest.php
|
||||
|
@@ -76,6 +76,7 @@ class CorrectDatabase extends Command
|
||||
'firefly-iii:fix-recurring-transactions',
|
||||
'firefly-iii:restore-oauth-keys',
|
||||
'firefly-iii:fix-transaction-types',
|
||||
'firefly-iii:fix-frontpage-accounts'
|
||||
];
|
||||
foreach ($commands as $command) {
|
||||
$this->line(sprintf('Now executing %s', $command));
|
||||
|
@@ -71,17 +71,18 @@ class DeleteEmptyJournals extends Command
|
||||
->groupBy('transactions.transaction_journal_id')
|
||||
->get([DB::raw('COUNT(transactions.transaction_journal_id) as the_count'), 'transaction_journal_id']);
|
||||
$total = 0;
|
||||
/** @var Transaction $row */
|
||||
foreach ($set as $row) {
|
||||
$count = (int)$row->the_count;
|
||||
if (1 === $count % 2) {
|
||||
// uneven number, delete journal and transactions:
|
||||
try {
|
||||
TransactionJournal::find((int)$row->transaction_journal_id)->delete();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
|
||||
} catch (Exception $e) { // @phpstan-ignore-line
|
||||
Log::info(sprintf('Could not delete journal: %s', $e->getMessage()));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
|
||||
Transaction::where('transaction_journal_id', (int)$row->transaction_journal_id)->delete();
|
||||
$this->info(sprintf('Deleted transaction journal #%d because it had an uneven number of transactions.', $row->transaction_journal_id));
|
||||
@@ -105,11 +106,11 @@ class DeleteEmptyJournals extends Command
|
||||
foreach ($set as $entry) {
|
||||
try {
|
||||
TransactionJournal::find($entry->id)->delete();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
|
||||
} catch (Exception $e) { // @phpstan-ignore-line
|
||||
Log::info(sprintf('Could not delete entry: %s', $e->getMessage()));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
|
||||
$this->info(sprintf('Deleted empty transaction journal #%d', $entry->id));
|
||||
++$count;
|
||||
|
@@ -118,11 +118,11 @@ class DeleteOrphanedTransactions extends Command
|
||||
if ($journal) {
|
||||
try {
|
||||
$journal->delete();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
|
||||
} catch (Exception $e) { // @phpstan-ignore-line
|
||||
Log::info(sprintf('Could not delete journal %s', $e->getMessage()));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
}
|
||||
Transaction::where('transaction_journal_id', (int)$transaction->transaction_journal_id)->delete();
|
||||
$this->line(
|
||||
|
@@ -64,11 +64,11 @@ class DeleteZeroAmount extends Command
|
||||
$this->info(sprintf('Deleted transaction journal #%d because the amount is zero (0.00).', $journal->id));
|
||||
try {
|
||||
$journal->delete();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
|
||||
} catch (Exception $e) { // @phpstan-ignore-line
|
||||
$this->line($e->getMessage());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
Transaction::where('transaction_journal_id', $journal->id)->delete();
|
||||
}
|
||||
if (0 === $journals->count()) {
|
||||
|
@@ -121,12 +121,12 @@ class FixAccountTypes extends Command
|
||||
$destAccountType = $destAccount->accountType->type;
|
||||
|
||||
if (!array_key_exists($type, $this->expected)) {
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
Log::info(sprintf('No source/destination info for transaction type %s.', $type));
|
||||
$this->info(sprintf('No source/destination info for transaction type %s.', $type));
|
||||
|
||||
return;
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
}
|
||||
if (!array_key_exists($sourceAccountType, $this->expected[$type])) {
|
||||
Log::debug(sprintf('Going to fix journal #%d', $journal->id));
|
||||
|
106
app/Console/Commands/Correction/FixFrontpageAccounts.php
Normal file
106
app/Console/Commands/Correction/FixFrontpageAccounts.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* FixFrontpageAccounts.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\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Facades\Preferences;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class FixFrontpageAccounts
|
||||
*/
|
||||
class FixFrontpageAccounts extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Fixes a preference that may include deleted accounts or accounts of another type.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-frontpage-accounts';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
|
||||
$users = User::get();
|
||||
/** @var User $user */
|
||||
foreach ($users as $user) {
|
||||
$preference = Preferences::getForUser($user, 'frontPageAccounts', null);
|
||||
if (null !== $preference) {
|
||||
$this->fixPreference($preference);
|
||||
}
|
||||
}
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verifying account preferences took %s seconds', $end));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Preference $preference
|
||||
*/
|
||||
private function fixPreference(Preference $preference): void
|
||||
{
|
||||
$fixed = [];
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
if (null === $preference->user) {
|
||||
return;
|
||||
}
|
||||
$repository->setUser($preference->user);
|
||||
$data = $preference->data;
|
||||
if (is_array($data)) {
|
||||
/** @var string $accountId */
|
||||
foreach ($data as $accountId) {
|
||||
$accountId = (int)$accountId;
|
||||
$account = $repository->findNull($accountId);
|
||||
if (null !== $account) {
|
||||
if (
|
||||
in_array($account->accountType->type, [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE], true)
|
||||
&& true === $account->active
|
||||
) {
|
||||
$fixed[] = $account->id;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Preferences::setForUser($preference->user, 'frontPageAccounts', $fixed);
|
||||
}
|
||||
}
|
@@ -60,6 +60,7 @@ class FixGroupAccounts extends Command
|
||||
$res = TransactionJournal
|
||||
::groupBy('transaction_group_id')
|
||||
->get(['transaction_group_id', DB::raw('COUNT(transaction_group_id) as the_count')]);
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($res as $journal) {
|
||||
if ((int)$journal->the_count > 1) {
|
||||
$groups[] = (int)$journal->transaction_group_id;
|
||||
|
@@ -70,14 +70,14 @@ class FixPiggies extends Command
|
||||
}
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = $event->transactionJournal;
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
if (null === $journal) {
|
||||
$event->transaction_journal_id = null;
|
||||
$event->save();
|
||||
$this->count++;
|
||||
continue;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
|
||||
$type = $journal->transactionType->type;
|
||||
if (TransactionType::TRANSFER !== $type) {
|
||||
|
132
app/Console/Commands/Correction/FixPostgresSequences.php
Normal file
132
app/Console/Commands/Correction/FixPostgresSequences.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use DB;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class FixPostgresSequences
|
||||
*/
|
||||
class FixPostgresSequences extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Fixes issues with PostgreSQL sequences.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-pgsql-sequences';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
|
||||
if (DB::connection()->getName() !== 'pgsql') {
|
||||
$this->info('Command executed successfully.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
$this->line('Going to verify PostgreSQL table sequences.');
|
||||
$tablesToCheck = [
|
||||
'2fa_tokens',
|
||||
'account_meta',
|
||||
'account_types',
|
||||
'accounts',
|
||||
'attachments',
|
||||
'auto_budgets',
|
||||
'available_budgets',
|
||||
'bills',
|
||||
'budget_limits',
|
||||
'budget_transaction',
|
||||
'budget_transaction_journal',
|
||||
'budgets',
|
||||
'categories',
|
||||
'category_transaction',
|
||||
'category_transaction_journal',
|
||||
'configuration',
|
||||
'currency_exchange_rates',
|
||||
'export_jobs',
|
||||
'failed_jobs',
|
||||
'group_journals',
|
||||
'import_jobs',
|
||||
'jobs',
|
||||
'journal_links',
|
||||
'journal_meta',
|
||||
'limit_repetitions',
|
||||
'link_types',
|
||||
'locations',
|
||||
'migrations',
|
||||
'notes',
|
||||
'oauth_clients',
|
||||
'oauth_personal_access_clients',
|
||||
'object_groups',
|
||||
'permissions',
|
||||
'piggy_bank_events',
|
||||
'piggy_bank_repetitions',
|
||||
'piggy_banks',
|
||||
'preferences',
|
||||
'recurrences',
|
||||
'recurrences_meta',
|
||||
'recurrences_repetitions',
|
||||
'recurrences_transactions',
|
||||
'roles',
|
||||
'rt_meta',
|
||||
'rule_actions',
|
||||
'rule_groups',
|
||||
'rule_triggers',
|
||||
'rules',
|
||||
'tag_transaction_journal',
|
||||
'tags',
|
||||
'telemetry',
|
||||
'transaction_currencies',
|
||||
'transaction_groups',
|
||||
'transaction_journals',
|
||||
'transaction_types',
|
||||
'transactions',
|
||||
'users',
|
||||
'webhook_attempts',
|
||||
'webhook_messages',
|
||||
'webhooks',
|
||||
];
|
||||
|
||||
foreach ($tablesToCheck as $tableToCheck) {
|
||||
$this->info(sprintf('Checking the next id sequence for table "%s".', $tableToCheck));
|
||||
|
||||
$highestId = DB::table($tableToCheck)->select(DB::raw('MAX(id)'))->first();
|
||||
$nextId = DB::table($tableToCheck)->select(DB::raw(sprintf('nextval(\'%s_id_seq\')', $tableToCheck)))->first();
|
||||
if(null === $nextId) {
|
||||
$this->line(sprintf('nextval is NULL for table "%s", go to next table.', $tableToCheck));
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($nextId->nextval < $highestId->max) {
|
||||
DB::select(sprintf('SELECT setval(\'%s_id_seq\', %d)', $tableToCheck, $highestId->max));
|
||||
$highestId = DB::table($tableToCheck)->select(DB::raw('MAX(id)'))->first();
|
||||
$nextId = DB::table($tableToCheck)->select(DB::raw(sprintf('nextval(\'%s_id_seq\')', $tableToCheck)))->first();
|
||||
if ($nextId->nextval > $highestId->max) {
|
||||
$this->info(sprintf('Table "%s" autoincrement corrected.', $tableToCheck));
|
||||
}
|
||||
if ($nextId->nextval <= $highestId->max) {
|
||||
$this->warn(sprintf('Arff! The nextval sequence is still all screwed up on table "%s".', $tableToCheck));
|
||||
}
|
||||
}
|
||||
if ($nextId->nextval >= $highestId->max) {
|
||||
$this->info(sprintf('Table "%s" autoincrement is correct.', $tableToCheck));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
@@ -91,7 +91,7 @@ class FixUnevenAmount extends Command
|
||||
// one of the transactions is bad.
|
||||
$journal = TransactionJournal::find($param);
|
||||
if (!$journal) {
|
||||
return; // @codeCoverageIgnore
|
||||
return;
|
||||
}
|
||||
/** @var Transaction $source */
|
||||
$source = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
|
@@ -177,7 +177,7 @@ class DecryptDatabase extends Command
|
||||
/**
|
||||
* Tries to decrypt data. Will only throw an exception when the MAC is invalid.
|
||||
*
|
||||
* @param $value
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
@@ -188,7 +188,7 @@ class DecryptDatabase extends Command
|
||||
$value = Crypt::decrypt($value);
|
||||
} catch (DecryptException $e) {
|
||||
if ('The MAC is invalid.' === $e->getMessage()) {
|
||||
throw new FireflyException($e->getMessage()); // @codeCoverageIgnore
|
||||
throw new FireflyException($e->getMessage(), 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -28,6 +28,7 @@ use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Console\Commands\VerifiesAccessToken;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
@@ -124,11 +125,11 @@ class ExportData extends Command
|
||||
$exporter->setExportBills($options['export']['bills']);
|
||||
$exporter->setExportPiggies($options['export']['piggies']);
|
||||
$data = $exporter->export();
|
||||
if (empty($data)) {
|
||||
if (0 === count($data)) {
|
||||
$this->error('You must export *something*. Use --export-transactions or another option. See docs.firefly-iii.org');
|
||||
}
|
||||
$returnCode = 0;
|
||||
if (!empty($data)) {
|
||||
if (0 !== count($data)) {
|
||||
try {
|
||||
$this->exportData($options, $data);
|
||||
app('telemetry')->feature('system.command.executed', $this->signature);
|
||||
@@ -199,24 +200,27 @@ class ExportData extends Command
|
||||
$error = false;
|
||||
if (null !== $this->option($field)) {
|
||||
try {
|
||||
$date = Carbon::createFromFormat('Y-m-d', $this->option($field));
|
||||
$date = Carbon::createFromFormat('!Y-m-d', $this->option($field));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Log::error($e->getMessage());
|
||||
$this->error(sprintf('%s date "%s" must be formatted YYYY-MM-DD. Field will be ignored.', $field, $this->option('start')));
|
||||
$error = true;
|
||||
}
|
||||
}
|
||||
if (false === $error && 'start' === $field) {
|
||||
|
||||
if (true === $error && 'start' === $field) {
|
||||
$journal = $this->journalRepository->firstNull();
|
||||
$date = null === $journal ? Carbon::now()->subYear() : $journal->date;
|
||||
$date->startOfDay();
|
||||
}
|
||||
if (false === $error && 'end' === $field) {
|
||||
if (true === $error && 'end' === $field) {
|
||||
$date = today(config('app.timezone'));
|
||||
$date->endOfDay();
|
||||
}
|
||||
if ('end' === $field) {
|
||||
$date->endOfDay();
|
||||
}
|
||||
|
||||
// fallback
|
||||
return $date;
|
||||
}
|
||||
|
||||
@@ -238,7 +242,7 @@ class ExportData extends Command
|
||||
$accounts = $this->accountRepository->getAccountsByType($types);
|
||||
}
|
||||
// filter accounts,
|
||||
/** @var AccountType $account */
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
if (in_array($account->accountType->type, $types, true)) {
|
||||
$final->push($account);
|
||||
|
@@ -214,14 +214,6 @@ class ApplyRules extends Command
|
||||
$finalList = new Collection;
|
||||
$accountList = explode(',', $accountString);
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if (0 === count($accountList)) {
|
||||
$this->error('Please use the --accounts option to indicate the accounts to apply rules to.');
|
||||
|
||||
return false;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$accountRepository->setUser($this->getUser());
|
||||
@@ -255,12 +247,7 @@ class ApplyRules extends Command
|
||||
return true;
|
||||
}
|
||||
$ruleGroupList = explode(',', $ruleGroupString);
|
||||
// @codeCoverageIgnoreStart
|
||||
if (0 === count($ruleGroupList)) {
|
||||
// can be empty.
|
||||
return true;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
foreach ($ruleGroupList as $ruleGroupId) {
|
||||
$ruleGroup = $this->ruleGroupRepository->find((int)$ruleGroupId);
|
||||
if ($ruleGroup->active) {
|
||||
@@ -286,14 +273,6 @@ class ApplyRules extends Command
|
||||
}
|
||||
$ruleList = explode(',', $ruleString);
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if (0 === count($ruleList)) {
|
||||
// can be empty.
|
||||
|
||||
return true;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
foreach ($ruleList as $ruleId) {
|
||||
$rule = $this->ruleRepository->find((int)$ruleId);
|
||||
if (null !== $rule && $rule->active) {
|
||||
|
@@ -65,9 +65,8 @@ class Cron extends Command
|
||||
$date = null;
|
||||
try {
|
||||
$date = new Carbon($this->option('date'));
|
||||
} catch (InvalidArgumentException | Exception $e) {
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$this->error(sprintf('"%s" is not a valid date', $this->option('date')));
|
||||
$e->getMessage();
|
||||
}
|
||||
$force = (bool)$this->option('force');
|
||||
|
||||
@@ -127,13 +126,15 @@ class Cron extends Command
|
||||
$recurring->setDate($date);
|
||||
}
|
||||
|
||||
$result = $recurring->fire();
|
||||
|
||||
if (false === $result) {
|
||||
$this->line('The recurring transaction cron job did not fire.');
|
||||
$recurring->fire();
|
||||
if($recurring->jobErrored) {
|
||||
$this->error(sprintf('Error in "create recurring transactions" cron: %s', $recurring->message));
|
||||
}
|
||||
if (true === $result) {
|
||||
$this->line('The recurring transaction cron job fired successfully.');
|
||||
if($recurring->jobFired) {
|
||||
$this->error(sprintf('"Create recurring transactions" cron fired: %s', $recurring->message));
|
||||
}
|
||||
if($recurring->jobSucceeded) {
|
||||
$this->error(sprintf('"Create recurring transactions" cron ran with success: %s', $recurring->message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +143,6 @@ class Cron extends Command
|
||||
* @param Carbon|null $date
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws Exception
|
||||
*/
|
||||
private function autoBudgetCronJob(bool $force, ?Carbon $date): void
|
||||
{
|
||||
@@ -153,13 +153,16 @@ class Cron extends Command
|
||||
$autoBudget->setDate($date);
|
||||
}
|
||||
|
||||
$result = $autoBudget->fire();
|
||||
$autoBudget->fire();
|
||||
|
||||
if (false === $result) {
|
||||
$this->line('The auto budget cron job did not fire.');
|
||||
if($autoBudget->jobErrored) {
|
||||
$this->error(sprintf('Error in "create auto budgets" cron: %s', $autoBudget->message));
|
||||
}
|
||||
if (true === $result) {
|
||||
$this->line('The auto budget cron job fired successfully.');
|
||||
if($autoBudget->jobFired) {
|
||||
$this->error(sprintf('"Create auto budgets" cron fired: %s', $autoBudget->message));
|
||||
}
|
||||
if($autoBudget->jobSucceeded) {
|
||||
$this->error(sprintf('"Create auto budgets" cron ran with success: %s', $autoBudget->message));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -167,6 +170,8 @@ class Cron extends Command
|
||||
/**
|
||||
* @param bool $force
|
||||
* @param Carbon|null $date
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function telemetryCronJob(bool $force, ?Carbon $date): void
|
||||
{
|
||||
@@ -182,13 +187,16 @@ class Cron extends Command
|
||||
$telemetry->setDate($date);
|
||||
}
|
||||
|
||||
$result = $telemetry->fire();
|
||||
$telemetry->fire();
|
||||
|
||||
if (false === $result) {
|
||||
$this->line('The telemetry cron job did not fire.');
|
||||
if($telemetry->jobErrored) {
|
||||
$this->error(sprintf('Error in "send telemetry" cron: %s', $telemetry->message));
|
||||
}
|
||||
if (true === $result) {
|
||||
$this->line('The telemetry cron job fired successfully.');
|
||||
if($telemetry->jobFired) {
|
||||
$this->error(sprintf('"Send telemetry" cron fired: %s', $telemetry->message));
|
||||
}
|
||||
if($telemetry->jobSucceeded) {
|
||||
$this->error(sprintf('"Send telemetry" cron ran with success: %s', $telemetry->message));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -114,7 +114,7 @@ class AccountCurrencies extends Command
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
return false; // @codeCoverageIgnore
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,7 +148,7 @@ class AccountCurrencies extends Command
|
||||
}
|
||||
Log::debug(sprintf('Users currency pref is %s', $defaultCurrencyCode));
|
||||
|
||||
/** @var TransactionCurrency $defaultCurrency */
|
||||
/** @var TransactionCurrency|null $defaultCurrency */
|
||||
$defaultCurrency = TransactionCurrency::where('code', $defaultCurrencyCode)->first();
|
||||
|
||||
if (null === $defaultCurrency) {
|
||||
|
@@ -73,11 +73,8 @@ class AppendBudgetLimitPeriods extends Command
|
||||
private function isExecuted(): bool
|
||||
{
|
||||
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
|
||||
if (null !== $configVar) {
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
return false; // @codeCoverageIgnore
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -58,20 +58,20 @@ class BackToJournals extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
$start = microtime(true);
|
||||
if (!$this->isMigrated()) {
|
||||
$this->error('Please run firefly-iii:migrate-to-groups first.');
|
||||
}
|
||||
if ($this->isExecuted() && true !== $this->option('force')) {
|
||||
$this->info('This command has already been executed.');
|
||||
$this->warn('This command has already been executed.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (true === $this->option('force')) {
|
||||
$this->warn('Forcing the command.');
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
|
||||
$this->migrateAll();
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
@@ -87,11 +87,8 @@ class BackToJournals extends Command
|
||||
private function isMigrated(): bool
|
||||
{
|
||||
$configVar = app('fireflyconfig')->get(MigrateToGroups::CONFIG_NAME, false);
|
||||
if (null !== $configVar) {
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
return false; // @codeCoverageIgnore
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,11 +97,8 @@ class BackToJournals extends Command
|
||||
private function isExecuted(): bool
|
||||
{
|
||||
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
|
||||
if (null !== $configVar) {
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
return false; // @codeCoverageIgnore
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,15 +139,12 @@ class BackToJournals extends Command
|
||||
*/
|
||||
private function getIdsForBudgets(): array
|
||||
{
|
||||
$transactions = DB::table('budget_transaction')->distinct()->get(['transaction_id'])->pluck('transaction_id')->toArray();
|
||||
$transactions = DB::table('budget_transaction')->distinct()->get(['transaction_id'])->pluck('transaction_id')->toArray(); // @phpstan-ignore-line
|
||||
$array = [];
|
||||
$chunks = array_chunk($transactions, 500);
|
||||
|
||||
foreach ($chunks as $chunk) {
|
||||
$set = DB::table('transactions')
|
||||
->whereIn('transactions.id', $chunk)
|
||||
->get(['transaction_journal_id'])->pluck('transaction_journal_id')->toArray();
|
||||
/** @noinspection SlowArrayOperationsInLoopInspection */
|
||||
$set = DB::table('transactions')->whereIn('transactions.id', $chunk)->get(['transaction_journal_id'])->pluck('transaction_journal_id')->toArray();
|
||||
$array = array_merge($array, $set);
|
||||
}
|
||||
|
||||
@@ -170,11 +161,11 @@ class BackToJournals extends Command
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = $journal->transactions->first();
|
||||
if (null === $transaction) {
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
$this->info(sprintf('Transaction journal #%d has no transactions. Will be fixed later.', $journal->id));
|
||||
|
||||
return;
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
}
|
||||
/** @var Budget $budget */
|
||||
$budget = $transaction->budgets->first();
|
||||
@@ -225,12 +216,12 @@ class BackToJournals extends Command
|
||||
*/
|
||||
private function getIdsForCategories(): array
|
||||
{
|
||||
$transactions = DB::table('category_transaction')->distinct()->get(['transaction_id'])->pluck('transaction_id')->toArray();
|
||||
$transactions = DB::table('category_transaction')->distinct()->get(['transaction_id'])->pluck('transaction_id')->toArray(); // @phpstan-ignore-line
|
||||
$array = [];
|
||||
$chunks = array_chunk($transactions, 500);
|
||||
|
||||
foreach ($chunks as $chunk) {
|
||||
$set = DB::table('transactions')
|
||||
$set = DB::table('transactions') // @phpstan-ignore-line
|
||||
->whereIn('transactions.id', $chunk)
|
||||
->get(['transaction_journal_id'])->pluck('transaction_journal_id')->toArray();
|
||||
/** @noinspection SlowArrayOperationsInLoopInspection */
|
||||
@@ -249,11 +240,11 @@ class BackToJournals extends Command
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = $journal->transactions->first();
|
||||
if (null === $transaction) {
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
$this->info(sprintf('Transaction journal #%d has no transactions. Will be fixed later.', $journal->id));
|
||||
|
||||
return;
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
}
|
||||
/** @var Category $category */
|
||||
$category = $transaction->categories->first();
|
||||
|
@@ -54,13 +54,13 @@ class BudgetLimitCurrency extends Command
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
if ($this->isExecuted() && true !== $this->option('force')) {
|
||||
$this->warn('This command has already been executed.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
|
||||
$count = 0;
|
||||
$budgetLimits = BudgetLimit::get();
|
||||
@@ -104,7 +104,7 @@ class BudgetLimitCurrency extends Command
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
return false; // @codeCoverageIgnore
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -56,13 +56,13 @@ class CCLiabilities extends Command
|
||||
{
|
||||
$start = microtime(true);
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
if ($this->isExecuted() && true !== $this->option('force')) {
|
||||
$this->warn('This command has already been executed.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
|
||||
$ccType = AccountType::where('type', AccountType::CREDITCARD)->first();
|
||||
$debtType = AccountType::where('type', AccountType::DEBT)->first();
|
||||
@@ -101,7 +101,7 @@ class CCLiabilities extends Command
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
return false; // @codeCoverageIgnore
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -54,14 +54,14 @@ class MigrateAttachments extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
$start = microtime(true);
|
||||
if ($this->isExecuted() && true !== $this->option('force')) {
|
||||
$this->warn('This command has already been executed.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
|
||||
$attachments = Attachment::get();
|
||||
$count = 0;
|
||||
@@ -113,7 +113,7 @@ class MigrateAttachments extends Command
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
return false; // @codeCoverageIgnore
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -56,13 +56,13 @@ class MigrateJournalNotes extends Command
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
if ($this->isExecuted() && true !== $this->option('force')) {
|
||||
$this->warn('This command has already been executed.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
$count = 0;
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$set = TransactionJournalMeta::whereName('notes')->get();
|
||||
@@ -80,11 +80,11 @@ class MigrateJournalNotes extends Command
|
||||
Log::debug(sprintf('Migrated meta note #%d to Note #%d', $meta->id, $note->id));
|
||||
try {
|
||||
$meta->delete();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
|
||||
} catch (Exception $e) { // @phpstan-ignore-line
|
||||
Log::error(sprintf('Could not delete old meta entry #%d: %s', $meta->id, $e->getMessage()));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
$count++;
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ class MigrateJournalNotes extends Command
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
return false; // @codeCoverageIgnore
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -87,7 +87,7 @@ class MigrateRecurrenceMeta extends Command
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
return false; // @codeCoverageIgnore
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user