mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 10:47:00 +00:00 
			
		
		
		
	Compare commits
	
		
			52 Commits
		
	
	
		
			develop-20
			...
			develop-20
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 56bac9fc97 | ||
|  | b93cfc5de2 | ||
|  | d41f5b1090 | ||
|  | 40322813c9 | ||
|  | 4a98927e32 | ||
|  | 193e529803 | ||
|  | fbf20ef2c2 | ||
|  | 54de829c8a | ||
|  | 131b987561 | ||
|  | dce6754c62 | ||
|  | f4bca90080 | ||
|  | b2960b1ed9 | ||
|  | 33f87bce23 | ||
|  | 23aa45609b | ||
|  | b098952f82 | ||
|  | 68c3e14b0c | ||
|  | 19d08137a5 | ||
|  | 73776e7869 | ||
|  | bf04ca12c1 | ||
|  | a4637debe9 | ||
|  | 48c1b525be | ||
|  | 56470bfbba | ||
|  | 0f732ca874 | ||
|  | e452ba938d | ||
|  | 9921c5a925 | ||
|  | 58fab75681 | ||
|  | 54990308f6 | ||
|  | f95758ff47 | ||
|  | 8d830e178f | ||
|  | 334a521ca1 | ||
|  | 12629a1955 | ||
|  | 2e3669a32f | ||
|  | ea337607c4 | ||
|  | f7f317a3b2 | ||
|  | adbf6defe5 | ||
|  | e0709f2975 | ||
|  | 30007b05cb | ||
|  | 13fc7f0d8d | ||
|  | 7c85138115 | ||
|  | 2c25f65f7f | ||
|  | 7eaba962e8 | ||
|  | 7c38393cde | ||
|  | 153fd2ae74 | ||
|  | c0204c810c | ||
|  | 944c107e26 | ||
|  | 18e05c06fd | ||
|  | fb79dbf17c | ||
|  | 31a8163c61 | ||
|  | 8bcd729250 | ||
|  | 80c4e69528 | ||
|  | 7f6d8fdb87 | ||
|  | c8e301326e | 
							
								
								
									
										12
									
								
								.ci/php-cs-fixer/composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										12
									
								
								.ci/php-cs-fixer/composer.lock
									
									
									
										generated
									
									
									
								
							| @@ -406,16 +406,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "friendsofphp/php-cs-fixer", | ||||
|             "version": "v3.69.0", | ||||
|             "version": "v3.70.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", | ||||
|                 "reference": "630a59448c00729bc235d5e95cfedefeaca37523" | ||||
|                 "reference": "2ecd5aae0edc937f0d5aa4a22d1d705c6b2e084e" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/630a59448c00729bc235d5e95cfedefeaca37523", | ||||
|                 "reference": "630a59448c00729bc235d5e95cfedefeaca37523", | ||||
|                 "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/2ecd5aae0edc937f0d5aa4a22d1d705c6b2e084e", | ||||
|                 "reference": "2ecd5aae0edc937f0d5aa4a22d1d705c6b2e084e", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -497,7 +497,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.69.0" | ||||
|                 "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.70.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -505,7 +505,7 @@ | ||||
|                     "type": "github" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-02-14T16:19:23+00:00" | ||||
|             "time": "2025-02-22T23:30:51+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "psr/container", | ||||
|   | ||||
| @@ -19,7 +19,7 @@ SITE_OWNER=mail@example.com | ||||
| APP_KEY=SomeRandomStringOf32CharsExactly | ||||
|  | ||||
| # Firefly III will launch using this language (for new users and unauthenticated visitors) | ||||
| # For a list of available languages: https://github.com/firefly-iii/firefly-iii/tree/main/resources/lang | ||||
| # For a list of available languages: https://github.com/firefly-iii/firefly-iii/blob/main/config/firefly.php#L123 | ||||
| # | ||||
| # If text is still in English, remember that not everything may have been translated. | ||||
| DEFAULT_LANGUAGE=en_US | ||||
|   | ||||
							
								
								
									
										12
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -204,9 +204,9 @@ jobs: | ||||
|  | ||||
|           # zip and tar everything | ||||
|           echo 'Zip and tar...' | ||||
|           zip -rq $zipName . -x "*.git*" "*.ci*" "*.github*" "*node_modules*" "*output.txt*" | ||||
|           zip -rq $zipName . -x "*.git*" "*.ci*" "*.github*" "*node_modules*" "*output.txt*" "*Procfile*" "*crowdin.yml*" "*sonar-project.properties*" | ||||
|           touch $tarName | ||||
|           tar --exclude=$tarName --exclude=$zipName --exclude='./.git' --exclude='./.ci' --exclude='./.github' --exclude='./node_modules' --exclude='./output.txt' -czf $tarName . | ||||
|           tar --exclude=$tarName --exclude=$zipName --exclude='./.git' --exclude='./.ci' --exclude='./.github' --exclude='./node_modules' --exclude='./output.txt' --exclude='./Procfile' --exclude='../crowdin.yml' --exclude='./sonar-project.properties' -czf $tarName . | ||||
|  | ||||
|           # add sha256 sum | ||||
|           echo 'Sha sum ...' | ||||
| @@ -225,7 +225,7 @@ jobs: | ||||
|             sudo chown -R runner:docker output.txt | ||||
|             echo "Weekly development release of Firefly III with the latest fixes, translations and features. Docker users can find this release under the \`develop\` tag." >> output.txt | ||||
|             echo "" >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo "" >> output.txt | ||||
|             echo "* Please read the installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt | ||||
|             echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt | ||||
| @@ -240,7 +240,7 @@ jobs: | ||||
|             sudo chown -R runner:docker output.txt | ||||
|             echo "Irregular BRANCH release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt | ||||
|             echo "" >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo "" >> output.txt | ||||
|             echo "* Please read the installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt | ||||
|             echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt | ||||
| @@ -268,7 +268,7 @@ jobs: | ||||
|             sudo chown -R runner:docker output.txt | ||||
|             echo "Very early ALPHA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo '### Instructions' >> output.txt | ||||
|             echo '' >> output.txt | ||||
| @@ -286,7 +286,7 @@ jobs: | ||||
|             sudo chown -R runner:docker output.txt | ||||
|             echo "Very early BETA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo '### Instructions' >> output.txt | ||||
|             echo '' >> output.txt | ||||
|   | ||||
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -14,7 +14,16 @@ public/build | ||||
| # ignore v1 build files | ||||
| resources/assets/v1/node_modules | ||||
| resources/assets/v1/build | ||||
| public/v1/js/app.js* | ||||
| public/v1/js/app_vue.js* | ||||
| public/v1/js/create* | ||||
| public/v1/js/edit* | ||||
| public/v1/js/profile* | ||||
| public/v1/js/administrations | ||||
| public/v1/js/exchange-rates | ||||
| public/v1/js/webhooks | ||||
|  | ||||
| # ignore v2 build files | ||||
| resources/assets/v2/node_modules | ||||
| resources/assets/v2/build | ||||
| public/v2/i18n | ||||
|   | ||||
| @@ -4,6 +4,7 @@ Over time, many people have contributed to Firefly III. Their efforts are not al | ||||
| Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution. | ||||
| 
 | ||||
| ## 2025 | ||||
| - Jose Diaz-Gonzalez | ||||
| - SoftBrix | ||||
| 
 | ||||
| ## 2024 | ||||
|   | ||||
| @@ -90,6 +90,7 @@ class StoreController extends Controller | ||||
|         $data['user']       = auth()->user(); | ||||
|         $data['user_group'] = $this->userGroup; | ||||
| 
 | ||||
| 
 | ||||
|         Log::channel('audit')->info('Store new transaction over API.', $data); | ||||
| 
 | ||||
