Compare commits

..

1 Commits

Author SHA1 Message Date
JC5
5b052b1169 🤖 Auto commit for release 'develop' on 2026-01-14 2026-01-14 06:05:36 +01:00
1233 changed files with 37918 additions and 39395 deletions

View File

@@ -26,7 +26,6 @@ $paths = [
$current . '/../../config',
$current . '/../../routes',
$current . '/../../tests',
$current . '/../../resources/lang/en_US',
];
$finder = PhpCsFixer\Finder::create()
@@ -43,7 +42,6 @@ return $config->setRules(
// rule sets
'@PHP8x3Migration' => true,
'@PHP8x4Migration' => true,
'@PHP8x5Migration' => true,
'@PhpCsFixer' => true,
'@PhpCsFixer:risky' => true,
'@PSR12' => true,

View File

@@ -1,6 +1,5 @@
{
"require": {
"php": ">=8.5.0",
"friendsofphp/php-cs-fixer": "^3.12"
}
}

View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "35b5ad9b3c4e1ffe78ef9bec73987499",
"content-hash": "f1e0b38af4ded66da271a99d2bff5be8",
"packages": [
{
"name": "clue/ndjson-react",
@@ -402,16 +402,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.94.2",
"version": "v3.92.5",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "7787ceff91365ba7d623ec410b8f429cdebb4f63"
"reference": "260cc8c4a1d2f6d2f22cd4f9c70aa72e55ebac58"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7787ceff91365ba7d623ec410b8f429cdebb4f63",
"reference": "7787ceff91365ba7d623ec410b8f429cdebb4f63",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/260cc8c4a1d2f6d2f22cd4f9c70aa72e55ebac58",
"reference": "260cc8c4a1d2f6d2f22cd4f9c70aa72e55ebac58",
"shasum": ""
},
"require": {
@@ -428,7 +428,7 @@
"react/event-loop": "^1.5",
"react/socket": "^1.16",
"react/stream": "^1.4",
"sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0 || ^8.0",
"sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0",
"symfony/console": "^5.4.47 || ^6.4.24 || ^7.0 || ^8.0",
"symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0",
"symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0",
@@ -442,18 +442,18 @@
"symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0"
},
"require-dev": {
"facile-it/paraunit": "^1.3.1 || ^2.7.1",
"infection/infection": "^0.32.3",
"justinrainbow/json-schema": "^6.6.4",
"facile-it/paraunit": "^1.3.1 || ^2.7",
"infection/infection": "^0.31",
"justinrainbow/json-schema": "^6.6",
"keradus/cli-executor": "^2.3",
"mikey179/vfsstream": "^1.6.12",
"php-coveralls/php-coveralls": "^2.9.1",
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.7",
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.7",
"phpunit/phpunit": "^9.6.34 || ^10.5.63 || ^11.5.51",
"php-coveralls/php-coveralls": "^2.9",
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6",
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6",
"phpunit/phpunit": "^9.6.31 || ^10.5.60 || ^11.5.46",
"symfony/polyfill-php85": "^1.33",
"symfony/var-dumper": "^5.4.48 || ^6.4.32 || ^7.4.4 || ^8.0.4",
"symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0.1"
"symfony/var-dumper": "^5.4.48 || ^6.4.26 || ^7.4.0 || ^8.0",
"symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0"
},
"suggest": {
"ext-dom": "For handling output formats in XML",
@@ -494,7 +494,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.94.2"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.92.5"
},
"funding": [
{
@@ -502,7 +502,7 @@
"type": "github"
}
],
"time": "2026-02-20T16:13:53+00:00"
"time": "2026-01-08T21:57:37+00:00"
},
{
"name": "psr/container",
@@ -1185,29 +1185,29 @@
},
{
"name": "sebastian/diff",
"version": "8.0.0",
"version": "7.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
"reference": "a2b6d09d7729ee87d605a439469f9dcc39be5ea3"
"reference": "7ab1ea946c012266ca32390913653d844ecd085f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/a2b6d09d7729ee87d605a439469f9dcc39be5ea3",
"reference": "a2b6d09d7729ee87d605a439469f9dcc39be5ea3",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f",
"reference": "7ab1ea946c012266ca32390913653d844ecd085f",
"shasum": ""
},
"require": {
"php": ">=8.4"
"php": ">=8.3"
},
"require-dev": {
"phpunit/phpunit": "^13.0",
"phpunit/phpunit": "^12.0",
"symfony/process": "^7.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "8.0-dev"
"dev-main": "7.0-dev"
}
},
"autoload": {
@@ -1240,40 +1240,28 @@
"support": {
"issues": "https://github.com/sebastianbergmann/diff/issues",
"security": "https://github.com/sebastianbergmann/diff/security/policy",
"source": "https://github.com/sebastianbergmann/diff/tree/8.0.0"
"source": "https://github.com/sebastianbergmann/diff/tree/7.0.0"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
},
{
"url": "https://liberapay.com/sebastianbergmann",
"type": "liberapay"
},
{
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/diff",
"type": "tidelift"
}
],
"time": "2026-02-06T04:42:27+00:00"
"time": "2025-02-07T04:55:46+00:00"
},
{
"name": "symfony/console",
"version": "v8.0.6",
"version": "v8.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "488285876e807a4777f074041d8bb508623419fa"
"reference": "6145b304a5c1ea0bdbd0b04d297a5864f9a7d587"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/488285876e807a4777f074041d8bb508623419fa",
"reference": "488285876e807a4777f074041d8bb508623419fa",
"url": "https://api.github.com/repos/symfony/console/zipball/6145b304a5c1ea0bdbd0b04d297a5864f9a7d587",
"reference": "6145b304a5c1ea0bdbd0b04d297a5864f9a7d587",
"shasum": ""
},
"require": {
@@ -1330,7 +1318,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v8.0.6"
"source": "https://github.com/symfony/console/tree/v8.0.3"
},
"funding": [
{
@@ -1350,7 +1338,7 @@
"type": "tidelift"
}
],
"time": "2026-02-25T16:59:43+00:00"
"time": "2025-12-23T14:52:06+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -1421,16 +1409,16 @@
},
{
"name": "symfony/event-dispatcher",
"version": "v8.0.4",
"version": "v8.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "99301401da182b6cfaa4700dbe9987bb75474b47"
"reference": "573f95783a2ec6e38752979db139f09fec033f03"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/99301401da182b6cfaa4700dbe9987bb75474b47",
"reference": "99301401da182b6cfaa4700dbe9987bb75474b47",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/573f95783a2ec6e38752979db139f09fec033f03",
"reference": "573f95783a2ec6e38752979db139f09fec033f03",
"shasum": ""
},
"require": {
@@ -1482,7 +1470,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/event-dispatcher/tree/v8.0.4"
"source": "https://github.com/symfony/event-dispatcher/tree/v8.0.0"
},
"funding": [
{
@@ -1502,7 +1490,7 @@
"type": "tidelift"
}
],
"time": "2026-01-05T11:45:55+00:00"
"time": "2025-10-30T14:17:19+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
@@ -1582,16 +1570,16 @@
},
{
"name": "symfony/filesystem",
"version": "v8.0.6",
"version": "v8.0.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "7bf9162d7a0dff98d079b72948508fa48018a770"
"reference": "d937d400b980523dc9ee946bb69972b5e619058d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/7bf9162d7a0dff98d079b72948508fa48018a770",
"reference": "7bf9162d7a0dff98d079b72948508fa48018a770",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/d937d400b980523dc9ee946bb69972b5e619058d",
"reference": "d937d400b980523dc9ee946bb69972b5e619058d",
"shasum": ""
},
"require": {
@@ -1628,7 +1616,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/filesystem/tree/v8.0.6"
"source": "https://github.com/symfony/filesystem/tree/v8.0.1"
},
"funding": [
{
@@ -1648,20 +1636,20 @@
"type": "tidelift"
}
],
"time": "2026-02-25T16:59:43+00:00"
"time": "2025-12-01T09:13:36+00:00"
},
{
"name": "symfony/finder",
"version": "v8.0.6",
"version": "v8.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "441404f09a54de6d1bd6ad219e088cdf4c91f97c"
"reference": "dd3a2953570a283a2ba4e17063bb98c734cf5b12"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/441404f09a54de6d1bd6ad219e088cdf4c91f97c",
"reference": "441404f09a54de6d1bd6ad219e088cdf4c91f97c",
"url": "https://api.github.com/repos/symfony/finder/zipball/dd3a2953570a283a2ba4e17063bb98c734cf5b12",
"reference": "dd3a2953570a283a2ba4e17063bb98c734cf5b12",
"shasum": ""
},
"require": {
@@ -1696,7 +1684,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/v8.0.6"
"source": "https://github.com/symfony/finder/tree/v8.0.3"
},
"funding": [
{
@@ -1716,7 +1704,7 @@
"type": "tidelift"
}
],
"time": "2026-01-29T09:41:02+00:00"
"time": "2025-12-23T14:52:06+00:00"
},
{
"name": "symfony/options-resolver",
@@ -2370,16 +2358,16 @@
},
{
"name": "symfony/process",
"version": "v8.0.5",
"version": "v8.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674"
"reference": "0cbbd88ec836f8757641c651bb995335846abb78"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674",
"reference": "b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674",
"url": "https://api.github.com/repos/symfony/process/zipball/0cbbd88ec836f8757641c651bb995335846abb78",
"reference": "0cbbd88ec836f8757641c651bb995335846abb78",
"shasum": ""
},
"require": {
@@ -2411,7 +2399,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v8.0.5"
"source": "https://github.com/symfony/process/tree/v8.0.3"
},
"funding": [
{
@@ -2431,7 +2419,7 @@
"type": "tidelift"
}
],
"time": "2026-01-26T15:08:38+00:00"
"time": "2025-12-19T10:01:18+00:00"
},
{
"name": "symfony/service-contracts",
@@ -2588,16 +2576,16 @@
},
{
"name": "symfony/string",
"version": "v8.0.6",
"version": "v8.0.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "6c9e1108041b5dce21a9a4984b531c4923aa9ec4"
"reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/6c9e1108041b5dce21a9a4984b531c4923aa9ec4",
"reference": "6c9e1108041b5dce21a9a4984b531c4923aa9ec4",
"url": "https://api.github.com/repos/symfony/string/zipball/ba65a969ac918ce0cc3edfac6cdde847eba231dc",
"reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc",
"shasum": ""
},
"require": {
@@ -2654,7 +2642,7 @@
"utf8"
],
"support": {
"source": "https://github.com/symfony/string/tree/v8.0.6"
"source": "https://github.com/symfony/string/tree/v8.0.1"
},
"funding": [
{
@@ -2674,7 +2662,7 @@
"type": "tidelift"
}
],
"time": "2026-02-09T10:14:57+00:00"
"time": "2025-12-01T09:13:36+00:00"
}
],
"packages-dev": [],
@@ -2683,9 +2671,7 @@
"stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=8.5.0"
},
"platform": {},
"platform-dev": {},
"plugin-api-version": "2.9.0"
}

View File

@@ -9,55 +9,10 @@ parameters:
- Illuminate\Database\Eloquent\Model
reportUnmatchedIgnoredErrors: true
ignoreErrors:
# these are actually interesting but not right now:
- identifier: notIdentical.alwaysTrue
- identifier: method.notFound
- identifier: nullsafe.neverNull
- identifier: identical.alwaysFalse
- identifier: if.condNotBoolean
# - identifier: booleanNot.exprNotBoolean
- identifier: method.nonObject
- identifier: function.impossibleType
- identifier: booleanNot.exprNotBoolean
- identifier: ternary.condNotBoolean
- identifier: booleanNot.alwaysFalse
- identifier: booleanAnd.alwaysFalse
- identifier: greater.alwaysTrue
- identifier: function.alreadyNarrowedType
- identifier: booleanNot.alwaysTrue
- identifier: property.phpDocType
- identifier: nullCoalesce.offset
- identifier: nullCoalesce.variable
- identifier: larastan.noUnnecessaryCollectionCall
- identifier: varTag.differentVariable
- identifier: identical.alwaysTrue
- identifier: clone.nonObject
- identifier: assign.propertyReadOnly
- identifier: property.nonObject
- identifier: varTag.nativeType
- identifier: booleanAnd.leftAlwaysFalse
- identifier: property.onlyWritten
- identifier: parameter.phpDocType
- identifier: property.dynamicName
- identifier: property.unusedType
- identifier: staticMethod.deprecated
- identifier: greater.invalid
- identifier: instanceof.alwaysTrue
# ignore everything but things that BREAK
- identifier: property.deprecated
- identifier: method.deprecated
- identifier: cast.useless
- identifier: parameter.deprecatedClass
- identifier: method.deprecatedClass
- identifier: argument.type
- identifier: return.type
- identifier: assign.propertyType
- identifier: return.unusedType
- identifier: return.phpDocType
# all errors below I will never fix.
# - '#expects view-string\|null, string given#'
# - '#expects view-string, string given#'
# - "#Parameter \\#[1-2] \\$num[1-2] of function bc[a-z]+ expects numeric-string, [a-z\\-|&]+ given#"
- '#expects view-string\|null, string given#'
- '#expects view-string, string given#'
- "#Parameter \\#[1-2] \\$num[1-2] of function bc[a-z]+ expects numeric-string, [a-z\\-|&]+ given#"
- identifier: missingType.generics # not interesting enough to fix.
-
identifier: larastan.noEnvCallsOutsideOfConfig
@@ -65,11 +20,11 @@ parameters:
- identifier: missingType.iterableValue # not interesting enough to fix.
- identifier: varTag.type # needs a custom extension for every repository, not gonna happen.
- '#Dynamic call to static method Illuminate#'
# - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::before#' # is custom scope
# - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::after#' # is custom scope
# - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::withTrashed#' # is to allow soft delete
# - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::accountTypeIn#' # is a custom scope
# - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\BelongsTo::withTrashed#' # is to allow soft delete
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::before#' # is custom scope
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::after#' # is custom scope
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::withTrashed#' # is to allow soft delete
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::accountTypeIn#' # is a custom scope
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\BelongsTo::withTrashed#' # is to allow soft delete
# The level 8 is the highest level. original was 5
# 7 is more than enough, higher just leaves NULL things.

View File

@@ -14,15 +14,7 @@ SITE_OWNER=mail@example.com
# Change it to a string of exactly 32 chars or use something like `php artisan key:generate` to generate it.
# If you use Docker or similar, you can set this variable from a file by using APP_KEY_FILE
#
# Try to avoid special characters like #, < and > in your app key. This string does not need full entropy
# When in doubt, follow the link below and pick one.
#
# https://www.random.org/strings/?num=5&len=32&digits=on&upperalpha=on&loweralpha=on&unique=on&format=html&rnd=new
#
# If you are a fancy linux nerd like me, use this command:
#
# head /dev/urandom | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 32 && echo
#
# Avoid the "#" character in your APP_KEY, it may break things.
#
APP_KEY=SomeRandomStringOf32CharsExactly

View File

@@ -4,9 +4,9 @@ body:
- type: checkboxes
attributes:
label: Support guidelines
description: Thank you for reading the support guidelines before proceeding.
description: Please read the support guidelines before proceeding.
options:
- label: I'm smart and I read the <!-- MZ2udTpin6FL --> [support guidelines](https://github.com/firefly-iii/firefly-iii/blob/main/.github/support.md)
- label: I've read the <!-- MZ2udTpin6FL --> [support guidelines](https://github.com/firefly-iii/firefly-iii/blob/main/.github/support.md)
required: true
- type: checkboxes
@@ -29,7 +29,7 @@ body:
attributes:
label: Debug information
description: Please provide the table from the /debug page. Do not add backticks or quotes.
placeholder: The output from the /debug page or "N/A"
placeholder: The output from the /debug page
validations:
required: true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

7
.github/mergify.yml vendored
View File

@@ -1,4 +1,11 @@
pull_request_rules:
- name: Make sure PR are up to date before merging
description: This automatically updates PRs when they are out-of-date with the
base branch to avoid semantic conflicts (next step is using a merge
queue).
conditions: []
actions:
update:
- name: Close all on main
conditions:
- base=main

View File

@@ -1,22 +1,20 @@
<!--
Thank you for submitting new code to Firefly III, or any of the related projects. Please read the following rules carefully.
Please TALK TO ME FIRST before you open a PR.
- Please do not submit solutions for problems that are not already reported in an issue.
- Unfortunately, Firefly III can't be your learning experience. If you're new to all of this, please open an issue first.
- Please do not open PRs to "discuss" possible solutions or to "get feedback" on your code. I simply don't have time for that.
- Pull requests for the MAIN branch will be closed.
- DO NOT include translated strings in your PR.
- PRs (or parts thereof) that only fix issues inside code comments will not be accepted.
1. If you fix a problem that has no ticket, talk to me FIRST.
2. If you introduce new financial solutions or concepts, talk to me FIRST.
3. If your PR is more than 25 lines, talk to me FIRST.
4. If you used AI to write your PR, talk to me FIRST.
5. If you fix spelling or code comments, talk to me FIRST.
Wanna talk to me? Open a GitHub Issue, Discussion, or send me an email: james@firefly-iii.org
If it feels necessary to open an issue first, please do so, before you open a PR.
See also: https://docs.firefly-iii.org/explanation/support/#contributing-code
-->
@JC5
This PR fixes issue # <!-- mandatory field! -->.
This PR fixes issue # (if relevant).
Changes in this pull request:

View File

@@ -41,7 +41,7 @@ jobs:
DDNOV="${DDNOV:1}"
echo "Firefly III version is ${{ steps.ff3version.outputs.release }}, without v is $FFNOV"
echo "Data importer version is ${{ steps.ff3version.outputs.release }}, without v is $DDNOV"
echo "Data importer version is ${{ steps.ff3version.outputs.release }}, without v is $FFNOV"
# user includes no debug info at all, and does not mention current version.
# user includes no debug info at all, but does mention current version

View File

@@ -10,7 +10,7 @@ on:
phpversion:
description: 'PHP version'
required: true
default: '8.5'
default: '8.4'
schedule:
- cron: '0 3 * * MON'
@@ -42,7 +42,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ github.event.inputs.phpversion || '8.5' }}
php-version: ${{ github.event.inputs.phpversion }}
extensions: mbstring, intl, zip, bcmath
- name: Switch and pull
run: |
@@ -170,22 +170,12 @@ jobs:
npm run prod --workspace=v1
npm run build --workspace=v2
npm update
- name: Setup Mago
uses: nhedger/setup-mago@v1
- name: Run CI
run: |
# install all packages etc.
rm -rf vendor composer.lock
composer update --no-scripts --no-plugins -q
# format code.
mago format || true
composer update --no-dev --no-scripts --no-plugins -q
sudo chown -R runner:docker resources/lang
.ci/phpcs.sh || true
# lint and check
mago lint
.ci/phpstan.sh
- name: Calculate variables
run: |

View File

@@ -4,14 +4,6 @@ Over time, many people have contributed to Firefly III. Their efforts are not al
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
## 2026
- Matthew Grove
- Cinnamon Pyro
- R1DEN
- RiDEN
- Khoa Nguyen
- Nick Huang
- mateuszkulapl
- Gianluca Martino
- embedded
## 2025

View File

@@ -31,6 +31,7 @@ use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Debug\Timer;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Api\AccountFilter;
@@ -41,7 +42,7 @@ use Illuminate\Support\Facades\Log;
/**
* Class AccountController
*/
final class AccountController extends Controller
class AccountController extends Controller
{
use AccountFilter;
@@ -79,7 +80,7 @@ final class AccountController extends Controller
*/
public function accounts(AutocompleteApiRequest $request): JsonResponse
{
// Log::debug('Before All.');
Log::debug('Before All.');
['types' => $types, 'query' => $query, 'date' => $date, 'limit' => $limit] = $request->attributes->all();
$date ??= today(config('app.timezone'));
@@ -88,6 +89,8 @@ final class AccountController extends Controller
$date->endOfDay();
$return = [];
$timer = Timer::getInstance();
$timer->start(sprintf('AC accounts "%s"', $query));
$result = $this->repository->searchAccount((string) $query, $types, $limit);
$allBalances = Steam::accountsBalancesOptimized($result, $date, $this->primaryCurrency, $this->convertToPrimary);
@@ -133,6 +136,7 @@ final class AccountController extends Controller
return $posA - $posB;
});
$timer->stop(sprintf('AC accounts "%s"', $query));
return response()->api($return);
}

View File

@@ -35,7 +35,7 @@ use Illuminate\Http\Request;
/**
* Class BillController
*/
final class BillController extends Controller
class BillController extends Controller
{
private BillRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_SUBSCRIPTIONS];

View File

@@ -35,7 +35,7 @@ use Illuminate\Http\Request;
/**
* Class BudgetController
*/
final class BudgetController extends Controller
class BudgetController extends Controller
{
private BudgetRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_BUDGETS];

View File

@@ -35,7 +35,7 @@ use Illuminate\Http\Request;
/**
* Class CategoryController
*/
final class CategoryController extends Controller
class CategoryController extends Controller
{
private CategoryRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];

View File

@@ -37,7 +37,7 @@ use Illuminate\Http\Request;
/**
* Class CurrencyController
*/
final class CurrencyController extends Controller
class CurrencyController extends Controller
{
private CurrencyRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];

View File

@@ -35,7 +35,7 @@ use Illuminate\Http\Request;
/**
* Class ObjectGroupController
*/
final class ObjectGroupController extends Controller
class ObjectGroupController extends Controller
{
private ObjectGroupRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];

View File

@@ -38,7 +38,7 @@ use Illuminate\Http\Request;
/**
* Class PiggyBankController
*/
final class PiggyBankController extends Controller
class PiggyBankController extends Controller
{
private AccountRepositoryInterface $accountRepository;
private PiggyBankRepositoryInterface $piggyRepository;
@@ -82,7 +82,6 @@ final class PiggyBankController extends Controller
'currency_decimal_places' => $currency->decimal_places,
'object_group_id' => null === $objectGroup ? null : (string) $objectGroup->id,
'object_group_title' => $objectGroup?->title,
'object_group_order' => $objectGroup?->order,
];
}

View File

@@ -35,7 +35,7 @@ use Illuminate\Http\Request;
/**
* Class RecurrenceController
*/
final class RecurrenceController extends Controller
class RecurrenceController extends Controller
{
private RecurringRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_RECURRING];

View File

@@ -35,7 +35,7 @@ use Illuminate\Http\Request;
/**
* Class RuleController
*/
final class RuleController extends Controller
class RuleController extends Controller
{
private RuleRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_RULES];

View File

@@ -35,7 +35,7 @@ use Illuminate\Http\Request;
/**
* Class RuleGroupController
*/
final class RuleGroupController extends Controller
class RuleGroupController extends Controller
{
private RuleGroupRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_RULES];

View File

@@ -35,7 +35,7 @@ use Illuminate\Http\Request;
/**
* Class TagController
*/
final class TagController extends Controller
class TagController extends Controller
{
private TagRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];

View File