|         try { | ||||
|   | ||||
| @@ -185,8 +185,8 @@ class BasicController extends Controller | ||||
|                 'currency_decimal_places' => $currency->decimal_places, | ||||
|                 'value_parsed'            => app('amount')->formatAnything($currency, $sums[$currencyId] ?? '0', false), | ||||
|                 'local_icon'              => 'balance-scale', | ||||
|                 'sub_title'               => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false). | ||||
|                                              ' + '.app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false), | ||||
|                 'sub_title'               => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false) | ||||
|                                              .' + '.app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false), | ||||
|             ]; | ||||
|             $return[] = [ | ||||
|                 'key'                     => sprintf('spent-in-%s', $currency->code), | ||||
|   | ||||
| @@ -49,9 +49,9 @@ class DestroyRequest extends FormRequest | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $valid = 'budgets,bills,piggy_banks,rules,recurring,categories,tags,object_groups'. | ||||
|                  ',accounts,asset_accounts,expense_accounts,revenue_accounts,liabilities,transactions,withdrawals,deposits,transfers'. | ||||
|                  ',not_assets_liabilities'; | ||||
|         $valid = 'budgets,bills,piggy_banks,rules,recurring,categories,tags,object_groups' | ||||
|                  .',accounts,asset_accounts,expense_accounts,revenue_accounts,liabilities,transactions,withdrawals,deposits,transfers' | ||||
|                  .',not_assets_liabilities'; | ||||
| 
 | ||||
|         return [ | ||||
|             'objects' => sprintf('required|max:255|min:1|string|in:%s', $valid), | ||||
|   | ||||
| @@ -65,25 +65,6 @@ class StoreRequest extends FormRequest | ||||
|         return $data; | ||||
|     } | ||||
| 
 | ||||
|     private function parseAccounts(mixed $array): array | ||||
|     { | ||||
|         if (!is_array($array)) { | ||||
|             return []; | ||||
|         } | ||||
|         $return = []; | ||||
|         foreach ($array as $entry) { | ||||
|             if (!is_array($entry)) { | ||||
|                 continue; | ||||
|             } | ||||
|             $return[] = [ | ||||
|                 'account_id'     => $this->integerFromValue((string) ($entry['account_id'] ?? '0')), | ||||
|                 'current_amount' => $this->clearString((string) ($entry['current_amount'] ?? '0')), | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      */ | ||||
|   | ||||
| @@ -25,8 +25,8 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Requests\Models\PiggyBank; | ||||
| 
 | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Rules\IsAssetAccountId; | ||||
| use FireflyIII\Rules\IsValidPositiveAmount; | ||||
| use FireflyIII\Rules\IsValidZeroOrMoreAmount; | ||||
| use FireflyIII\Rules\LessThanPiggyTarget; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| use FireflyIII\Support\Request\ConvertsDataTypes; | ||||
| @@ -45,20 +45,23 @@ class UpdateRequest extends FormRequest | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         $fields = [ | ||||
|             'name'               => ['name', 'convertString'], | ||||
|             'account_id'         => ['account_id', 'convertInteger'], | ||||
|             'targetamount'       => ['target_amount', 'convertString'], | ||||
|             'current_amount'     => ['current_amount', 'convertString'], | ||||
|             'startdate'          => ['start_date', 'convertDateTime'], | ||||
|             'targetdate'         => ['target_date', 'convertDateTime'], | ||||
|             'notes'              => ['notes', 'stringWithNewlines'], | ||||
|             'order'              => ['order', 'convertInteger'], | ||||
|             'object_group_title' => ['object_group_title', 'convertString'], | ||||
|             'object_group_id'    => ['object_group_id', 'convertInteger'], | ||||
|         $fields             = [ | ||||
|             'name'                      => ['name', 'convertString'], | ||||
|             'target_amount'             => ['target_amount', 'convertString'], | ||||
|             'start_date'                => ['start_date', 'convertDateTime'], | ||||
|             'target_date'               => ['target_date', 'convertDateTime'], | ||||
|             'notes'                     => ['notes', 'stringWithNewlines'], | ||||
|             'order'                     => ['order', 'convertInteger'], | ||||
|             'object_group_title'        => ['object_group_title', 'convertString'], | ||||
|             'object_group_id'           => ['object_group_id', 'convertInteger'], | ||||
|             'transaction_currency_code' => ['transaction_currency_code', 'convertString'], | ||||
|             'transaction_currency_id'   => ['transaction_currency_id', 'convertInteger'], | ||||
|         ]; | ||||
| 
 | ||||
|         return $this->getAllData($fields); | ||||
|         $result             = $this->getAllData($fields); | ||||
|         $result['accounts'] = $this->parseAccounts($this->get('accounts')); | ||||
| 
 | ||||
|         return $result; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @@ -70,13 +73,20 @@ class UpdateRequest extends FormRequest | ||||
|         $piggyBank = $this->route()->parameter('piggyBank'); | ||||
| 
 | ||||
|         return [ | ||||
|             'name'           => 'min:1|max:255|uniquePiggyBankForUser:'.$piggyBank->id, | ||||
|             'current_amount' => ['nullable', new LessThanPiggyTarget(), new IsValidPositiveAmount()], | ||||
|             'target_amount'  => ['nullable', new IsValidPositiveAmount()], | ||||
|             'start_date'     => 'date|nullable', | ||||
|             'target_date'    => 'date|nullable|after:start_date', | ||||
|             'notes'          => 'max:65000', | ||||
|             'account_id'     => ['belongsToUser:accounts', new IsAssetAccountId()], | ||||
|             'name'                      => 'min:1|max:255|uniquePiggyBankForUser:'.$piggyBank->id, | ||||
|             'current_amount'            => ['nullable', new LessThanPiggyTarget(), new IsValidPositiveAmount()], | ||||
|             'target_amount'             => ['nullable', new IsValidZeroOrMoreAmount()], | ||||
|             'start_date'                => 'date|nullable', | ||||
|             'target_date'               => 'date|nullable|after:start_date', | ||||
|             'notes'                     => 'max:65000', | ||||
|             'accounts'                  => 'required', | ||||
|             'accounts.*'                => 'array|required', | ||||
|             'accounts.*.account_id'     => ['required', 'numeric', 'belongsToUser:accounts,id'], | ||||
|             'accounts.*.current_amount' => ['numeric', new IsValidZeroOrMoreAmount()], | ||||
|             'object_group_id'           => 'numeric|belongsToUser:object_groups,id', | ||||
|             'object_group_title'        => ['min:1', 'max:255'], | ||||
|             'transaction_currency_id'   => 'exists:transaction_currencies,id|nullable', | ||||
|             'transaction_currency_code' => 'exists:transaction_currencies,code|nullable', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -73,6 +73,7 @@ class StoreController extends Controller | ||||
|         $userGroup          = $request->getUserGroup(); | ||||
|         $data['user_group'] = $userGroup; | ||||
| 
 | ||||
| 
 | ||||
|         // overrule user group and see where we end up.
 | ||||
|         // what happens when we refer to a budget that is not in this user group?
 | ||||
| 
 | ||||
|   | ||||
| @@ -106,7 +106,7 @@ class ExportsData extends Command | ||||
|         $exporter->setExportTags($options['export']['tags']); | ||||
|         $exporter->setExportRecurring($options['export']['recurring']); | ||||
|         $exporter->setExportRules($options['export']['rules']); | ||||
|         $exporter->setExportBills($options['export']['subscriptions']); | ||||
|         $exporter->setExportBills($options['export']['bills']); | ||||
|         $exporter->setExportPiggies($options['export']['piggies']); | ||||
|         $data       = $exporter->export(); | ||||
|         if (0 === count($data)) { | ||||
|   | ||||
| @@ -238,7 +238,8 @@ class UpgradesToGroups extends Command | ||||
|         return [ | ||||
|             'type'                => strtolower($journal->transactionType->type), | ||||
|             'date'                => $journal->date, | ||||
|             'user'                => $journal->user_id, | ||||
|             'user'                => $journal->user, | ||||
|             'user_group'          => $journal->user->userGroup, | ||||
|             'currency_id'         => $transaction->transaction_currency_id, | ||||
|             'foreign_currency_id' => $transaction->foreign_currency_id, | ||||
|             'amount'              => $transaction->amount, | ||||
|   | ||||
| @@ -48,8 +48,8 @@ class BillFactory | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now in %s', __METHOD__), $data); | ||||
|         $factory          = app(TransactionCurrencyFactory::class); | ||||
|         $currency         = $factory->find((int) ($data['currency_id'] ?? null), (string) ($data['currency_code'] ?? null)) ?? | ||||
|                     app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); | ||||
|         $currency         = $factory->find((int) ($data['currency_id'] ?? null), (string) ($data['currency_code'] ?? null)) | ||||
|                     ?? app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); | ||||
| 
 | ||||
|         try { | ||||
|             $skip   = array_key_exists('skip', $data) ? $data['skip'] : 0; | ||||
|   | ||||
| @@ -225,11 +225,13 @@ class ReconcileController extends Controller | ||||
|             ] | ||||
|         ); | ||||
|         $submission     = [ | ||||
|             'user'         => auth()->user()->id, | ||||
|             'group_title'  => null, | ||||
|             'transactions' => [ | ||||
|             'user'               => auth()->user(), | ||||
|             'user_group'         => auth()->user()->userGroup, | ||||
|             'group_title'        => null, | ||||
|             'transactions'       => [ | ||||
|                 [ | ||||
|                     'user'                => auth()->user()->id, | ||||
|                     'user'                => auth()->user(), | ||||
|                     'user_group'          => auth()->user()->userGroup, | ||||
|                     'type'                => strtolower(TransactionTypeEnum::RECONCILIATION->value), | ||||
|                     'date'                => $end, | ||||
|                     'order'               => 0, | ||||
|   | ||||
| @@ -224,7 +224,7 @@ class LoginController extends Controller | ||||
|     { | ||||
|         Log::channel('audit')->info('Show login form (1.1).'); | ||||
| 
 | ||||
|         $count             = DB::table('users')->whereNull('deleted_at')->count(); | ||||
|         $count             = DB::table('users')->count(); | ||||
|         $guard             = config('auth.defaults.guard'); | ||||
|         $title             = (string) trans('firefly.login_page_title'); | ||||
| 
 | ||||
|   | ||||
| @@ -31,6 +31,7 @@ use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Repositories\ObjectGroup\OrganisesObjectGroups; | ||||
| use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment; | ||||
| use FireflyIII\Transformers\AccountTransformer; | ||||
| use FireflyIII\Transformers\PiggyBankTransformer; | ||||
| use Illuminate\Contracts\View\Factory; | ||||
| @@ -81,25 +82,25 @@ class IndexController extends Controller | ||||
|     { | ||||
|         $this->cleanupObjectGroups(); | ||||
|         $this->piggyRepos->resetOrder(); | ||||
|         $collection         = $this->piggyRepos->getPiggyBanks(); | ||||
|         $collection = $this->piggyRepos->getPiggyBanks(); | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end                = session('end', today(config('app.timezone'))->endOfMonth()); | ||||
|         $end        = session('end', today(config('app.timezone'))->endOfMonth()); | ||||
| 
 | ||||
|         // transform piggies using the transformer:
 | ||||
|         $parameters         = new ParameterBag(); | ||||
|         $parameters->set('end', $end); | ||||
|         // $parameters         = new ParameterBag();
 | ||||
|         // $parameters->set('end', $end);
 | ||||
| 
 | ||||
| 
 | ||||
|         /** @var AccountTransformer $accountTransformer */ | ||||
|         $accountTransformer = app(AccountTransformer::class); | ||||
|         $accountTransformer->setParameters($parameters); | ||||
|         // /** @var AccountTransformer $accountTransformer */
 | ||||
|         // $accountTransformer = app(AccountTransformer::class);
 | ||||
|         // $accountTransformer->setParameters($parameters);
 | ||||
| 
 | ||||
|         // data
 | ||||
|         $piggyBanks         = $this->groupPiggyBanks($collection); | ||||
|         $accounts           = $this->collectAccounts($collection); | ||||
|         $accounts           = $this->mergeAccountsAndPiggies($piggyBanks, $accounts); | ||||
|         $piggyBanks         = $this->makeSums($piggyBanks); | ||||
|         $piggyBanks = $this->groupPiggyBanks($collection); | ||||
|         $accounts   = $this->collectAccounts($collection); | ||||
|         $accounts   = $this->mergeAccountsAndPiggies($piggyBanks, $accounts); | ||||
|         $piggyBanks = $this->makeSums($piggyBanks); | ||||
| 
 | ||||
|         ksort($piggyBanks); | ||||
| 
 | ||||
| @@ -144,6 +145,11 @@ class IndexController extends Controller | ||||
|         $accountTransformer = app(AccountTransformer::class); | ||||
|         $accountTransformer->setParameters($parameters); | ||||
| 
 | ||||
|         // enrich each account.
 | ||||
|         $enrichment         = new AccountEnrichment(); | ||||
|         $enrichment->setUser(auth()->user()); | ||||
|         $enrichment->setConvertToNative($this->convertToNative); | ||||
|         $enrichment->setNative($this->defaultCurrency); | ||||
|         $return             = []; | ||||
| 
 | ||||
|         /** @var PiggyBank $piggy */ | ||||
| @@ -152,6 +158,7 @@ class IndexController extends Controller | ||||
| 
 | ||||
|             /** @var Account $account */ | ||||
|             foreach ($accounts as $account) { | ||||
|                 $account   = $enrichment->enrichSingle($account); | ||||
|                 $array     = $accountTransformer->transform($account); | ||||
|                 $accountId = (int) $array['id']; | ||||
|                 if (!array_key_exists($accountId, $return)) { | ||||
|   | ||||
| @@ -141,8 +141,8 @@ class MassController extends Controller | ||||
|         // reverse amounts
 | ||||
|         foreach ($journals as $index => $journal) { | ||||
|             $journals[$index]['amount']         = app('steam')->bcround(app('steam')->positive($journal['amount']), $journal['currency_decimal_places']); | ||||
|             $journals[$index]['foreign_amount'] = null === $journal['foreign_amount'] ? | ||||
|                 null : app('steam')->positive($journal['foreign_amount']); | ||||
|             $journals[$index]['foreign_amount'] = null === $journal['foreign_amount'] | ||||
|                 ? null : app('steam')->positive($journal['foreign_amount']); | ||||
|         } | ||||
| 
 | ||||
|         $this->rememberPreviousUrl('transactions.mass-edit.url'); | ||||
|   | ||||
| @@ -103,7 +103,7 @@ class ShowController extends Controller | ||||
| 
 | ||||
|         foreach (array_keys($groupArray['transactions']) as $index) { | ||||
|             $groupArray['transactions'][$index]['tags'] = $this->repository->getTagObjects( | ||||
|                 $groupArray['transactions'][$index]['transaction_journal_id'] | ||||
|                 (int) $groupArray['transactions'][$index]['transaction_journal_id'] | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -84,7 +84,7 @@ class Installer | ||||
|         // Log::debug('Now in routine hasNoTables()');
 | ||||
| 
 | ||||
|         try { | ||||
|             DB::table('users')->whereNull('deleted_at')->count(); | ||||
|             DB::table('users')->count(); | ||||
|         } catch (QueryException $e) { | ||||
|             $message = $e->getMessage(); | ||||
|             Log::error(sprintf('Error message trying to access users-table: %s', $message)); | ||||
|   | ||||
| @@ -33,11 +33,11 @@ class TrustProxies extends Middleware | ||||
| { | ||||
|     // After...
 | ||||
|     protected $headers | ||||
|         = Request::HEADER_X_FORWARDED_FOR | | ||||
|         Request::HEADER_X_FORWARDED_HOST | | ||||
|         Request::HEADER_X_FORWARDED_PORT | | ||||
|         Request::HEADER_X_FORWARDED_PROTO | | ||||
|         Request::HEADER_X_FORWARDED_AWS_ELB; | ||||
|         = Request::HEADER_X_FORWARDED_FOR | ||||
|         | Request::HEADER_X_FORWARDED_HOST | ||||
|         | Request::HEADER_X_FORWARDED_PORT | ||||
|         | Request::HEADER_X_FORWARDED_PROTO | ||||
|         | Request::HEADER_X_FORWARDED_AWS_ELB; | ||||
| 
 | ||||
|     /** | ||||
|      * TrustProxies constructor. | ||||
|   | ||||
| @@ -498,6 +498,8 @@ class AccountRepository implements AccountRepositoryInterface | ||||
|             } | ||||
|             $query->orderBy('accounts.active', 'DESC'); | ||||
|             $query->orderBy('accounts.name', 'ASC'); | ||||
|             $query->orderBy('accounts.account_type_id', 'ASC'); | ||||
|             $query->orderBy('accounts.id', 'ASC'); | ||||
|         } | ||||
| 
 | ||||
|         return $query->get(['accounts.*']); | ||||
|   | ||||
| @@ -222,7 +222,8 @@ trait ModifiesPiggyBanks | ||||
|         // update the accounts
 | ||||
|         $factory       = new PiggyBankFactory(); | ||||
|         $factory->user = $this->user; | ||||
|         $factory->linkToAccountIds($piggyBank, $data['accounts']); | ||||
| 
 | ||||
|         $factory->linkToAccountIds($piggyBank, $data['accounts'] ?? []); | ||||
| 
 | ||||
| 
 | ||||
|         // if the piggy bank is now smaller than the sum of the money saved,
 | ||||
| @@ -233,8 +234,8 @@ trait ModifiesPiggyBanks | ||||
|             $difference = bcsub($piggyBank->target_amount, $currentAmount); | ||||
| 
 | ||||
|             // an amount will be removed, create "negative" event:
 | ||||
|             Log::debug(sprintf('ChangedAmount: is triggered with difference "%s"', $difference)); | ||||
|             event(new ChangedAmount($piggyBank, $difference, null, null)); | ||||
|             //            Log::debug(sprintf('ChangedAmount: is triggered with difference "%s"', $difference));
 | ||||
|             //            event(new ChangedAmount($piggyBank, $difference, null, null));
 | ||||
| 
 | ||||
|             // question is, from which account(s) to remove the difference?
 | ||||
|             // solution: just start from the top until there is no more money left to remove.
 | ||||
|   | ||||
| @@ -361,6 +361,8 @@ class AccountRepository implements AccountRepositoryInterface | ||||
|             } | ||||
|             $query->orderBy('accounts.order', 'ASC'); | ||||
|             $query->orderBy('accounts.name', 'ASC'); | ||||
|             $query->orderBy('accounts.account_type_id', 'ASC'); | ||||
|             $query->orderBy('accounts.id', 'ASC'); | ||||
|         } | ||||
| 
 | ||||
|         return $query->get(['accounts.*']); | ||||
|   | ||||
| @@ -239,7 +239,8 @@ trait AccountServiceTrait | ||||
|         // submit to factory:
 | ||||
|         $submission = [ | ||||
|             'group_title'  => null, | ||||
|             'user'         => $account->user_id, | ||||
|             'user'         => $account->user, | ||||
|             'user_group'   => $account->user->userGroup, | ||||
|             'transactions' => [ | ||||
|                 [ | ||||
|                     'type'             => 'Opening balance', | ||||
| @@ -460,11 +461,11 @@ trait AccountServiceTrait | ||||
|         if (null === $currency) { | ||||
|             $currency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); | ||||
|         } | ||||
| 
 | ||||
|         // submit to factory:
 | ||||
|         $submission = [ | ||||
|             'group_title'  => null, | ||||
|             'user'         => $account->user_id, | ||||
|             'user'         => $account->user, | ||||
|             'user_group'   => $account->user->userGroup, | ||||
|             'transactions' => [ | ||||
|                 [ | ||||
|                     'type'             => 'Liability credit', | ||||
|   | ||||
| @@ -54,8 +54,8 @@ class BillUpdateService | ||||
| 
 | ||||
|         if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) { | ||||
|             $factory                       = app(TransactionCurrencyFactory::class); | ||||
|             $currency                      = $factory->find((int) ($data['currency_id'] ?? null), $data['currency_code'] ?? null) ?? | ||||
|                         app('amount')->getNativeCurrencyByUserGroup($bill->user->userGroup); | ||||
|             $currency                      = $factory->find((int) ($data['currency_id'] ?? null), $data['currency_code'] ?? null) | ||||
|                         ?? app('amount')->getNativeCurrencyByUserGroup($bill->user->userGroup); | ||||
| 
 | ||||
|             // enable the currency if it isn't.
 | ||||
|             $currency->enabled             = true; | ||||
|   | ||||
| @@ -703,8 +703,8 @@ class JournalUpdateService | ||||
|         // find currency in data array
 | ||||
|         $newForeignId    = $this->data['foreign_currency_id'] ?? null; | ||||
|         $newForeignCode  = $this->data['foreign_currency_code'] ?? null; | ||||
|         $foreignCurrency = $this->currencyRepository->findCurrencyNull($newForeignId, $newForeignCode) ?? | ||||
|                            $foreignCurrency; | ||||
|         $foreignCurrency = $this->currencyRepository->findCurrencyNull($newForeignId, $newForeignCode) | ||||
|                            ?? $foreignCurrency; | ||||
| 
 | ||||
|         // not the same as normal currency
 | ||||
|         if (null !== $foreignCurrency && $foreignCurrency->id === $this->transactionJournal->transaction_currency_id) { | ||||
|   | ||||
| @@ -31,6 +31,7 @@ use Illuminate\Contracts\Auth\Guard; | ||||
| use Illuminate\Contracts\Auth\UserProvider; | ||||
| use Illuminate\Contracts\Foundation\Application; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| 
 | ||||
| /** | ||||
|  * Class RemoteUserGuard | ||||
| @@ -48,7 +49,7 @@ class RemoteUserGuard implements Guard | ||||
|     { | ||||
|         /** @var null|Request $request */ | ||||
|         $request           = $app->get('request'); | ||||
|         app('log')->debug(sprintf('Created RemoteUserGuard for %s "%s"', $request?->getMethod(), $request?->getRequestUri())); | ||||
|         Log::debug(sprintf('Created RemoteUserGuard for %s "%s"', $request?->getMethod(), $request?->getRequestUri())); | ||||
|         $this->application = $app; | ||||
|         $this->provider    = $provider; | ||||
|         $this->user        = null; | ||||
| @@ -56,9 +57,9 @@ class RemoteUserGuard implements Guard | ||||
| 
 | ||||
|     public function authenticate(): void | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now at %s', __METHOD__)); | ||||
|         Log::debug(sprintf('Now at %s', __METHOD__)); | ||||
|         if (null !== $this->user) { | ||||
|             app('log')->debug(sprintf('%s is found: #%d, "%s".', get_class($this->user), $this->user->id, $this->user->email)); | ||||
|             Log::debug(sprintf('%s is found: #%d, "%s".', get_class($this->user), $this->user->id, $this->user->email)); | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
| @@ -67,17 +68,17 @@ class RemoteUserGuard implements Guard | ||||
|         $userID        = request()->server($header) ?? null; | ||||
| 
 | ||||
|         if (function_exists('apache_request_headers')) { | ||||
|             app('log')->debug('Use apache_request_headers to find user ID.'); | ||||
|             Log::debug('Use apache_request_headers to find user ID.'); | ||||
|             $userID = request()->server($header) ?? apache_request_headers()[$header] ?? null; | ||||
|         } | ||||
| 
 | ||||
|         if (null === $userID || '' === $userID) { | ||||
|             app('log')->error(sprintf('No user in header "%s".', $header)); | ||||
|             Log::error(sprintf('No user in header "%s".', $header)); | ||||
| 
 | ||||
|             throw new FireflyException('The guard header was unexpectedly empty. See the logs.'); | ||||
|         } | ||||
| 
 | ||||
|         app('log')->debug(sprintf('User ID found in header is "%s"', $userID)); | ||||
|         Log::debug(sprintf('User ID found in header is "%s"', $userID)); | ||||
| 
 | ||||
|         /** @var User $retrievedUser */ | ||||
|         $retrievedUser = $this->provider->retrieveById($userID); | ||||
| @@ -98,30 +99,30 @@ class RemoteUserGuard implements Guard | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         app('log')->debug(sprintf('Result of getting user from provider: %s', $retrievedUser->email)); | ||||
|         Log::debug(sprintf('Result of getting user from provider: %s', $retrievedUser->email)); | ||||
|         $this->user    = $retrievedUser; | ||||
|     } | ||||
| 
 | ||||
|     public function guest(): bool | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now at %s', __METHOD__)); | ||||
|         Log::debug(sprintf('Now at %s', __METHOD__)); | ||||
| 
 | ||||
|         return !$this->check(); | ||||
|     } | ||||
| 
 | ||||
|     public function check(): bool | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now at %s', __METHOD__)); | ||||
|         Log::debug(sprintf('Now at %s', __METHOD__)); | ||||
| 
 | ||||
|         return null !== $this->user(); | ||||
|     } | ||||
| 
 | ||||
|     public function user(): ?User | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now at %s', __METHOD__)); | ||||
|         Log::debug(sprintf('Now at %s', __METHOD__)); | ||||
|         $user = $this->user; | ||||
|         if (null === $user) { | ||||
|             app('log')->debug('User is NULL'); | ||||
|             Log::debug('User is NULL'); | ||||
| 
 | ||||
|             return null; | ||||
|         } | ||||
| @@ -131,7 +132,7 @@ class RemoteUserGuard implements Guard | ||||
| 
 | ||||
|     public function hasUser(): bool | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now at %s', __METHOD__)); | ||||
|         Log::debug(sprintf('Now at %s', __METHOD__)); | ||||
| 
 | ||||
|         throw new FireflyException('Did not implement RemoteUserGuard::hasUser()'); | ||||
|     } | ||||
| @@ -141,20 +142,20 @@ class RemoteUserGuard implements Guard | ||||
|      */ | ||||
|     public function id(): null|int|string | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now at %s', __METHOD__)); | ||||
|         Log::debug(sprintf('Now at %s', __METHOD__)); | ||||
| 
 | ||||
|         return $this->user?->id; | ||||
|     } | ||||
| 
 | ||||
|     public function setUser(null|Authenticatable|User $user): void // @phpstan-ignore-line
 | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now at %s', __METHOD__)); | ||||
|         Log::debug(sprintf('Now at %s', __METHOD__)); | ||||
|         if ($user instanceof User) { | ||||
|             $this->user = $user; | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
|         app('log')->error(sprintf('Did not set user at %s', __METHOD__)); | ||||
|         Log::error(sprintf('Did not set user at %s', __METHOD__)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @@ -164,14 +165,14 @@ class RemoteUserGuard implements Guard | ||||
|      */ | ||||
|     public function validate(array $credentials = []): bool | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now at %s', __METHOD__)); | ||||
|         Log::debug(sprintf('Now at %s', __METHOD__)); | ||||
| 
 | ||||
|         throw new FireflyException('Did not implement RemoteUserGuard::validate()'); | ||||
|     } | ||||
| 
 | ||||
|     public function viaRemember(): bool | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now at %s', __METHOD__)); | ||||
|         Log::debug(sprintf('Now at %s', __METHOD__)); | ||||
| 
 | ||||
|         return false; | ||||
|     } | ||||
|   | ||||
| @@ -117,30 +117,6 @@ class AccountEnrichment implements EnrichmentInterface | ||||
|         $this->collectNotes(); | ||||
|         $this->collectLocations(); | ||||
|         $this->collectOpeningBalances(); | ||||
|         //        $this->default      = app('amount')->getNativeCurrency();
 | ||||
|         //        $this->currencies   = [];
 | ||||
|         //        $this->balances     = [];
 | ||||
|         //        $this->objectGroups = [];
 | ||||
|         //        $this->grouped      = [];
 | ||||
|         //
 | ||||
|         //        // do everything here:
 | ||||
|         //        $this->getLastActivity();
 | ||||
|         //        $this->collectAccountTypes();
 | ||||
|         //        $this->collectMetaData();
 | ||||
|         //        $this->getMetaBalances();
 | ||||
|         //        $this->getObjectGroups();
 | ||||
| 
 | ||||
|         //        $this->collection->transform(function (Account $account) {
 | ||||
|         //            $account->user_array = ['id' => 1, 'bla bla' => 'bla'];
 | ||||
|         //            $account->balances   = collect([
 | ||||
|         //                ['balance_id' => 1, 'balance' => 5],
 | ||||
|         //                ['balance_id' => 2, 'balance' => 5],
 | ||||
|         //                ['balance_id' => 3, 'balance' => 5],
 | ||||
|         //            ]);
 | ||||
|         //
 | ||||
|         //            return $account;
 | ||||
|         //        });
 | ||||
| 
 | ||||
|         $this->appendCollectedData(); | ||||
| 
 | ||||
|         return $this->collection; | ||||
| @@ -258,7 +234,7 @@ class AccountEnrichment implements EnrichmentInterface | ||||
| 
 | ||||
|     private function collectMetaData(): void | ||||
|     { | ||||
|         $set        = AccountMeta::whereIn('name', ['is_multi_currency', 'currency_id', 'account_role', 'account_number', 'liability_direction', 'interest', 'interest_period', 'current_debt']) | ||||
|         $set                 = AccountMeta::whereIn('name', ['is_multi_currency', 'include_net_worth', 'currency_id', 'account_role', 'account_number', 'liability_direction', 'interest', 'interest_period', 'current_debt']) | ||||
|             ->whereIn('account_id', $this->accountIds) | ||||
|             ->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data'])->toArray() | ||||
|         ; | ||||
| @@ -270,10 +246,11 @@ class AccountEnrichment implements EnrichmentInterface | ||||
|                 $this->currencies[(int) $entry['data']] = true; | ||||
|             } | ||||
|         } | ||||
|         $currencies = TransactionCurrency::whereIn('id', array_keys($this->currencies))->get(); | ||||
|         $currencies          = TransactionCurrency::whereIn('id', array_keys($this->currencies))->get(); | ||||
|         foreach ($currencies as $currency) { | ||||
|             $this->currencies[(int) $currency->id] = $currency; | ||||
|         } | ||||
|         $this->currencies[0] = $this->native; | ||||
|         foreach ($this->currencies as $id => $currency) { | ||||
|             if (true === $currency) { | ||||
|                 throw new FireflyException(sprintf('Currency #%d not found.', $id)); | ||||
|   | ||||
| @@ -72,20 +72,32 @@ class Preferences | ||||
| 
 | ||||
|     public function getForUser(User $user, string $name, null|array|bool|int|string $default = null): ?Preference | ||||
|     { | ||||
|         Log::debug(sprintf('getForUser(#%d, "%s")', $user->id, $name)); | ||||
|         // don't care about user group ID, except for some specific preferences.
 | ||||
|         $userGroupId = $this->getUserGroupId($user, $name); | ||||
|         $preference  = Preference::where('user_group_id', $userGroupId)->where('user_id', $user->id)->where('name', $name)->first(['id', 'user_id', 'name', 'data', 'updated_at', 'created_at']); | ||||
|         $query       = Preference::where('user_id', $user->id)->where('name', $name); | ||||
|         if (null !== $userGroupId) { | ||||
|             Log::debug('Include user group ID in query'); | ||||
|             $query->where('user_group_id', $userGroupId); | ||||
|         } | ||||
| 
 | ||||
|         $preference  = $query->first(['id', 'user_id', 'user_group_id', 'name', 'data', 'updated_at', 'created_at']); | ||||
| 
 | ||||
|         if (null !== $preference && null === $preference->data) { | ||||
|             $preference->delete(); | ||||
|             $preference = null; | ||||
|             Log::debug('Removed empty preference.'); | ||||
|         } | ||||
| 
 | ||||
|         if (null !== $preference) { | ||||
|             Log::debug(sprintf('Found preference #%d for user #%d: %s', $preference->id, $user->id, $name)); | ||||
| 
 | ||||
|             return $preference; | ||||
|         } | ||||
|         // no preference found and default is null:
 | ||||
|         if (null === $default) { | ||||
|             Log::debug('Return NULL, create no preference.'); | ||||
| 
 | ||||
|             // return NULL
 | ||||
|             return null; | ||||
|         } | ||||
| @@ -124,35 +136,40 @@ class Preferences | ||||
| 
 | ||||
|     public function setForUser(User $user, string $name, null|array|bool|int|string $value): Preference | ||||
|     { | ||||
|         $fullName   = sprintf('preference%s%s', $user->id, $name); | ||||
|         $groupId    = $this->getUserGroupId($user, $name); | ||||
|         $groupId    = 0 === (int) $groupId ? null : (int) $groupId; | ||||
|         $fullName         = sprintf('preference%s%s', $user->id, $name); | ||||
|         $userGroupId      = $this->getUserGroupId($user, $name); | ||||
|         $userGroupId      = 0 === (int) $userGroupId ? null : (int) $userGroupId; | ||||
| 
 | ||||
|         Cache::forget($fullName); | ||||
| 
 | ||||
|         /** @var null|Preference $pref */ | ||||
|         $pref       = Preference::where('user_group_id', $groupId)->where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data', 'updated_at', 'created_at']); | ||||
|         $query            = Preference::where('user_id', $user->id)->where('name', $name); | ||||
|         if (null !== $userGroupId) { | ||||
|             Log::debug('Include user group ID in query'); | ||||
|             $query->where('user_group_id', $userGroupId); | ||||
|         } | ||||
| 
 | ||||
|         if (null !== $pref && null === $value) { | ||||
|             $pref->delete(); | ||||
|         $preference       = $query->first(['id', 'user_id', 'user_group_id', 'name', 'data', 'updated_at', 'created_at']); | ||||
| 
 | ||||
|         if (null !== $preference && null === $value) { | ||||
|             $preference->delete(); | ||||
| 
 | ||||
|             return new Preference(); | ||||
|         } | ||||
|         if (null === $value) { | ||||
|             return new Preference(); | ||||
|         } | ||||
|         if (null === $pref) { | ||||
|             $pref                = new Preference(); | ||||
|             $pref->user_id       = (int) $user->id; | ||||
|             $pref->user_group_id = $groupId; | ||||
|             $pref->name          = $name; | ||||
|         if (null === $preference) { | ||||
|             $preference                = new Preference(); | ||||
|             $preference->user_id       = (int) $user->id; | ||||
|             $preference->user_group_id = $userGroupId; | ||||
|             $preference->name          = $name; | ||||
| 
 | ||||
|         } | ||||
|         $pref->data = $value; | ||||
|         $pref->save(); | ||||
|         Cache::forever($fullName, $pref); | ||||
|         $preference->data = $value; | ||||
|         $preference->save(); | ||||
|         Cache::forever($fullName, $preference); | ||||
| 
 | ||||
|         return $pref; | ||||
|         return $preference; | ||||
|     } | ||||
| 
 | ||||
|     public function beginsWith(User $user, string $search): Collection | ||||
|   | ||||
| @@ -390,6 +390,25 @@ trait ConvertsDataTypes | ||||
|         return (int) $string; | ||||
|     } | ||||
| 
 | ||||
|     protected function parseAccounts(mixed $array): array | ||||
|     { | ||||
|         if (!is_array($array)) { | ||||
|             return []; | ||||
|         } | ||||
|         $return = []; | ||||
|         foreach ($array as $entry) { | ||||
|             if (!is_array($entry)) { | ||||
|                 continue; | ||||
|             } | ||||
|             $return[] = [ | ||||
|                 'account_id'     => $this->integerFromValue((string) ($entry['account_id'] ?? '0')), | ||||
|                 'current_amount' => $this->clearString((string) ($entry['current_amount'] ?? '0')), | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| 
 | ||||
|     protected function floatFromValue(?string $string): ?float | ||||
|     { | ||||
|         if (null === $string) { | ||||
|   | ||||
| @@ -62,6 +62,10 @@ class AccountTransformer extends AbstractTransformer | ||||
|      */ | ||||
|     public function transform(Account $account): array | ||||
|     { | ||||
|         if (null === $account->meta) { | ||||
|             $account->meta = []; | ||||
|         } | ||||
| 
 | ||||
|         // get account type:
 | ||||
|         $accountType                                                  = (string) config(sprintf('firefly.shortNamesByFullName.%s', $account->full_account_type)); | ||||
|         $liabilityType                                                = (string) config(sprintf('firefly.shortLiabilityNameByFullName.%s', $account->full_account_type)); | ||||
| @@ -88,7 +92,7 @@ class AccountTransformer extends AbstractTransformer | ||||
|         $decimalPlaces                                                = (int) $account->meta['currency']?->decimal_places; | ||||
|         $decimalPlaces                                                = 0 === $decimalPlaces ? 2 : $decimalPlaces; | ||||
|         $openingBalance                                               = Steam::bcround($openingBalance, $decimalPlaces); | ||||
|         $includeNetWorth                                              = '0' !== ($account->meta['include_net_worth'] ?? null); | ||||
|         $includeNetWorth                                              = 1 === (int) ($account->meta['include_net_worth'] ?? 0); | ||||
|         $longitude                                                    = $account->meta['location']['longitude'] ?? null; | ||||
|         $latitude                                                     = $account->meta['location']['latitude'] ?? null; | ||||
|         $zoomLevel                                                    = $account->meta['location']['zoom_level'] ?? null; | ||||
|   | ||||
| @@ -131,7 +131,7 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
| 
 | ||||
|         return [ | ||||
|             'user'                            => (string) $transaction['user_id'], | ||||
|             'transaction_journal_id'          => $transaction['transaction_journal_id'], | ||||
|             'transaction_journal_id'          => (string) $transaction['transaction_journal_id'], | ||||
|             'type'                            => strtolower($type), | ||||
|             'date'                            => $transaction['date']->toAtomString(), | ||||
|             'order'                           => $transaction['order'], | ||||
| @@ -320,17 +320,17 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
| 
 | ||||
|         return [ | ||||
|             'user'                            => $journal->user_id, | ||||
|             'transaction_journal_id'          => $journal->id, | ||||
|             'transaction_journal_id'          => (string) $journal->id, | ||||
|             'type'                            => strtolower($type), | ||||
|             'date'                            => $journal->date->toAtomString(), | ||||
|             'order'                           => $journal->order, | ||||
| 
 | ||||
|             'currency_id'                     => $currency->id, | ||||
|             'currency_id'                     => (string) $currency->id, | ||||
|             'currency_code'                   => $currency->code, | ||||
|             'currency_symbol'                 => $currency->symbol, | ||||
|             'currency_decimal_places'         => $currency->decimal_places, | ||||
| 
 | ||||
|             'foreign_currency_id'             => $foreignCurrency['id'], | ||||
|             'foreign_currency_id'             => (string) $foreignCurrency['id'], | ||||
|             'foreign_currency_code'           => $foreignCurrency['code'], | ||||
|             'foreign_currency_symbol'         => $foreignCurrency['symbol'], | ||||
|             'foreign_currency_decimal_places' => $foreignCurrency['decimal_places'], | ||||
| @@ -340,23 +340,23 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
| 
 | ||||
|             'description'                     => $journal->description, | ||||
| 
 | ||||
|             'source_id'                       => $source->account_id, | ||||
|             'source_id'                       => (string) $source->account_id, | ||||
|             'source_name'                     => $source->account->name, | ||||
|             'source_iban'                     => $source->account->iban, | ||||
|             'source_type'                     => $source->account->accountType->type, | ||||
| 
 | ||||
|             'destination_id'                  => $destination->account_id, | ||||
|             'destination_id'                  => (string) $destination->account_id, | ||||
|             'destination_name'                => $destination->account->name, | ||||
|             'destination_iban'                => $destination->account->iban, | ||||
|             'destination_type'                => $destination->account->accountType->type, | ||||
| 
 | ||||
|             'budget_id'                       => $budget['id'], | ||||
|             'budget_id'                       => (string) $budget['id'], | ||||
|             'budget_name'                     => $budget['name'], | ||||
| 
 | ||||
|             'category_id'                     => $category['id'], | ||||
|             'category_id'                     => (string) $category['id'], | ||||
|             'category_name'                   => $category['name'], | ||||
| 
 | ||||
|             'bill_id'                         => $bill['id'], | ||||
|             'bill_id'                         => (string) $bill['id'], | ||||
|             'bill_name'                       => $bill['name'], | ||||
| 
 | ||||
|             'reconciled'                      => $source->reconciled, | ||||
|   | ||||
							
								
								
									
										43
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								changelog.md
									
									
									
									
									
								
							| @@ -3,6 +3,49 @@ | ||||
| All notable changes to this project will be documented in this file. | ||||
| This project adheres to [Semantic Versioning](http://semver.org/). | ||||
| 
 | ||||
| ## 6.2.9 - 2025-02-22 | ||||
| 
 | ||||
| ### Fixed | ||||
| 
 | ||||
| - [Issue 9861](https://github.com/firefly-iii/firefly-iii/issues/9861) (lower piggy amount when full creates double audit log entry) reported by @4e868df3 | ||||
| - [Issue 9862](https://github.com/firefly-iii/firefly-iii/issues/9862) (Can't retrieve all accounts with the same name via API) reported by @Toshik1978 | ||||
| - [Issue 9863](https://github.com/firefly-iii/firefly-iii/issues/9863) (User preferences reset after restart) reported by @mico28 | ||||
| - [Issue 9868](https://github.com/firefly-iii/firefly-iii/issues/9868) (API: `TransactionSplit` -> `transaction_journal_id` returns int, not String) reported by @dreautall | ||||
| - [Issue 9871](https://github.com/firefly-iii/firefly-iii/issues/9871) (include net worth is ignored in the API - from PICO developer) reported by @fate8383 | ||||
| - [Issue 9882](https://github.com/firefly-iii/firefly-iii/issues/9882) (Reconciliation bug on Docker instance) reported by @benjaminteyssier | ||||
| - [Issue 9884](https://github.com/firefly-iii/firefly-iii/issues/9884) (Data import, currency #0 not found) reported by @ragnarkarlsson | ||||
| - [Issue 9885](https://github.com/firefly-iii/firefly-iii/issues/9885) (Invalid server configuration: missing required package) reported by @EricVanCaenenberghe | ||||
| - [Issue 9887](https://github.com/firefly-iii/firefly-iii/issues/9887) (Creating a Liability Account Throws TypeError in TransactionJournalFactory::setUser()) reported by @mikeashi | ||||
| 
 | ||||
| ## 6.2.8 - 2025-02-22 | ||||
| 
 | ||||
| ### Fixed | ||||
| 
 | ||||
| - [Issue 9861](https://github.com/firefly-iii/firefly-iii/issues/9861) (lower piggy amount when full creates double audit log entry) reported by @4e868df3 | ||||
| - [Issue 9862](https://github.com/firefly-iii/firefly-iii/issues/9862) (Can't retrieve all accounts with the same name via API) reported by @Toshik1978 | ||||
| - [Issue 9863](https://github.com/firefly-iii/firefly-iii/issues/9863) (User preferences reset after restart) reported by @mico28 | ||||
| - [Issue 9868](https://github.com/firefly-iii/firefly-iii/issues/9868) (API: `TransactionSplit` -> `transaction_journal_id` returns int, not String) reported by @dreautall | ||||
| - [Issue 9871](https://github.com/firefly-iii/firefly-iii/issues/9871) (include net worth is ignored in the API - from PICO developer) reported by @fate8383 | ||||
| - [Issue 9882](https://github.com/firefly-iii/firefly-iii/issues/9882) (Reconciliation bug on Docker instance) reported by @benjaminteyssier | ||||
| - [Issue 9884](https://github.com/firefly-iii/firefly-iii/issues/9884) (Data import, currency #0 not found) reported by @ragnarkarlsson | ||||
| - [Issue 9885](https://github.com/firefly-iii/firefly-iii/issues/9885) (Invalid server configuration: missing required package) reported by @EricVanCaenenberghe | ||||
| - [Issue 9887](https://github.com/firefly-iii/firefly-iii/issues/9887) (Creating a Liability Account Throws TypeError in TransactionJournalFactory::setUser()) reported by @mikeashi | ||||
| 
 | ||||
| ## 6.2.7 - 2025-02-19 | ||||
| 
 | ||||
| ### Changed | ||||
| 
 | ||||
| - Optimised Account and Transaction API endpoints, should be a lot faster | ||||
| - Optimized account deletion, should be a lot faster | ||||
| 
 | ||||
| ### Fixed | ||||
| 
 | ||||
| - [Issue 9803](https://github.com/firefly-iii/firefly-iii/issues/9803) (Left to spend - All negativ after update.) reported by @nedsined | ||||
| - [Issue 9835](https://github.com/firefly-iii/firefly-iii/issues/9835) (Failed to create transaction in recurring transactions on 6.2.6) reported by @hhl5350 | ||||
| - [Issue 9842](https://github.com/firefly-iii/firefly-iii/issues/9842) (Net worth on dashboard does not go up to the end of month for the current month) reported by @standingduck3 | ||||
| - [Issue 9848](https://github.com/firefly-iii/firefly-iii/issues/9848) (Failed to export accounts data) reported by @Jaeger87 | ||||
| - [Issue 9855](https://github.com/firefly-iii/firefly-iii/issues/9855) (Demo Website not working) reported by @xfarrow | ||||
| 
 | ||||
| ## 6.2.6 - 2025-02-13 | ||||
| 
 | ||||
| ### Fixed | ||||
|   | ||||
							
								
								
									
										351
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										351
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							| @@ -1874,16 +1874,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "laravel/framework", | ||||
|             "version": "v11.42.1", | ||||
|             "version": "v11.43.2", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/laravel/framework.git", | ||||
|                 "reference": "ff392f42f6c55cc774ce75553a11c6b031da67f8" | ||||
|                 "reference": "99d1573698abc42222f04d25fcd5b213d0eedf21" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/laravel/framework/zipball/ff392f42f6c55cc774ce75553a11c6b031da67f8", | ||||
|                 "reference": "ff392f42f6c55cc774ce75553a11c6b031da67f8", | ||||
|                 "url": "https://api.github.com/repos/laravel/framework/zipball/99d1573698abc42222f04d25fcd5b213d0eedf21", | ||||
|                 "reference": "99d1573698abc42222f04d25fcd5b213d0eedf21", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -2085,7 +2085,7 @@ | ||||
|                 "issues": "https://github.com/laravel/framework/issues", | ||||
|                 "source": "https://github.com/laravel/framework" | ||||
|             }, | ||||
|             "time": "2025-02-12T20:58:18+00:00" | ||||
|             "time": "2025-02-19T21:53:48+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "laravel/passport", | ||||
| @@ -3703,16 +3703,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "nesbot/carbon", | ||||
|             "version": "3.8.5", | ||||
|             "version": "3.8.6", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/CarbonPHP/carbon.git", | ||||
|                 "reference": "b1a53a27898639579a67de42e8ced5d5386aa9a4" | ||||
|                 "reference": "ff2f20cf83bd4d503720632ce8a426dc747bf7fd" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/b1a53a27898639579a67de42e8ced5d5386aa9a4", | ||||
|                 "reference": "b1a53a27898639579a67de42e8ced5d5386aa9a4", | ||||
|                 "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/ff2f20cf83bd4d503720632ce8a426dc747bf7fd", | ||||
|                 "reference": "ff2f20cf83bd4d503720632ce8a426dc747bf7fd", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -3805,7 +3805,7 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-02-11T16:28:45+00:00" | ||||
|             "time": "2025-02-20T17:33:38+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "nette/schema", | ||||
| @@ -6113,16 +6113,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "spatie/ignition", | ||||
|             "version": "1.15.0", | ||||
|             "version": "1.15.1", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/spatie/ignition.git", | ||||
|                 "reference": "e3a68e137371e1eb9edc7f78ffa733f3b98991d2" | ||||
|                 "reference": "31f314153020aee5af3537e507fef892ffbf8c85" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/spatie/ignition/zipball/e3a68e137371e1eb9edc7f78ffa733f3b98991d2", | ||||
|                 "reference": "e3a68e137371e1eb9edc7f78ffa733f3b98991d2", | ||||
|                 "url": "https://api.github.com/repos/spatie/ignition/zipball/31f314153020aee5af3537e507fef892ffbf8c85", | ||||
|                 "reference": "31f314153020aee5af3537e507fef892ffbf8c85", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -6135,7 +6135,7 @@ | ||||
|                 "symfony/var-dumper": "^5.4|^6.0|^7.0" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "illuminate/cache": "^9.52|^10.0|^11.0", | ||||
|                 "illuminate/cache": "^9.52|^10.0|^11.0|^12.0", | ||||
|                 "mockery/mockery": "^1.4", | ||||
|                 "pestphp/pest": "^1.20|^2.0", | ||||
|                 "phpstan/extension-installer": "^1.1", | ||||
| @@ -6192,31 +6192,31 @@ | ||||
|                     "type": "github" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-06-12T14:55:22+00:00" | ||||
|             "time": "2025-02-21T14:31:39+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "spatie/laravel-html", | ||||
|             "version": "3.11.2", | ||||
|             "version": "3.11.3", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/spatie/laravel-html.git", | ||||
|                 "reference": "248508f3ed50e6538707fc54a4b3b23fb53e8045" | ||||
|                 "reference": "b1bb159bd9845b1ff02b8f945ecd583d93353d06" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/spatie/laravel-html/zipball/248508f3ed50e6538707fc54a4b3b23fb53e8045", | ||||
|                 "reference": "248508f3ed50e6538707fc54a4b3b23fb53e8045", | ||||
|                 "url": "https://api.github.com/repos/spatie/laravel-html/zipball/b1bb159bd9845b1ff02b8f945ecd583d93353d06", | ||||
|                 "reference": "b1bb159bd9845b1ff02b8f945ecd583d93353d06", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "illuminate/http": "^10.0|^11.0", | ||||
|                 "illuminate/support": "^10.0|^11.0", | ||||
|                 "illuminate/http": "^10.0|^11.0|^12.0", | ||||
|                 "illuminate/support": "^10.0|^11.0|^12.0", | ||||
|                 "php": "^8.2" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "mockery/mockery": "^1.3", | ||||
|                 "orchestra/testbench": "^8.0|^9.0", | ||||
|                 "pestphp/pest": "^2.34" | ||||
|                 "orchestra/testbench": "^8.0|^9.0|^10.0", | ||||
|                 "pestphp/pest": "^2.34|^3.7" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
| @@ -6262,7 +6262,7 @@ | ||||
|                 "spatie" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/spatie/laravel-html/tree/3.11.2" | ||||
|                 "source": "https://github.com/spatie/laravel-html/tree/3.11.3" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -6270,27 +6270,27 @@ | ||||
|                     "type": "custom" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-02-05T08:27:24+00:00" | ||||
|             "time": "2025-02-17T09:59:20+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "spatie/laravel-ignition", | ||||
|             "version": "2.9.0", | ||||
|             "version": "2.9.1", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/spatie/laravel-ignition.git", | ||||
|                 "reference": "62042df15314b829d0f26e02108f559018e2aad0" | ||||
|                 "reference": "1baee07216d6748ebd3a65ba97381b051838707a" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/62042df15314b829d0f26e02108f559018e2aad0", | ||||
|                 "reference": "62042df15314b829d0f26e02108f559018e2aad0", | ||||
|                 "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/1baee07216d6748ebd3a65ba97381b051838707a", | ||||
|                 "reference": "1baee07216d6748ebd3a65ba97381b051838707a", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "ext-curl": "*", | ||||
|                 "ext-json": "*", | ||||
|                 "ext-mbstring": "*", | ||||
|                 "illuminate/support": "^10.0|^11.0", | ||||
|                 "illuminate/support": "^10.0|^11.0|^12.0", | ||||
|                 "php": "^8.1", | ||||
|                 "spatie/ignition": "^1.15", | ||||
|                 "symfony/console": "^6.2.3|^7.0", | ||||
| @@ -6299,12 +6299,12 @@ | ||||
|             "require-dev": { | ||||
|                 "livewire/livewire": "^2.11|^3.3.5", | ||||
|                 "mockery/mockery": "^1.5.1", | ||||
|                 "openai-php/client": "^0.8.1", | ||||
|                 "orchestra/testbench": "8.22.3|^9.0", | ||||
|                 "pestphp/pest": "^2.34", | ||||
|                 "openai-php/client": "^0.8.1|^0.10", | ||||
|                 "orchestra/testbench": "8.22.3|^9.0|^10.0", | ||||
|                 "pestphp/pest": "^2.34|^3.7", | ||||
|                 "phpstan/extension-installer": "^1.3.1", | ||||
|                 "phpstan/phpstan-deprecation-rules": "^1.1.1", | ||||
|                 "phpstan/phpstan-phpunit": "^1.3.16", | ||||
|                 "phpstan/phpstan-deprecation-rules": "^1.1.1|^2.0", | ||||
|                 "phpstan/phpstan-phpunit": "^1.3.16|^2.0", | ||||
|                 "vlucas/phpdotenv": "^5.5" | ||||
|             }, | ||||
|             "suggest": { | ||||
| @@ -6361,7 +6361,7 @@ | ||||
|                     "type": "github" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-12-02T08:43:31+00:00" | ||||
|             "time": "2025-02-20T13:13:55+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "spatie/laravel-package-tools", | ||||
| @@ -10033,30 +10033,30 @@ | ||||
|     "packages-dev": [ | ||||
|         { | ||||
|             "name": "barryvdh/laravel-debugbar", | ||||
|             "version": "v3.14.10", | ||||
|             "version": "v3.15.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/barryvdh/laravel-debugbar.git", | ||||
|                 "reference": "56b9bd235e3fe62e250124804009ce5bab97cc63" | ||||
|                 "reference": "77cca4a1162d45e1fe64e7a71b4a3031656b6c86" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/56b9bd235e3fe62e250124804009ce5bab97cc63", | ||||
|                 "reference": "56b9bd235e3fe62e250124804009ce5bab97cc63", | ||||
|                 "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/77cca4a1162d45e1fe64e7a71b4a3031656b6c86", | ||||
|                 "reference": "77cca4a1162d45e1fe64e7a71b4a3031656b6c86", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "illuminate/routing": "^9|^10|^11", | ||||
|                 "illuminate/session": "^9|^10|^11", | ||||
|                 "illuminate/support": "^9|^10|^11", | ||||
|                 "maximebf/debugbar": "~1.23.0", | ||||
|                 "php": "^8.0", | ||||
|                 "illuminate/routing": "^9|^10|^11|^12", | ||||
|                 "illuminate/session": "^9|^10|^11|^12", | ||||
|                 "illuminate/support": "^9|^10|^11|^12", | ||||
|                 "php": "^8.1", | ||||
|                 "php-debugbar/php-debugbar": "~2.1.1", | ||||
|                 "symfony/finder": "^6|^7" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "mockery/mockery": "^1.3.3", | ||||
|                 "orchestra/testbench-dusk": "^5|^6|^7|^8|^9", | ||||
|                 "phpunit/phpunit": "^9.6|^10.5", | ||||
|                 "orchestra/testbench-dusk": "^7|^8|^9|^10", | ||||
|                 "phpunit/phpunit": "^9.5.10|^10|^11", | ||||
|                 "squizlabs/php_codesniffer": "^3.5" | ||||
|             }, | ||||
|             "type": "library", | ||||
| @@ -10070,7 +10070,7 @@ | ||||
|                     ] | ||||
|                 }, | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "3.14-dev" | ||||
|                     "dev-master": "3.15-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
| @@ -10095,13 +10095,14 @@ | ||||
|             "keywords": [ | ||||
|                 "debug", | ||||
|                 "debugbar", | ||||
|                 "dev", | ||||
|                 "laravel", | ||||
|                 "profiler", | ||||
|                 "webprofiler" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "issues": "https://github.com/barryvdh/laravel-debugbar/issues", | ||||
|                 "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.14.10" | ||||
|                 "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.15.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -10113,40 +10114,40 @@ | ||||
|                     "type": "github" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-12-23T10:10:42+00:00" | ||||
|             "time": "2025-02-21T15:00:44+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "barryvdh/laravel-ide-helper", | ||||
|             "version": "v3.5.4", | ||||
|             "version": "v3.5.5", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/barryvdh/laravel-ide-helper.git", | ||||
|                 "reference": "980a87e250fc2a7558bc46e07f61c7594500ea53" | ||||
|                 "reference": "8d441ec99f8612b942b55f5183151d91591b618a" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/980a87e250fc2a7558bc46e07f61c7594500ea53", | ||||
|                 "reference": "980a87e250fc2a7558bc46e07f61c7594500ea53", | ||||
|                 "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/8d441ec99f8612b942b55f5183151d91591b618a", | ||||
|                 "reference": "8d441ec99f8612b942b55f5183151d91591b618a", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "barryvdh/reflection-docblock": "^2.3", | ||||
|                 "composer/class-map-generator": "^1.0", | ||||
|                 "ext-json": "*", | ||||
|                 "illuminate/console": "^11.15", | ||||
|                 "illuminate/database": "^11.15", | ||||
|                 "illuminate/filesystem": "^11.15", | ||||
|                 "illuminate/support": "^11.15", | ||||
|                 "illuminate/console": "^11.15 || ^12", | ||||
|                 "illuminate/database": "^11.15 || ^12", | ||||
|                 "illuminate/filesystem": "^11.15 || ^12", | ||||
|                 "illuminate/support": "^11.15 || ^12", | ||||
|                 "php": "^8.2" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "ext-pdo_sqlite": "*", | ||||
|                 "friendsofphp/php-cs-fixer": "^3", | ||||
|                 "illuminate/config": "^11.15", | ||||
|                 "illuminate/view": "^11.15", | ||||
|                 "illuminate/config": "^11.15 || ^12", | ||||
|                 "illuminate/view": "^11.15 || ^12", | ||||
|                 "mockery/mockery": "^1.4", | ||||
|                 "orchestra/testbench": "^9.2", | ||||
|                 "phpunit/phpunit": "^10.5", | ||||
|                 "orchestra/testbench": "^9.2 || ^10", | ||||
|                 "phpunit/phpunit": "^10.5 || ^11.5.3", | ||||
|                 "spatie/phpunit-snapshot-assertions": "^4 || ^5", | ||||
|                 "vimeo/psalm": "^5.4", | ||||
|                 "vlucas/phpdotenv": "^5" | ||||
| @@ -10195,7 +10196,7 @@ | ||||
|             ], | ||||
|             "support": { | ||||
|                 "issues": "https://github.com/barryvdh/laravel-ide-helper/issues", | ||||
|                 "source": "https://github.com/barryvdh/laravel-ide-helper/tree/v3.5.4" | ||||
|                 "source": "https://github.com/barryvdh/laravel-ide-helper/tree/v3.5.5" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -10207,7 +10208,7 @@ | ||||
|                     "type": "github" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-01-14T09:07:00+00:00" | ||||
|             "time": "2025-02-11T13:59:46+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "barryvdh/reflection-docblock", | ||||
| @@ -10587,40 +10588,40 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "larastan/larastan", | ||||
|             "version": "v3.0.4", | ||||
|             "version": "v3.1.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/larastan/larastan.git", | ||||
|                 "reference": "b394eba5805727423071fac9b53ea50dd7e920f4" | ||||
|                 "reference": "dbb2dc20e5c8e1ed3ff289054e1955f269187312" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/larastan/larastan/zipball/b394eba5805727423071fac9b53ea50dd7e920f4", | ||||
|                 "reference": "b394eba5805727423071fac9b53ea50dd7e920f4", | ||||
|                 "url": "https://api.github.com/repos/larastan/larastan/zipball/dbb2dc20e5c8e1ed3ff289054e1955f269187312", | ||||
|                 "reference": "dbb2dc20e5c8e1ed3ff289054e1955f269187312", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "ext-json": "*", | ||||
|                 "illuminate/console": "^11.15.0", | ||||
|                 "illuminate/container": "^11.15.0", | ||||
|                 "illuminate/contracts": "^11.15.0", | ||||
|                 "illuminate/database": "^11.15.0", | ||||
|                 "illuminate/http": "^11.15.0", | ||||
|                 "illuminate/pipeline": "^11.15.0", | ||||
|                 "illuminate/support": "^11.15.0", | ||||
|                 "illuminate/console": "^11.15.0 || ^12.0", | ||||
|                 "illuminate/container": "^11.15.0 || ^12.0", | ||||
|                 "illuminate/contracts": "^11.15.0 || ^12.0", | ||||
|                 "illuminate/database": "^11.15.0 || ^12.0", | ||||
|                 "illuminate/http": "^11.15.0 || ^12.0", | ||||
|                 "illuminate/pipeline": "^11.15.0 || ^12.0", | ||||
|                 "illuminate/support": "^11.15.0 || ^12.0", | ||||
|                 "php": "^8.2", | ||||
|                 "phpmyadmin/sql-parser": "^5.9.0", | ||||
|                 "phpstan/phpstan": "^2.1.3" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "doctrine/coding-standard": "^12.0", | ||||
|                 "laravel/framework": "^11.15.0", | ||||
|                 "laravel/framework": "^11.15.0 || ^12.0", | ||||
|                 "mockery/mockery": "^1.6", | ||||
|                 "nikic/php-parser": "^5.3", | ||||
|                 "orchestra/canvas": "^v9.1.3", | ||||
|                 "orchestra/testbench-core": "^9.5.2", | ||||
|                 "orchestra/canvas": "^v9.1.3 || ^10.0", | ||||
|                 "orchestra/testbench-core": "^9.5.2 || ^10.0", | ||||
|                 "phpstan/phpstan-deprecation-rules": "^2.0.0", | ||||
|                 "phpunit/phpunit": "^10.5.16" | ||||
|                 "phpunit/phpunit": "^10.5.35 || ^11.3.6" | ||||
|             }, | ||||
|             "suggest": { | ||||
|                 "orchestra/testbench": "Using Larastan for analysing a package needs Testbench" | ||||
| @@ -10633,7 +10634,7 @@ | ||||
|                     ] | ||||
|                 }, | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "2.0-dev" | ||||
|                     "dev-master": "3.0-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
| @@ -10668,7 +10669,7 @@ | ||||
|             ], | ||||
|             "support": { | ||||
|                 "issues": "https://github.com/larastan/larastan/issues", | ||||
|                 "source": "https://github.com/larastan/larastan/tree/v3.0.4" | ||||
|                 "source": "https://github.com/larastan/larastan/tree/v3.1.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -10676,7 +10677,7 @@ | ||||
|                     "type": "github" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-02-06T21:03:36+00:00" | ||||
|             "time": "2025-02-20T15:25:15+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "laravel-json-api/testing", | ||||
| @@ -10743,74 +10744,6 @@ | ||||
|             }, | ||||
|             "time": "2024-11-30T16:50:45+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "maximebf/debugbar", | ||||
|             "version": "v1.23.6", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/php-debugbar/php-debugbar.git", | ||||
|                 "reference": "4b3d5f1afe09a7db5a9d3282890f49f6176d6542" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/4b3d5f1afe09a7db5a9d3282890f49f6176d6542", | ||||
|                 "reference": "4b3d5f1afe09a7db5a9d3282890f49f6176d6542", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "php": "^7.2|^8", | ||||
|                 "psr/log": "^1|^2|^3", | ||||
|                 "symfony/var-dumper": "^4|^5|^6|^7" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "dbrekelmans/bdi": "^1", | ||||
|                 "phpunit/phpunit": "^8|^9", | ||||
|                 "symfony/panther": "^1|^2.1", | ||||
|                 "twig/twig": "^1.38|^2.7|^3.0" | ||||
|             }, | ||||
|             "suggest": { | ||||
|                 "kriswallsmith/assetic": "The best way to manage assets", | ||||
|                 "monolog/monolog": "Log using Monolog", | ||||
|                 "predis/predis": "Redis storage" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "1.23-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
|                 "psr-4": { | ||||
|                     "DebugBar\\": "src/DebugBar/" | ||||
|                 } | ||||
|             }, | ||||
|             "notification-url": "https://packagist.org/downloads/", | ||||
|             "license": [ | ||||
|                 "MIT" | ||||
|             ], | ||||
|             "authors": [ | ||||
|                 { | ||||
|                     "name": "Maxime Bouroumeau-Fuseau", | ||||
|                     "email": "maxime.bouroumeau@gmail.com", | ||||
|                     "homepage": "http://maximebf.com" | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "Barry vd. Heuvel", | ||||
|                     "email": "barryvdh@gmail.com" | ||||
|                 } | ||||
|             ], | ||||
|             "description": "Debug bar in the browser for php application", | ||||
|             "homepage": "https://github.com/maximebf/php-debugbar", | ||||
|             "keywords": [ | ||||
|                 "debug", | ||||
|                 "debugbar" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "issues": "https://github.com/php-debugbar/php-debugbar/issues", | ||||
|                 "source": "https://github.com/php-debugbar/php-debugbar/tree/v1.23.6" | ||||
|             }, | ||||
|             "time": "2025-02-13T12:22:36+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "mockery/mockery", | ||||
|             "version": "1.6.12", | ||||
| @@ -11131,17 +11064,87 @@ | ||||
|             "time": "2022-02-21T01:04:05+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpmyadmin/sql-parser", | ||||
|             "version": "5.10.3", | ||||
|             "name": "php-debugbar/php-debugbar", | ||||
|             "version": "v2.1.5", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/phpmyadmin/sql-parser.git", | ||||
|                 "reference": "5346664973d10cf1abff20837fb1183f3c11a055" | ||||
|                 "url": "https://github.com/php-debugbar/php-debugbar.git", | ||||
|                 "reference": "3f589bbbaed53039d9699702c2908148647c27a1" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/5346664973d10cf1abff20837fb1183f3c11a055", | ||||
|                 "reference": "5346664973d10cf1abff20837fb1183f3c11a055", | ||||
|                 "url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/3f589bbbaed53039d9699702c2908148647c27a1", | ||||
|                 "reference": "3f589bbbaed53039d9699702c2908148647c27a1", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "php": "^8", | ||||
|                 "psr/log": "^1|^2|^3", | ||||
|                 "symfony/var-dumper": "^4|^5|^6|^7" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "dbrekelmans/bdi": "^1", | ||||
|                 "phpunit/phpunit": "^8|^9", | ||||
|                 "symfony/panther": "^1|^2.1", | ||||
|                 "twig/twig": "^1.38|^2.7|^3.0" | ||||
|             }, | ||||
|             "suggest": { | ||||
|                 "kriswallsmith/assetic": "The best way to manage assets", | ||||
|                 "monolog/monolog": "Log using Monolog", | ||||
|                 "predis/predis": "Redis storage" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "2.0-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
|                 "psr-4": { | ||||
|                     "DebugBar\\": "src/DebugBar/" | ||||
|                 } | ||||
|             }, | ||||
|             "notification-url": "https://packagist.org/downloads/", | ||||
|             "license": [ | ||||
|                 "MIT" | ||||
|             ], | ||||
|             "authors": [ | ||||
|                 { | ||||
|                     "name": "Maxime Bouroumeau-Fuseau", | ||||
|                     "email": "maxime.bouroumeau@gmail.com", | ||||
|                     "homepage": "http://maximebf.com" | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "Barry vd. Heuvel", | ||||
|                     "email": "barryvdh@gmail.com" | ||||
|                 } | ||||
|             ], | ||||
|             "description": "Debug bar in the browser for php application", | ||||
|             "homepage": "https://github.com/php-debugbar/php-debugbar", | ||||
|             "keywords": [ | ||||
|                 "debug", | ||||
|                 "debug bar", | ||||
|                 "debugbar", | ||||
|                 "dev" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "issues": "https://github.com/php-debugbar/php-debugbar/issues", | ||||
|                 "source": "https://github.com/php-debugbar/php-debugbar/tree/v2.1.5" | ||||
|             }, | ||||
|             "time": "2025-02-21T13:02:05+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpmyadmin/sql-parser", | ||||
|             "version": "5.11.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/phpmyadmin/sql-parser.git", | ||||
|                 "reference": "07044bc8c13abd542756c3fd34dc66a5d6dee8e4" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/07044bc8c13abd542756c3fd34dc66a5d6dee8e4", | ||||
|                 "reference": "07044bc8c13abd542756c3fd34dc66a5d6dee8e4", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -11156,9 +11159,11 @@ | ||||
|                 "phpbench/phpbench": "^1.1", | ||||
|                 "phpmyadmin/coding-standard": "^3.0", | ||||
|                 "phpmyadmin/motranslator": "^4.0 || ^5.0", | ||||
|                 "phpstan/extension-installer": "^1.1", | ||||
|                 "phpstan/phpstan": "^1.9.12", | ||||
|                 "phpstan/phpstan-phpunit": "^1.3.3", | ||||
|                 "phpstan/extension-installer": "^1.4", | ||||
|                 "phpstan/phpstan": "^1.12", | ||||
|                 "phpstan/phpstan-deprecation-rules": "^1.2", | ||||
|                 "phpstan/phpstan-phpunit": "^1.4", | ||||
|                 "phpstan/phpstan-strict-rules": "^1.6", | ||||
|                 "phpunit/phpunit": "^8.5 || ^9.6", | ||||
|                 "psalm/plugin-phpunit": "^0.16.1", | ||||
|                 "vimeo/psalm": "^4.11", | ||||
| @@ -11215,7 +11220,7 @@ | ||||
|                     "type": "other" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-01-19T04:14:02+00:00" | ||||
|             "time": "2025-02-22T20:00:59+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpstan/extension-installer", | ||||
| @@ -11267,16 +11272,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpstan/phpstan", | ||||
|             "version": "2.1.5", | ||||
|             "version": "2.1.6", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/phpstan/phpstan.git", | ||||
|                 "reference": "451b17f9665481ee502adc39be987cb71067ece2" | ||||
|                 "reference": "6eaec7c6c9e90dcfe46ad1e1ffa5171e2dab641c" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/phpstan/phpstan/zipball/451b17f9665481ee502adc39be987cb71067ece2", | ||||
|                 "reference": "451b17f9665481ee502adc39be987cb71067ece2", | ||||
|                 "url": "https://api.github.com/repos/phpstan/phpstan/zipball/6eaec7c6c9e90dcfe46ad1e1ffa5171e2dab641c", | ||||
|                 "reference": "6eaec7c6c9e90dcfe46ad1e1ffa5171e2dab641c", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -11321,7 +11326,7 @@ | ||||
|                     "type": "github" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-02-13T12:49:56+00:00" | ||||
|             "time": "2025-02-19T15:46:42+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpstan/phpstan-deprecation-rules", | ||||
| @@ -11743,16 +11748,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpunit/phpunit", | ||||
|             "version": "11.5.7", | ||||
|             "version": "11.5.9", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/sebastianbergmann/phpunit.git", | ||||
|                 "reference": "e1cb706f019e2547039ca2c839898cd5f557ee5d" | ||||
|                 "reference": "c91c830e7108a81e5845aeb6ba8fe3c1a4351c0b" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e1cb706f019e2547039ca2c839898cd5f557ee5d", | ||||
|                 "reference": "e1cb706f019e2547039ca2c839898cd5f557ee5d", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c91c830e7108a81e5845aeb6ba8fe3c1a4351c0b", | ||||
|                 "reference": "c91c830e7108a81e5845aeb6ba8fe3c1a4351c0b", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -11762,7 +11767,7 @@ | ||||
|                 "ext-mbstring": "*", | ||||
|                 "ext-xml": "*", | ||||
|                 "ext-xmlwriter": "*", | ||||
|                 "myclabs/deep-copy": "^1.12.1", | ||||
|                 "myclabs/deep-copy": "^1.13.0", | ||||
|                 "phar-io/manifest": "^2.0.4", | ||||
|                 "phar-io/version": "^3.2.1", | ||||
|                 "php": ">=8.2", | ||||
| @@ -11824,7 +11829,7 @@ | ||||
|             "support": { | ||||
|                 "issues": "https://github.com/sebastianbergmann/phpunit/issues", | ||||
|                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy", | ||||
|                 "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.7" | ||||
|                 "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.9" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -11840,7 +11845,7 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-02-06T16:10:05+00:00" | ||||
|             "time": "2025-02-21T06:08:50+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "sebastian/cli-parser", | ||||
|   | ||||
| @@ -81,7 +81,7 @@ return [ | ||||
|         'running_balance_column' => env('USE_RUNNING_BALANCE', false), | ||||
|         // see cer.php for exchange rates feature flag.
 | ||||
|     ], | ||||
|     'version'                      => 'develop/2025-02-17', | ||||
|     'version'                      => 'develop/2025-02-24', | ||||
|     'api_version'                  => '2.1.0', // field is no longer used.
 | ||||
|     'db_version'                   => 25, | ||||
| 
 | ||||
|   | ||||
							
								
								
									
										214
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										214
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -2605,9 +2605,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-android-arm-eabi": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.7.tgz", | ||||
|             "integrity": "sha512-l6CtzHYo8D2TQ3J7qJNpp3Q1Iye56ssIAtqbM2H8axxCEEwvN7o8Ze9PuIapbxFL3OHrJU2JBX6FIIVnP/rYyw==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", | ||||
|             "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", | ||||
|             "cpu": [ | ||||
|                 "arm" | ||||
|             ], | ||||
| @@ -2619,9 +2619,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-android-arm64": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.7.tgz", | ||||
|             "integrity": "sha512-KvyJpFUueUnSp53zhAa293QBYqwm94TgYTIfXyOTtidhm5V0LbLCJQRGkQClYiX3FXDQGSvPxOTD/6rPStMMDg==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", | ||||
|             "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", | ||||
|             "cpu": [ | ||||
|                 "arm64" | ||||
|             ], | ||||
| @@ -2633,9 +2633,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-darwin-arm64": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.7.tgz", | ||||
|             "integrity": "sha512-jq87CjmgL9YIKvs8ybtIC98s/M3HdbqXhllcy9EdLV0yMg1DpxES2gr65nNy7ObNo/vZ/MrOTxt0bE5LinL6mA==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", | ||||
|             "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", | ||||
|             "cpu": [ | ||||
|                 "arm64" | ||||
|             ], | ||||
| @@ -2647,9 +2647,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-darwin-x64": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.7.tgz", | ||||
|             "integrity": "sha512-rSI/m8OxBjsdnMMg0WEetu/w+LhLAcCDEiL66lmMX4R3oaml3eXz3Dxfvrxs1FbzPbJMaItQiksyMfv1hoIxnA==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", | ||||
|             "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", | ||||
|             "cpu": [ | ||||
|                 "x64" | ||||
|             ], | ||||
| @@ -2661,9 +2661,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-freebsd-arm64": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.7.tgz", | ||||
|             "integrity": "sha512-oIoJRy3ZrdsXpFuWDtzsOOa/E/RbRWXVokpVrNnkS7npz8GEG++E1gYbzhYxhxHbO2om1T26BZjVmdIoyN2WtA==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", | ||||
|             "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", | ||||
|             "cpu": [ | ||||
|                 "arm64" | ||||
|             ], | ||||
| @@ -2675,9 +2675,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-freebsd-x64": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.7.tgz", | ||||
|             "integrity": "sha512-X++QSLm4NZfZ3VXGVwyHdRf58IBbCu9ammgJxuWZYLX0du6kZvdNqPwrjvDfwmi6wFdvfZ/s6K7ia0E5kI7m8Q==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", | ||||
|             "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", | ||||
|             "cpu": [ | ||||
|                 "x64" | ||||
|             ], | ||||
| @@ -2689,9 +2689,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-linux-arm-gnueabihf": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.7.tgz", | ||||
|             "integrity": "sha512-Z0TzhrsNqukTz3ISzrvyshQpFnFRfLunYiXxlCRvcrb3nvC5rVKI+ZXPFG/Aa4jhQa1gHgH3A0exHaRRN4VmdQ==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", | ||||
|             "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", | ||||
|             "cpu": [ | ||||
|                 "arm" | ||||
|             ], | ||||
| @@ -2703,9 +2703,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-linux-arm-musleabihf": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.7.tgz", | ||||
|             "integrity": "sha512-nkznpyXekFAbvFBKBy4nNppSgneB1wwG1yx/hujN3wRnhnkrYVugMTCBXED4+Ni6thoWfQuHNYbFjgGH0MBXtw==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", | ||||
|             "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", | ||||
|             "cpu": [ | ||||
|                 "arm" | ||||
|             ], | ||||
| @@ -2717,9 +2717,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-linux-arm64-gnu": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.7.tgz", | ||||
|             "integrity": "sha512-KCjlUkcKs6PjOcxolqrXglBDcfCuUCTVlX5BgzgoJHw+1rWH1MCkETLkLe5iLLS9dP5gKC7mp3y6x8c1oGBUtA==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", | ||||
|             "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", | ||||
|             "cpu": [ | ||||
|                 "arm64" | ||||
|             ], | ||||
| @@ -2731,9 +2731,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-linux-arm64-musl": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.7.tgz", | ||||
|             "integrity": "sha512-uFLJFz6+utmpbR313TTx+NpPuAXbPz4BhTQzgaP0tozlLnGnQ6rCo6tLwaSa6b7l6gRErjLicXQ1iPiXzYotjw==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", | ||||
|             "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", | ||||
|             "cpu": [ | ||||
|                 "arm64" | ||||
|             ], | ||||
| @@ -2745,9 +2745,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-linux-loongarch64-gnu": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.7.tgz", | ||||
|             "integrity": "sha512-ws8pc68UcJJqCpneDFepnwlsMUFoWvPbWXT/XUrJ7rWUL9vLoIN3GAasgG+nCvq8xrE3pIrd+qLX/jotcLy0Qw==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", | ||||
|             "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", | ||||
|             "cpu": [ | ||||
|                 "loong64" | ||||
|             ], | ||||
| @@ -2759,9 +2759,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.7.tgz", | ||||
|             "integrity": "sha512-vrDk9JDa/BFkxcS2PbWpr0C/LiiSLxFbNOBgfbW6P8TBe9PPHx9Wqbvx2xgNi1TOAyQHQJ7RZFqBiEohm79r0w==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", | ||||
|             "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", | ||||
|             "cpu": [ | ||||
|                 "ppc64" | ||||
|             ], | ||||
| @@ -2773,9 +2773,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-linux-riscv64-gnu": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.7.tgz", | ||||
|             "integrity": "sha512-rB+ejFyjtmSo+g/a4eovDD1lHWHVqizN8P0Hm0RElkINpS0XOdpaXloqM4FBkF9ZWEzg6bezymbpLmeMldfLTw==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", | ||||
|             "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", | ||||
|             "cpu": [ | ||||
|                 "riscv64" | ||||
|             ], | ||||
| @@ -2787,9 +2787,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-linux-s390x-gnu": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.7.tgz", | ||||
|             "integrity": "sha512-nNXNjo4As6dNqRn7OrsnHzwTgtypfRA3u3AKr0B3sOOo+HkedIbn8ZtFnB+4XyKJojIfqDKmbIzO1QydQ8c+Pw==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", | ||||
|             "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", | ||||
|             "cpu": [ | ||||
|                 "s390x" | ||||
|             ], | ||||
| @@ -2801,9 +2801,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-linux-x64-gnu": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.7.tgz", | ||||
|             "integrity": "sha512-9kPVf9ahnpOMSGlCxXGv980wXD0zRR3wyk8+33/MXQIpQEOpaNe7dEHm5LMfyRZRNt9lMEQuH0jUKj15MkM7QA==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", | ||||
|             "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", | ||||
|             "cpu": [ | ||||
|                 "x64" | ||||
|             ], | ||||
| @@ -2815,9 +2815,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-linux-x64-musl": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.7.tgz", | ||||
|             "integrity": "sha512-7wJPXRWTTPtTFDFezA8sle/1sdgxDjuMoRXEKtx97ViRxGGkVQYovem+Q8Pr/2HxiHp74SSRG+o6R0Yq0shPwQ==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", | ||||
|             "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", | ||||
|             "cpu": [ | ||||
|                 "x64" | ||||
|             ], | ||||
| @@ -2829,9 +2829,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-win32-arm64-msvc": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.7.tgz", | ||||
|             "integrity": "sha512-MN7aaBC7mAjsiMEZcsJvwNsQVNZShgES/9SzWp1HC9Yjqb5OpexYnRjF7RmE4itbeesHMYYQiAtUAQaSKs2Rfw==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", | ||||
|             "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", | ||||
|             "cpu": [ | ||||
|                 "arm64" | ||||
|             ], | ||||
| @@ -2843,9 +2843,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-win32-ia32-msvc": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.7.tgz", | ||||
|             "integrity": "sha512-aeawEKYswsFu1LhDM9RIgToobquzdtSc4jSVqHV8uApz4FVvhFl/mKh92wc8WpFc6aYCothV/03UjY6y7yLgbg==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", | ||||
|             "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", | ||||
|             "cpu": [ | ||||
|                 "ia32" | ||||
|             ], | ||||
| @@ -2857,9 +2857,9 @@ | ||||
|             ] | ||||
|         }, | ||||
|         "node_modules/@rollup/rollup-win32-x64-msvc": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.7.tgz", | ||||
|             "integrity": "sha512-4ZedScpxxIrVO7otcZ8kCX1mZArtH2Wfj3uFCxRJ9NO80gg1XV0U/b2f/MKaGwj2X3QopHfoWiDQ917FRpwY3w==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", | ||||
|             "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", | ||||
|             "cpu": [ | ||||
|                 "x64" | ||||
|             ], | ||||
| @@ -3147,9 +3147,9 @@ | ||||
|             "license": "MIT" | ||||
|         }, | ||||
|         "node_modules/@types/node": { | ||||
|             "version": "22.13.4", | ||||
|             "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.4.tgz", | ||||
|             "integrity": "sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==", | ||||
|             "version": "22.13.5", | ||||
|             "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz", | ||||
|             "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
| @@ -4510,9 +4510,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/chart.js": { | ||||
|             "version": "4.4.7", | ||||
|             "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.7.tgz", | ||||
|             "integrity": "sha512-pwkcKfdzTMAU/+jNosKhNL2bHtJc/sSmYgVbuGTEDhzkrhmyihmP7vUc/5ZK9WopidMDHNe3Wm7jOd/WhuHWuw==", | ||||
|             "version": "4.4.8", | ||||
|             "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.8.tgz", | ||||
|             "integrity": "sha512-IkGZlVpXP+83QpMm4uxEiGqSI7jFizwVtF3+n5Pc3k7sMO+tkd0qxh2OzLhenM0K80xtmAONWGBn082EiBQSDA==", | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "@kurkle/color": "^0.3.0" | ||||
| @@ -5677,9 +5677,9 @@ | ||||
|             "license": "MIT" | ||||
|         }, | ||||
|         "node_modules/electron-to-chromium": { | ||||
|             "version": "1.5.101", | ||||
|             "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.101.tgz", | ||||
|             "integrity": "sha512-L0ISiQrP/56Acgu4/i/kfPwWSgrzYZUnQrC0+QPFuhqlLP1Ir7qzPPDVS9BcKIyWTRU8+o6CC8dKw38tSWhYIA==", | ||||
|             "version": "1.5.103", | ||||
|             "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.103.tgz", | ||||
|             "integrity": "sha512-P6+XzIkfndgsrjROJWfSvVEgNHtPgbhVyTkwLjUM2HU/h7pZRORgaTlHqfAikqxKmdJMLW8fftrdGWbd/Ds0FA==", | ||||
|             "dev": true, | ||||
|             "license": "ISC" | ||||
|         }, | ||||
| @@ -6491,18 +6491,18 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/get-intrinsic": { | ||||
|             "version": "1.2.7", | ||||
|             "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", | ||||
|             "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", | ||||
|             "version": "1.3.0", | ||||
|             "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", | ||||
|             "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "call-bind-apply-helpers": "^1.0.1", | ||||
|                 "call-bind-apply-helpers": "^1.0.2", | ||||
|                 "es-define-property": "^1.0.1", | ||||
|                 "es-errors": "^1.3.0", | ||||
|                 "es-object-atoms": "^1.0.0", | ||||
|                 "es-object-atoms": "^1.1.1", | ||||
|                 "function-bind": "^1.1.2", | ||||
|                 "get-proto": "^1.0.0", | ||||
|                 "get-proto": "^1.0.1", | ||||
|                 "gopd": "^1.2.0", | ||||
|                 "has-symbols": "^1.1.0", | ||||
|                 "hasown": "^2.0.2", | ||||
| @@ -7778,9 +7778,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/launch-editor": { | ||||
|             "version": "2.9.1", | ||||
|             "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", | ||||
|             "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", | ||||
|             "version": "2.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.10.0.tgz", | ||||
|             "integrity": "sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
| @@ -8901,9 +8901,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/postcss": { | ||||
|             "version": "8.5.2", | ||||
|             "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz", | ||||
|             "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==", | ||||
|             "version": "8.5.3", | ||||
|             "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", | ||||
|             "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", | ||||
|             "dev": true, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -10034,9 +10034,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/rollup": { | ||||
|             "version": "4.34.7", | ||||
|             "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.7.tgz", | ||||
|             "integrity": "sha512-8qhyN0oZ4x0H6wmBgfKxJtxM7qS98YJ0k0kNh5ECVtuchIJ7z9IVVvzpmtQyT10PXKMtBxYr1wQ5Apg8RS8kXQ==", | ||||
|             "version": "4.34.8", | ||||
|             "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", | ||||
|             "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
| @@ -10050,25 +10050,25 @@ | ||||
|                 "npm": ">=8.0.0" | ||||
|             }, | ||||
|             "optionalDependencies": { | ||||
|                 "@rollup/rollup-android-arm-eabi": "4.34.7", | ||||
|                 "@rollup/rollup-android-arm64": "4.34.7", | ||||
|                 "@rollup/rollup-darwin-arm64": "4.34.7", | ||||
|                 "@rollup/rollup-darwin-x64": "4.34.7", | ||||
|                 "@rollup/rollup-freebsd-arm64": "4.34.7", | ||||
|                 "@rollup/rollup-freebsd-x64": "4.34.7", | ||||
|                 "@rollup/rollup-linux-arm-gnueabihf": "4.34.7", | ||||
|                 "@rollup/rollup-linux-arm-musleabihf": "4.34.7", | ||||
|                 "@rollup/rollup-linux-arm64-gnu": "4.34.7", | ||||
|                 "@rollup/rollup-linux-arm64-musl": "4.34.7", | ||||
|                 "@rollup/rollup-linux-loongarch64-gnu": "4.34.7", | ||||
|                 "@rollup/rollup-linux-powerpc64le-gnu": "4.34.7", | ||||
|                 "@rollup/rollup-linux-riscv64-gnu": "4.34.7", | ||||
|                 "@rollup/rollup-linux-s390x-gnu": "4.34.7", | ||||
|                 "@rollup/rollup-linux-x64-gnu": "4.34.7", | ||||
|                 "@rollup/rollup-linux-x64-musl": "4.34.7", | ||||
|                 "@rollup/rollup-win32-arm64-msvc": "4.34.7", | ||||
|                 "@rollup/rollup-win32-ia32-msvc": "4.34.7", | ||||
|                 "@rollup/rollup-win32-x64-msvc": "4.34.7", | ||||
|                 "@rollup/rollup-android-arm-eabi": "4.34.8", | ||||
|                 "@rollup/rollup-android-arm64": "4.34.8", | ||||
|                 "@rollup/rollup-darwin-arm64": "4.34.8", | ||||
|                 "@rollup/rollup-darwin-x64": "4.34.8", | ||||
|                 "@rollup/rollup-freebsd-arm64": "4.34.8", | ||||
|                 "@rollup/rollup-freebsd-x64": "4.34.8", | ||||
|                 "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", | ||||
|                 "@rollup/rollup-linux-arm-musleabihf": "4.34.8", | ||||
|                 "@rollup/rollup-linux-arm64-gnu": "4.34.8", | ||||
|                 "@rollup/rollup-linux-arm64-musl": "4.34.8", | ||||
|                 "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", | ||||
|                 "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", | ||||
|                 "@rollup/rollup-linux-riscv64-gnu": "4.34.8", | ||||
|                 "@rollup/rollup-linux-s390x-gnu": "4.34.8", | ||||
|                 "@rollup/rollup-linux-x64-gnu": "4.34.8", | ||||
|                 "@rollup/rollup-linux-x64-musl": "4.34.8", | ||||
|                 "@rollup/rollup-win32-arm64-msvc": "4.34.8", | ||||
|                 "@rollup/rollup-win32-ia32-msvc": "4.34.8", | ||||
|                 "@rollup/rollup-win32-x64-msvc": "4.34.8", | ||||
|                 "fsevents": "~2.3.2" | ||||
|             } | ||||
|         }, | ||||
| @@ -11344,14 +11344,14 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/vite": { | ||||
|             "version": "6.1.0", | ||||
|             "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz", | ||||
|             "integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==", | ||||
|             "version": "6.1.1", | ||||
|             "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.1.tgz", | ||||
|             "integrity": "sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "esbuild": "^0.24.2", | ||||
|                 "postcss": "^8.5.1", | ||||
|                 "postcss": "^8.5.2", | ||||
|                 "rollup": "^4.30.1" | ||||
|             }, | ||||
|             "bin": { | ||||
| @@ -12174,9 +12174,9 @@ | ||||
|             "license": "ISC" | ||||
|         }, | ||||
|         "node_modules/ws": { | ||||
|             "version": "8.18.0", | ||||
|             "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", | ||||
|             "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", | ||||
|             "version": "8.18.1", | ||||
|             "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", | ||||
|             "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "engines": { | ||||
|   | ||||
| @@ -172,8 +172,8 @@ | ||||
|     }, | ||||
|     "list": { | ||||
|         "title": "Titolo", | ||||
|         "active": "Attivo", | ||||
|         "native_currency": "Native currency", | ||||
|         "active": "\u00c8 attivo?", | ||||
|         "native_currency": "Valuta nativa", | ||||
|         "trigger": "Trigger", | ||||
|         "response": "Risposta", | ||||
|         "delivery": "Consegna", | ||||
|   | ||||
| @@ -1,25 +1,25 @@ | ||||
| { | ||||
|     "firefly": { | ||||
|         "administrations_page_title": "Financial administrations", | ||||
|         "administrations_index_menu": "Financial administrations", | ||||
|         "temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.", | ||||
|         "administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.", | ||||
|         "administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"", | ||||
|         "administrations_page_title": "Ustawienia finansowe", | ||||
|         "administrations_index_menu": "Ustawienia finansowe", | ||||
|         "temp_administrations_introduction": "Firefly III wkr\u00f3tce uzyska mo\u017cliwo\u015b\u0107 zarz\u0105dzania wieloma ustawieniami finansowymi. W tej chwili jest tylko jedno domy\u015blne ustawienie. Mo\u017cesz ustawi\u0107 jego tytu\u0142 i natywn\u0105 walut\u0119. To zast\u0119puje poprzednie ustawienia, w kt\u00f3rym mo\u017cna by\u0142o ustawi\u0107 \"domy\u015bln\u0105 walut\u0119\". Jest ona obecnie powi\u0105zana z wybranym ustawieniem finansowym i mo\u017ce by\u0107 zmienione w tej zak\u0142adce.", | ||||
|         "administration_currency_form_help": "Wczytywanie strony mo\u017ce zaj\u0105\u0107 du\u017co czasu, je\u015bli zmienisz natywn\u0105 walut\u0119, poniewa\u017c transakcja mo\u017ce wymaga\u0107 przewalutowania na (now\u0105) natywn\u0105 walut\u0119.", | ||||
|         "administrations_page_edit_sub_title_js": "Edytuj ustawienia finansowe \"{title}\"", | ||||
|         "table": "Tabela", | ||||
|         "welcome_back": "Co jest grane?", | ||||
|         "flash_error": "B\u0142\u0105d!", | ||||
|         "flash_warning": "Ostrze\u017cenie!", | ||||
|         "flash_success": "Sukces!", | ||||
|         "close": "Zamknij", | ||||
|         "select_dest_account": "Please select or type a valid destination account name", | ||||
|         "select_dest_account": "Wybierz lub wpisz prawid\u0142ow\u0105 nazw\u0119 konta docelowego", | ||||
|         "select_source_account": "Wybierz lub wpisz prawid\u0142ow\u0105 nazw\u0119 konta \u017ar\u00f3d\u0142owego", | ||||
|         "split_transaction_title": "Opis podzielonej transakcji", | ||||
|         "errors_submission": "Co\u015b posz\u0142o nie tak w czasie zapisu. Prosz\u0119, sprawd\u017a b\u0142\u0119dy poni\u017cej.", | ||||
|         "is_reconciled": "Is reconciled", | ||||
|         "is_reconciled": "Jest uzgodniona", | ||||
|         "split": "Podziel", | ||||
|         "single_split": "Podzia\u0142", | ||||
|         "not_enough_currencies": "Not enough currencies", | ||||
|         "not_enough_currencies_enabled": "If you have just one currency enabled, there is no need to add exchange rates.", | ||||
|         "not_enough_currencies": "Za ma\u0142o walut", | ||||
|         "not_enough_currencies_enabled": "Je\u015bli masz w\u0142\u0105czon\u0105 tylko jedn\u0105 walut\u0119, nie ma potrzeby dodawania kurs\u00f3w wymiany.", | ||||
|         "transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Transakcja #{ID} (\"{title}\")<\/a> zosta\u0142a zapisana.", | ||||
|         "webhook_stored_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID} (\"{title}\")<\/a> zosta\u0142 zapisany.", | ||||
|         "webhook_updated_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID}<\/a> (\"{title}\") zosta\u0142 zaktualizowany.", | ||||
| @@ -42,10 +42,10 @@ | ||||
|         "submit": "Prze\u015blij", | ||||
|         "amount": "Kwota", | ||||
|         "date": "Data", | ||||
|         "is_reconciled_fields_dropped": "Because this transaction is reconciled, you will not be able to update the accounts, nor the amount(s) unless you remove the reconciliation flag.", | ||||
|         "is_reconciled_fields_dropped": "Poniewa\u017c ta transakcja jest uzgodniona, nie b\u0119dziesz w stanie zaktualizowa\u0107 kont, ani kwot(y), chyba \u017ce usuniesz flag\u0119 uzgodnienia.", | ||||
|         "tags": "Tagi", | ||||
|         "no_budget": "(brak bud\u017cetu)", | ||||
|         "no_bill": "(no subscription)", | ||||
|         "no_bill": "(brak subskrypcji)", | ||||
|         "category": "Kategoria", | ||||
|         "attachments": "Za\u0142\u0105czniki", | ||||
|         "notes": "Notatki", | ||||
| @@ -61,7 +61,7 @@ | ||||
|         "destination_account_reconciliation": "Nie mo\u017cesz edytowa\u0107 konta docelowego transakcji uzgadniania.", | ||||
|         "source_account_reconciliation": "Nie mo\u017cesz edytowa\u0107 konta \u017ar\u00f3d\u0142owego transakcji uzgadniania.", | ||||
|         "budget": "Bud\u017cet", | ||||
|         "bill": "Subscription", | ||||
|         "bill": "Subskrypcja", | ||||
|         "you_create_withdrawal": "Tworzysz wydatek.", | ||||
|         "you_create_transfer": "Tworzysz przelew.", | ||||
|         "you_create_deposit": "Tworzysz wp\u0142at\u0119.", | ||||
| @@ -139,15 +139,15 @@ | ||||
|         "response": "Odpowied\u017a", | ||||
|         "visit_webhook_url": "Odwied\u017a adres URL webhooka", | ||||
|         "reset_webhook_secret": "Resetuj sekret webhooka", | ||||
|         "header_exchange_rates": "Exchange rates", | ||||
|         "exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">the documentation<\/a>.", | ||||
|         "exchange_rates_from_to": "Between {from} and {to} (and the other way around)", | ||||
|         "exchange_rates_intro_rates": "Firefly III uses the following exchange rates. The inverse is automatically calculated when it is not provided. If no exchange rate exists for the date of the transaction, Firefly III will go back in time to find one. If none are present, the rate \"1\" will be used.", | ||||
|         "header_exchange_rates_rates": "Exchange rates", | ||||
|         "header_exchange_rates_table": "Table with exchange rates", | ||||
|         "help_rate_form": "On this day, how many {to} will you get for one {from}?", | ||||
|         "add_new_rate": "Add a new exchange rate", | ||||
|         "save_new_rate": "Save new rate" | ||||
|         "header_exchange_rates": "Kursy walutowe", | ||||
|         "exchange_rates_intro": "Firefly III obs\u0142uguje pobieranie i korzystanie z kurs\u00f3w wymiany walut. Wi\u0119cej informacji na ten temat w <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">dokumentacji<\/a>.", | ||||
|         "exchange_rates_from_to": "Pomi\u0119dzy {from} i {to} (i odwrotnie)", | ||||
|         "exchange_rates_intro_rates": "Firefly III u\u017cywa nast\u0119puj\u0105cych kurs\u00f3w wymiany. Odwrotny jest obliczany automatycznie, w przypadku gdy nie jest dostarczony. Je\u015bli dla daty transakcji nie istnieje kurs wymiany, Firefly III skorzysta z kursu z przesz\u0142o\u015bci. Je\u015bli \u017caden nie istnieje, zostanie zastosowany kurs \"1\".", | ||||
|         "header_exchange_rates_rates": "Kursy walutowe", | ||||
|         "header_exchange_rates_table": "Tabela z kursami wymiany walut", | ||||
|         "help_rate_form": "Tego dnia, ile {to} otrzymasz za jeden {from}?", | ||||
|         "add_new_rate": "Dodaj nowy kurs wymiany", | ||||
|         "save_new_rate": "Zapisz nowy kurs" | ||||
|     }, | ||||
|     "form": { | ||||
|         "url": "URL", | ||||
|   | ||||
| @@ -30,7 +30,7 @@ | ||||
|         "apply_rules_checkbox": "\u0417\u0430\u0441\u0442\u043e\u0441\u0443\u0432\u0430\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430", | ||||
|         "fire_webhooks_checkbox": "\u041f\u043e\u0436\u0435\u0436\u043d\u0456 \u0432\u0435\u0431\u0433\u0430\u043a\u0438", | ||||
|         "no_budget_pointer": "\u0417\u0434\u0430\u0454\u0442\u044c\u0441\u044f, \u043d\u0435 \u0441\u0442\u0432\u043e\u0440\u0438\u043b\u0438 \u0436\u043e\u0434\u043d\u043e\u0433\u043e \u0431\u044e\u0434\u0436\u0435\u0442\u0443. \u0421\u0442\u0432\u043e\u0440\u0456\u0442\u044c \u043e\u0434\u0438\u043d \u043d\u0430 \u0441\u0442\u043e\u0440\u0456\u043d\u0446\u0456 <a href=\"budgets\">\u0431\u044e\u0434\u0436\u0435\u0442\u0456\u0432<\/a>. \u0411\u044e\u0434\u0436\u0435\u0442\u0438 \u043c\u043e\u0436\u0443\u0442\u044c \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u0442\u0438 \u0432\u0430\u043c \u0441\u0442\u0435\u0436\u0438\u0442\u0438 \u0437\u0430 \u0432\u0438\u0442\u0440\u0430\u0442\u0430\u043c\u0438.", | ||||
|         "no_bill_pointer": "You seem to have no subscription yet. You should create some on the <a href=\"subscriptions\">subscription<\/a>-page. Subscriptions can help you keep track of expenses.", | ||||
|         "no_bill_pointer": "\u0421\u0445\u043e\u0436\u0435, \u0443 \u0432\u0430\u0441 \u0449\u0435 \u043d\u0435\u043c\u0430\u0454 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0438. \u0421\u0442\u0432\u043e\u0440\u0456\u0442\u044c \u0457\u0457 \u043d\u0430 \u0441\u0442\u043e\u0440\u0456\u043d\u0446\u0456 <a href=\"subscriptions\">\u043f\u0456\u0434\u043f\u0438\u0441\u043e\u043a<\/a>. \u041f\u0456\u0434\u043f\u0438\u0441\u043a\u0438 \u0434\u043e\u043f\u043e\u043c\u043e\u0436\u0443\u0442\u044c \u0432\u0430\u043c \u0432\u0456\u0434\u0441\u0442\u0435\u0436\u0443\u0432\u0430\u0442\u0438 \u0432\u0438\u0442\u0440\u0430\u0442\u0438.", | ||||
|         "source_account": "\u0412\u0438\u0445\u0456\u0434\u043d\u0438\u0439 \u0440\u0430\u0445\u0443\u043d\u043e\u043a", | ||||
|         "hidden_fields_preferences": "\u0412\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0431\u0456\u043b\u044c\u0448\u0435 \u043e\u043f\u0446\u0456\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0456\u0457 \u0443 \u0432\u0430\u0448\u043e\u043c\u0443 <a href=\"preferences\">\u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f<\/a>.", | ||||
|         "destination_account": "\u0420\u0430\u0445\u0443\u043d\u043e\u043a \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f", | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| { | ||||
|     "firefly": { | ||||
|         "administrations_page_title": "Financial administrations", | ||||
|         "administrations_index_menu": "Financial administrations", | ||||
|         "temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.", | ||||
|         "administrations_page_title": "\u8d22\u52a1\u7ba1\u7406", | ||||
|         "administrations_index_menu": "\u8d22\u52a1\u7ba1\u7406", | ||||
|         "temp_administrations_introduction": "Firefly III \u4e0d\u4e45\u5c06\u80fd\u591f\u7ba1\u7406\u591a\u4e2a\u8d22\u52a1\u7ba1\u7406\u3002 \u73b0\u5728\uff0c\u4f60\u53ea\u80fd\u6709\u4e00\u4e2a\u8d22\u52a1\u7ba1\u7406\u3002\u4f60\u53ef\u4ee5\u8bbe\u7f6e\u8fd9\u4e2a\u8d22\u52a1\u7ba1\u7406\u7684\u6807\u9898\u53ca\u5176\u5f53\u5730\u8d27\u5e01\u3002 \u8fd9\u5c06\u53d6\u4ee3\u60a8\u5148\u524d\u8bbe\u7f6e\u7684\u201c\u9ed8\u8ba4\u8d27\u5e01\u201d\u3002 \u8fd9\u79cd\u8bbe\u7f6e\u73b0\u5728\u4e0e\u8d22\u52a1\u7ba1\u7406\u6302\u94a9\uff0c\u6bcf\u4e2a\u7ba1\u7406\u53ef\u4ee5\u6709\u4e0d\u540c\u7684\u8bbe\u7f6e\u3002", | ||||
|         "administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.", | ||||
|         "administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"", | ||||
|         "table": "\u8868\u683c", | ||||
| @@ -19,7 +19,7 @@ | ||||
|         "split": "\u62c6\u5206", | ||||
|         "single_split": "\u62c6\u5206", | ||||
|         "not_enough_currencies": "Not enough currencies", | ||||
|         "not_enough_currencies_enabled": "If you have just one currency enabled, there is no need to add exchange rates.", | ||||
|         "not_enough_currencies_enabled": "\u5982\u679c\u60a8\u53ea\u542f\u7528\u4e86\u4e00\u79cd\u8d27\u5e01\uff0c\u5c31\u4e0d\u9700\u8981\u6dfb\u52a0\u6c47\u7387\u3002", | ||||
|         "transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">\u4ea4\u6613 #{ID} (\u201c{title}\u201d)<\/a> \u5df2\u4fdd\u5b58\u3002", | ||||
|         "webhook_stored_link": "<a href=\"webhooks\/show\/{ID}\">\u63a8\u9001 #{ID} (\"{title}\")<\/a> \u5df2\u4fdd\u5b58.", | ||||
|         "webhook_updated_link": "<a href=\"webhooks\/show\/{ID}\">\u63a8\u9001 #{ID}<\/a> (\"{title}\") \u5df2\u66f4\u65b0.", | ||||
| @@ -45,7 +45,7 @@ | ||||
|         "is_reconciled_fields_dropped": "Because this transaction is reconciled, you will not be able to update the accounts, nor the amount(s) unless you remove the reconciliation flag.", | ||||
|         "tags": "\u6807\u7b7e", | ||||
|         "no_budget": "(\u65e0\u9884\u7b97)", | ||||
|         "no_bill": "(no subscription)", | ||||
|         "no_bill": "(\u65e0\u8ba2\u9605)", | ||||
|         "category": "\u5206\u7c7b", | ||||
|         "attachments": "\u9644\u4ef6", | ||||
|         "notes": "\u5907\u6ce8", | ||||
| @@ -146,8 +146,8 @@ | ||||
|         "header_exchange_rates_rates": "\u6c47\u7387", | ||||
|         "header_exchange_rates_table": "Table with exchange rates", | ||||
|         "help_rate_form": "On this day, how many {to} will you get for one {from}?", | ||||
|         "add_new_rate": "Add a new exchange rate", | ||||
|         "save_new_rate": "Save new rate" | ||||
|         "add_new_rate": "\u6dfb\u52a0\u65b0\u6c47\u7387", | ||||
|         "save_new_rate": "\u4fdd\u5b58\u65b0\u6c47\u7387" | ||||
|     }, | ||||
|     "form": { | ||||
|         "url": "\u7f51\u5740", | ||||
| @@ -182,6 +182,6 @@ | ||||
|     }, | ||||
|     "config": { | ||||
|         "html_language": "zh-cn", | ||||
|         "date_time_fns": "YYYY\u5e74M\u6708D\u65e5 HH:mm:ss" | ||||
|         "date_time_fns": "yyyy\u5e74M\u6708d\u65e5 HH:mm:ss" | ||||
|     } | ||||
| } | ||||
| @@ -220,7 +220,6 @@ | ||||
|  | ||||
| {# Moment JS #} | ||||
| <script src="v1/js/lib/moment.min.js?v={{ FF_VERSION }}" type="text/javascript" nonce="{{ JS_NONCE }}"></script> | ||||
| <script src="v1/js/lib/moment-tz.js?v={{ FF_VERSION }}" type="text/javascript" nonce="{{ JS_NONCE }}"></script> | ||||
| <script src="v1/js/lib/moment/{{ language|replace({'-':'_'}) }}.js?v={{ FF_VERSION }}" type="text/javascript" | ||||
|         nonce="{{ JS_NONCE }}"></script> | ||||
|  | ||||
|   | ||||
| @@ -45,6 +45,17 @@ final class BillDateCalculatorTest extends TestCase | ||||
|         $this->calculator = new BillDateCalculator(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Stupid long method names I'm not going to do that. | ||||
|      * | ||||
|      * @dataProvider provideDates | ||||
|      */ | ||||
|     public function testGivenSomeDataItWorks(Carbon $earliest, Carbon $latest, Carbon $billStart, string $period, int $skip, ?Carbon $lastPaid, array $expected): void | ||||
|     { | ||||
|         $result = $this->calculator->getPayDates($earliest, $latest, $billStart, $period, $skip, $lastPaid); | ||||
|         self::assertSame($expected, $result); | ||||
|     } | ||||
| 
 | ||||
|     public static function provideDates(): iterable | ||||
|     { | ||||
|         // Carbon $earliest, Carbon $latest, Carbon $billStart, string $period, int $skip, ?Carbon $lastPaid
 | ||||
| @@ -66,15 +77,4 @@ final class BillDateCalculatorTest extends TestCase | ||||
|             '1Ya' => ['earliest' => Carbon::parse('2023-11-01'), 'latest' => Carbon::parse('2023-11-30'), 'billStart' => Carbon::parse('2021-05-01'), 'period' => 'yearly', 'skip' => 0, 'lastPaid' => Carbon::parse('2023-05-02'), 'expected' => ['2024-05-01']], | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Stupid long method names I'm not going to do that. | ||||
|      * | ||||
|      * @dataProvider provideDates | ||||
|      */ | ||||
|     public function testGivenSomeDataItWorks(Carbon $earliest, Carbon $latest, Carbon $billStart, string $period, int $skip, ?Carbon $lastPaid, array $expected): void | ||||
|     { | ||||
|         $result = $this->calculator->getPayDates($earliest, $latest, $billStart, $period, $skip, $lastPaid); | ||||
|         self::assertSame($expected, $result); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -50,6 +50,32 @@ use Tests\unit\Support\Calendar\Periodicity\YearlyTest; | ||||
|  */ | ||||
| final class CalculatorTest extends TestCase | ||||
| { | ||||
|     private static function convert(Periodicity $periodicity, array $intervals): array | ||||
|     { | ||||
|         $periodicityIntervals = []; | ||||
| 
 | ||||
|         /** @var IntervalProvider $interval */ | ||||
|         foreach ($intervals as $index => $interval) { | ||||
|             $calculator                                             = CalculatorProvider::from($periodicity, $interval); | ||||
| 
 | ||||
|             $periodicityIntervals["#{$index} {$calculator->label}"] = [$calculator]; | ||||
|         } | ||||
| 
 | ||||
|         return $periodicityIntervals; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider provideAllPeriodicity | ||||
|      * | ||||
|      * @throws IntervalException | ||||
|      */ | ||||
|     public function testGivenADailyPeriodicityWhenCallTheNextDateByIntervalMethodThenReturnsTheExpectedDateSuccessful(CalculatorProvider $provider): void | ||||
|     { | ||||
|         $calculator = new Calculator(); | ||||
|         $period     = $calculator->nextDateByInterval($provider->epoch(), $provider->periodicity); | ||||
|         self::assertSame($provider->expected()->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     public static function provideAllPeriodicity(): iterable | ||||
|     { | ||||
|         $intervals = []; | ||||
| @@ -68,37 +94,6 @@ final class CalculatorTest extends TestCase | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private static function convert(Periodicity $periodicity, array $intervals): array | ||||
|     { | ||||
|         $periodicityIntervals = []; | ||||
| 
 | ||||
|         /** @var IntervalProvider $interval */ | ||||
|         foreach ($intervals as $index => $interval) { | ||||
|             $calculator                                             = CalculatorProvider::from($periodicity, $interval); | ||||
| 
 | ||||
|             $periodicityIntervals["#{$index} {$calculator->label}"] = [$calculator]; | ||||
|         } | ||||
| 
 | ||||
|         return $periodicityIntervals; | ||||
|     } | ||||
| 
 | ||||
|     public static function provideSkippedIntervals(): iterable | ||||
|     { | ||||
|         return CalculatorProvider::providePeriodicityWithSkippedIntervals(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider provideAllPeriodicity | ||||
|      * | ||||
|      * @throws IntervalException | ||||
|      */ | ||||
|     public function testGivenADailyPeriodicityWhenCallTheNextDateByIntervalMethodThenReturnsTheExpectedDateSuccessful(CalculatorProvider $provider): void | ||||
|     { | ||||
|         $calculator = new Calculator(); | ||||
|         $period     = $calculator->nextDateByInterval($provider->epoch(), $provider->periodicity); | ||||
|         self::assertSame($provider->expected()->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider provideSkippedIntervals | ||||
|      * | ||||
| @@ -110,4 +105,9 @@ final class CalculatorTest extends TestCase | ||||
|         $period     = $calculator->nextDateByInterval($provider->epoch(), $provider->periodicity, $provider->skip); | ||||
|         self::assertSame($provider->expected()->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     public static function provideSkippedIntervals(): iterable | ||||
|     { | ||||
|         return CalculatorProvider::providePeriodicityWithSkippedIntervals(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -29,16 +29,6 @@ use Tests\integration\TestCase; | ||||
| 
 | ||||
| abstract class IntervalTestCase extends TestCase | ||||
| { | ||||
|     public static function provider(): iterable | ||||
|     { | ||||
|         $intervals = static::provideIntervals(); | ||||
| 
 | ||||
|         /** @var IntervalProvider $interval */ | ||||
|         foreach ($intervals as $interval) { | ||||
|             yield "{$interval->label}" => [$interval]; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     abstract public static function provideIntervals(): array; | ||||
| 
 | ||||
|     /** | ||||
| @@ -50,5 +40,15 @@ abstract class IntervalTestCase extends TestCase | ||||
|         self::assertSame($provider->expected->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     public static function provider(): iterable | ||||
|     { | ||||
|         $intervals = static::provideIntervals(); | ||||
| 
 | ||||
|         /** @var IntervalProvider $interval */ | ||||
|         foreach ($intervals as $interval) { | ||||
|             yield "{$interval->label}" => [$interval]; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     abstract public static function factory(): Interval; | ||||
| } | ||||
|   | ||||
| @@ -48,74 +48,13 @@ final class NavigationAddPeriodTest extends TestCase | ||||
|         $this->navigation = new Navigation(); | ||||
|     } | ||||
| 
 | ||||
|     public static function provideFrequencies(): iterable | ||||
|     /** | ||||
|      * @dataProvider providePeriodsWithSkippingParam | ||||
|      */ | ||||
|     public function testGivenAFrequencyAndSkipIntervalWhenCalculateTheDateThenReturnsTheSkippedDateSuccessful(int $skip, string $frequency, Carbon $from, Carbon $expected): void | ||||
|     { | ||||
|         return [ | ||||
|             Periodicity::Daily->name       => ['periodicity' => Periodicity::Daily, 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()], | ||||
|             Periodicity::Weekly->name      => ['periodicity' => Periodicity::Weekly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)], | ||||
|             Periodicity::Fortnightly->name => ['periodicity' => Periodicity::Fortnightly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(2)], | ||||
|             Periodicity::Monthly->name     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)], | ||||
|             '2019-01-01 to 2019-02-01'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-01'), 'expected' => Carbon::parse('2019-02-01')], | ||||
|             '2019-01-29 to 2019-02-28'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-02-28')], | ||||
|             '2019-01-30 to 2019-02-28'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-02-28')], | ||||
|             '2019-01-31 to 2019-02-28'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-02-28')], | ||||
|             '2023-03-31 to 2023-04-30'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-03-31'), 'expected' => Carbon::parse('2023-04-30')], | ||||
|             '2023-05-31 to 2023-06-30'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-05-31'), 'expected' => Carbon::parse('2023-06-30')], | ||||
|             '2023-08-31 to 2023-09-30'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-08-31'), 'expected' => Carbon::parse('2023-09-30')], | ||||
|             '2023-10-31 to 2023-11-30'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-10-31'), 'expected' => Carbon::parse('2023-11-30')], | ||||
|             Periodicity::Quarterly->name   => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], | ||||
|             '2019-01-29 to 2020-04-29'     => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-04-29')], | ||||
|             '2019-01-30 to 2020-04-30'     => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-04-30')], | ||||
|             '2019-01-31 to 2020-04-30'     => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-04-30')], | ||||
|             Periodicity::HalfYearly->name  => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)], | ||||
|             '2019-01-31 to 2020-07-29'     => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-07-29')], | ||||
|             '2019-01-31 to 2020-07-30'     => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-07-30')], | ||||
|             '2019-01-31 to 2020-07-31'     => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-07-31')], | ||||
|             Periodicity::Yearly->name      => ['periodicity' => Periodicity::Yearly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], | ||||
|             '2020-02-29 to 2021-02-28'     => ['periodicity' => Periodicity::Yearly, 'from' => Carbon::parse('2020-02-29'), 'expected' => Carbon::parse('2021-02-28')], | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     public static function provideMonthPeriods(): iterable | ||||
|     { | ||||
|         return [ | ||||
|             '1M'                       => ['frequency' => '1M', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)], | ||||
|             'month'                    => ['frequency' => 'month', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)], | ||||
|             'monthly'                  => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)], | ||||
|             '2019-01-29 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-02-28')], | ||||
|             '2019-01-30 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-02-28')], | ||||
|             '2019-01-31 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-02-28')], | ||||
|             '2023-03-31 to 2023-04-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-03-31'), 'expected' => Carbon::parse('2023-04-30')], | ||||
|             '2023-05-31 to 2023-06-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-05-31'), 'expected' => Carbon::parse('2023-06-30')], | ||||
|             '2023-08-31 to 2023-09-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-08-31'), 'expected' => Carbon::parse('2023-09-30')], | ||||
|             '2023-10-31 to 2023-11-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-10-31'), 'expected' => Carbon::parse('2023-11-30')], | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     public static function providePeriods(): iterable | ||||
|     { | ||||
|         return [ | ||||
|             '1D'        => ['frequency' => '1D', 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()], | ||||
|             'daily'     => ['frequency' => 'daily', 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()], | ||||
|             '1W'        => ['frequency' => '1W', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)], | ||||
|             'weekly'    => ['frequency' => 'weekly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)], | ||||
|             'week'      => ['frequency' => 'week', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)], | ||||
|             '3M'        => ['frequency' => '3M', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], | ||||
|             'quarter'   => ['frequency' => 'quarter', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], | ||||
|             'quarterly' => ['frequency' => 'quarterly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], | ||||
|             '6M'        => ['frequency' => '6M', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)], | ||||
|             'half-year' => ['frequency' => 'half-year', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)], | ||||
|             'year'      => ['frequency' => 'year', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], | ||||
|             'yearly'    => ['frequency' => 'yearly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], | ||||
|             '1Y'        => ['frequency' => '1Y', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], | ||||
|             'last7'     => ['frequency' => 'last7', 'from' => Carbon::now(), 'expected' => Carbon::now()->addDays(7)], | ||||
|             'last30'    => ['frequency' => 'last30', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)], | ||||
|             'last90'    => ['frequency' => 'last90', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], | ||||
|             'last365'   => ['frequency' => 'last365', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], | ||||
|             'MTD'       => ['frequency' => 'MTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)], | ||||
|             'QTD'       => ['frequency' => 'QTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], | ||||
|             'YTD'       => ['frequency' => 'YTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], | ||||
|         ]; | ||||
|         $period = $this->navigation->addPeriod($from, $frequency, $skip); | ||||
|         self::assertSame($expected->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     public static function providePeriodsWithSkippingParam(): iterable | ||||
| @@ -163,15 +102,6 @@ final class NavigationAddPeriodTest extends TestCase | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider providePeriodsWithSkippingParam | ||||
|      */ | ||||
|     public function testGivenAFrequencyAndSkipIntervalWhenCalculateTheDateThenReturnsTheSkippedDateSuccessful(int $skip, string $frequency, Carbon $from, Carbon $expected): void | ||||
|     { | ||||
|         $period = $this->navigation->addPeriod($from, $frequency, $skip); | ||||
|         self::assertSame($expected->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider providePeriods | ||||
|      */ | ||||
| @@ -181,6 +111,32 @@ final class NavigationAddPeriodTest extends TestCase | ||||
|         self::assertSame($expected->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     public static function providePeriods(): iterable | ||||
|     { | ||||
|         return [ | ||||
|             '1D'        => ['frequency' => '1D', 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()], | ||||
|             'daily'     => ['frequency' => 'daily', 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()], | ||||
|             '1W'        => ['frequency' => '1W', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)], | ||||
|             'weekly'    => ['frequency' => 'weekly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)], | ||||
|             'week'      => ['frequency' => 'week', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)], | ||||
|             '3M'        => ['frequency' => '3M', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], | ||||
|             'quarter'   => ['frequency' => 'quarter', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], | ||||
|             'quarterly' => ['frequency' => 'quarterly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], | ||||
|             '6M'        => ['frequency' => '6M', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)], | ||||
|             'half-year' => ['frequency' => 'half-year', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)], | ||||
|             'year'      => ['frequency' => 'year', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], | ||||
|             'yearly'    => ['frequency' => 'yearly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], | ||||
|             '1Y'        => ['frequency' => '1Y', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], | ||||
|             'last7'     => ['frequency' => 'last7', 'from' => Carbon::now(), 'expected' => Carbon::now()->addDays(7)], | ||||
|             'last30'    => ['frequency' => 'last30', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)], | ||||
|             'last90'    => ['frequency' => 'last90', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], | ||||
|             'last365'   => ['frequency' => 'last365', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], | ||||
|             'MTD'       => ['frequency' => 'MTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)], | ||||
|             'QTD'       => ['frequency' => 'QTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], | ||||
|             'YTD'       => ['frequency' => 'YTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider provideFrequencies | ||||
|      */ | ||||
| @@ -190,6 +146,34 @@ final class NavigationAddPeriodTest extends TestCase | ||||
|         self::assertSame($expected->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     public static function provideFrequencies(): iterable | ||||
|     { | ||||
|         return [ | ||||
|             Periodicity::Daily->name       => ['periodicity' => Periodicity::Daily, 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()], | ||||
|             Periodicity::Weekly->name      => ['periodicity' => Periodicity::Weekly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)], | ||||
|             Periodicity::Fortnightly->name => ['periodicity' => Periodicity::Fortnightly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(2)], | ||||
|             Periodicity::Monthly->name     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)], | ||||
|             '2019-01-01 to 2019-02-01'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-01'), 'expected' => Carbon::parse('2019-02-01')], | ||||
|             '2019-01-29 to 2019-02-28'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-02-28')], | ||||
|             '2019-01-30 to 2019-02-28'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-02-28')], | ||||
|             '2019-01-31 to 2019-02-28'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-02-28')], | ||||
|             '2023-03-31 to 2023-04-30'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-03-31'), 'expected' => Carbon::parse('2023-04-30')], | ||||
|             '2023-05-31 to 2023-06-30'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-05-31'), 'expected' => Carbon::parse('2023-06-30')], | ||||
|             '2023-08-31 to 2023-09-30'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-08-31'), 'expected' => Carbon::parse('2023-09-30')], | ||||
|             '2023-10-31 to 2023-11-30'     => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-10-31'), 'expected' => Carbon::parse('2023-11-30')], | ||||
|             Periodicity::Quarterly->name   => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], | ||||
|             '2019-01-29 to 2020-04-29'     => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-04-29')], | ||||
|             '2019-01-30 to 2020-04-30'     => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-04-30')], | ||||
|             '2019-01-31 to 2020-04-30'     => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-04-30')], | ||||
|             Periodicity::HalfYearly->name  => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)], | ||||
|             '2019-01-31 to 2020-07-29'     => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-07-29')], | ||||
|             '2019-01-31 to 2020-07-30'     => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-07-30')], | ||||
|             '2019-01-31 to 2020-07-31'     => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-07-31')], | ||||
|             Periodicity::Yearly->name      => ['periodicity' => Periodicity::Yearly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], | ||||
|             '2020-02-29 to 2021-02-28'     => ['periodicity' => Periodicity::Yearly, 'from' => Carbon::parse('2020-02-29'), 'expected' => Carbon::parse('2021-02-28')], | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider provideMonthPeriods | ||||
|      */ | ||||
| @@ -198,4 +182,20 @@ final class NavigationAddPeriodTest extends TestCase | ||||
|         $period = $this->navigation->addPeriod($from, $frequency, 0); | ||||
|         self::assertSame($expected->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     public static function provideMonthPeriods(): iterable | ||||
|     { | ||||
|         return [ | ||||
|             '1M'                       => ['frequency' => '1M', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)], | ||||
|             'month'                    => ['frequency' => 'month', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)], | ||||
|             'monthly'                  => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)], | ||||
|             '2019-01-29 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-02-28')], | ||||
|             '2019-01-30 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-02-28')], | ||||
|             '2019-01-31 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-02-28')], | ||||
|             '2023-03-31 to 2023-04-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-03-31'), 'expected' => Carbon::parse('2023-04-30')], | ||||
|             '2023-05-31 to 2023-06-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-05-31'), 'expected' => Carbon::parse('2023-06-30')], | ||||
|             '2023-08-31 to 2023-09-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-08-31'), 'expected' => Carbon::parse('2023-09-30')], | ||||
|             '2023-10-31 to 2023-11-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-10-31'), 'expected' => Carbon::parse('2023-11-30')], | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -47,6 +47,15 @@ final class NavigationEndOfPeriodTest extends TestCase | ||||
|         $this->navigation = new Navigation(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider        provideDates | ||||
|      */ | ||||
|     public function testGivenADateAndFrequencyWhenCalculateTheDateThenReturnsTheExpectedDateSuccessful(string $frequency, Carbon $from, Carbon $expected): void | ||||
|     { | ||||
|         $period = clone $this->navigation->endOfPeriod($from, $frequency); | ||||
|         self::assertSame($expected->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     public static function provideDates(): iterable | ||||
|     { | ||||
|         return [ | ||||
| @@ -78,24 +87,6 @@ final class NavigationEndOfPeriodTest extends TestCase | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     public static function provideUnknownFrequencies(): iterable | ||||
|     { | ||||
|         return [ | ||||
|             '1day'    => ['frequency' => '1day', 'from' => Carbon::now(), 'expected' => Carbon::now()], | ||||
|             'unknown' => ['frequency' => 'unknown', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], | ||||
|             'empty'   => ['frequency' => '', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider        provideDates | ||||
|      */ | ||||
|     public function testGivenADateAndFrequencyWhenCalculateTheDateThenReturnsTheExpectedDateSuccessful(string $frequency, Carbon $from, Carbon $expected): void | ||||
|     { | ||||
|         $period = clone $this->navigation->endOfPeriod($from, $frequency); | ||||
|         self::assertSame($expected->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider provideUnknownFrequencies | ||||
|      */ | ||||
| @@ -109,4 +100,13 @@ final class NavigationEndOfPeriodTest extends TestCase | ||||
| 
 | ||||
|         Log::shouldHaveReceived('error', [$expectedMessage]); | ||||
|     } | ||||
| 
 | ||||
|     public static function provideUnknownFrequencies(): iterable | ||||
|     { | ||||
|         return [ | ||||
|             '1day'    => ['frequency' => '1day', 'from' => Carbon::now(), 'expected' => Carbon::now()], | ||||
|             'unknown' => ['frequency' => 'unknown', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], | ||||
|             'empty'   => ['frequency' => '', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -46,6 +46,15 @@ final class NavigationPreferredCarbonFormatByPeriodTest extends TestCase | ||||
|         $this->navigation = new Navigation(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider providePeriods | ||||
|      */ | ||||
|     public function testGivenAPeriodWhenCallPreferredCarbonFormatByPeriodThenReturnsExpectedFormat(string $period, string $expected): void | ||||
|     { | ||||
|         $formatPeriod = $this->navigation->preferredCarbonFormatByPeriod($period); | ||||
|         self::assertSame($expected, $formatPeriod); | ||||
|     } | ||||
| 
 | ||||
|     public static function providePeriods(): iterable | ||||
|     { | ||||
|         return [ | ||||
| @@ -57,13 +66,4 @@ final class NavigationPreferredCarbonFormatByPeriodTest extends TestCase | ||||
|             'yearly'      => ['period' => '1Y', 'expected' => 'Y'], | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider providePeriods | ||||
|      */ | ||||
|     public function testGivenAPeriodWhenCallPreferredCarbonFormatByPeriodThenReturnsExpectedFormat(string $period, string $expected): void | ||||
|     { | ||||
|         $formatPeriod = $this->navigation->preferredCarbonFormatByPeriod($period); | ||||
|         self::assertSame($expected, $formatPeriod); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -47,6 +47,15 @@ final class NavigationPreferredCarbonFormatTest extends TestCase | ||||
|         $this->navigation = new Navigation(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider providePeriods | ||||
|      */ | ||||
|     public function testGivenStartAndEndDatesWhenCallPreferredCarbonFormatThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void | ||||
|     { | ||||
|         $carbonFormat = $this->navigation->preferredCarbonFormat($start, $end); | ||||
|         self::assertSame($expected, $carbonFormat); | ||||
|     } | ||||
| 
 | ||||
|     public static function providePeriods(): iterable | ||||
|     { | ||||
|         return [ | ||||
| @@ -64,13 +73,4 @@ final class NavigationPreferredCarbonFormatTest extends TestCase | ||||
|             '2 years'   => ['start' => Carbon::now(), 'end' => Carbon::now()->addYears(2), 'expected' => 'Y'], | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider providePeriods | ||||
|      */ | ||||
|     public function testGivenStartAndEndDatesWhenCallPreferredCarbonFormatThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void | ||||
|     { | ||||
|         $carbonFormat = $this->navigation->preferredCarbonFormat($start, $end); | ||||
|         self::assertSame($expected, $carbonFormat); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -47,6 +47,15 @@ final class NavigationPreferredEndOfPeriodTest extends TestCase | ||||
|         $this->navigation = new Navigation(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider providePeriods | ||||
|      */ | ||||
|     public function testGivenStartAndEndDatesWhenCallPreferredEndOfPeriodThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void | ||||
|     { | ||||
|         $formatPeriod = $this->navigation->preferredEndOfPeriod($start, $end); | ||||
|         self::assertSame($expected, $formatPeriod); | ||||
|     } | ||||
| 
 | ||||
|     public static function providePeriods(): iterable | ||||
|     { | ||||
|         return [ | ||||
| @@ -64,13 +73,4 @@ final class NavigationPreferredEndOfPeriodTest extends TestCase | ||||
|             '2 years'   => ['start' => Carbon::now(), 'end' => Carbon::now()->addYears(2), 'expected' => 'endOfYear'], | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider providePeriods | ||||
|      */ | ||||
|     public function testGivenStartAndEndDatesWhenCallPreferredEndOfPeriodThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void | ||||
|     { | ||||
|         $formatPeriod = $this->navigation->preferredEndOfPeriod($start, $end); | ||||
|         self::assertSame($expected, $formatPeriod); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -47,6 +47,15 @@ final class NavigationPreferredRangeFormatTest extends TestCase | ||||
|         $this->navigation = new Navigation(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider providePeriods | ||||
|      */ | ||||
|     public function testGivenStartAndEndDatesWhenCallPreferredRangeFormatThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void | ||||
|     { | ||||
|         $formatPeriod = $this->navigation->preferredRangeFormat($start, $end); | ||||
|         self::assertSame($expected, $formatPeriod); | ||||
|     } | ||||
| 
 | ||||
|     public static function providePeriods(): iterable | ||||
|     { | ||||
|         return [ | ||||
| @@ -64,13 +73,4 @@ final class NavigationPreferredRangeFormatTest extends TestCase | ||||
|             '2 years'   => ['start' => Carbon::now(), 'end' => Carbon::now()->addYears(2), 'expected' => '1Y'], | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider providePeriods | ||||
|      */ | ||||
|     public function testGivenStartAndEndDatesWhenCallPreferredRangeFormatThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void | ||||
|     { | ||||
|         $formatPeriod = $this->navigation->preferredRangeFormat($start, $end); | ||||
|         self::assertSame($expected, $formatPeriod); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -47,6 +47,15 @@ final class NavigationPreferredSqlFormatTest extends TestCase | ||||
|         $this->navigation = new Navigation(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider provideDates | ||||
|      */ | ||||
|     public function testGivenStartAndEndDatesWhenCallPreferredSqlFormatThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void | ||||
|     { | ||||
|         $formatPeriod = $this->navigation->preferredSqlFormat($start, $end); | ||||
|         self::assertSame($expected, $formatPeriod); | ||||
|     } | ||||
| 
 | ||||
|     public static function provideDates(): iterable | ||||
|     { | ||||
|         return [ | ||||
| @@ -64,13 +73,4 @@ final class NavigationPreferredSqlFormatTest extends TestCase | ||||
|             '2 years'   => ['start' => Carbon::now(), 'end' => Carbon::now()->addYears(2), 'expected' => '%Y'], | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider provideDates | ||||
|      */ | ||||
|     public function testGivenStartAndEndDatesWhenCallPreferredSqlFormatThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void | ||||
|     { | ||||
|         $formatPeriod = $this->navigation->preferredSqlFormat($start, $end); | ||||
|         self::assertSame($expected, $formatPeriod); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -48,6 +48,15 @@ final class NavigationStartOfPeriodTest extends TestCase | ||||
|         $this->navigation = new Navigation(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider provideDates | ||||
|      */ | ||||
|     public function testGivenADateAndFrequencyWhenCalculateTheDateThenReturnsTheExpectedDateSuccessful(string $frequency, Carbon $from, Carbon $expected): void | ||||
|     { | ||||
|         $period = $this->navigation->startOfPeriod($from, $frequency); | ||||
|         self::assertSame($expected->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     public static function provideDates(): iterable | ||||
|     { | ||||
|         return [ | ||||
| @@ -78,24 +87,6 @@ final class NavigationStartOfPeriodTest extends TestCase | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     public static function provideUnknownFrequencies(): iterable | ||||
|     { | ||||
|         return [ | ||||
|             '1day'    => ['frequency' => '1day', 'from' => Carbon::now(), 'expected' => Carbon::now()], | ||||
|             'unknown' => ['frequency' => 'unknown', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], | ||||
|             'empty'   => ['frequency' => '', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider provideDates | ||||
|      */ | ||||
|     public function testGivenADateAndFrequencyWhenCalculateTheDateThenReturnsTheExpectedDateSuccessful(string $frequency, Carbon $from, Carbon $expected): void | ||||
|     { | ||||
|         $period = $this->navigation->startOfPeriod($from, $frequency); | ||||
|         self::assertSame($expected->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider provideUnknownFrequencies | ||||
|      */ | ||||
| @@ -111,4 +102,13 @@ final class NavigationStartOfPeriodTest extends TestCase | ||||
|         $period = $this->navigation->startOfPeriod($from, $frequency); | ||||
|         self::assertSame($expected->toDateString(), $period->toDateString()); | ||||
|     } | ||||
| 
 | ||||
|     public static function provideUnknownFrequencies(): iterable | ||||
|     { | ||||
|         return [ | ||||
|             '1day'    => ['frequency' => '1day', 'from' => Carbon::now(), 'expected' => Carbon::now()], | ||||
|             'unknown' => ['frequency' => 'unknown', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], | ||||
|             'empty'   => ['frequency' => '', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -15,6 +15,20 @@ abstract class AbstractQueryParserInterfaceParseQueryTester extends TestCase | ||||
| { | ||||
|     abstract protected function createParser(): QueryParserInterface; | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider queryDataProvider | ||||
|      * | ||||
|      * @param string $query    The query string to parse | ||||
|      * @param Node   $expected The expected parse result | ||||
|      */ | ||||
|     public function testQueryParsing(string $query, Node $expected): void | ||||
|     { | ||||
|         $actual = $this->createParser()->parse($query); | ||||
| 
 | ||||
|         self::assertObjectEquals($expected, $actual); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public static function queryDataProvider(): iterable | ||||
|     { | ||||
|         return [ | ||||
| @@ -181,18 +195,4 @@ abstract class AbstractQueryParserInterfaceParseQueryTester extends TestCase | ||||
|             ], | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @dataProvider queryDataProvider | ||||
|      * | ||||
|      * @param string $query    The query string to parse | ||||
|      * @param Node   $expected The expected parse result | ||||
|      */ | ||||
|     public function testQueryParsing(string $query, Node $expected): void | ||||
|     { | ||||
|         $actual = $this->createParser()->parse($query); | ||||
| 
 | ||||
|         self::assertObjectEquals($expected, $actual); | ||||
| 
 | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user