@@ -39,7 +39,7 @@ use Illuminate\Support\Collection;
/**
* Class TransactionController
*/
final class TransactionController extends Controller
class TransactionController extends Controller
{
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
private TransactionGroupRepositoryInterface $groupRepository;

View File

@@ -35,7 +35,7 @@ use Illuminate\Http\Request;
/**
* Class TransactionTypeController
*/
final class TransactionTypeController extends Controller
class TransactionTypeController extends Controller
{
private TransactionTypeRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];

View File

@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Chart;
use Carbon\Carbon;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Chart\ChartRequest;
use FireflyIII\Enums\UserRoleEnum;
@@ -44,7 +43,7 @@ use Illuminate\Support\Facades\Log;
/**
* Class AccountController
*/
final class AccountController extends Controller
class AccountController extends Controller
{
use ApiSupport;
use CleansChartData;
@@ -143,29 +142,23 @@ final class AccountController extends Controller
}
// create array of values to collect.
$rangeDates = array_map(static fn (string $d): Carbon => Carbon::createFromFormat('Y-m-d', $d)->startOfDay(), array_keys($range));
$rangeVals = array_values($range);
$rangeIdx = 0;
$rangeCount = count($rangeDates);
while ($currentStart <= $params['end']) {
$format = $currentStart->format('Y-m-d');
$label = $currentStart->toAtomString();
$balance = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous;
$previous = $balance;
$currentSet['entries'][$label] = $balance;
// Advance through all range entries up to current chart date
while ($rangeIdx < $rangeCount && $rangeDates[$rangeIdx] <= $currentStart) {
$previous = $rangeVals[$rangeIdx]['balance'];
if ($this->convertToPrimary) {
$pcPrevious = $rangeVals[$rangeIdx]['pc_balance'];
}
++$rangeIdx;
}
$currentSet['entries'][$label] = $previous;
// do the same for the primary currency balance, if relevant:
$pcBalance = null;
if ($this->convertToPrimary) {
$currentSet['pc_entries'][$label] = $pcPrevious;
$pcBalance = array_key_exists($format, $range) ? $range[$format]['pc_balance'] : $pcPrevious;
$pcPrevious = $pcBalance;
$currentSet['pc_entries'][$label] = $pcBalance;
}
$currentStart = Navigation::addPeriod($currentStart, $period);
// $currentStart->addDay();
}
$this->chartData[] = $currentSet;
}

View File

@@ -40,7 +40,7 @@ use Illuminate\Http\Request;
/**
* Class BalanceController
*/
final class BalanceController extends Controller
class BalanceController extends Controller
{
use CleansChartData;
use CollectsAccountsFromFilter;

View File

@@ -47,7 +47,7 @@ use Illuminate\Support\Facades\Log;
/**
* Class BudgetController
*/
final class BudgetController extends Controller
class BudgetController extends Controller
{
use CleansChartData;
use ValidatesUserGroupTrait;
@@ -104,48 +104,6 @@ final class BudgetController extends Controller
return response()->json($this->clean($data));
}
private function filterLimit(int $currencyId, Collection $limits): ?BudgetLimit
{
$amount = '0';
$limit = null;
$converter = new ExchangeRateConverter();
/** @var BudgetLimit $current */
foreach ($limits as $current) {
if ($this->convertToPrimary) {
if ($current->transaction_currency_id === $this->primaryCurrency->id) {
// simply add it.
$amount = bcadd($amount, (string) $current->amount);
Log::debug(sprintf('Set amount in limit to %s', $amount));
}
if ($current->transaction_currency_id !== $this->primaryCurrency->id) {
// convert and then add it.
$converted = $converter->convert($current->transactionCurrency, $this->primaryCurrency, $current->start_date, $current->amount);
$amount = bcadd($amount, $converted);
Log::debug(sprintf(
'Budgeted in limit #%d: %s %s, converted to %s %s',
$current->id,
$current->transactionCurrency->code,
$current->amount,
$this->primaryCurrency->code,
$converted
));
Log::debug(sprintf('Set amount in limit to %s', $amount));
}
}
if ($current->transaction_currency_id === $currencyId) {
$limit = $current;
}
}
if (null !== $limit && $this->convertToPrimary) {
// convert and add all amounts.
$limit->amount = Steam::positive($amount);
Log::debug(sprintf('Final amount in limit with converted amount %s', $limit->amount));
}
return $limit;
}
/**
* @throws FireflyException
*/
@@ -292,4 +250,46 @@ final class BudgetController extends Controller
return $return;
}
private function filterLimit(int $currencyId, Collection $limits): ?BudgetLimit
{
$amount = '0';
$limit = null;
$converter = new ExchangeRateConverter();
/** @var BudgetLimit $current */
foreach ($limits as $current) {
if ($this->convertToPrimary) {
if ($current->transaction_currency_id === $this->primaryCurrency->id) {
// simply add it.
$amount = bcadd($amount, (string) $current->amount);
Log::debug(sprintf('Set amount in limit to %s', $amount));
}
if ($current->transaction_currency_id !== $this->primaryCurrency->id) {
// convert and then add it.
$converted = $converter->convert($current->transactionCurrency, $this->primaryCurrency, $current->start_date, $current->amount);
$amount = bcadd($amount, $converted);
Log::debug(sprintf(
'Budgeted in limit #%d: %s %s, converted to %s %s',
$current->id,
$current->transactionCurrency->code,
$current->amount,
$this->primaryCurrency->code,
$converted
));
Log::debug(sprintf('Set amount in limit to %s', $amount));
}
}
if ($current->transaction_currency_id === $currencyId) {
$limit = $current;
}
}
if (null !== $limit && $this->convertToPrimary) {
// convert and add all amounts.
$limit->amount = Steam::positive($amount);
Log::debug(sprintf('Final amount in limit with converted amount %s', $limit->amount));
}
return $limit;
}
}

View File

@@ -45,7 +45,7 @@ use Illuminate\Support\Facades\Log;
/**
* Class BudgetController
*/
final class CategoryController extends Controller
class CategoryController extends Controller
{
use CleansChartData;
use ValidatesUserGroupTrait;

View File

@@ -98,77 +98,6 @@ abstract class Controller extends BaseController
});
}
/**
* Method to help build URL's.
*/
final protected function buildParams(): string
{
$return = '?';
$params = [];
foreach ($this->parameters as $key => $value) {
if ('page' === $key) {
continue;
}
if ($value instanceof Carbon) {
$params[$key] = $value->format('Y-m-d');
continue;
}
$params[$key] = $value;
}
return $return.http_build_query($params);
}
final protected function getManager(): Manager
{
// create some objects:
$manager = new Manager();
$baseUrl = request()->getSchemeAndHttpHost().'/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
return $manager;
}
final protected function jsonApiList(string $key, LengthAwarePaginator $paginator, AbstractTransformer $transformer): array
{
$manager = new Manager();
$baseUrl = sprintf('%s/api/v1/', request()->getSchemeAndHttpHost());
// TODO add stuff to path?
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$objects = $paginator->getCollection();
// the transformer, at this point, needs to collect information that ALL items in the collection
// require, like meta-data and stuff like that, and save it for later.
// $objects = $transformer->collectMetaData($objects);
$paginator->setCollection($objects);
$resource = new FractalCollection($objects, $transformer, $key);
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return $manager->createData($resource)->toArray();
}
/**
* Returns a JSON API object and returns it.
*
* @param array<int, mixed>|Model $object
*/
final protected function jsonApiObject(string $key, array|Model $object, AbstractTransformer $transformer): array
{
// create some objects:
$manager = new Manager();
$baseUrl = sprintf('%s/api/v1', request()->getSchemeAndHttpHost());
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($object, $transformer, $key);
return $manager->createData($resource)->toArray();
}
#[Deprecated(message: <<<'TXT'
use Request classes
Method to grab all parameters from the URL
@@ -241,4 +170,75 @@ abstract class Controller extends BaseController
// return $this->getSortParameters($bag);
}
/**
* Method to help build URL's.
*/
final protected function buildParams(): string
{
$return = '?';
$params = [];
foreach ($this->parameters as $key => $value) {
if ('page' === $key) {
continue;
}
if ($value instanceof Carbon) {
$params[$key] = $value->format('Y-m-d');
continue;
}
$params[$key] = $value;
}
return $return.http_build_query($params);
}
final protected function getManager(): Manager
{
// create some objects:
$manager = new Manager();
$baseUrl = request()->getSchemeAndHttpHost().'/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
return $manager;
}
final protected function jsonApiList(string $key, LengthAwarePaginator $paginator, AbstractTransformer $transformer): array
{
$manager = new Manager();
$baseUrl = sprintf('%s/api/v1/', request()->getSchemeAndHttpHost());
// TODO add stuff to path?
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$objects = $paginator->getCollection();
// the transformer, at this point, needs to collect information that ALL items in the collection
// require, like meta-data and stuff like that, and save it for later.
// $objects = $transformer->collectMetaData($objects);
$paginator->setCollection($objects);
$resource = new FractalCollection($objects, $transformer, $key);
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return $manager->createData($resource)->toArray();
}
/**
* Returns a JSON API object and returns it.
*
* @param array<int, mixed>|Model $object
*/
final protected function jsonApiObject(string $key, array|Model $object, AbstractTransformer $transformer): array
{
// create some objects:
$manager = new Manager();
$baseUrl = sprintf('%s/api/v1', request()->getSchemeAndHttpHost());
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($object, $transformer, $key);
return $manager->createData($resource)->toArray();
}
}

View File

@@ -24,13 +24,13 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Data\Bulk;
use Illuminate\Http\Request;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Data\Bulk\TransactionRequest;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\AccountDestroyService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
/**
* Class TransactionController
@@ -42,7 +42,7 @@ use Illuminate\Http\Request;
* Because this is a security nightmare waiting to happen validation
* is pretty strict.
*/
final class TransactionController extends Controller
class TransactionController extends Controller
{
private AccountRepositoryInterface $repository;
@@ -51,14 +51,16 @@ final class TransactionController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function (Request $request, $next) {
$this->validateUserGroup($request);
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUserGroup($this->userGroup);
$this->repository->setUser($this->user);
$this->middleware(
function (Request $request, $next) {
$this->validateUserGroup($request);
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUserGroup($this->userGroup);
$this->repository->setUser($this->user);
return $next($request);
});
return $next($request);
}
);
}
public function update(TransactionRequest $request): JsonResponse

View File

@@ -54,7 +54,7 @@ use Illuminate\Support\Facades\Log;
/**
* Class DestroyController
*/
final class DestroyController extends Controller
class DestroyController extends Controller
{
private bool $unused;
@@ -137,6 +137,70 @@ final class DestroyController extends Controller
return response()->json([], 204);
}
private function destroyBudgets(): void
{
/** @var AvailableBudgetRepositoryInterface $abRepository */
$abRepository = app(AvailableBudgetRepositoryInterface::class);
$abRepository->destroyAll();
/** @var BudgetLimitRepositoryInterface $blRepository */
$blRepository = app(BudgetLimitRepositoryInterface::class);
$blRepository->destroyAll();
/** @var BudgetRepositoryInterface $budgetRepository */
$budgetRepository = app(BudgetRepositoryInterface::class);
$budgetRepository->destroyAll();
}
private function destroyBills(): void
{
/** @var BillRepositoryInterface $repository */
$repository = app(BillRepositoryInterface::class);
$repository->destroyAll();
}
private function destroyPiggyBanks(): void
{
/** @var PiggyBankRepositoryInterface $repository */
$repository = app(PiggyBankRepositoryInterface::class);
$repository->destroyAll();
}
private function destroyRules(): void
{
/** @var RuleGroupRepositoryInterface $repository */
$repository = app(RuleGroupRepositoryInterface::class);
$repository->destroyAll();
}
private function destroyRecurringTransactions(): void
{
/** @var RecurringRepositoryInterface $repository */
$repository = app(RecurringRepositoryInterface::class);
$repository->destroyAll();
}
private function destroyCategories(): void
{
/** @var CategoryRepositoryInterface $categoryRepos */
$categoryRepos = app(CategoryRepositoryInterface::class);
$categoryRepos->destroyAll();
}
private function destroyTags(): void
{
/** @var TagRepositoryInterface $tagRepository */
$tagRepository = app(TagRepositoryInterface::class);
$tagRepository->destroyAll();
}
private function destroyObjectGroups(): void
{
/** @var ObjectGroupRepositoryInterface $repository */
$repository = app(ObjectGroupRepositoryInterface::class);
$repository->deleteAll();
}
/**
* @param array<int, string> $types
*/
@@ -165,70 +229,6 @@ final class DestroyController extends Controller
}
}
private function destroyBills(): void
{
/** @var BillRepositoryInterface $repository */
$repository = app(BillRepositoryInterface::class);
$repository->destroyAll();
}
private function destroyBudgets(): void
{
/** @var AvailableBudgetRepositoryInterface $abRepository */
$abRepository = app(AvailableBudgetRepositoryInterface::class);
$abRepository->destroyAll();
/** @var BudgetLimitRepositoryInterface $blRepository */
$blRepository = app(BudgetLimitRepositoryInterface::class);
$blRepository->destroyAll();
/** @var BudgetRepositoryInterface $budgetRepository */
$budgetRepository = app(BudgetRepositoryInterface::class);
$budgetRepository->destroyAll();
}
private function destroyCategories(): void
{
/** @var CategoryRepositoryInterface $categoryRepos */
$categoryRepos = app(CategoryRepositoryInterface::class);
$categoryRepos->destroyAll();
}
private function destroyObjectGroups(): void
{
/** @var ObjectGroupRepositoryInterface $repository */
$repository = app(ObjectGroupRepositoryInterface::class);
$repository->deleteAll();
}
private function destroyPiggyBanks(): void
{
/** @var PiggyBankRepositoryInterface $repository */
$repository = app(PiggyBankRepositoryInterface::class);
$repository->destroyAll();
}
private function destroyRecurringTransactions(): void
{
/** @var RecurringRepositoryInterface $repository */
$repository = app(RecurringRepositoryInterface::class);
$repository->destroyAll();
}
private function destroyRules(): void
{
/** @var RuleGroupRepositoryInterface $repository */
$repository = app(RuleGroupRepositoryInterface::class);
$repository->destroyAll();
}
private function destroyTags(): void
{
/** @var TagRepositoryInterface $tagRepository */
$tagRepository = app(TagRepositoryInterface::class);
$tagRepository->destroyAll();
}
/**
* @param array<int, string> $types
*/

View File

@@ -24,12 +24,12 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Data\Export;
use Illuminate\Http\Request;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Data\Export\ExportRequest;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\Export\ExportDataGenerator;
use Illuminate\Http\Request;
use Illuminate\Http\Response as LaravelResponse;
use Safe\Exceptions\DatetimeException;
@@ -38,7 +38,7 @@ use function Safe\date;
/**
* Class ExportController
*/
final class ExportController extends Controller
class ExportController extends Controller
{
private ExportDataGenerator $exporter;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
@@ -49,14 +49,16 @@ final class ExportController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function (Request $request, $next) {
$this->validateUserGroup($request);
$this->exporter = app(ExportDataGenerator::class);
$this->exporter->setUserGroup($this->userGroup);
$this->exporter->setUser($this->user);
$this->middleware(
function (Request $request, $next) {
$this->validateUserGroup($request);
$this->exporter = app(ExportDataGenerator::class);
$this->exporter->setUserGroup($this->userGroup);
$this->exporter->setUser($this->user);
return $next($request);
});
return $next($request);
}
);
}
/**
@@ -72,6 +74,33 @@ final class ExportController extends Controller
return $this->returnExport('accounts');
}
/**
* @throws FireflyException
* @throws DatetimeException
*/
private function returnExport(string $key): LaravelResponse
{
$date = date('Y-m-d-H-i-s');
$fileName = sprintf('%s-export-%s.csv', $date, $key);
$data = $this->exporter->export();
/** @var LaravelResponse $response */
$response = response($data[$key]);
$response
->header('Content-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename='.$fileName)
->header('Content-Transfer-Encoding', 'binary')
->header('Connection', 'Keep-Alive')
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
->header('Content-Length', (string) strlen((string) $data[$key]))
;
return $response;
}
/**
* @throws DatetimeException
* @throws FireflyException
@@ -177,31 +206,4 @@ final class ExportController extends Controller
return $this->returnExport('transactions');
}
/**
* @throws FireflyException
* @throws DatetimeException
*/
private function returnExport(string $key): LaravelResponse
{
$date = date('Y-m-d-H-i-s');
$fileName = sprintf('%s-export-%s.csv', $date, $key);
$data = $this->exporter->export();
/** @var LaravelResponse $response */
$response = response($data[$key]);
$response
->header('Content-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename='.$fileName)
->header('Content-Transfer-Encoding', 'binary')
->header('Connection', 'Keep-Alive')
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
->header('Content-Length', (string) strlen((string) $data[$key]))
;
return $response;
}
}

View File

@@ -44,7 +44,7 @@ use Illuminate\Http\Request;
/**
* Class PurgeController
*/
final class PurgeController extends Controller
class PurgeController extends Controller
{
protected array $acceptedRoles = [UserRoleEnum::FULL];

View File

@@ -37,12 +37,12 @@ use Illuminate\Http\JsonResponse;
* Shows expense information grouped or limited by date.
* I.e. all expenses grouped by account + currency.
*/
final class AccountController extends Controller
class AccountController extends Controller
{
use ApiSupport;
private OperationsRepositoryInterface $opsRepository;
private AccountRepositoryInterface $repository;
private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
@@ -50,16 +50,18 @@ final class AccountController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$user = auth()->user();
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser($user);
$this->middleware(
function ($request, $next) {
$user = auth()->user();
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser($user);
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->opsRepository->setUser($user);
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->opsRepository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
public function asset(GenericRequest $request): JsonResponse

View File

@@ -36,7 +36,7 @@ use Illuminate\Support\Facades\Log;
/**
* Class BillController
*/
final class BillController extends Controller
class BillController extends Controller
{
private BillRepositoryInterface $repository;
@@ -46,13 +46,15 @@ final class BillController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$user = auth()->user();
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser($user);
$this->middleware(
function ($request, $next) {
$user = auth()->user();
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**
@@ -95,14 +97,7 @@ final class BillController extends Controller
if ($convertToPrimary && $journal['currency_id'] !== $primary->id && $primary->id === $journal['foreign_currency_id']) {
$field = 'foreign_amount';
}
Log::debug(sprintf(
'Journal #%d in bill #%d will use %s (%s %s)',
$journal['transaction_group_id'],
$billId,
$field,
$currencyCode,
$journal[$field] ?? '0'
));
Log::debug(sprintf('Journal #%d in bill #%d will use %s (%s %s)', $journal['transaction_group_id'], $billId, $field, $currencyCode, $journal[$field] ?? '0'));
$key = sprintf('%d-%d', $billId, $currencyId);

View File

@@ -36,11 +36,11 @@ use Illuminate\Support\Collection;
/**
* Class BudgetController
*/
final class BudgetController extends Controller
class BudgetController extends Controller
{
private NoBudgetRepositoryInterface $noRepository;
private NoBudgetRepositoryInterface $noRepository;
private OperationsRepositoryInterface $opsRepository;
private BudgetRepositoryInterface $repository;
private BudgetRepositoryInterface $repository;
/**
* AccountController constructor.
@@ -48,17 +48,19 @@ final class BudgetController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->repository = app(BudgetRepositoryInterface::class);
$this->noRepository = app(NoBudgetRepositoryInterface::class);
$user = auth()->user();
$this->opsRepository->setUser($user);
$this->repository->setUser($user);
$this->noRepository->setUser($user);
$this->middleware(
function ($request, $next) {
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->repository = app(BudgetRepositoryInterface::class);
$this->noRepository = app(NoBudgetRepositoryInterface::class);
$user = auth()->user();
$this->opsRepository->setUser($user);
$this->repository->setUser($user);
$this->noRepository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
public function budget(GenericRequest $request): JsonResponse

View File

@@ -36,11 +36,11 @@ use Illuminate\Support\Collection;
/**
* Class CategoryController
*/
final class CategoryController extends Controller
class CategoryController extends Controller
{
private NoCategoryRepositoryInterface $noRepository;
private OperationsRepositoryInterface $opsRepository;
private CategoryRepositoryInterface $repository;
private CategoryRepositoryInterface $repository;
/**
* AccountController constructor.
@@ -48,17 +48,19 @@ final class CategoryController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->repository = app(CategoryRepositoryInterface::class);
$this->noRepository = app(NoCategoryRepositoryInterface::class);
$user = auth()->user();
$this->opsRepository->setUser($user);
$this->repository->setUser($user);
$this->noRepository->setUser($user);
$this->middleware(
function ($request, $next) {
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->repository = app(CategoryRepositoryInterface::class);
$this->noRepository = app(NoCategoryRepositoryInterface::class);
$user = auth()->user();
$this->opsRepository->setUser($user);
$this->repository->setUser($user);
$this->noRepository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
public function category(GenericRequest $request): JsonResponse

View File

@@ -35,7 +35,7 @@ use Illuminate\Support\Facades\Log;
/**
* Class PeriodController
*/
final class PeriodController extends Controller
class PeriodController extends Controller
{
public function total(GenericRequest $request): JsonResponse
{
@@ -73,6 +73,7 @@ final class PeriodController extends Controller
$amount = $journal['amount'];
}
$response[$currencyId] ??= [
'difference' => '0',
'difference_float' => 0,

View File

@@ -36,7 +36,7 @@ use Illuminate\Support\Facades\Log;
/**
* Class TagController
*/
final class TagController extends Controller
class TagController extends Controller
{
private TagRepositoryInterface $repository;
@@ -46,12 +46,14 @@ final class TagController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(TagRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(TagRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -37,12 +37,12 @@ use Illuminate\Http\JsonResponse;
* Shows income information grouped or limited by date.
* I.e. all income grouped by account + currency.
*/
final class AccountController extends Controller
class AccountController extends Controller
{
use ApiSupport;
private OperationsRepositoryInterface $opsRepository;
private AccountRepositoryInterface $repository;
private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
@@ -50,16 +50,18 @@ final class AccountController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$user = auth()->user();
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser($user);
$this->middleware(
function ($request, $next) {
$user = auth()->user();
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser($user);
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->opsRepository->setUser($user);
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->opsRepository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
public function asset(GenericRequest $request): JsonResponse

View File

@@ -36,11 +36,11 @@ use Illuminate\Support\Collection;
/**
* Class CategoryController
*/
final class CategoryController extends Controller
class CategoryController extends Controller
{
private NoCategoryRepositoryInterface $noRepository;
private OperationsRepositoryInterface $opsRepository;
private CategoryRepositoryInterface $repository;
private CategoryRepositoryInterface $repository;
/**
* AccountController constructor.
@@ -48,17 +48,19 @@ final class CategoryController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->repository = app(CategoryRepositoryInterface::class);
$this->noRepository = app(NoCategoryRepositoryInterface::class);
$user = auth()->user();
$this->opsRepository->setUser($user);
$this->repository->setUser($user);
$this->noRepository->setUser($user);
$this->middleware(
function ($request, $next) {
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->repository = app(CategoryRepositoryInterface::class);
$this->noRepository = app(NoCategoryRepositoryInterface::class);
$user = auth()->user();
$this->opsRepository->setUser($user);
$this->repository->setUser($user);
$this->noRepository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
public function category(GenericRequest $request): JsonResponse

View File

@@ -35,7 +35,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class PeriodController
*/
final class PeriodController extends Controller
class PeriodController extends Controller
{
public function total(GenericRequest $request): JsonResponse
{

View File

@@ -36,7 +36,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class TagController
*/
final class TagController extends Controller
class TagController extends Controller
{
private TagRepositoryInterface $repository;
@@ -46,13 +46,15 @@ final class TagController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$user = auth()->user();
$this->repository = app(TagRepositoryInterface::class);
$this->repository->setUser($user);
$this->middleware(
function ($request, $next) {
$user = auth()->user();
$this->repository = app(TagRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**
@@ -98,6 +100,7 @@ final class TagController extends Controller
];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field]));
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
}
return response()->json(array_values($response));
@@ -158,10 +161,7 @@ final class TagController extends Controller
'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'],
];
$response[$foreignKey]['difference'] = bcadd(
(string) $response[$foreignKey]['difference'],
Steam::positive($journal['foreign_amount'])
);
$response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount']));
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference'];
}
}

View File

@@ -33,7 +33,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class AccountController
*/
final class AccountController extends Controller
class AccountController extends Controller
{
use ApiSupport;
@@ -45,13 +45,15 @@ final class AccountController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$user = auth()->user();
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->opsRepository->setUser($user);
$this->middleware(
function ($request, $next) {
$user = auth()->user();
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->opsRepository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
public function asset(GenericRequest $request): JsonResponse

View File

@@ -36,11 +36,11 @@ use Illuminate\Support\Collection;
/**
* Class CategoryController
*/
final class CategoryController extends Controller
class CategoryController extends Controller
{
private NoCategoryRepositoryInterface $noRepository;
private OperationsRepositoryInterface $opsRepository;
private CategoryRepositoryInterface $repository;
private CategoryRepositoryInterface $repository;
/**
* AccountController constructor.
@@ -48,17 +48,19 @@ final class CategoryController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->repository = app(CategoryRepositoryInterface::class);
$this->noRepository = app(NoCategoryRepositoryInterface::class);
$user = auth()->user();
$this->opsRepository->setUser($user);
$this->repository->setUser($user);
$this->noRepository->setUser($user);
$this->middleware(
function ($request, $next) {
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->repository = app(CategoryRepositoryInterface::class);
$this->noRepository = app(NoCategoryRepositoryInterface::class);
$user = auth()->user();
$this->opsRepository->setUser($user);
$this->repository->setUser($user);
$this->noRepository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
public function category(GenericRequest $request): JsonResponse

View File

@@ -35,7 +35,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class PeriodController
*/
final class PeriodController extends Controller
class PeriodController extends Controller
{
public function total(GenericRequest $request): JsonResponse
{
@@ -74,6 +74,7 @@ final class PeriodController extends Controller
];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field]));
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
}
return response()->json(array_values($response));

View File

@@ -36,7 +36,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class TagController
*/
final class TagController extends Controller
class TagController extends Controller
{
private TagRepositoryInterface $repository;
@@ -46,13 +46,15 @@ final class TagController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$user = auth()->user();
$this->repository = app(TagRepositoryInterface::class);
$this->repository->setUser($user);
$this->middleware(
function ($request, $next) {
$user = auth()->user();
$this->repository = app(TagRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
public function noTag(GenericRequest $request): JsonResponse
@@ -64,6 +66,7 @@ final class TagController extends Controller
$convertToPrimary = Amount::convertToPrimary();
$primary = Amount::getPrimaryCurrency();
// collect all expenses in this period (regardless of type) by the given bills and accounts.
$collector = app(GroupCollectorInterface::class);
$collector->setTypes([TransactionTypeEnum::TRANSFER->value])->setRange($start, $end)->setDestinationAccounts($accounts);
@@ -95,6 +98,7 @@ final class TagController extends Controller
];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field]));
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
}
return response()->json(array_values($response));

View File

@@ -33,7 +33,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class DestroyController
*/
final class DestroyController extends Controller
class DestroyController extends Controller
{
public const string RESOURCE_KEY = 'accounts';
@@ -45,12 +45,14 @@ final class DestroyController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -46,7 +46,7 @@ use League\Fractal\Resource\Collection as FractalCollection;
/**
* Class ListController
*/
final class ListController extends Controller
class ListController extends Controller
{
use TransactionFilter;
@@ -60,31 +60,37 @@ final class ListController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
public function attachments(PaginationRequest $request, Account $account): JsonResponse
{
$manager = $this->getManager();
['limit' => $limit, 'offset' => $offset, 'page' => $page] = $request->attributes->all();
$collection = $this->repository->getAttachments($account);
$manager = $this->getManager();
[
'limit' => $limit,
'offset' => $offset,
'page' => $page,
] = $request->attributes->all();
$collection = $this->repository->getAttachments($account);
$count = $collection->count();
$attachments = $collection->slice($offset, $limit);
$count = $collection->count();
$attachments = $collection->slice($offset, $limit);
// make paginator:
$paginator = new LengthAwarePaginator($attachments, $count, $limit, $page);
$paginator = new LengthAwarePaginator($attachments, $count, $limit, $page);
$paginator->setPath(route('api.v1.accounts.attachments', [$account->id]).$this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer = app(AttachmentTransformer::class);
$resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -93,31 +99,35 @@ final class ListController extends Controller
public function piggyBanks(PaginationRequest $request, Account $account): JsonResponse
{
// create some objects:
$manager = $this->getManager();
$manager = $this->getManager();
['limit' => $limit, 'offset' => $offset, 'page' => $page] = $request->attributes->all();
[
'limit' => $limit,
'offset' => $offset,
'page' => $page,
] = $request->attributes->all();
// get list of piggy banks. Count it and split it.
$collection = $this->repository->getPiggyBanks($account);
$count = $collection->count();
$piggyBanks = $collection->slice($offset, $limit);
$collection = $this->repository->getPiggyBanks($account);
$count = $collection->count();
$piggyBanks = $collection->slice($offset, $limit);
// enrich
/** @var User $admin */
$admin = auth()->user();
$enrichment = new PiggyBankEnrichment();
$admin = auth()->user();
$enrichment = new PiggyBankEnrichment();
$enrichment->setUser($admin);
$piggyBanks = $enrichment->enrich($piggyBanks);
$piggyBanks = $enrichment->enrich($piggyBanks);
// make paginator:
$paginator = new LengthAwarePaginator($piggyBanks, $count, $limit, $page);
$paginator = new LengthAwarePaginator($piggyBanks, $count, $limit, $page);
$paginator->setPath(route('api.v1.accounts.piggy-banks', [$account->id]).$this->buildParams());
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);
$transformer = app(PiggyBankTransformer::class);
// $transformer->setParameters($this->parameters);
$resource = new FractalCollection($piggyBanks, $transformer, 'piggy-banks');
$resource = new FractalCollection($piggyBanks, $transformer, 'piggy-banks');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -128,16 +138,21 @@ final class ListController extends Controller
*/
public function transactions(PaginationDateRangeRequest $request, Account $account): JsonResponse
{
['limit' => $limit, 'page' => $page, 'start' => $start, 'end' => $end, 'type' => $type] = $request->attributes->all();
$types = $this->mapTransactionTypes($type ?? 'default');
$manager = $this->getManager();
[
'limit' => $limit,
'page' => $page,
'start' => $start,
'end' => $end,
'types' => $types,
] = $request->attributes->all();
$manager = $this->getManager();
/** @var User $admin */
$admin = auth()->user();
$admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setUser($admin)->setAccounts(new Collection()->push($account))->withAPIInformation()->setLimit($limit)->setPage($page)->setTypes($types);
if (null !== $start) {
$collector->setStart($start);
@@ -146,18 +161,18 @@ final class ListController extends Controller
$collector->setEnd($end);
}
$paginator = $collector->getPaginatedGroups();
$paginator = $collector->getPaginatedGroups();
$paginator->setPath(route('api.v1.accounts.transactions', [$account->id]).$this->buildParams());
// enrich
$enrichment = new TransactionGroupEnrichment();
$enrichment = new TransactionGroupEnrichment();
$enrichment->setUser($admin);
$transactions = $enrichment->enrich($paginator->getCollection());
$transactions = $enrichment->enrich($paginator->getCollection());
/** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionGroupTransformer::class);
$transformer = app(TransactionGroupTransformer::class);
$resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);

View File

@@ -41,7 +41,7 @@ use League\Fractal\Resource\Item;
/**
* Class ShowController
*/
final class ShowController extends Controller
class ShowController extends Controller
{
use AccountFilter;
@@ -55,12 +55,14 @@ final class ShowController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**
@@ -78,7 +80,8 @@ final class ShowController extends Controller
'start' => $start,
'end' => $end,
'date' => $date,
] = $request->attributes->all();
]
= $request->attributes->all();
// get list of accounts. Count it and split it.
$this->repository->resetAccountOrder();
$collection = $this->repository->getAccountsByType($types, $sort);
@@ -124,22 +127,25 @@ final class ShowController extends Controller
// get list of accounts. Count it and split it.
$this->repository->resetAccountOrder();
$account->refresh();
$manager = $this->getManager();
['start' => $start, 'end' => $end, 'date' => $date] = $request->attributes->all();
$manager = $this->getManager();
['start' => $start,
'end' => $end,
'date' => $date,] = $request->attributes->all();
// enrich
/** @var User $admin */
$admin = auth()->user();
$enrichment = new AccountEnrichment();
$admin = auth()->user();
$enrichment = new AccountEnrichment();
$enrichment->setDate($date);
$enrichment->setStart($start);
$enrichment->setEnd($end);
$enrichment->setUser($admin);
$account = $enrichment->enrichSingle($account);
$account = $enrichment->enrichSingle($account);
/** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class);
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
$transformer = app(AccountTransformer::class);
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}

View File

@@ -36,7 +36,7 @@ use League\Fractal\Resource\Item;
/**
* Class StoreController
*/
final class StoreController extends Controller
class StoreController extends Controller
{
public const string RESOURCE_KEY = 'accounts';
@@ -48,12 +48,14 @@ final class StoreController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -39,7 +39,7 @@ use League\Fractal\Resource\Item;
/**
* Class UpdateController
*/
final class UpdateController extends Controller
class UpdateController extends Controller
{
public const string RESOURCE_KEY = 'accounts';
@@ -51,12 +51,14 @@ final class UpdateController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -37,7 +37,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class DestroyController
*/
final class DestroyController extends Controller
class DestroyController extends Controller
{
private AttachmentRepositoryInterface $repository;
@@ -48,14 +48,16 @@ final class DestroyController extends Controller
{
parent::__construct();
$this->middleware(ApiDemoUser::class)->except(['delete', 'download', 'show', 'index']);
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(AttachmentRepositoryInterface::class);
$this->repository->setUser($user);
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(AttachmentRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -44,7 +44,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class ShowController
*/
final class ShowController extends Controller
class ShowController extends Controller
{
private AttachmentRepositoryInterface $repository;
@@ -55,14 +55,16 @@ final class ShowController extends Controller
{
parent::__construct();
$this->middleware(ApiDemoUser::class)->except(['delete', 'download', 'show', 'index']);
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(AttachmentRepositoryInterface::class);
$this->repository->setUser($user);
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(AttachmentRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**
@@ -121,7 +123,11 @@ final class ShowController extends Controller
*/
public function index(PaginationRequest $request): JsonResponse
{
['limit' => $limit, 'offset' => $offset, 'page' => $page] = $request->attributes->all();
[
'limit' => $limit,
'offset' => $offset,
'page' => $page,
] = $request->attributes->all();
if (true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
@@ -129,21 +135,21 @@ final class ShowController extends Controller
throw new NotFoundHttpException();
}
$manager = $this->getManager();
$manager = $this->getManager();
// get list of attachments. Count it and split it.
$collection = $this->repository->get();
$count = $collection->count();
$attachments = $collection->slice($offset, $limit);
$collection = $this->repository->get();
$count = $collection->count();
$attachments = $collection->slice($offset, $limit);
// make paginator:
$paginator = new LengthAwarePaginator($attachments, $count, $limit, $page);
$paginator = new LengthAwarePaginator($attachments, $count, $limit, $page);
$paginator->setPath(route('api.v1.attachments.index').$this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer = app(AttachmentTransformer::class);
$resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);

View File

@@ -42,7 +42,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class StoreController
*/
final class StoreController extends Controller
class StoreController extends Controller
{
private AttachmentRepositoryInterface $repository;
@@ -53,14 +53,16 @@ final class StoreController extends Controller
{
parent::__construct();
$this->middleware(ApiDemoUser::class)->except(['delete', 'download', 'show', 'index']);
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(AttachmentRepositoryInterface::class);
$this->repository->setUser($user);
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(AttachmentRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -39,7 +39,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class UpdateController
*/
final class UpdateController extends Controller
class UpdateController extends Controller
{
private AttachmentRepositoryInterface $repository;
@@ -50,14 +50,16 @@ final class UpdateController extends Controller
{
parent::__construct();
$this->middleware(ApiDemoUser::class)->except(['delete', 'download', 'show', 'index']);
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(AttachmentRepositoryInterface::class);
$this->repository->setUser($user);
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(AttachmentRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -40,7 +40,7 @@ use League\Fractal\Resource\Item;
/**
* Class ShowController
*/
final class ShowController extends Controller
class ShowController extends Controller
{
private AvailableBudgetRepositoryInterface $abRepository;
@@ -50,14 +50,16 @@ final class ShowController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->abRepository = app(AvailableBudgetRepositoryInterface::class);
$this->abRepository->setUser($user);
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->abRepository = app(AvailableBudgetRepositoryInterface::class);
$this->abRepository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**
@@ -68,29 +70,35 @@ final class ShowController extends Controller
*/
public function index(PaginationDateRangeRequest $request): JsonResponse
{
$manager = $this->getManager();
['limit' => $limit, 'offset' => $offset, 'page' => $page, 'start' => $start, 'end' => $end] = $request->attributes->all();
$manager = $this->getManager();
[
'limit' => $limit,
'offset' => $offset,
'page' => $page,
'start' => $start,
'end' => $end,
] = $request->attributes->all();
// get list of available budgets. Count it and split it.
$collection = $this->abRepository->getAvailableBudgetsByDate($start, $end);
$count = $collection->count();
$availableBudgets = $collection->slice($offset, $limit);
$collection = $this->abRepository->getAvailableBudgetsByDate($start, $end);
$count = $collection->count();
$availableBudgets = $collection->slice($offset, $limit);
// enrich
/** @var User $admin */
$admin = auth()->user();
$enrichment = new AvailableBudgetEnrichment();
$admin = auth()->user();
$enrichment = new AvailableBudgetEnrichment();
$enrichment->setUser($admin);
$availableBudgets = $enrichment->enrich($availableBudgets);
$availableBudgets = $enrichment->enrich($availableBudgets);
// make paginator:
$paginator = new LengthAwarePaginator($availableBudgets, $count, $limit, $page);
$paginator = new LengthAwarePaginator($availableBudgets, $count, $limit, $page);
$paginator->setPath(route('api.v1.available-budgets.index').$this->buildParams());
/** @var AvailableBudgetTransformer $transformer */
$transformer = app(AvailableBudgetTransformer::class);
$transformer = app(AvailableBudgetTransformer::class);
$resource = new FractalCollection($availableBudgets, $transformer, 'available_budgets');
$resource = new FractalCollection($availableBudgets, $transformer, 'available_budgets');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -118,6 +126,7 @@ final class ShowController extends Controller
$enrichment->setUser($admin);
$availableBudget = $enrichment->enrichSingle($availableBudget);
$resource = new Item($availableBudget, $transformer, 'available_budgets');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);

View File

@@ -33,7 +33,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class DestroyController
*/
final class DestroyController extends Controller
class DestroyController extends Controller
{
private BillRepositoryInterface $repository;
@@ -43,12 +43,14 @@ final class DestroyController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -44,7 +44,7 @@ use League\Fractal\Resource\Collection as FractalCollection;
/**
* Class ListController
*/
final class ListController extends Controller
class ListController extends Controller
{
use TransactionFilter;
@@ -56,12 +56,14 @@ final class ListController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**
@@ -72,21 +74,25 @@ final class ListController extends Controller
*/
public function attachments(PaginationRequest $request, Bill $bill): JsonResponse
{
['limit' => $limit, 'offset' => $offset, 'page' => $page] = $request->attributes->all();
$manager = $this->getManager();
$collection = $this->repository->getAttachments($bill);
[
'limit' => $limit,
'offset' => $offset,
'page' => $page,
] = $request->attributes->all();
$manager = $this->getManager();
$collection = $this->repository->getAttachments($bill);
$count = $collection->count();
$attachments = $collection->slice($offset, $limit);
$count = $collection->count();
$attachments = $collection->slice($offset, $limit);
// make paginator:
$paginator = new LengthAwarePaginator($attachments, $count, $limit, $page);
$paginator = new LengthAwarePaginator($attachments, $count, $limit, $page);
$paginator->setPath(route('api.v1.bills.attachments', [$bill->id]).$this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer = app(AttachmentTransformer::class);
$resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -100,20 +106,24 @@ final class ListController extends Controller
*/
public function rules(PaginationRequest $request, Bill $bill): JsonResponse
{
['limit' => $limit, 'offset' => $offset, 'page' => $page] = $request->attributes->all();
[
'limit' => $limit,
'offset' => $offset,
'page' => $page,
] = $request->attributes->all();
$manager = $this->getManager();
$collection = $this->repository->getRulesForBill($bill);
$count = $collection->count();
$rules = $collection->slice($offset, $limit);
$manager = $this->getManager();
$collection = $this->repository->getRulesForBill($bill);
$count = $collection->count();
$rules = $collection->slice($offset, $limit);
// make paginator:
$paginator = new LengthAwarePaginator($rules, $count, $limit, $page);
$paginator = new LengthAwarePaginator($rules, $count, $limit, $page);
$paginator->setPath(route('api.v1.bills.rules', [$bill->id]).$this->buildParams());
/** @var RuleTransformer $transformer */
$transformer = app(RuleTransformer::class);
$resource = new FractalCollection($rules, $transformer, 'rules');
$transformer = app(RuleTransformer::class);
$resource = new FractalCollection($rules, $transformer, 'rules');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -127,16 +137,22 @@ final class ListController extends Controller
*/
public function transactions(PaginationDateRangeRequest $request, Bill $bill): JsonResponse
{
['limit' => $limit, 'page' => $page, 'types' => $types, 'start' => $start, 'end' => $end] = $request->attributes->all();
[
'limit' => $limit,
'page' => $page,
'types' => $types,
'start' => $start,
'end' => $end,
] = $request->attributes->all();
$manager = $this->getManager();
$manager = $this->getManager();
/** @var User $admin */
$admin = auth()->user();
$admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// include source + destination account name and type.
@@ -159,18 +175,18 @@ final class ListController extends Controller
}
// get paginator.
$paginator = $collector->getPaginatedGroups();
$paginator = $collector->getPaginatedGroups();
$paginator->setPath(route('api.v1.bills.transactions', [$bill->id]).$this->buildParams());
// enrich
$enrichment = new TransactionGroupEnrichment();
$enrichment = new TransactionGroupEnrichment();
$enrichment->setUser($admin);
$transactions = $enrichment->enrich($paginator->getCollection());
$transactions = $enrichment->enrich($paginator->getCollection());
/** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionGroupTransformer::class);
$transformer = app(TransactionGroupTransformer::class);
$resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);

View File

@@ -41,7 +41,7 @@ use League\Fractal\Resource\Item;
/**
* Class ShowController
*/
final class ShowController extends Controller
class ShowController extends Controller
{
private BillRepositoryInterface $repository;
@@ -51,12 +51,14 @@ final class ShowController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**
@@ -67,28 +69,34 @@ final class ShowController extends Controller
*/
public function index(PaginationDateRangeRequest $request): JsonResponse
{
['limit' => $limit, 'offset' => $offset, 'start' => $start, 'end' => $end, 'page' => $page] = $request->attributes->all();
[
'limit' => $limit,
'offset' => $offset,
'start' => $start,
'end' => $end,
'page' => $page,
] = $request->attributes->all();
$this->repository->correctOrder();
$bills = $this->repository->getBills();
$manager = $this->getManager();
$count = $bills->count();
$bills = $bills->slice($offset, $limit);
$paginator = new LengthAwarePaginator($bills, $count, $limit, $page);
$bills = $this->repository->getBills();
$manager = $this->getManager();
$count = $bills->count();
$bills = $bills->slice($offset, $limit);
$paginator = new LengthAwarePaginator($bills, $count, $limit, $page);
// enrich
/** @var User $admin */
$admin = auth()->user();
$enrichment = new SubscriptionEnrichment();
$admin = auth()->user();
$enrichment = new SubscriptionEnrichment();
$enrichment->setUser($admin);
$enrichment->setStart($start);
$enrichment->setEnd($end);
$bills = $enrichment->enrich($bills);
$bills = $enrichment->enrich($bills);
/** @var BillTransformer $transformer */
$transformer = app(BillTransformer::class);
$transformer = app(BillTransformer::class);
$resource = new FractalCollection($bills, $transformer, 'bills');
$resource = new FractalCollection($bills, $transformer, 'bills');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -102,23 +110,26 @@ final class ShowController extends Controller
*/
public function show(DateRangeRequest $request, Bill $bill): JsonResponse
{
['start' => $start, 'end' => $end] = $request->attributes->all();
[
'start' => $start,
'end' => $end,
] = $request->attributes->all();
$manager = $this->getManager();
$manager = $this->getManager();
// enrich
/** @var User $admin */
$admin = auth()->user();
$enrichment = new SubscriptionEnrichment();
$admin = auth()->user();
$enrichment = new SubscriptionEnrichment();
$enrichment->setUser($admin);
$enrichment->setStart($start);
$enrichment->setEnd($end);
$bill = $enrichment->enrichSingle($bill);
$bill = $enrichment->enrichSingle($bill);
/** @var BillTransformer $transformer */
$transformer = app(BillTransformer::class);
$transformer = app(BillTransformer::class);
$resource = new Item($bill, $transformer, 'bills');
$resource = new Item($bill, $transformer, 'bills');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}

View File

@@ -38,7 +38,7 @@ use League\Fractal\Resource\Item;
/**
* Class StoreController
*/
final class StoreController extends Controller
class StoreController extends Controller
{
use TransactionFilter;
@@ -50,12 +50,14 @@ final class StoreController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -37,7 +37,7 @@ use League\Fractal\Resource\Item;
/**
* Class UpdateController
*/
final class UpdateController extends Controller
class UpdateController extends Controller
{
private BillRepositoryInterface $repository;
@@ -47,12 +47,14 @@ final class UpdateController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -33,7 +33,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class DestroyController
*/
final class DestroyController extends Controller
class DestroyController extends Controller
{
private BudgetRepositoryInterface $repository;
@@ -43,12 +43,14 @@ final class DestroyController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(BudgetRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(BudgetRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -44,12 +44,12 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
// Class ListController
final class ListController extends Controller
class ListController extends Controller
{
use TransactionFilter;
private BudgetLimitRepositoryInterface $blRepository;
private BudgetRepositoryInterface $repository;
private BudgetRepositoryInterface $repository;
/**
* ListController constructor.
@@ -57,14 +57,16 @@ final class ListController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(BudgetRepositoryInterface::class);
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->blRepository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(BudgetRepositoryInterface::class);
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->blRepository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**
@@ -118,6 +120,7 @@ final class ListController extends Controller
$enrichment->setUser($admin);
$budgetLimits = $enrichment->enrich($budgetLimits);
/** @var BudgetLimitTransformer $transformer */
$transformer = app(BudgetLimitTransformer::class);
$transformer->setParameters($this->parameters);

View File

@@ -40,10 +40,10 @@ use League\Fractal\Resource\Item;
/**
* Class ShowController
*/
final class ShowController extends Controller
class ShowController extends Controller
{
private BudgetLimitRepositoryInterface $blRepository;
private BudgetRepositoryInterface $repository;
private BudgetRepositoryInterface $repository;
/**
* ListController constructor.
@@ -51,14 +51,16 @@ final class ShowController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(BudgetRepositoryInterface::class);
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->blRepository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(BudgetRepositoryInterface::class);
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->blRepository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -37,7 +37,7 @@ use League\Fractal\Resource\Item;
/**
* Class StoreController
*/
final class StoreController extends Controller
class StoreController extends Controller
{
private BudgetRepositoryInterface $repository;
@@ -47,12 +47,14 @@ final class StoreController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(BudgetRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(BudgetRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -37,7 +37,7 @@ use League\Fractal\Resource\Item;
/**
* Class UpdateController
*/
final class UpdateController extends Controller
class UpdateController extends Controller
{
private BudgetRepositoryInterface $repository;
@@ -47,12 +47,14 @@ final class UpdateController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(BudgetRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(BudgetRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
public function update(UpdateRequest $request, Budget $budget): JsonResponse

View File

@@ -36,7 +36,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class DestroyController
*/
final class DestroyController extends Controller
class DestroyController extends Controller
{
private BudgetLimitRepositoryInterface $blRepository;
@@ -46,14 +46,16 @@ final class DestroyController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
$this->blRepository->setUser($user);
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
$this->blRepository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -40,7 +40,7 @@ use League\Fractal\Resource\Collection as FractalCollection;
/**
* Class ListController
*/
final class ListController extends Controller
class ListController extends Controller
{
use TransactionFilter;

View File

@@ -44,10 +44,10 @@ use League\Fractal\Resource\Item;
/**
* Class ShowController
*/
final class ShowController extends Controller
class ShowController extends Controller
{
private BudgetLimitRepositoryInterface $blRepository;
private BudgetRepositoryInterface $repository;
private BudgetRepositoryInterface $repository;
/**
* BudgetLimitController constructor.
@@ -55,16 +55,18 @@ final class ShowController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(BudgetRepositoryInterface::class);
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
$this->repository->setUser($user);
$this->blRepository->setUser($user);
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(BudgetRepositoryInterface::class);
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
$this->repository->setUser($user);
$this->blRepository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**
@@ -86,6 +88,7 @@ final class ShowController extends Controller
/** @var Budget $budget */
$budget = $enrichment->enrichSingle($budget);
$manager = $this->getManager();
$manager->parseIncludes('budget');
$pageSize = $this->parameters->get('limit');

View File

@@ -37,7 +37,7 @@ use League\Fractal\Resource\Item;
/**
* Class StoreController
*/
final class StoreController extends Controller
class StoreController extends Controller
{
private BudgetLimitRepositoryInterface $blRepository;
@@ -47,14 +47,16 @@ final class StoreController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
$this->blRepository->setUser($user);
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
$this->blRepository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -39,7 +39,7 @@ use League\Fractal\Resource\Item;
/**
* Class UpdateController
*/
final class UpdateController extends Controller
class UpdateController extends Controller
{
private BudgetLimitRepositoryInterface $blRepository;
@@ -52,14 +52,16 @@ final class UpdateController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
$this->blRepository->setUser($user);
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
$this->blRepository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -33,7 +33,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class DestroyController
*/
final class DestroyController extends Controller
class DestroyController extends Controller
{
private CategoryRepositoryInterface $repository;
@@ -43,12 +43,14 @@ final class DestroyController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(CategoryRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(CategoryRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -42,7 +42,7 @@ use League\Fractal\Resource\Collection as FractalCollection;
/**
* Class ListController
*/
final class ListController extends Controller
class ListController extends Controller
{
use TransactionFilter;
@@ -54,12 +54,14 @@ final class ListController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(CategoryRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(CategoryRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -39,7 +39,7 @@ use League\Fractal\Resource\Item;
/**
* Class ShowController
*/
final class ShowController extends Controller
class ShowController extends Controller
{
private CategoryRepositoryInterface $repository;
@@ -49,12 +49,14 @@ final class ShowController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(CategoryRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(CategoryRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -37,7 +37,7 @@ use League\Fractal\Resource\Item;
/**
* Class StoreController
*/
final class StoreController extends Controller
class StoreController extends Controller
{
private CategoryRepositoryInterface $repository;
@@ -47,12 +47,14 @@ final class StoreController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(CategoryRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(CategoryRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -37,7 +37,7 @@ use League\Fractal\Resource\Item;
/**
* Class UpdateController
*/
final class UpdateController extends Controller
class UpdateController extends Controller
{
private CategoryRepositoryInterface $repository;
@@ -47,12 +47,14 @@ final class UpdateController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(CategoryRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(CategoryRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
use Illuminate\Http\Request;
use Carbon\Carbon;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\DestroyRequest;
@@ -34,26 +35,26 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
final class DestroyController extends Controller
class DestroyController extends Controller
{
use ValidatesUserGroupTrait;
public const string RESOURCE_KEY = 'exchange-rates';
protected array $acceptedRoles = [UserRoleEnum::OWNER];
private ExchangeRateRepositoryInterface $repository;
public function __construct()
{
parent::__construct();
$this->middleware(function (Request $request, $next) {
$this->repository = app(ExchangeRateRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
$this->middleware(
function (Request $request, $next) {
$this->repository = app(ExchangeRateRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
return $next($request);
});
return $next($request);
}
);
}
public function destroy(DestroyRequest $request, TransactionCurrency $from, TransactionCurrency $to): JsonResponse
@@ -63,6 +64,13 @@ final class DestroyController extends Controller
return response()->json([], 204);
}
public function destroySingleById(CurrencyExchangeRate $exchangeRate): JsonResponse
{
$this->repository->deleteRate($exchangeRate);
return response()->json([], 204);
}
public function destroySingleByDate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): JsonResponse
{
$exchangeRate = $this->repository->getSpecificRateOnDate($from, $to, $date);
@@ -75,11 +83,4 @@ final class DestroyController extends Controller
return response()->json([], 204);
}
public function destroySingleById(CurrencyExchangeRate $exchangeRate): JsonResponse
{
$this->repository->deleteRate($exchangeRate);
return response()->json([], 204);
}
}

View File

@@ -24,36 +24,37 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
use Illuminate\Http\Request;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Transformers\ExchangeRateTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
/**
* Class ShowController
*/
final class IndexController extends Controller
class IndexController extends Controller
{
use ValidatesUserGroupTrait;
public const string RESOURCE_KEY = 'exchange-rates';
protected array $acceptedRoles = [UserRoleEnum::OWNER];
private ExchangeRateRepositoryInterface $repository;
public function __construct()
{
parent::__construct();
$this->middleware(function (Request $request, $next) {
$this->repository = app(ExchangeRateRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
$this->middleware(
function (Request $request, $next) {
$this->repository = app(ExchangeRateRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
return $next($request);
});
return $next($request);
}
);
}
public function index(): JsonResponse
@@ -66,6 +67,9 @@ final class IndexController extends Controller
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters); // give params to transformer
return response()->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))->header('Content-Type', self::CONTENT_TYPE);
return response()
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
->header('Content-Type', self::CONTENT_TYPE)
;
}
}

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
use Illuminate\Http\Request;
use Carbon\Carbon;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Enums\UserRoleEnum;
@@ -33,31 +34,31 @@ use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Transformers\ExchangeRateTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class ShowController
*/
final class ShowController extends Controller
class ShowController extends Controller
{
use ValidatesUserGroupTrait;
public const string RESOURCE_KEY = 'exchange-rates';
protected array $acceptedRoles = [UserRoleEnum::OWNER];
private ExchangeRateRepositoryInterface $repository;
public function __construct()
{
parent::__construct();
$this->middleware(function (Request $request, $next) {
$this->repository = app(ExchangeRateRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
$this->middleware(
function (Request $request, $next) {
$this->repository = app(ExchangeRateRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
return $next($request);
});
return $next($request);
}
);
}
public function show(TransactionCurrency $from, TransactionCurrency $to): JsonResponse
@@ -72,7 +73,21 @@ final class ShowController extends Controller
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters); // give params to transformer
return response()->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))->header('Content-Type', self::CONTENT_TYPE);
return response()
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
->header('Content-Type', self::CONTENT_TYPE)
;
}
public function showSingleById(CurrencyExchangeRate $exchangeRate): JsonResponse
{
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters);
return response()
->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer))
->header('Content-Type', self::CONTENT_TYPE)
;
}
public function showSingleByDate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): JsonResponse
@@ -85,14 +100,9 @@ final class ShowController extends Controller
throw new NotFoundHttpException();
}
return response()->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer))->header('Content-Type', self::CONTENT_TYPE);
}
public function showSingleById(CurrencyExchangeRate $exchangeRate): JsonResponse
{
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters);
return response()->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer))->header('Content-Type', self::CONTENT_TYPE);
return response()
->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer))
->header('Content-Type', self::CONTENT_TYPE)
;
}
}

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
use Illuminate\Http\Request;
use Carbon\Carbon;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\StoreByCurrenciesRequest;
@@ -37,28 +38,90 @@ use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Transformers\ExchangeRateTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
final class StoreController extends Controller
class StoreController extends Controller
{
use ValidatesUserGroupTrait;
public const string RESOURCE_KEY = 'exchange-rates';
protected array $acceptedRoles = [UserRoleEnum::OWNER];
public const string RESOURCE_KEY = 'exchange-rates';
protected array $acceptedRoles = [UserRoleEnum::OWNER];
private ExchangeRateRepositoryInterface $repository;
public function __construct()
{
parent::__construct();
$this->middleware(function (Request $request, $next) {
$this->repository = app(ExchangeRateRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
$this->middleware(
function (Request $request, $next) {
$this->repository = app(ExchangeRateRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
return $next($request);
});
return $next($request);
}
);
}
public function storeByCurrencies(StoreByCurrenciesRequest $request, TransactionCurrency $from, TransactionCurrency $to): JsonResponse
{
$data = $request->getAll();
$collection = new Collection();
foreach ($data as $date => $rate) {
$date = Carbon::createFromFormat('Y-m-d', $date);
$existing = $this->repository->getSpecificRateOnDate($from, $to, $date);
if ($existing instanceof CurrencyExchangeRate) {
// update existing rate.
$existing = $this->repository->updateExchangeRate($existing, $rate);
$collection->push($existing);
continue;
}
$new = $this->repository->storeExchangeRate($from, $to, $rate, $date);
$collection->push($new);
}
$count = $collection->count();
$paginator = new LengthAwarePaginator($collection, $count, $count, 1);
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters); // give params to transformer
return response()
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
->header('Content-Type', self::CONTENT_TYPE)
;
}
public function storeByDate(StoreByDateRequest $request, Carbon $date): JsonResponse
{
$data = $request->getAll();
$from = $request->getFromCurrency();
$collection = new Collection();
foreach ($data['rates'] as $key => $rate) {
$to = Amount::getTransactionCurrencyByCode($key);
$existing = $this->repository->getSpecificRateOnDate($from, $to, $date);
if ($existing instanceof CurrencyExchangeRate) {
// update existing rate.
$existing = $this->repository->updateExchangeRate($existing, $rate);
$collection->push($existing);
continue;
}
$new = $this->repository->storeExchangeRate($from, $to, $rate, $date);
$collection->push($new);
}
$count = $collection->count();
$paginator = new LengthAwarePaginator($collection, $count, $count, 1);
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters); // give params to transformer
return response()
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
->header('Content-Type', self::CONTENT_TYPE)
;
}
public function store(StoreRequest $request): JsonResponse
@@ -82,60 +145,9 @@ final class StoreController extends Controller
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters);
return response()->api($this->jsonApiObject(self::RESOURCE_KEY, $rate, $transformer))->header('Content-Type', self::CONTENT_TYPE);
}
public function storeByCurrencies(StoreByCurrenciesRequest $request, TransactionCurrency $from, TransactionCurrency $to): JsonResponse
{
$data = $request->getAll();
$collection = new Collection();
foreach ($data as $date => $rate) {
$date = Carbon::createFromFormat('Y-m-d', $date);
$existing = $this->repository->getSpecificRateOnDate($from, $to, $date);
if ($existing instanceof CurrencyExchangeRate) {
// update existing rate.
$existing = $this->repository->updateExchangeRate($existing, $rate);
$collection->push($existing);
continue;
}
$new = $this->repository->storeExchangeRate($from, $to, $rate, $date);
$collection->push($new);
}
$count = $collection->count();
$paginator = new LengthAwarePaginator($collection, $count, $count, 1);
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters); // give params to transformer
return response()->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))->header('Content-Type', self::CONTENT_TYPE);
}
public function storeByDate(StoreByDateRequest $request, Carbon $date): JsonResponse
{
$data = $request->getAll();
$from = $request->getFromCurrency();
$collection = new Collection();
foreach ($data['rates'] as $key => $rate) {
$to = Amount::getTransactionCurrencyByCode($key);
$existing = $this->repository->getSpecificRateOnDate($from, $to, $date);
if ($existing instanceof CurrencyExchangeRate) {
// update existing rate.
$existing = $this->repository->updateExchangeRate($existing, $rate);
$collection->push($existing);
continue;
}
$new = $this->repository->storeExchangeRate($from, $to, $rate, $date);
$collection->push($new);
}
$count = $collection->count();
$paginator = new LengthAwarePaginator($collection, $count, $count, 1);
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters); // give params to transformer
return response()->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))->header('Content-Type', self::CONTENT_TYPE);
return response()
->api($this->jsonApiObject(self::RESOURCE_KEY, $rate, $transformer))
->header('Content-Type', self::CONTENT_TYPE)
;
}
}

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
use Illuminate\Http\Request;
use Carbon\Carbon;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\UpdateRequest;
@@ -34,27 +35,41 @@ use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Transformers\ExchangeRateTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
final class UpdateController extends Controller
class UpdateController extends Controller
{
use ValidatesUserGroupTrait;
public const string RESOURCE_KEY = 'exchange-rates';
protected array $acceptedRoles = [UserRoleEnum::OWNER];
public const string RESOURCE_KEY = 'exchange-rates';
protected array $acceptedRoles = [UserRoleEnum::OWNER];
private ExchangeRateRepositoryInterface $repository;
public function __construct()
{
parent::__construct();
$this->middleware(function (Request $request, $next) {
$this->repository = app(ExchangeRateRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
$this->middleware(
function (Request $request, $next) {
$this->repository = app(ExchangeRateRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
return $next($request);
});
return $next($request);
}
);
}
public function updateById(UpdateRequest $request, CurrencyExchangeRate $exchangeRate): JsonResponse
{
$date = $request->getDate();
$rate = $request->getRate();
$exchangeRate = $this->repository->updateExchangeRate($exchangeRate, $rate, $date);
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters);
return response()
->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer))
->header('Content-Type', self::CONTENT_TYPE)
;
}
public function updateByDate(UpdateRequest $request, TransactionCurrency $from, TransactionCurrency $to, Carbon $date): JsonResponse
@@ -69,17 +84,9 @@ final class UpdateController extends Controller
$transformer = new ExchangeRateTransformer();
return response()->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer))->header('Content-Type', self::CONTENT_TYPE);
}
public function updateById(UpdateRequest $request, CurrencyExchangeRate $exchangeRate): JsonResponse
{
$date = $request->getDate();
$rate = $request->getRate();
$exchangeRate = $this->repository->updateExchangeRate($exchangeRate, $rate, $date);
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters);
return response()->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer))->header('Content-Type', self::CONTENT_TYPE);
return response()
->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer))
->header('Content-Type', self::CONTENT_TYPE)
;
}
}

View File

@@ -34,7 +34,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class DestroyController
*/
final class DestroyController extends Controller
class DestroyController extends Controller
{
private ObjectGroupRepositoryInterface $repository;
@@ -44,14 +44,16 @@ final class DestroyController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(ObjectGroupRepositoryInterface::class);
$this->repository->setUser($user);
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(ObjectGroupRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -40,7 +40,7 @@ use League\Fractal\Resource\Collection as FractalCollection;
/**
* Class ListController
*/
final class ListController extends Controller
class ListController extends Controller
{
private ObjectGroupRepositoryInterface $repository;
@@ -50,14 +50,16 @@ final class ListController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(ObjectGroupRepositoryInterface::class);
$this->repository->setUser($user);
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(ObjectGroupRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -38,7 +38,7 @@ use League\Fractal\Resource\Item;
/**
* Class ShowController
*/
final class ShowController extends Controller
class ShowController extends Controller
{
private ObjectGroupRepositoryInterface $repository;
@@ -48,14 +48,16 @@ final class ShowController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(ObjectGroupRepositoryInterface::class);
$this->repository->setUser($user);
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(ObjectGroupRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -36,7 +36,7 @@ use League\Fractal\Resource\Item;
/**
* Class UpdateController
*/
final class UpdateController extends Controller
class UpdateController extends Controller
{
private ObjectGroupRepositoryInterface $repository;
@@ -46,14 +46,16 @@ final class UpdateController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(ObjectGroupRepositoryInterface::class);
$this->repository->setUser($user);
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(ObjectGroupRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -33,7 +33,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class DestroyController
*/
final class DestroyController extends Controller
class DestroyController extends Controller
{
private PiggyBankRepositoryInterface $repository;
@@ -43,12 +43,14 @@ final class DestroyController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(PiggyBankRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(PiggyBankRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -41,7 +41,7 @@ use League\Fractal\Resource\Collection as FractalCollection;
/**
* Class ListController
*/
final class ListController extends Controller
class ListController extends Controller
{
private PiggyBankRepositoryInterface $repository;
@@ -51,12 +51,14 @@ final class ListController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(PiggyBankRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(PiggyBankRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -39,7 +39,7 @@ use League\Fractal\Resource\Item;
/**
* Class ShowController
*/
final class ShowController extends Controller
class ShowController extends Controller
{
private PiggyBankRepositoryInterface $repository;
@@ -49,12 +49,14 @@ final class ShowController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(PiggyBankRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(PiggyBankRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**
@@ -112,6 +114,7 @@ final class ShowController extends Controller
$enrichment->setUser($admin);
$piggyBank = $enrichment->enrichSingle($piggyBank);
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);
$transformer->setParameters($this->parameters);

View File

@@ -37,7 +37,7 @@ use League\Fractal\Resource\Item;
/**
* Class StoreController
*/
final class StoreController extends Controller
class StoreController extends Controller
{
private PiggyBankRepositoryInterface $repository;
@@ -47,12 +47,14 @@ final class StoreController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(PiggyBankRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(PiggyBankRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -37,7 +37,7 @@ use League\Fractal\Resource\Item;
/**
* Class UpdateController
*/
final class UpdateController extends Controller
class UpdateController extends Controller
{
private PiggyBankRepositoryInterface $repository;
@@ -47,12 +47,14 @@ final class UpdateController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(PiggyBankRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(PiggyBankRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -33,7 +33,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class DestroyController
*/
final class DestroyController extends Controller
class DestroyController extends Controller
{
private RecurringRepositoryInterface $repository;
@@ -43,12 +43,14 @@ final class DestroyController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(RecurringRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(RecurringRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -40,7 +40,7 @@ use League\Fractal\Resource\Collection as FractalCollection;
/**
* Class ListController
*/
final class ListController extends Controller
class ListController extends Controller
{
use TransactionFilter;
@@ -52,12 +52,14 @@ final class ListController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(RecurringRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(RecurringRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -39,7 +39,7 @@ use League\Fractal\Resource\Item;
/**
* Class ShowController
*/
final class ShowController extends Controller
class ShowController extends Controller
{
private RecurringRepositoryInterface $repository;
@@ -49,12 +49,14 @@ final class ShowController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(RecurringRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(RecurringRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -37,7 +37,7 @@ use League\Fractal\Resource\Item;
/**
* Class StoreController
*/
final class StoreController extends Controller
class StoreController extends Controller
{
private RecurringRepositoryInterface $repository;
@@ -47,12 +47,14 @@ final class StoreController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(RecurringRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(RecurringRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -1,7 +1,6 @@
<?php
declare(strict_types=1);
/*
* TriggerController.php
* Copyright (c) 2025 james@firefly-iii.org
@@ -41,7 +40,7 @@ use Illuminate\Support\Facades\Log;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
final class TriggerController extends Controller
class TriggerController extends Controller
{
private RecurringRepositoryInterface $repository;
@@ -51,40 +50,44 @@ final class TriggerController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(RecurringRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(RecurringRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
public function trigger(SingleDateRequest $request, Recurrence $recurrence): JsonResponse
{
// find recurrence occurrence for this date and trigger it.
// grab the date from the last time the recurrence fired:
$backupDate = $recurrence->latest_date;
$date = $request->getDate();
$backupDate = $recurrence->latest_date;
$date = $request->getDate();
// fire the recurring cron job on the given date, then post-date the created transaction.
Log::info(sprintf('Trigger: will now fire recurring cron job task for date "%s".', $date->format('Y-m-d H:i:s')));
/** @var CreateRecurringTransactions $job */
$job = app(CreateRecurringTransactions::class);
$job = app(CreateRecurringTransactions::class);
$job->setRecurrences(new Collection()->push($recurrence));
$job->setDate($date);
$job->setForce(false);
$job->handle();
Log::debug('Done with recurrence.');
$groups = $job->getGroups();
$groups = $job->getGroups();
$this->repository->markGroupsAsNow($groups);
$recurrence = $this->repository->setLatestDate($recurrence, $backupDate);
$recurrence->latest_date = $backupDate;
$recurrence->latest_date_tz = $backupDate?->format('e');
$recurrence->save();
Preferences::mark();
// enrich groups and return them:
$paginator = new LengthAwarePaginator(new Collection(), 0, 1);
$paginator = new LengthAwarePaginator(new Collection(), 0, 1);
if ($groups->count() > 0) {
/** @var User $admin */
$admin = auth()->user();
@@ -92,24 +95,28 @@ final class TriggerController extends Controller
// use new group collector:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($admin)->setIds($groups->pluck('id')->toArray())->withAPIInformation();
$collector
->setUser($admin)
->setIds($groups->pluck('id')->toArray())
->withAPIInformation()
;
$paginator = $collector->getPaginatedGroups();
}
$manager = $this->getManager();
$manager = $this->getManager();
$paginator->setPath(route('api.v1.recurrences.trigger', [$recurrence->id]).$this->buildParams());
// enrich
$admin = auth()->user();
$enrichment = new TransactionGroupEnrichment();
$admin = auth()->user();
$enrichment = new TransactionGroupEnrichment();
$enrichment->setUser($admin);
$transactions = $enrichment->enrich($paginator->getCollection());
$transactions = $enrichment->enrich($paginator->getCollection());
/** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionGroupTransformer::class);
$transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);

View File

@@ -37,7 +37,7 @@ use League\Fractal\Resource\Item;
/**
* Class UpdateController
*/
final class UpdateController extends Controller
class UpdateController extends Controller
{
private RecurringRepositoryInterface $repository;
@@ -47,12 +47,14 @@ final class UpdateController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(RecurringRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->middleware(
function ($request, $next) {
$this->repository = app(RecurringRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
});
return $next($request);
}
);
}
/**

View File

@@ -34,7 +34,7 @@ use Illuminate\Http\JsonResponse;
/**
* Class DestroyController
*/
final class DestroyController extends Controller
class DestroyController extends Controller
{
private RuleRepositoryInterface $ruleRepository;
@@ -44,15 +44,17 @@ final class DestroyController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->ruleRepository = app(RuleRepositoryInterface::class);
$this->ruleRepository->setUser($user);
$this->ruleRepository = app(RuleRepositoryInterface::class);
$this->ruleRepository->setUser($user);
return $next($request);
});
return $next($request);
}
);
}
/**

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