From 3dcb35710b51a0a7b4674a5dd09cf57c2d036a48 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 21 Jun 2023 12:34:58 +0200 Subject: [PATCH] chore: reformat code. --- .ci/firefly-iii-standard.yml | 412 +- .ci/php-cs-fixer/.php-cs-fixer.php | 22 +- .ci/php-cs-fixer/composer.json | 6 +- .ci/php-cs-fixer/composer.lock | 4084 ++++++++--------- .ci/phpcs.sh | 5 +- .ci/phpmd.sh | 37 + .ci/phpmd/.gitignore | 1 + .ci/phpmd/composer.json | 5 + .ci/phpmd/composer.lock | 1012 ++++ .ci/phpmd/phpmd.xml | 52 + .env.example | 1 + .github/code_of_conduct.md | 29 +- .github/dependabot.yml | 8 +- .github/its_you_not_me.md | 10 +- .github/pull_request_template.md | 6 +- .github/support.md | 8 +- .github/workflows/closed-issues.yml | 21 +- .github/workflows/depsreview.yaml | 2 +- .../Autocomplete/AccountController.php | 2 +- .../Autocomplete/BillController.php | 2 +- .../Autocomplete/BudgetController.php | 2 +- .../Autocomplete/CategoryController.php | 2 +- .../Autocomplete/CurrencyController.php | 4 +- .../Autocomplete/ObjectGroupController.php | 2 +- .../Autocomplete/PiggyBankController.php | 4 +- .../Autocomplete/RecurrenceController.php | 2 +- .../Autocomplete/RuleController.php | 2 +- .../Autocomplete/RuleGroupController.php | 2 +- .../Autocomplete/TagController.php | 2 +- .../Autocomplete/TransactionController.php | 4 +- .../TransactionTypeController.php | 2 +- .../Controllers/Chart/AccountController.php | 2 +- app/Api/V1/Controllers/Controller.php | 76 +- .../Data/Bulk/TransactionController.php | 4 +- .../V1/Controllers/Data/DestroyController.php | 176 +- .../Data/Export/ExportController.php | 270 +- .../Insight/Expense/AccountController.php | 4 +- .../Insight/Expense/BillController.php | 4 +- .../Insight/Expense/BudgetController.php | 4 +- .../Insight/Expense/CategoryController.php | 4 +- .../Insight/Expense/PeriodController.php | 2 +- .../Insight/Expense/TagController.php | 4 +- .../Insight/Income/AccountController.php | 4 +- .../Insight/Income/CategoryController.php | 4 +- .../Insight/Income/PeriodController.php | 2 +- .../Insight/Income/TagController.php | 4 +- .../Insight/Transfer/AccountController.php | 2 +- .../Insight/Transfer/CategoryController.php | 4 +- .../Insight/Transfer/PeriodController.php | 2 +- .../Insight/Transfer/TagController.php | 4 +- .../Models/Account/DestroyController.php | 2 +- .../Models/Account/ListController.php | 14 +- .../Models/Account/ShowController.php | 6 +- .../Models/Account/StoreController.php | 2 +- .../Models/Account/UpdateController.php | 6 +- .../Models/Attachment/DestroyController.php | 2 +- .../Models/Attachment/ShowController.php | 8 +- .../Models/Attachment/StoreController.php | 6 +- .../Models/Attachment/UpdateController.php | 4 +- .../Models/AvailableBudget/ShowController.php | 4 +- .../Models/Bill/DestroyController.php | 2 +- .../Models/Bill/ListController.php | 14 +- .../Models/Bill/ShowController.php | 2 +- .../Models/Bill/StoreController.php | 2 +- .../Models/Bill/UpdateController.php | 4 +- .../Models/Budget/DestroyController.php | 2 +- .../Models/Budget/ListController.php | 18 +- .../Models/Budget/ShowController.php | 4 +- .../Models/Budget/StoreController.php | 2 +- .../Models/Budget/UpdateController.php | 4 +- .../Models/BudgetLimit/DestroyController.php | 4 +- .../Models/BudgetLimit/ListController.php | 8 +- .../Models/BudgetLimit/ShowController.php | 16 +- .../Models/BudgetLimit/StoreController.php | 4 +- .../Models/BudgetLimit/UpdateController.php | 6 +- .../Models/Category/DestroyController.php | 2 +- .../Models/Category/ListController.php | 10 +- .../Models/Category/ShowController.php | 4 +- .../Models/Category/StoreController.php | 2 +- .../Models/Category/UpdateController.php | 4 +- .../Models/ObjectGroup/DestroyController.php | 2 +- .../Models/ObjectGroup/ListController.php | 8 +- .../Models/ObjectGroup/ShowController.php | 6 +- .../Models/ObjectGroup/UpdateController.php | 4 +- .../Models/PiggyBank/DestroyController.php | 2 +- .../Models/PiggyBank/ListController.php | 8 +- .../Models/PiggyBank/ShowController.php | 4 +- .../Models/PiggyBank/StoreController.php | 2 +- .../Models/PiggyBank/UpdateController.php | 4 +- .../Models/Recurrence/DestroyController.php | 2 +- .../Models/Recurrence/ListController.php | 6 +- .../Models/Recurrence/ShowController.php | 4 +- .../Models/Recurrence/StoreController.php | 2 +- .../Models/Recurrence/UpdateController.php | 4 +- .../Models/Rule/DestroyController.php | 2 +- .../Models/Rule/ShowController.php | 4 +- .../Models/Rule/StoreController.php | 2 +- .../Models/Rule/TriggerController.php | 10 +- .../Models/Rule/UpdateController.php | 4 +- .../Models/RuleGroup/DestroyController.php | 2 +- .../Models/RuleGroup/ListController.php | 4 +- .../Models/RuleGroup/ShowController.php | 4 +- .../Models/RuleGroup/StoreController.php | 2 +- .../Models/RuleGroup/TriggerController.php | 10 +- .../Models/RuleGroup/UpdateController.php | 4 +- .../Models/Tag/DestroyController.php | 2 +- .../Controllers/Models/Tag/ListController.php | 10 +- .../Controllers/Models/Tag/ShowController.php | 4 +- .../Models/Tag/StoreController.php | 2 +- .../Models/Tag/UpdateController.php | 4 +- .../Models/Transaction/DestroyController.php | 4 +- .../Models/Transaction/ListController.php | 12 +- .../Models/Transaction/ShowController.php | 36 +- .../Models/Transaction/StoreController.php | 2 +- .../Models/Transaction/UpdateController.php | 4 +- .../TransactionCurrency/DestroyController.php | 2 +- .../TransactionCurrency/ListController.php | 32 +- .../TransactionCurrency/ShowController.php | 4 +- .../TransactionCurrency/StoreController.php | 2 +- .../TransactionCurrency/UpdateController.php | 66 +- .../TransactionLink/DestroyController.php | 2 +- .../Models/TransactionLink/ShowController.php | 6 +- .../TransactionLink/StoreController.php | 2 +- .../TransactionLink/UpdateController.php | 4 +- .../TransactionLinkType/DestroyController.php | 2 +- .../TransactionLinkType/ListController.php | 6 +- .../TransactionLinkType/ShowController.php | 4 +- .../TransactionLinkType/StoreController.php | 2 +- .../TransactionLinkType/UpdateController.php | 4 +- .../Controllers/Search/AccountController.php | 5 +- .../Search/TransactionController.php | 6 +- .../Controllers/Summary/BasicController.php | 70 +- .../System/ConfigurationController.php | 78 +- .../V1/Controllers/System/CronController.php | 4 +- .../V1/Controllers/System/UserController.php | 12 +- .../User/PreferencesController.php | 10 +- .../Controllers/Webhook/AttemptController.php | 12 +- .../Controllers/Webhook/DestroyController.php | 12 +- .../Controllers/Webhook/MessageController.php | 8 +- .../V1/Controllers/Webhook/ShowController.php | 8 +- .../Controllers/Webhook/StoreController.php | 2 +- .../Controllers/Webhook/SubmitController.php | 2 +- .../Controllers/Webhook/UpdateController.php | 4 +- app/Api/V1/Middleware/ApiDemoUser.php | 4 +- .../Data/Bulk/MoveTransactionsRequest.php | 4 +- .../Requests/Data/Bulk/TransactionRequest.php | 2 +- app/Api/V1/Requests/Data/DestroyRequest.php | 4 +- .../V1/Requests/Insight/GenericRequest.php | 216 +- .../Requests/Models/Account/StoreRequest.php | 2 +- .../Requests/Models/Account/UpdateRequest.php | 2 +- .../Models/AvailableBudget/Request.php | 2 +- .../V1/Requests/Models/Bill/StoreRequest.php | 2 +- .../V1/Requests/Models/Bill/UpdateRequest.php | 2 +- .../Requests/Models/Budget/StoreRequest.php | 2 +- .../Requests/Models/Budget/UpdateRequest.php | 2 +- .../Models/BudgetLimit/UpdateRequest.php | 2 +- .../Models/PiggyBank/UpdateRequest.php | 2 +- .../Models/Recurrence/StoreRequest.php | 120 +- .../Models/Recurrence/UpdateRequest.php | 148 +- .../V1/Requests/Models/Rule/StoreRequest.php | 164 +- .../V1/Requests/Models/Rule/TestRequest.php | 42 +- .../Requests/Models/Rule/TriggerRequest.php | 26 +- .../V1/Requests/Models/Rule/UpdateRequest.php | 308 +- .../Requests/Models/RuleGroup/TestRequest.php | 26 +- .../Models/RuleGroup/TriggerRequest.php | 22 +- .../Models/RuleGroup/UpdateRequest.php | 2 +- .../V1/Requests/Models/Tag/UpdateRequest.php | 2 +- .../Models/Transaction/StoreRequest.php | 258 +- .../Models/Transaction/UpdateRequest.php | 30 +- .../Models/TransactionLink/StoreRequest.php | 4 +- .../Models/TransactionLink/UpdateRequest.php | 4 +- .../V1/Requests/System/UserUpdateRequest.php | 2 +- .../Autocomplete/AccountController.php | 3 +- .../Controllers/Chart/AccountController.php | 2 +- app/Api/V2/Controllers/Controller.php | 100 +- .../Controllers/Model/Bill/SumController.php | 4 +- .../Model/Budget/ListController.php | 2 +- .../Model/Budget/SumController.php | 4 +- app/Api/V2/Controllers/NetWorthController.php | 2 +- .../System/PreferencesController.php | 2 +- .../Transaction/List/AccountController.php | 4 +- .../Autocomplete/AutocompleteRequest.php | 2 +- app/Api/V2/Response/Sum/AutoSum.php | 6 +- .../Commands/Correction/CorrectAmounts.php | 40 +- .../CorrectOpeningBalanceCurrencies.php | 58 +- .../Correction/DeleteEmptyJournals.php | 48 +- .../Correction/DeleteOrphanedTransactions.php | 64 +- .../Commands/Correction/EnableCurrencies.php | 1 - .../Commands/Correction/FixAccountTypes.php | 156 +- .../Correction/FixFrontpageAccounts.php | 2 +- app/Console/Commands/Correction/FixIbans.php | 46 +- .../Correction/FixRecurringTransactions.php | 58 +- .../Correction/FixTransactionTypes.php | 78 +- .../Commands/Correction/FixUnevenAmount.php | 2 +- .../Commands/Correction/RenameMetaFields.php | 4 +- .../Correction/TriggerCreditCalculation.php | 23 +- app/Console/Commands/Export/ExportData.php | 164 +- .../Integrity/CreateGroupMemberships.php | 57 +- .../Commands/Integrity/ReportEmptyObjects.php | 90 +- .../Commands/Integrity/RestoreOAuthKeys.php | 64 +- .../Integrity/UpdateGroupInformation.php | 6 +- .../Commands/ShowsFriendlyMessages.php | 28 +- .../Commands/System/ForceDecimalSize.php | 242 +- .../System/UpgradeFireflyInstructions.php | 181 +- .../Commands/System/VerifySecurityAlerts.php | 2 +- app/Console/Commands/Tools/ApplyRules.php | 158 +- app/Console/Commands/Tools/Cron.php | 122 +- .../Commands/Upgrade/AccountCurrencies.php | 121 +- .../Upgrade/AppendBudgetLimitPeriods.php | 52 +- .../Commands/Upgrade/BackToJournals.php | 107 +- .../Commands/Upgrade/DecryptDatabase.php | 160 +- .../Upgrade/MigrateRecurrenceMeta.php | 32 +- .../Upgrade/MigrateRecurrenceType.php | 38 +- .../Commands/Upgrade/MigrateTagLocations.php | 48 +- .../Commands/Upgrade/MigrateToGroups.php | 301 +- .../Commands/Upgrade/MigrateToRules.php | 100 +- .../Upgrade/OtherCurrenciesCorrections.php | 192 +- .../Upgrade/TransactionIdentifier.php | 127 +- .../Upgrade/TransferCurrenciesCorrections.php | 624 +-- .../Commands/Upgrade/UpgradeLiabilities.php | 117 +- .../Upgrade/UpgradeLiabilitiesEight.php | 258 +- app/Console/Commands/VerifiesAccessToken.php | 2 +- app/Console/Kernel.php | 4 +- app/Enums/AccountTypeEnum.php | 26 +- app/Enums/AutoBudgetType.php | 2 +- app/Enums/RecurrenceRepetitionWeekend.php | 6 +- app/Enums/TransactionTypeEnum.php | 12 +- app/Enums/UserRoleEnum.php | 14 +- app/Enums/WebhookResponse.php | 4 +- app/Events/ActuallyLoggedIn.php | 2 +- app/Events/Admin/InvitationCreated.php | 2 +- app/Events/AdminRequestedTestMessage.php | 2 +- app/Events/ChangedPiggyBankAmount.php | 8 +- app/Events/DestroyedTransactionGroup.php | 2 +- app/Events/DestroyedTransactionLink.php | 2 +- app/Events/DetectedNewIPAddress.php | 4 +- app/Events/Model/BudgetLimit/Created.php | 2 +- app/Events/Model/BudgetLimit/Deleted.php | 2 +- app/Events/Model/BudgetLimit/Updated.php | 2 +- app/Events/NewVersionAvailable.php | 2 +- app/Events/RegisteredUser.php | 3 +- app/Events/RequestedNewPassword.php | 6 +- app/Events/RequestedReportOnJournals.php | 4 +- app/Events/RequestedVersionCheckStatus.php | 2 +- app/Events/StoredAccount.php | 2 +- app/Events/StoredTransactionGroup.php | 6 +- app/Events/UpdatedAccount.php | 2 +- app/Events/UpdatedTransactionGroup.php | 6 +- app/Events/UserChangedEmail.php | 6 +- app/Events/WarnUserAboutBill.php | 6 +- app/Exceptions/GracefulNotFoundHandler.php | 90 +- app/Exceptions/Handler.php | 48 +- app/Factory/AccountFactory.php | 200 +- app/Factory/AccountMetaFactory.php | 27 +- app/Factory/AttachmentFactory.php | 4 +- app/Factory/BillFactory.php | 10 +- app/Factory/BudgetFactory.php | 8 +- app/Factory/CategoryFactory.php | 26 +- app/Factory/PiggyBankEventFactory.php | 4 +- app/Factory/PiggyBankFactory.php | 8 +- app/Factory/RecurrenceFactory.php | 4 +- app/Factory/TagFactory.php | 72 +- app/Factory/TransactionCurrencyFactory.php | 6 +- app/Factory/TransactionFactory.php | 186 +- app/Factory/TransactionGroupFactory.php | 4 +- app/Factory/TransactionJournalFactory.php | 508 +- app/Factory/TransactionJournalMetaFactory.php | 2 +- app/Factory/TransactionTypeFactory.php | 2 +- .../Chart/Basic/ChartJsGenerator.php | 10 +- .../Chart/Basic/GeneratorInterface.php | 10 +- .../Report/Account/MonthReportGenerator.php | 35 +- .../Report/Audit/MonthReportGenerator.php | 18 +- .../Report/Budget/MonthReportGenerator.php | 66 +- .../Report/Category/MonthReportGenerator.php | 66 +- .../Report/ReportGeneratorFactory.php | 6 +- .../Report/ReportGeneratorInterface.php | 14 +- .../Report/Standard/MonthReportGenerator.php | 14 +- .../Standard/MultiYearReportGenerator.php | 14 +- .../Report/Standard/YearReportGenerator.php | 14 +- .../Report/Tag/MonthReportGenerator.php | 14 +- .../Webhook/MessageGeneratorInterface.php | 8 +- .../Webhook/StandardMessageGenerator.php | 170 +- app/Handlers/Events/APIEventHandler.php | 2 +- app/Handlers/Events/AdminEventHandler.php | 6 +- app/Handlers/Events/AutomationHandler.php | 2 +- app/Handlers/Events/BillEventHandler.php | 2 +- .../Events/DestroyedGroupEventHandler.php | 2 +- .../Events/Model/BudgetLimitHandler.php | 226 +- app/Handlers/Events/PiggyBankEventHandler.php | 2 +- .../Events/StoredAccountEventHandler.php | 2 +- .../Events/StoredGroupEventHandler.php | 6 +- .../Events/UpdatedAccountEventHandler.php | 2 +- .../Events/UpdatedGroupEventHandler.php | 8 +- app/Handlers/Events/UserEventHandler.php | 27 +- .../Events/VersionCheckEventHandler.php | 4 +- app/Helpers/Attachments/AttachmentHelper.php | 187 +- .../Attachments/AttachmentHelperInterface.php | 12 +- .../Extensions/AccountCollection.php | 18 +- .../Collector/Extensions/AmountCollection.php | 14 +- .../Extensions/AttachmentCollection.php | 32 +- .../Collector/Extensions/MetaCollection.php | 306 +- .../Collector/Extensions/TimeCollection.php | 200 +- app/Helpers/Collector/GroupCollector.php | 632 +-- .../Collector/GroupCollectorInterface.php | 386 +- app/Helpers/Fiscal/FiscalHelper.php | 4 +- app/Helpers/Fiscal/FiscalHelperInterface.php | 4 +- app/Helpers/Report/NetWorth.php | 8 +- app/Helpers/Report/NetWorthInterface.php | 10 +- app/Helpers/Report/PopupReport.php | 26 +- app/Helpers/Report/PopupReportInterface.php | 26 +- app/Helpers/Report/ReportHelper.php | 10 +- app/Helpers/Report/ReportHelperInterface.php | 8 +- .../Webhook/SignatureGeneratorInterface.php | 2 +- .../Controllers/Account/CreateController.php | 6 +- .../Controllers/Account/DeleteController.php | 6 +- .../Controllers/Account/EditController.php | 10 +- .../Controllers/Account/IndexController.php | 8 +- .../Account/ReconcileController.php | 22 +- .../Controllers/Account/ShowController.php | 14 +- .../Admin/ConfigurationController.php | 2 +- app/Http/Controllers/Admin/HomeController.php | 2 +- app/Http/Controllers/Admin/LinkController.php | 20 +- .../Controllers/Admin/UpdateController.php | 2 +- app/Http/Controllers/Admin/UserController.php | 16 +- app/Http/Controllers/AttachmentController.php | 24 +- .../Auth/ForgotPasswordController.php | 4 +- app/Http/Controllers/Auth/LoginController.php | 66 +- .../Controllers/Auth/RegisterController.php | 52 +- .../Auth/ResetPasswordController.php | 6 +- .../Controllers/Auth/TwoFactorController.php | 62 +- .../Controllers/Bill/CreateController.php | 6 +- .../Controllers/Bill/DeleteController.php | 6 +- app/Http/Controllers/Bill/EditController.php | 10 +- app/Http/Controllers/Bill/IndexController.php | 146 +- app/Http/Controllers/Bill/ShowController.php | 8 +- .../Budget/BudgetLimitController.php | 19 +- .../Controllers/Budget/CreateController.php | 4 +- .../Controllers/Budget/DeleteController.php | 6 +- .../Controllers/Budget/EditController.php | 8 +- .../Controllers/Budget/IndexController.php | 68 +- .../Controllers/Budget/ShowController.php | 18 +- .../Controllers/Category/CreateController.php | 4 +- .../Controllers/Category/DeleteController.php | 6 +- .../Controllers/Category/EditController.php | 8 +- .../Controllers/Category/IndexController.php | 2 +- .../Category/NoCategoryController.php | 8 +- .../Controllers/Category/ShowController.php | 12 +- .../Controllers/Chart/AccountController.php | 206 +- app/Http/Controllers/Chart/BillController.php | 4 +- .../Controllers/Chart/BudgetController.php | 36 +- .../Chart/BudgetReportController.php | 86 +- .../Controllers/Chart/CategoryController.php | 168 +- .../Chart/CategoryReportController.php | 114 +- .../Chart/DoubleReportController.php | 148 +- .../Chart/ExpenseReportController.php | 28 +- .../Controllers/Chart/PiggyBankController.php | 4 +- .../Controllers/Chart/ReportController.php | 14 +- .../Controllers/Chart/TagReportController.php | 130 +- .../Chart/TransactionController.php | 22 +- app/Http/Controllers/CurrencyController.php | 30 +- app/Http/Controllers/DebugController.php | 8 +- .../Controllers/Export/IndexController.php | 2 +- app/Http/Controllers/HomeController.php | 4 +- app/Http/Controllers/JavascriptController.php | 14 +- app/Http/Controllers/Json/BoxController.php | 2 +- .../Controllers/Json/BudgetController.php | 6 +- .../Controllers/Json/FrontpageController.php | 2 +- app/Http/Controllers/Json/IntroController.php | 22 +- .../Controllers/Json/ReconcileController.php | 98 +- .../Controllers/Json/RecurrenceController.php | 6 +- app/Http/Controllers/Json/RuleController.php | 6 +- app/Http/Controllers/NewUserController.php | 4 +- .../ObjectGroup/DeleteController.php | 4 +- .../ObjectGroup/EditController.php | 6 +- .../ObjectGroup/IndexController.php | 4 +- .../PiggyBank/AmountController.php | 18 +- .../PiggyBank/CreateController.php | 2 +- .../PiggyBank/DeleteController.php | 4 +- .../Controllers/PiggyBank/EditController.php | 6 +- .../Controllers/PiggyBank/IndexController.php | 50 +- .../Controllers/PiggyBank/ShowController.php | 2 +- .../Controllers/Popup/ReportController.php | 2 +- .../Controllers/PreferencesController.php | 6 +- app/Http/Controllers/ProfileController.php | 234 +- .../Recurring/CreateController.php | 8 +- .../Recurring/DeleteController.php | 10 +- .../Controllers/Recurring/EditController.php | 10 +- .../Controllers/Recurring/IndexController.php | 2 +- .../Recurring/TriggerController.php | 4 +- .../Controllers/Report/AccountController.php | 6 +- .../Controllers/Report/BalanceController.php | 6 +- .../Controllers/Report/BillController.php | 6 +- .../Controllers/Report/BudgetController.php | 52 +- .../Controllers/Report/CategoryController.php | 74 +- .../Controllers/Report/DoubleController.php | 98 +- .../Report/OperationsController.php | 18 +- app/Http/Controllers/Report/TagController.php | 56 +- app/Http/Controllers/ReportController.php | 50 +- .../Controllers/Rule/CreateController.php | 16 +- .../Controllers/Rule/DeleteController.php | 4 +- app/Http/Controllers/Rule/EditController.php | 58 +- app/Http/Controllers/Rule/IndexController.php | 8 +- .../Controllers/Rule/SelectController.php | 10 +- .../RuleGroup/CreateController.php | 2 +- .../RuleGroup/DeleteController.php | 6 +- .../Controllers/RuleGroup/EditController.php | 10 +- .../RuleGroup/ExecutionController.php | 6 +- app/Http/Controllers/SearchController.php | 10 +- .../Controllers/System/InstallController.php | 54 +- app/Http/Controllers/TagController.php | 60 +- .../Transaction/BulkController.php | 52 +- .../Transaction/ConvertController.php | 276 +- .../Transaction/CreateController.php | 4 +- .../Transaction/DeleteController.php | 8 +- .../Transaction/EditController.php | 2 +- .../Transaction/IndexController.php | 22 +- .../Transaction/LinkController.php | 12 +- .../Transaction/MassController.php | 146 +- .../Controllers/Webhooks/DeleteController.php | 2 +- .../Controllers/Webhooks/EditController.php | 2 +- .../Controllers/Webhooks/IndexController.php | 2 +- .../Controllers/Webhooks/ShowController.php | 2 +- app/Http/Middleware/AcceptHeaders.php | 8 +- app/Http/Middleware/Authenticate.php | 16 +- app/Http/Middleware/Binder.php | 12 +- app/Http/Middleware/InstallationId.php | 4 +- app/Http/Middleware/Installer.php | 52 +- app/Http/Middleware/InterestingMessage.php | 198 +- app/Http/Middleware/IsAdmin.php | 6 +- app/Http/Middleware/IsDemoUser.php | 4 +- app/Http/Middleware/Range.php | 68 +- .../Middleware/RedirectIfAuthenticated.php | 6 +- app/Http/Middleware/SecureHeaders.php | 4 +- app/Http/Middleware/StartFireflySession.php | 4 +- app/Http/Middleware/TrustProxies.php | 12 +- app/Http/Requests/AccountFormRequest.php | 10 +- app/Http/Requests/BudgetFormStoreRequest.php | 2 +- app/Http/Requests/BudgetFormUpdateRequest.php | 4 +- app/Http/Requests/CategoryFormRequest.php | 2 +- app/Http/Requests/RecurrenceFormRequest.php | 112 +- app/Http/Requests/RuleFormRequest.php | 130 +- app/Http/Requests/RuleGroupFormRequest.php | 2 +- .../Requests/SelectTransactionsRequest.php | 4 +- app/Http/Requests/TagFormRequest.php | 2 +- app/Http/Requests/TestRuleFormRequest.php | 2 +- app/Jobs/CreateAutoBudgetLimits.php | 394 +- app/Jobs/CreateRecurringTransactions.php | 480 +- app/Jobs/DownloadExchangeRates.php | 46 +- app/Jobs/MailError.php | 11 +- app/Jobs/SendWebhookMessage.php | 2 +- app/Jobs/WarnAboutBills.php | 72 +- app/Mail/BillWarningMail.php | 6 +- app/Mail/ConfirmEmailChangeMail.php | 6 +- app/Mail/InvitationMail.php | 6 +- app/Mail/NewIPAddressWarningMail.php | 2 +- app/Mail/OAuthTokenCreatedMail.php | 2 +- app/Mail/RegisteredUser.php | 2 +- app/Mail/ReportNewJournalsMail.php | 2 +- app/Mail/RequestedNewPassword.php | 2 +- app/Mail/UndoEmailChangeMail.php | 6 +- app/Models/Account.php | 106 +- app/Models/AccountMeta.php | 17 +- app/Models/AccountType.php | 10 +- app/Models/Attachment.php | 58 +- app/Models/AuditLogEntry.php | 37 +- app/Models/AutoBudget.php | 20 +- app/Models/AvailableBudget.php | 32 +- app/Models/Bill.php | 82 +- app/Models/Budget.php | 64 +- app/Models/BudgetLimit.php | 39 +- app/Models/Category.php | 52 +- app/Models/Configuration.php | 10 +- app/Models/CurrencyExchangeRate.php | 24 +- app/Models/GroupMembership.php | 18 +- app/Models/InvitedUser.php | 16 +- app/Models/LinkType.php | 22 +- app/Models/Location.php | 24 +- app/Models/Note.php | 16 +- app/Models/ObjectGroup.php | 44 +- app/Models/PiggyBank.php | 48 +- app/Models/PiggyBankEvent.php | 18 +- app/Models/PiggyBankRepetition.php | 20 +- app/Models/Preference.php | 14 +- app/Models/Recurrence.php | 72 +- app/Models/RecurrenceMeta.php | 14 +- app/Models/RecurrenceRepetition.php | 18 +- app/Models/RecurrenceTransaction.php | 40 +- app/Models/RecurrenceTransactionMeta.php | 14 +- app/Models/Role.php | 14 +- app/Models/Rule.php | 58 +- app/Models/RuleAction.php | 16 +- app/Models/RuleGroup.php | 44 +- app/Models/RuleTrigger.php | 16 +- app/Models/Tag.php | 56 +- app/Models/Transaction.php | 106 +- app/Models/TransactionCurrency.php | 30 +- app/Models/TransactionGroup.php | 36 +- app/Models/TransactionJournal.php | 168 +- app/Models/TransactionJournalLink.php | 26 +- app/Models/TransactionJournalMeta.php | 20 +- app/Models/TransactionType.php | 14 +- app/Models/UserGroup.php | 23 +- app/Models/UserRole.php | 12 +- app/Models/Webhook.php | 32 +- app/Models/WebhookAttempt.php | 18 +- app/Models/WebhookMessage.php | 28 +- app/Notifications/Admin/TestNotification.php | 8 +- app/Notifications/Admin/UserInvitation.php | 8 +- app/Notifications/Admin/UserRegistration.php | 8 +- .../Admin/VersionCheckResult.php | 8 +- app/Notifications/User/BillReminder.php | 8 +- app/Notifications/User/NewAccessToken.php | 8 +- .../User/TransactionCreation.php | 6 +- app/Notifications/User/UserLogin.php | 8 +- app/Notifications/User/UserNewPassword.php | 6 +- app/Notifications/User/UserRegistration.php | 6 +- app/Providers/FireflySessionProvider.php | 26 +- app/Providers/JournalServiceProvider.php | 76 +- .../Account/AccountRepository.php | 322 +- .../Account/AccountRepositoryInterface.php | 92 +- app/Repositories/Account/AccountTasker.php | 104 +- .../Account/AccountTaskerInterface.php | 22 +- .../Account/OperationsRepository.php | 394 +- .../Account/OperationsRepositoryInterface.php | 144 +- .../Account/AccountRepositoryInterface.php | 6 +- .../Attachment/AttachmentRepository.php | 78 +- .../AttachmentRepositoryInterface.php | 18 +- .../AuditLogEntry/ALERepositoryInterface.php | 4 +- app/Repositories/Bill/BillRepository.php | 294 +- .../Bill/BillRepositoryInterface.php | 96 +- .../Budget/AvailableBudgetRepository.php | 128 +- .../AvailableBudgetRepositoryInterface.php | 58 +- .../Budget/BudgetLimitRepository.php | 90 +- .../Budget/BudgetLimitRepositoryInterface.php | 52 +- app/Repositories/Budget/BudgetRepository.php | 532 +-- .../Budget/BudgetRepositoryInterface.php | 62 +- .../Budget/NoBudgetRepository.php | 40 +- .../Budget/NoBudgetRepositoryInterface.php | 24 +- .../Budget/OperationsRepository.php | 76 +- .../Budget/OperationsRepositoryInterface.php | 49 +- .../Category/CategoryRepository.php | 342 +- .../Category/CategoryRepositoryInterface.php | 50 +- .../Category/NoCategoryRepository.php | 44 +- .../NoCategoryRepositoryInterface.php | 34 +- .../Category/OperationsRepository.php | 80 +- .../OperationsRepositoryInterface.php | 60 +- .../Currency/CurrencyRepository.php | 155 +- .../Currency/CurrencyRepositoryInterface.php | 69 +- .../Journal/JournalAPIRepository.php | 10 +- .../Journal/JournalAPIRepositoryInterface.php | 12 +- .../Journal/JournalCLIRepository.php | 22 +- .../Journal/JournalCLIRepositoryInterface.php | 22 +- .../Journal/JournalRepository.php | 58 +- .../Journal/JournalRepositoryInterface.php | 42 +- .../LinkType/LinkTypeRepository.php | 220 +- .../LinkType/LinkTypeRepositoryInterface.php | 52 +- .../ObjectGroup/CreatesObjectGroups.php | 26 +- .../ObjectGroup/ObjectGroupRepository.php | 82 +- .../ObjectGroupRepositoryInterface.php | 22 +- .../PiggyBank/ModifiesPiggyBanks.php | 226 +- .../PiggyBank/PiggyBankRepository.php | 148 +- .../PiggyBankRepositoryInterface.php | 80 +- .../Recurring/RecurringRepository.php | 228 +- .../RecurringRepositoryInterface.php | 76 +- app/Repositories/Rule/RuleRepository.php | 396 +- .../Rule/RuleRepositoryInterface.php | 52 +- .../RuleGroup/RuleGroupRepository.php | 314 +- .../RuleGroupRepositoryInterface.php | 40 +- app/Repositories/Tag/OperationsRepository.php | 76 +- .../Tag/OperationsRepositoryInterface.php | 36 +- app/Repositories/Tag/TagRepository.php | 104 +- .../Tag/TagRepositoryInterface.php | 56 +- .../TransactionGroupRepository.php | 300 +- .../TransactionGroupRepositoryInterface.php | 40 +- .../TransactionTypeRepository.php | 32 +- .../TransactionTypeRepositoryInterface.php | 10 +- app/Repositories/User/UserRepository.php | 242 +- .../User/UserRepositoryInterface.php | 82 +- .../Webhook/WebhookRepository.php | 4 +- .../Webhook/WebhookRepositoryInterface.php | 22 +- app/Rules/BelongsUser.php | 202 +- app/Rules/IsAssetAccountId.php | 4 +- app/Rules/IsBoolean.php | 4 +- app/Rules/IsDateOrTime.php | 4 +- app/Rules/IsTransferAccount.php | 4 +- app/Rules/IsValidAttachmentModel.php | 50 +- app/Rules/IsValidBulkClause.php | 10 +- app/Rules/LessThanPiggyTarget.php | 4 +- app/Rules/UniqueAccountNumber.php | 52 +- app/Rules/UniqueIban.php | 80 +- app/Rules/ValidJournals.php | 4 +- app/Rules/ValidRecurrenceRepetitionType.php | 4 +- app/Rules/ValidRecurrenceRepetitionValue.php | 12 +- .../FireflyIIIOrg/Update/UpdateRequest.php | 6 +- .../Update/UpdateRequestInterface.php | 2 +- .../Destroy/AccountDestroyService.php | 134 +- .../Internal/Destroy/BillDestroyService.php | 2 +- .../Internal/Destroy/BudgetDestroyService.php | 2 +- .../Destroy/CategoryDestroyService.php | 2 +- .../Destroy/CurrencyDestroyService.php | 2 +- .../Destroy/JournalDestroyService.php | 2 +- .../Destroy/RecurrenceDestroyService.php | 30 +- .../TransactionGroupDestroyService.php | 2 +- .../Internal/Support/AccountServiceTrait.php | 744 +-- .../Internal/Support/BillServiceTrait.php | 10 +- .../Support/CreditRecalculateService.php | 136 +- .../Internal/Support/JournalServiceTrait.php | 572 +-- .../Internal/Support/LocationServiceTrait.php | 4 +- .../Support/RecurringTransactionTrait.php | 217 +- .../Internal/Support/TransactionTypeTrait.php | 2 +- .../Internal/Update/AccountUpdateService.php | 168 +- .../Internal/Update/BillUpdateService.php | 90 +- .../Internal/Update/CategoryUpdateService.php | 122 +- .../Internal/Update/CurrencyUpdateService.php | 4 +- .../Internal/Update/GroupCloneService.php | 44 +- .../Internal/Update/GroupUpdateService.php | 86 +- .../Internal/Update/JournalUpdateService.php | 726 +-- .../Update/RecurrenceUpdateService.php | 251 +- app/Services/Password/PwndVerifierV2.php | 4 +- app/Services/Password/Verifier.php | 2 +- .../Webhook/StandardWebhookSender.php | 2 +- .../Webhook/WebhookSenderInterface.php | 2 +- app/Support/Amount.php | 218 +- .../Authentication/RemoteUserGuard.php | 38 +- app/Support/Binder/AccountList.php | 4 +- app/Support/Binder/BinderInterface.php | 4 +- app/Support/Binder/BudgetList.php | 4 +- app/Support/Binder/CLIToken.php | 4 +- app/Support/Binder/CategoryList.php | 4 +- app/Support/Binder/CurrencyCode.php | 4 +- app/Support/Binder/Date.php | 4 +- app/Support/Binder/DynamicConfigKey.php | 4 +- app/Support/Binder/EitherConfigKey.php | 4 +- app/Support/Binder/JournalList.php | 6 +- app/Support/Binder/TagList.php | 4 +- app/Support/Binder/TagOrId.php | 4 +- app/Support/CacheProperties.php | 18 +- .../Chart/Budget/FrontpageChartGenerator.php | 131 +- .../Category/FrontpageChartGenerator.php | 48 +- .../Category/WholePeriodChartGenerator.php | 12 +- app/Support/ChartColour.php | 2 +- app/Support/Cronjobs/AbstractCronjob.php | 4 +- app/Support/ExpandedForm.php | 75 +- app/Support/Export/ExportDataGenerator.php | 242 +- app/Support/FireflyConfig.php | 102 +- app/Support/Form/AccountForm.php | 188 +- app/Support/Form/CurrencyForm.php | 266 +- app/Support/Form/FormSupport.php | 92 +- app/Support/Form/PiggyBankForm.php | 6 +- app/Support/Form/RuleForm.php | 8 +- app/Support/Http/Api/AccountFilter.php | 2 +- app/Support/Http/Api/ApiSupport.php | 4 +- .../Http/Api/ConvertsExchangeRates.php | 253 +- app/Support/Http/Api/TransactionFilter.php | 2 +- app/Support/Http/Controllers/AugumentData.php | 28 +- .../Http/Controllers/BasicDataSupport.php | 8 +- .../Http/Controllers/ChartGeneration.php | 6 +- app/Support/Http/Controllers/CreateStuff.php | 16 +- app/Support/Http/Controllers/CronRunner.php | 16 +- .../Http/Controllers/DateCalculation.php | 23 +- .../Http/Controllers/GetConfigurationData.php | 14 +- .../Http/Controllers/ModelInformation.php | 6 +- .../Http/Controllers/PeriodOverview.php | 250 +- .../Http/Controllers/RenderPartialViews.php | 14 +- .../Http/Controllers/RequestInformation.php | 50 +- .../Http/Controllers/RuleManagement.php | 6 +- .../Controllers/TransactionCalculation.php | 56 +- .../Http/Controllers/UserNavigation.php | 19 +- app/Support/Logging/AuditLogger.php | 2 +- app/Support/Logging/AuditProcessor.php | 2 +- app/Support/Navigation.php | 256 +- app/Support/NullArrayObject.php | 6 +- app/Support/ParseDateString.php | 434 +- app/Support/Preferences.php | 246 +- .../Report/Budget/BudgetReportGenerator.php | 300 +- .../Category/CategoryReportGenerator.php | 118 +- .../Administration/AdministrationTrait.php | 16 +- .../Recurring/CalculateRangeOccurrences.php | 53 +- .../Recurring/CalculateXOccurrences.php | 58 +- .../Recurring/CalculateXOccurrencesSince.php | 68 +- .../Recurring/FiltersWeekends.php | 4 +- app/Support/Request/AppendsLocationData.php | 106 +- app/Support/Request/ConvertsDataTypes.php | 116 +- app/Support/Request/GetRecurrenceData.php | 2 +- app/Support/Search/AccountSearch.php | 10 +- app/Support/Search/OperatorQuerySearch.php | 1440 +++--- app/Support/Search/SearchInterface.php | 10 +- app/Support/Steam.php | 312 +- app/Support/System/OAuthKeys.php | 90 +- app/Support/Twig/AmountFormat.php | 74 +- app/Support/Twig/General.php | 442 +- app/Support/Twig/Rule.php | 50 +- app/Support/Twig/TransactionGroupTwig.php | 390 +- .../Actions/ActionInterface.php | 2 +- app/TransactionRules/Actions/AddTag.php | 2 +- .../Actions/AppendDescription.php | 2 +- .../Actions/AppendDescriptionToNotes.php | 2 +- app/TransactionRules/Actions/AppendNotes.php | 2 +- .../Actions/AppendNotesToDescription.php | 2 +- app/TransactionRules/Actions/ClearBudget.php | 2 +- .../Actions/ClearCategory.php | 2 +- app/TransactionRules/Actions/ClearNotes.php | 2 +- .../Actions/ConvertToDeposit.php | 120 +- .../Actions/ConvertToTransfer.php | 156 +- .../Actions/ConvertToWithdrawal.php | 70 +- .../Actions/DeleteTransaction.php | 2 +- app/TransactionRules/Actions/LinkToBill.php | 2 +- .../Actions/MoveDescriptionToNotes.php | 2 +- .../Actions/MoveNotesToDescription.php | 2 +- .../Actions/PrependDescription.php | 2 +- app/TransactionRules/Actions/PrependNotes.php | 2 +- .../Actions/RemoveAllTags.php | 2 +- app/TransactionRules/Actions/RemoveTag.php | 2 +- app/TransactionRules/Actions/SetBudget.php | 2 +- app/TransactionRules/Actions/SetCategory.php | 2 +- .../Actions/SetDescription.php | 2 +- .../Actions/SetDestinationAccount.php | 4 +- app/TransactionRules/Actions/SetNotes.php | 2 +- .../Actions/SetSourceAccount.php | 4 +- .../Actions/UpdatePiggybank.php | 102 +- .../Engine/RuleEngineInterface.php | 10 +- .../Engine/SearchRuleEngine.php | 472 +- .../Factory/ActionFactory.php | 8 +- app/Transformers/AbstractTransformer.php | 2 +- app/Transformers/AccountTransformer.php | 129 +- app/Transformers/AttachmentTransformer.php | 4 +- .../AvailableBudgetTransformer.php | 4 +- app/Transformers/BillTransformer.php | 102 +- app/Transformers/BudgetLimitTransformer.php | 6 +- app/Transformers/BudgetTransformer.php | 6 +- app/Transformers/CategoryTransformer.php | 6 +- app/Transformers/CurrencyTransformer.php | 4 +- app/Transformers/LinkTypeTransformer.php | 4 +- app/Transformers/ObjectGroupTransformer.php | 4 +- .../PiggyBankEventTransformer.php | 4 +- app/Transformers/PiggyBankTransformer.php | 4 +- app/Transformers/PreferenceTransformer.php | 2 +- app/Transformers/RecurrenceTransformer.php | 146 +- app/Transformers/RuleGroupTransformer.php | 4 +- app/Transformers/RuleTransformer.php | 60 +- app/Transformers/TagTransformer.php | 4 +- .../TransactionGroupTransformer.php | 852 ++-- .../TransactionLinkTransformer.php | 4 +- app/Transformers/UserTransformer.php | 4 +- app/Transformers/V2/AbstractTransformer.php | 4 +- app/Transformers/V2/AccountTransformer.php | 30 +- .../V2/BudgetLimitTransformer.php | 4 +- app/Transformers/V2/BudgetTransformer.php | 4 +- app/Transformers/V2/PreferenceTransformer.php | 2 +- .../V2/TransactionGroupTransformer.php | 104 +- .../WebhookAttemptTransformer.php | 2 +- .../WebhookMessageTransformer.php | 2 +- app/Transformers/WebhookTransformer.php | 6 +- app/User.php | 156 +- app/Validation/Account/DepositValidation.php | 34 +- .../Account/LiabilityValidation.php | 4 +- app/Validation/Account/OBValidation.php | 18 +- .../Account/ReconciliationValidation.php | 5 +- app/Validation/Account/TransferValidation.php | 34 +- .../Account/WithdrawalValidation.php | 36 +- app/Validation/AccountValidator.php | 48 +- .../ValidatesAdministrationAccess.php | 4 +- .../Bulk/ValidatesBulkTransactionQuery.php | 2 +- .../AutoBudget/ValidatesAutoBudgetRequest.php | 2 +- app/Validation/CurrencyValidation.php | 20 +- app/Validation/FireflyValidator.php | 342 +- app/Validation/GroupValidation.php | 39 +- app/Validation/RecurrenceValidation.php | 95 +- app/Validation/TransactionValidation.php | 1007 ++-- bootstrap/app.php | 10 +- composer.lock | 16 +- config/database.php | 2 +- config/filesystems.php | 2 +- config/firefly.php | 2 +- config/ide-helper.php | 2 +- config/logging.php | 2 +- config/mail.php | 2 +- ...016_06_16_000000_create_support_tables.php | 116 +- .../2016_06_16_000002_create_main_tables.php | 97 +- ...10_09_150037_expand_transactions_table.php | 2 +- .../2016_12_28_203205_changes_for_v431.php | 12 +- .../2017_04_13_163623_changes_for_v440.php | 2 +- .../2017_06_02_105232_changes_for_v450.php | 4 +- .../2017_11_04_170844_changes_for_v470a.php | 2 +- .../2018_03_19_141348_changes_for_v472.php | 4 +- .../2018_04_07_210913_changes_for_v473.php | 4 +- .../2018_09_05_195147_changes_for_v477.php | 2 +- .../2018_11_06_172532_changes_for_v479.php | 2 +- ...19_03_11_223700_fix_ldap_configuration.php | 2 +- .../2019_03_22_183214_changes_for_v480.php | 6 +- .../2020_06_30_202620_changes_for_v530a.php | 2 +- .../2020_07_24_162820_changes_for_v540.php | 8 +- .../2020_11_12_070604_changes_for_v550.php | 6 +- .../2021_03_12_061213_changes_for_v550b2.php | 2 +- ...064644_add_ldap_columns_to_users_table.php | 2 +- .../2021_08_28_073733_user_groups.php | 4 +- .../2022_08_21_104626_add_user_groups.php | 2 +- database/seeders/ExchangeRateSeeder.php | 60 +- frontend/src/layouts/MainLayout.vue | 2 +- 799 files changed, 23319 insertions(+), 22173 deletions(-) create mode 100644 .ci/phpmd.sh create mode 100644 .ci/phpmd/.gitignore create mode 100644 .ci/phpmd/composer.json create mode 100644 .ci/phpmd/composer.lock create mode 100644 .ci/phpmd/phpmd.xml diff --git a/.ci/firefly-iii-standard.yml b/.ci/firefly-iii-standard.yml index c863d43be6..857d458f09 100644 --- a/.ci/firefly-iii-standard.yml +++ b/.ci/firefly-iii-standard.yml @@ -1,250 +1,250 @@ parameters: - indentation: spaces + indentation: spaces - file_extensions: - - php + file_extensions: + - php - exclude_files: - - fixtures/* - - fixtures*/* - - temp/* - - tmp/* + exclude_files: + - fixtures/* + - fixtures*/* + - temp/* + - tmp/* services: - # Checkers bellow aim on 1:1 copy of https://nette.org/en/coding-standard + # Checkers bellow aim on 1:1 copy of https://nette.org/en/coding-standard - # General rules - https://nette.org/en/coding-standard#toc-general-rules + # General rules - https://nette.org/en/coding-standard#toc-general-rules - # use tabs over spaces - # PHP_CodeSniffer\Standards\Generic\Sniffs\WhiteSpace\DisallowSpaceIndentSniff: ~ - # PHP code must use only UTF-8 without BOM - PhpCsFixer\Fixer\Basic\EncodingFixer: ~ - # tag must be omitted from files containing only PHP. - PhpCsFixer\Fixer\PhpTag\NoClosingTagFixer: ~ - # There must not be trailing whitespace at the end of lines. - PhpCsFixer\Fixer\Whitespace\NoTrailingWhitespaceFixer: ~ - # ...and at the end of blank lines. - PhpCsFixer\Fixer\Whitespace\NoWhitespaceInBlankLineFixer: ~ - # All files must end with a single blank line. - PhpCsFixer\Fixer\Whitespace\SingleBlankLineAtEofFixer: ~ - # File name should match class name if possible. - PhpCsFixer\Fixer\Basic\Psr4Fixer: ~ - # Enforces using shorthand scalar typehint variants in phpDocs: `int` instead of `integer` and `bool` instead of `boolean` - SlevomatCodingStandard\Sniffs\TypeHints\LongTypeHintsSniff: ~ + # use tabs over spaces + # PHP_CodeSniffer\Standards\Generic\Sniffs\WhiteSpace\DisallowSpaceIndentSniff: ~ + # PHP code must use only UTF-8 without BOM + PhpCsFixer\Fixer\Basic\EncodingFixer: ~ + # tag must be omitted from files containing only PHP. + PhpCsFixer\Fixer\PhpTag\NoClosingTagFixer: ~ + # There must not be trailing whitespace at the end of lines. + PhpCsFixer\Fixer\Whitespace\NoTrailingWhitespaceFixer: ~ + # ...and at the end of blank lines. + PhpCsFixer\Fixer\Whitespace\NoWhitespaceInBlankLineFixer: ~ + # All files must end with a single blank line. + PhpCsFixer\Fixer\Whitespace\SingleBlankLineAtEofFixer: ~ + # File name should match class name if possible. + PhpCsFixer\Fixer\Basic\Psr4Fixer: ~ + # Enforces using shorthand scalar typehint variants in phpDocs: `int` instead of `integer` and `bool` instead of `boolean` + SlevomatCodingStandard\Sniffs\TypeHints\LongTypeHintsSniff: ~ - # File Header - https://nette.org/en/coding-standard#toc-file-header + # File Header - https://nette.org/en/coding-standard#toc-file-header - # empty line before namespace - PhpCsFixer\Fixer\NamespaceNotation\SingleBlankLineBeforeNamespaceFixer: ~ - # 1 Use statement per line - PhpCsFixer\Fixer\Import\SingleImportPerStatementFixer: ~ - # Use statements are alphabetically ordered - PhpCsFixer\Fixer\Import\OrderedImportsFixer: ~ - # disallow group use declarations use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo } - SlevomatCodingStandard\Sniffs\Namespaces\DisallowGroupUseSniff: ~ - # Disallows leading backslash in use statement: use \Foo\Bar; - SlevomatCodingStandard\Sniffs\Namespaces\UseDoesNotStartWithBackslashSniff: ~ - # Looks for unused imports from other namespaces. - Nette\CodingStandard\Sniffs\Namespaces\UnusedUsesSniff: - searchAnnotations: yes - ignoredAnnotationNames: ['@testCase'] - ignoredAnnotations: ['@internal'] + # empty line before namespace + PhpCsFixer\Fixer\NamespaceNotation\SingleBlankLineBeforeNamespaceFixer: ~ + # 1 Use statement per line + PhpCsFixer\Fixer\Import\SingleImportPerStatementFixer: ~ + # Use statements are alphabetically ordered + PhpCsFixer\Fixer\Import\OrderedImportsFixer: ~ + # disallow group use declarations use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo } + SlevomatCodingStandard\Sniffs\Namespaces\DisallowGroupUseSniff: ~ + # Disallows leading backslash in use statement: use \Foo\Bar; + SlevomatCodingStandard\Sniffs\Namespaces\UseDoesNotStartWithBackslashSniff: ~ + # Looks for unused imports from other namespaces. + Nette\CodingStandard\Sniffs\Namespaces\UnusedUsesSniff: + searchAnnotations: yes + ignoredAnnotationNames: [ '@testCase' ] + ignoredAnnotations: [ '@internal' ] - # Language Construct (should be placed before some other fixers) + # Language Construct (should be placed before some other fixers) - # Functions should be used with `$strict` param set to `true` - PhpCsFixer\Fixer\Strict\StrictParamFixer: ~ - # replaces is_null(parameter) expression with `null === parameter`. - PhpCsFixer\Fixer\LanguageConstruct\IsNullFixer: - use_yoda_style: true - # Calling `unset` on multiple items should be done in one call. - PhpCsFixer\Fixer\LanguageConstruct\CombineConsecutiveUnsetsFixer: ~ - # Replace all `<>` with `!=`. - PhpCsFixer\Fixer\Operator\StandardizeNotEqualsFixer: ~ - # Include/Require and file path should be divided with a single space. File path should not be placed under brackets. - PhpCsFixer\Fixer\ControlStructure\IncludeFixer: ~ - # Requires short ternary operator ?: when possible - SlevomatCodingStandard\Sniffs\ControlStructures\RequireShortTernaryOperatorSniff: ~ + # Functions should be used with `$strict` param set to `true` + PhpCsFixer\Fixer\Strict\StrictParamFixer: ~ + # replaces is_null(parameter) expression with `null === parameter`. + PhpCsFixer\Fixer\LanguageConstruct\IsNullFixer: + use_yoda_style: true + # Calling `unset` on multiple items should be done in one call. + PhpCsFixer\Fixer\LanguageConstruct\CombineConsecutiveUnsetsFixer: ~ + # Replace all `<>` with `!=`. + PhpCsFixer\Fixer\Operator\StandardizeNotEqualsFixer: ~ + # Include/Require and file path should be divided with a single space. File path should not be placed under brackets. + PhpCsFixer\Fixer\ControlStructure\IncludeFixer: ~ + # Requires short ternary operator ?: when possible + SlevomatCodingStandard\Sniffs\ControlStructures\RequireShortTernaryOperatorSniff: ~ - # Arrays - https://nette.org/en/coding-standard#toc-arrays + # Arrays - https://nette.org/en/coding-standard#toc-arrays - # use short array fixes - PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer: - syntax: short - # use trailing command in last array element - PhpCsFixer\Fixer\ArrayNotation\TrailingCommaInMultilineArrayFixer: ~ - # PHP single-line arrays should not have trailing comma. - # PhpCsFixer\Fixer\ArrayNotation\NoTrailingCommaInSinglelineArrayFixer: ~ - # In array declaration, there MUST NOT be a whitespace before each comma. - PhpCsFixer\Fixer\ArrayNotation\NoWhitespaceBeforeCommaInArrayFixer: ~ - # Arrays should be formatted like function/method arguments, without leading or trailing single line space. - PhpCsFixer\Fixer\ArrayNotation\TrimArraySpacesFixer: ~ - # In array declaration, there MUST be a whitespace after each comma. - PhpCsFixer\Fixer\ArrayNotation\WhitespaceAfterCommaInArrayFixer: ~ + # use short array fixes + PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer: + syntax: short + # use trailing command in last array element + PhpCsFixer\Fixer\ArrayNotation\TrailingCommaInMultilineArrayFixer: ~ + # PHP single-line arrays should not have trailing comma. + # PhpCsFixer\Fixer\ArrayNotation\NoTrailingCommaInSinglelineArrayFixer: ~ + # In array declaration, there MUST NOT be a whitespace before each comma. + PhpCsFixer\Fixer\ArrayNotation\NoWhitespaceBeforeCommaInArrayFixer: ~ + # Arrays should be formatted like function/method arguments, without leading or trailing single line space. + PhpCsFixer\Fixer\ArrayNotation\TrimArraySpacesFixer: ~ + # In array declaration, there MUST be a whitespace after each comma. + PhpCsFixer\Fixer\ArrayNotation\WhitespaceAfterCommaInArrayFixer: ~ - # Strings + # Strings - # Convert `heredoc` to `nowdoc` where possible. - PhpCsFixer\Fixer\StringNotation\HeredocToNowdocFixer: ~ - # Convert double quotes to single quotes for simple strings. - PhpCsFixer\Fixer\StringNotation\SingleQuoteFixer: ~ + # Convert `heredoc` to `nowdoc` where possible. + PhpCsFixer\Fixer\StringNotation\HeredocToNowdocFixer: ~ + # Convert double quotes to single quotes for simple strings. + PhpCsFixer\Fixer\StringNotation\SingleQuoteFixer: ~ - # Keywords and True/False/Null - https://nette.org/en/coding-standard#toc-keywords-and-true-false-null + # Keywords and True/False/Null - https://nette.org/en/coding-standard#toc-keywords-and-true-false-null - # PHP keywords must be in lower case - PhpCsFixer\Fixer\Casing\LowercaseKeywordsFixer: ~ - # The PHP constants `true`, `false`, and `null` MUST be in lower case - PhpCsFixer\Fixer\Casing\LowercaseConstantsFixer: ~ + # PHP keywords must be in lower case + PhpCsFixer\Fixer\Casing\LowercaseKeywordsFixer: ~ + # The PHP constants `true`, `false`, and `null` MUST be in lower case + PhpCsFixer\Fixer\Casing\LowercaseConstantsFixer: ~ - # Method and Functions Calls - https://nette.org/en/coding-standard#toc-method-and-function-calls + # Method and Functions Calls - https://nette.org/en/coding-standard#toc-method-and-function-calls - # Function defined by PHP should be called using the correct casing - PhpCsFixer\Fixer\Casing\NativeFunctionCasingFixer: ~ - # In the argument list, there must be one space after each comma, and there must no be a space before each comma - PhpCsFixer\Fixer\FunctionNotation\MethodArgumentSpaceFixer: ~ - # This sniff checks that there are two blank lines between functions declarations and single between signatures. - #Nette\CodingStandard\Sniffs\WhiteSpace\FunctionSpacingSniff: ~ + # Function defined by PHP should be called using the correct casing + PhpCsFixer\Fixer\Casing\NativeFunctionCasingFixer: ~ + # In the argument list, there must be one space after each comma, and there must no be a space before each comma + PhpCsFixer\Fixer\FunctionNotation\MethodArgumentSpaceFixer: ~ + # This sniff checks that there are two blank lines between functions declarations and single between signatures. + #Nette\CodingStandard\Sniffs\WhiteSpace\FunctionSpacingSniff: ~ - # Classes - https://nette.org/en/coding-standard#toc-classes + # Classes - https://nette.org/en/coding-standard#toc-classes - # Inside a classy element "self" should be preferred to the class name itself. - PhpCsFixer\Fixer\ClassNotation\SelfAccessorFixer: ~ - # class element order: constants, properties, from public to private - PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer: - order: - - use_trait - - constant - - constant_public - - constant_protected - - constant_private - - property_public - - property_protected - - property_private + # Inside a classy element "self" should be preferred to the class name itself. + PhpCsFixer\Fixer\ClassNotation\SelfAccessorFixer: ~ + # class element order: constants, properties, from public to private + PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer: + order: + - use_trait + - constant + - constant_public + - constant_protected + - constant_private + - property_public + - property_protected + - property_private - # Constants - https://nette.org/en/coding-standard#toc-constants + # Constants - https://nette.org/en/coding-standard#toc-constants - # constant names are CAPITALIZED (manuall fixing only :() - PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\UpperCaseConstantNameSniff: ~ + # constant names are CAPITALIZED (manuall fixing only :() + PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\UpperCaseConstantNameSniff: ~ - # Class Properties - https://nette.org/en/coding-standard#toc-class-properties + # Class Properties - https://nette.org/en/coding-standard#toc-class-properties - # There MUST NOT be more than one property declared per statement. - PhpCsFixer\Fixer\ClassNotation\SingleClassElementPerStatementFixer: - elements: ['property'] + # There MUST NOT be more than one property declared per statement. + PhpCsFixer\Fixer\ClassNotation\SingleClassElementPerStatementFixer: + elements: [ 'property' ] - # Methods - https://nette.org/en/coding-standard#toc-methods + # Methods - https://nette.org/en/coding-standard#toc-methods - # They must be declared in camelCase. - PHP_CodeSniffer\Standards\PSR1\Sniffs\Methods\CamelCapsMethodNameSniff: ~ - # Checks that there's a single space between a typehint and a parameter name and no whitespace between a nullability symbol and a typehint - SlevomatCodingStandard\Sniffs\TypeHints\ParameterTypeHintSpacingSniff: ~ - # Spaces should be properly placed in a function declaration. - PhpCsFixer\Fixer\FunctionNotation\FunctionDeclarationFixer: ~ - # In function arguments there must not be arguments with default values before non-default ones. - PhpCsFixer\Fixer\FunctionNotation\NoUnreachableDefaultArgumentValueFixer: ~ + # They must be declared in camelCase. + PHP_CodeSniffer\Standards\PSR1\Sniffs\Methods\CamelCapsMethodNameSniff: ~ + # Checks that there's a single space between a typehint and a parameter name and no whitespace between a nullability symbol and a typehint + SlevomatCodingStandard\Sniffs\TypeHints\ParameterTypeHintSpacingSniff: ~ + # Spaces should be properly placed in a function declaration. + PhpCsFixer\Fixer\FunctionNotation\FunctionDeclarationFixer: ~ + # In function arguments there must not be arguments with default values before non-default ones. + PhpCsFixer\Fixer\FunctionNotation\NoUnreachableDefaultArgumentValueFixer: ~ - # Constans, Class Properties, Methods + # Constans, Class Properties, Methods - # Constants and Properties should be separated by 1 blank line - #PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer: - # elements: [const, property] + # Constants and Properties should be separated by 1 blank line + #PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer: + # elements: [const, property] - # Last property and 1st method should be separated by 2 spaces - Nette\CodingStandard\Fixer\ClassNotation\LastPropertyAndFirstMethodSeparationFixer: - space_count: 2 + # Last property and 1st method should be separated by 2 spaces + Nette\CodingStandard\Fixer\ClassNotation\LastPropertyAndFirstMethodSeparationFixer: + space_count: 2 - # Control Statements - https://nette.org/en/coding-standard#toc-control-statements + # Control Statements - https://nette.org/en/coding-standard#toc-control-statements - # The keyword `elseif` should be used instead of `else if` so that all control keywords look like single words. - PhpCsFixer\Fixer\ControlStructure\ElseifFixer: ~ - # Remove useless semicolon statements. - PhpCsFixer\Fixer\Semicolon\NoEmptyStatementFixer: ~ - # Remove trailing commas in list() calls. - PhpCsFixer\Fixer\ControlStructure\NoTrailingCommaInListCallFixer: ~ - # Removes unneeded parentheses around control statements. - PhpCsFixer\Fixer\ControlStructure\NoUnneededControlParenthesesFixer: ~ - # A case should be followed by a colon and not a semicolon. - PhpCsFixer\Fixer\ControlStructure\SwitchCaseSemicolonToColonFixer: ~ - # The structure body must be indented once. - # The closing brace must be on the next line after the body. - # There should not be more than one statement per line. - #Nette\CodingStandard\Fixer\Basic\BracesFixer: - # allow_single_line_closure: true - # changes if (1 === $cond) to if ($cond === 1) - #SlevomatCodingStandard\Sniffs\ControlStructures\DisallowYodaComparisonSniff: ~ - # finds unreachable catch blocks: - SlevomatCodingStandard\Sniffs\Exceptions\DeadCatchSniff: ~ + # The keyword `elseif` should be used instead of `else if` so that all control keywords look like single words. + PhpCsFixer\Fixer\ControlStructure\ElseifFixer: ~ + # Remove useless semicolon statements. + PhpCsFixer\Fixer\Semicolon\NoEmptyStatementFixer: ~ + # Remove trailing commas in list() calls. + PhpCsFixer\Fixer\ControlStructure\NoTrailingCommaInListCallFixer: ~ + # Removes unneeded parentheses around control statements. + PhpCsFixer\Fixer\ControlStructure\NoUnneededControlParenthesesFixer: ~ + # A case should be followed by a colon and not a semicolon. + PhpCsFixer\Fixer\ControlStructure\SwitchCaseSemicolonToColonFixer: ~ + # The structure body must be indented once. + # The closing brace must be on the next line after the body. + # There should not be more than one statement per line. + #Nette\CodingStandard\Fixer\Basic\BracesFixer: + # allow_single_line_closure: true + # changes if (1 === $cond) to if ($cond === 1) + #SlevomatCodingStandard\Sniffs\ControlStructures\DisallowYodaComparisonSniff: ~ + # finds unreachable catch blocks: + SlevomatCodingStandard\Sniffs\Exceptions\DeadCatchSniff: ~ - # Casting + # Casting - # A single space or none should be between cast and variable (int) $val - PhpCsFixer\Fixer\CastNotation\CastSpacesFixer: ~ - # Cast should be written in lower case. - PhpCsFixer\Fixer\CastNotation\LowercaseCastFixer: ~ - # Replaces `intval`, `floatval`, `doubleval`, `strval` and `boolval` function calls with according type casting operator - PhpCsFixer\Fixer\CastNotation\ModernizeTypesCastingFixer: ~ - # Short cast `bool` using double exclamation mark should not be used - PhpCsFixer\Fixer\CastNotation\NoShortBoolCastFixer: ~ - # Cast `(boolean)` and `(integer)` should be written as `(bool)` and `(int)`, `(double)` and `(real)` as `(float)` - PhpCsFixer\Fixer\CastNotation\ShortScalarCastFixer: ~ + # A single space or none should be between cast and variable (int) $val + PhpCsFixer\Fixer\CastNotation\CastSpacesFixer: ~ + # Cast should be written in lower case. + PhpCsFixer\Fixer\CastNotation\LowercaseCastFixer: ~ + # Replaces `intval`, `floatval`, `doubleval`, `strval` and `boolval` function calls with according type casting operator + PhpCsFixer\Fixer\CastNotation\ModernizeTypesCastingFixer: ~ + # Short cast `bool` using double exclamation mark should not be used + PhpCsFixer\Fixer\CastNotation\NoShortBoolCastFixer: ~ + # Cast `(boolean)` and `(integer)` should be written as `(bool)` and `(int)`, `(double)` and `(real)` as `(float)` + PhpCsFixer\Fixer\CastNotation\ShortScalarCastFixer: ~ - # Language Whitespace + # Language Whitespace - # Binary operators should be surrounded by at least one space. DO NOT USE - #PhpCsFixer\Fixer\Operator\BinaryOperatorSpacesFixer: ~ - # Unary operators should be placed adjacent to their operands. - PhpCsFixer\Fixer\Operator\UnaryOperatorSpacesFixer: ~ - # No space after the opening parenthesis and before the closing parenthesis - PhpCsFixer\Fixer\Whitespace\NoSpacesInsideParenthesisFixer: ~ - # There MUST NOT be spaces around offset braces $a[0] - PhpCsFixer\Fixer\Whitespace\NoSpacesAroundOffsetFixer: ~ - # There should not be space before or after object `T_OBJECT_OPERATOR` `->`. - PhpCsFixer\Fixer\Operator\ObjectOperatorWithoutWhitespaceFixer: ~ - # Standardize spaces around ternary operator. - PhpCsFixer\Fixer\Operator\TernaryOperatorSpacesFixer: ~ - # Concatenation $a . $b should be spaced according configuration - PhpCsFixer\Fixer\Operator\ConcatSpaceFixer: - spacing: one - # Removes extra spaces between colon and case value. - PhpCsFixer\Fixer\ControlStructure\SwitchCaseSpaceFixer: ~ + # Binary operators should be surrounded by at least one space. DO NOT USE + #PhpCsFixer\Fixer\Operator\BinaryOperatorSpacesFixer: ~ + # Unary operators should be placed adjacent to their operands. + PhpCsFixer\Fixer\Operator\UnaryOperatorSpacesFixer: ~ + # No space after the opening parenthesis and before the closing parenthesis + PhpCsFixer\Fixer\Whitespace\NoSpacesInsideParenthesisFixer: ~ + # There MUST NOT be spaces around offset braces $a[0] + PhpCsFixer\Fixer\Whitespace\NoSpacesAroundOffsetFixer: ~ + # There should not be space before or after object `T_OBJECT_OPERATOR` `->`. + PhpCsFixer\Fixer\Operator\ObjectOperatorWithoutWhitespaceFixer: ~ + # Standardize spaces around ternary operator. + PhpCsFixer\Fixer\Operator\TernaryOperatorSpacesFixer: ~ + # Concatenation $a . $b should be spaced according configuration + PhpCsFixer\Fixer\Operator\ConcatSpaceFixer: + spacing: one + # Removes extra spaces between colon and case value. + PhpCsFixer\Fixer\ControlStructure\SwitchCaseSpaceFixer: ~ - # Comments + # Comments - # Docblocks should have the same indentation as the documented subject. - PhpCsFixer\Fixer\Phpdoc\PhpdocIndentFixer: ~ - # There should not be any empty comments. - PhpCsFixer\Fixer\Comment\NoEmptyCommentFixer: ~ - # There should not be empty PHPDoc blocks. - #PhpCsFixer\Fixer\Phpdoc\NoEmptyPhpdocFixer: ~ - # Phpdocs should start and end with content, excluding the very first and last line of the docblocks. - PhpCsFixer\Fixer\Phpdoc\PhpdocTrimFixer: ~ - # Single-line comments comments with only one line of actual content should use the `//` syntax. - PhpCsFixer\Fixer\Comment\SingleLineCommentStyleFixer: - comment_types: ['hash'] - # Require comments with single-line content to be written as one-liners - SlevomatCodingStandard\Sniffs\Commenting\RequireOneLinePropertyDocCommentSniff: ~ + # Docblocks should have the same indentation as the documented subject. + PhpCsFixer\Fixer\Phpdoc\PhpdocIndentFixer: ~ + # There should not be any empty comments. + PhpCsFixer\Fixer\Comment\NoEmptyCommentFixer: ~ + # There should not be empty PHPDoc blocks. + #PhpCsFixer\Fixer\Phpdoc\NoEmptyPhpdocFixer: ~ + # Phpdocs should start and end with content, excluding the very first and last line of the docblocks. + PhpCsFixer\Fixer\Phpdoc\PhpdocTrimFixer: ~ + # Single-line comments comments with only one line of actual content should use the `//` syntax. + PhpCsFixer\Fixer\Comment\SingleLineCommentStyleFixer: + comment_types: [ 'hash' ] + # Require comments with single-line content to be written as one-liners + SlevomatCodingStandard\Sniffs\Commenting\RequireOneLinePropertyDocCommentSniff: ~ - # Properties MUST not be explicitly initialized with `null`. - #PhpCsFixer\Fixer\ClassNotation\NoNullPropertyInitializationFixer: ~ + # Properties MUST not be explicitly initialized with `null`. + #PhpCsFixer\Fixer\ClassNotation\NoNullPropertyInitializationFixer: ~ - PhpCsFixer\Fixer\ControlStructure\NoBreakCommentFixer: - comment_text: 'break omitted' + PhpCsFixer\Fixer\ControlStructure\NoBreakCommentFixer: + comment_text: 'break omitted' - # declare(strict_types=1); - PhpCsFixer\Fixer\Strict\DeclareStrictTypesFixer: ~ - # Enforces consistent formatting of return typehints: function foo(): ?int - SlevomatCodingStandard\Sniffs\TypeHints\ReturnTypeHintSpacingSniff: ~ - # Use `null` coalescing operator `??` where possible. - PhpCsFixer\Fixer\Operator\TernaryToNullCoalescingFixer: ~ + # declare(strict_types=1); + PhpCsFixer\Fixer\Strict\DeclareStrictTypesFixer: ~ + # Enforces consistent formatting of return typehints: function foo(): ?int + SlevomatCodingStandard\Sniffs\TypeHints\ReturnTypeHintSpacingSniff: ~ + # Use `null` coalescing operator `??` where possible. + PhpCsFixer\Fixer\Operator\TernaryToNullCoalescingFixer: ~ - Nette\CodingStandard\Fixer\ClassNotation\ClassAndTraitVisibilityRequiredFixer: - elements: ['const', 'property', 'method'] + Nette\CodingStandard\Fixer\ClassNotation\ClassAndTraitVisibilityRequiredFixer: + elements: [ 'const', 'property', 'method' ] - # short list() syntax [] - PhpCsFixer\Fixer\ListNotation\ListSyntaxFixer: - syntax: short + # short list() syntax [] + PhpCsFixer\Fixer\ListNotation\ListSyntaxFixer: + syntax: short diff --git a/.ci/php-cs-fixer/.php-cs-fixer.php b/.ci/php-cs-fixer/.php-cs-fixer.php index 0d6e38f9ec..1e5a1c2dff 100644 --- a/.ci/php-cs-fixer/.php-cs-fixer.php +++ b/.ci/php-cs-fixer/.php-cs-fixer.php @@ -22,12 +22,12 @@ $current = __DIR__; $paths = [ - $current.'/../../app', - $current.'/../../config', - $current.'/../../database', - $current.'/../../routes', - $current.'/../../tests', - $current.'/../../resources/lang', + $current . '/../../app', + $current . '/../../config', + $current . '/../../database', + $current . '/../../routes', + $current . '/../../tests', + $current . '/../../resources/lang', ]; $finder = PhpCsFixer\Finder::create() @@ -36,9 +36,9 @@ $finder = PhpCsFixer\Finder::create() $config = new PhpCsFixer\Config(); return $config->setRules([ - '@PSR12' => true, - 'declare_strict_types' => true, - 'strict_param' => true, - 'array_syntax' => ['syntax' => 'short'], -]) + '@PSR12' => true, + 'declare_strict_types' => true, + 'strict_param' => true, + 'array_syntax' => ['syntax' => 'short'], + ]) ->setFinder($finder); diff --git a/.ci/php-cs-fixer/composer.json b/.ci/php-cs-fixer/composer.json index 9795354e5e..bb677eeb9f 100644 --- a/.ci/php-cs-fixer/composer.json +++ b/.ci/php-cs-fixer/composer.json @@ -1,5 +1,5 @@ { - "require": { - "friendsofphp/php-cs-fixer": "^3.12" - } + "require": { + "friendsofphp/php-cs-fixer": "^3.12" + } } diff --git a/.ci/php-cs-fixer/composer.lock b/.ci/php-cs-fixer/composer.lock index c08317694d..7e491438fc 100644 --- a/.ci/php-cs-fixer/composer.lock +++ b/.ci/php-cs-fixer/composer.lock @@ -1,2045 +1,2045 @@ { - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "f1e0b38af4ded66da271a99d2bff5be8", - "packages": [ - { - "name": "composer/pcre", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/composer/pcre.git", - "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", - "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.3", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Pcre\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "PCRE wrapping library that offers type-safe preg_* replacements.", - "keywords": [ - "PCRE", - "preg", - "regex", - "regular expression" - ], - "support": { - "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.1.0" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-11-17T09:50:14+00:00" - }, - { - "name": "composer/semver", - "version": "3.3.2", - "source": { - "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", - "keywords": [ - "semantic", - "semver", - "validation", - "versioning" - ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.3.2" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-04-01T19:23:25+00:00" - }, - { - "name": "composer/xdebug-handler", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "ced299686f41dce890debac69273b47ffe98a40c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", - "reference": "ced299686f41dce890debac69273b47ffe98a40c", - "shasum": "" - }, - "require": { - "composer/pcre": "^1 || ^2 || ^3", - "php": "^7.2.5 || ^8.0", - "psr/log": "^1 || ^2 || ^3" - }, - "require-dev": { - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Composer\\XdebugHandler\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" - } - ], - "description": "Restarts a process without Xdebug.", - "keywords": [ - "Xdebug", - "performance" - ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-02-25T21:32:43+00:00" - }, - { - "name": "doctrine/annotations", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", - "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", - "shasum": "" - }, - "require": { - "doctrine/lexer": "^2 || ^3", - "ext-tokenizer": "*", - "php": "^7.2 || ^8.0", - "psr/cache": "^1 || ^2 || ^3" - }, - "require-dev": { - "doctrine/cache": "^2.0", - "doctrine/coding-standard": "^10", - "phpstan/phpstan": "^1.8.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "symfony/cache": "^5.4 || ^6", - "vimeo/psalm": "^4.10" - }, - "suggest": { - "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "https://www.doctrine-project.org/projects/annotations.html", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "support": { - "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/2.0.1" - }, - "time": "2023-02-02T22:02:53+00:00" - }, - { - "name": "doctrine/lexer", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "84a527db05647743d50373e0ec53a152f2cde568" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/84a527db05647743d50373e0ec53a152f2cde568", - "reference": "84a527db05647743d50373e0ec53a152f2cde568", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "require-dev": { - "doctrine/coding-standard": "^10", - "phpstan/phpstan": "^1.9", - "phpunit/phpunit": "^9.5", - "psalm/plugin-phpunit": "^0.18.3", - "vimeo/psalm": "^5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Lexer\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", - "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/3.0.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", - "type": "tidelift" - } - ], - "time": "2022-12-15T16:57:16+00:00" - }, - { - "name": "friendsofphp/php-cs-fixer", - "version": "v3.18.0", - "source": { - "type": "git", - "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "b123395c9fa3a70801f816f13606c0f3a7ada8df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/b123395c9fa3a70801f816f13606c0f3a7ada8df", - "reference": "b123395c9fa3a70801f816f13606c0f3a7ada8df", - "shasum": "" - }, - "require": { - "composer/semver": "^3.3", - "composer/xdebug-handler": "^3.0.3", - "doctrine/annotations": "^2", - "doctrine/lexer": "^2 || ^3", - "ext-json": "*", - "ext-tokenizer": "*", - "php": "^7.4 || ^8.0", - "sebastian/diff": "^4.0 || ^5.0", - "symfony/console": "^5.4 || ^6.0", - "symfony/event-dispatcher": "^5.4 || ^6.0", - "symfony/filesystem": "^5.4 || ^6.0", - "symfony/finder": "^5.4 || ^6.0", - "symfony/options-resolver": "^5.4 || ^6.0", - "symfony/polyfill-mbstring": "^1.27", - "symfony/polyfill-php80": "^1.27", - "symfony/polyfill-php81": "^1.27", - "symfony/process": "^5.4 || ^6.0", - "symfony/stopwatch": "^5.4 || ^6.0" - }, - "require-dev": { - "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^2.0", - "mikey179/vfsstream": "^1.6.11", - "php-coveralls/php-coveralls": "^2.5.3", - "php-cs-fixer/accessible-object": "^1.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.16", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", - "phpunitgoodpractices/polyfill": "^1.6", - "phpunitgoodpractices/traits": "^1.9.2", - "symfony/phpunit-bridge": "^6.2.3", - "symfony/yaml": "^5.4 || ^6.0" - }, - "suggest": { - "ext-dom": "For handling output formats in XML", - "ext-mbstring": "For handling non-UTF8 characters." - }, - "bin": [ - "php-cs-fixer" - ], - "type": "application", - "autoload": { - "psr-4": { - "PhpCsFixer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" - } - ], - "description": "A tool to automatically fix PHP code style", - "keywords": [ - "Static code analysis", - "fixer", - "standards", - "static analysis" - ], - "support": { - "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.18.0" - }, - "funding": [ - { - "url": "https://github.com/keradus", - "type": "github" - } - ], - "time": "2023-06-18T22:25:45+00:00" - }, - { - "name": "psr/cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ], - "support": { - "source": "https://github.com/php-fig/cache/tree/3.0.0" - }, - "time": "2021-02-03T23:26:27+00:00" - }, - { - "name": "psr/container", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], - "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/2.0.2" - }, - "time": "2021-11-05T16:47:00+00:00" - }, - { - "name": "psr/event-dispatcher", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", - "shasum": "" - }, - "require": { - "php": ">=7.2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\EventDispatcher\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Standard interfaces for event handling.", - "keywords": [ - "events", - "psr", - "psr-14" - ], - "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" - }, - "time": "2019-01-08T18:20:26+00:00" - }, - { - "name": "psr/log", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" - }, - "time": "2021-07-14T16:46:02+00:00" - }, - { - "name": "sebastian/diff", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", - "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-05-01T07:48:21+00:00" - }, - { - "name": "symfony/console", - "version": "v6.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7", - "reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^5.4|^6.0" - }, - "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/lock": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", - "keywords": [ - "cli", - "command-line", - "console", - "terminal" - ], - "support": { - "source": "https://github.com/symfony/console/tree/v6.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-05-29T12:49:39+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-05-23T14:45:45+00:00" - }, - { - "name": "symfony/event-dispatcher", - "version": "v6.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa", - "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/event-dispatcher-contracts": "^2.5|^3" - }, - "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/service-contracts": "<2.5" - }, - "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/error-handler": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^5.4|^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-04-21T14:41:17+00:00" - }, - { - "name": "symfony/event-dispatcher-contracts", - "version": "v3.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/event-dispatcher": "^1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\EventDispatcher\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to dispatching event", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-05-23T14:45:45+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v6.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "97b698e1d77d356304def77a8d0cd73090b359ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/97b698e1d77d356304def77a8d0cd73090b359ea", - "reference": "97b698e1d77d356304def77a8d0cd73090b359ea", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides basic utilities for the filesystem", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-05-30T17:12:32+00:00" - }, - { - "name": "symfony/finder", - "version": "v6.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/d9b01ba073c44cef617c7907ce2419f8d00d75e2", - "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "symfony/filesystem": "^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/finder/tree/v6.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-04-02T01:25:41+00:00" - }, - { - "name": "symfony/options-resolver", - "version": "v6.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a10f19f5198d589d5c33333cffe98dc9820332dd", - "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides an improved replacement for the array_replace PHP function", - "homepage": "https://symfony.com", - "keywords": [ - "config", - "configuration", - "options" - ], - "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-05-12T14:21:09+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's grapheme_* functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-php81", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", - "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/process", - "version": "v6.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/8741e3ed7fe2e91ec099e02446fb86667a0f1628", - "reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/process/tree/v6.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-05-19T08:06:44+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v3.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", - "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/container": "^2.0" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-05-23T14:45:45+00:00" - }, - { - "name": "symfony/stopwatch", - "version": "v6.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", - "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/service-contracts": "^2.5|^3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides a way to profile code", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-02-16T10:14:28+00:00" - }, - { - "name": "symfony/string", - "version": "v6.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/f2e190ee75ff0f5eced645ec0be5c66fac81f51f", - "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/translation-contracts": "<2.5" - }, - "require-dev": { - "symfony/error-handler": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/intl": "^6.2", - "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^5.4|^6.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\String\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", - "homepage": "https://symfony.com", - "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" - ], - "support": { - "source": "https://github.com/symfony/string/tree/v6.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-03-21T21:06:29+00:00" + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "f1e0b38af4ded66da271a99d2bff5be8", + "packages": [ + { + "name": "composer/pcre", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.3.0" + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.1.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-11-17T09:50:14+00:00" + }, + { + "name": "composer/semver", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-04-01T19:23:25+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "ced299686f41dce890debac69273b47ffe98a40c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-02-25T21:32:43+00:00" + }, + { + "name": "doctrine/annotations", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", + "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2 || ^3", + "ext-tokenizer": "*", + "php": "^7.2 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" + }, + "require-dev": { + "doctrine/cache": "^2.0", + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.8.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "symfony/cache": "^5.4 || ^6", + "vimeo/psalm": "^4.10" + }, + "suggest": { + "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/2.0.1" + }, + "time": "2023-02-02T22:02:53+00:00" + }, + { + "name": "doctrine/lexer", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "84a527db05647743d50373e0ec53a152f2cde568" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/84a527db05647743d50373e0ec53a152f2cde568", + "reference": "84a527db05647743d50373e0ec53a152f2cde568", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.9", + "phpunit/phpunit": "^9.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2022-12-15T16:57:16+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.18.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "b123395c9fa3a70801f816f13606c0f3a7ada8df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/b123395c9fa3a70801f816f13606c0f3a7ada8df", + "reference": "b123395c9fa3a70801f816f13606c0f3a7ada8df", + "shasum": "" + }, + "require": { + "composer/semver": "^3.3", + "composer/xdebug-handler": "^3.0.3", + "doctrine/annotations": "^2", + "doctrine/lexer": "^2 || ^3", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0", + "sebastian/diff": "^4.0 || ^5.0", + "symfony/console": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/finder": "^5.4 || ^6.0", + "symfony/options-resolver": "^5.4 || ^6.0", + "symfony/polyfill-mbstring": "^1.27", + "symfony/polyfill-php80": "^1.27", + "symfony/polyfill-php81": "^1.27", + "symfony/process": "^5.4 || ^6.0", + "symfony/stopwatch": "^5.4 || ^6.0" + }, + "require-dev": { + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^2.0", + "mikey179/vfsstream": "^1.6.11", + "php-coveralls/php-coveralls": "^2.5.3", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", + "phpspec/prophecy": "^1.16", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "phpunitgoodpractices/polyfill": "^1.6", + "phpunitgoodpractices/traits": "^1.9.2", + "symfony/phpunit-bridge": "^6.2.3", + "symfony/yaml": "^5.4 || ^6.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.18.0" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2023-06-18T22:25:45+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-05-01T07:48:21+00:00" + }, + { + "name": "symfony/console", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7", + "reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^5.4|^6.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-29T12:49:39+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa", + "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-04-21T14:41:17+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "97b698e1d77d356304def77a8d0cd73090b359ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/97b698e1d77d356304def77a8d0cd73090b359ea", + "reference": "97b698e1d77d356304def77a8d0cd73090b359ea", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-30T17:12:32+00:00" + }, + { + "name": "symfony/finder", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/d9b01ba073c44cef617c7907ce2419f8d00d75e2", + "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-04-02T01:25:41+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a10f19f5198d589d5c33333cffe98dc9820332dd", + "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-12T14:21:09+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/process", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/8741e3ed7fe2e91ec099e02446fb86667a0f1628", + "reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-19T08:06:44+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-02-16T10:14:28+00:00" + }, + { + "name": "symfony/string", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/f2e190ee75ff0f5eced645ec0be5c66fac81f51f", + "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/intl": "^6.2", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-03-21T21:06:29+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.3.0" } diff --git a/.ci/phpcs.sh b/.ci/phpcs.sh index ef57a468f8..49c6420f04 100755 --- a/.ci/phpcs.sh +++ b/.ci/phpcs.sh @@ -30,12 +30,9 @@ SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) # clean up php code cd $SCRIPT_DIR/php-cs-fixer -composer update +composer update --quiet rm -f .php-cs-fixer.cache -echo 'Removed cache...' -echo 'Running...' PHP_CS_FIXER_IGNORE_ENV=true ./vendor/bin/php-cs-fixer fix --config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php --allow-risky=yes -echo 'Done!' cd $SCRIPT_DIR/.. exit 0 diff --git a/.ci/phpmd.sh b/.ci/phpmd.sh new file mode 100644 index 0000000000..0cbadc94c6 --- /dev/null +++ b/.ci/phpmd.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# +# phpmd.sh +# Copyright (c) 2023 james@firefly-iii.org +# +# This file is part of Firefly III (https://github.com/firefly-iii). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + + +SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +cd $SCRIPT_DIR/phpmd +composer update --quiet +./vendor/bin/phpmd \ + $SCRIPT_DIR/../app text phpmd.xml \ + --exclude $SCRIPT_DIR/../app/resources/** \ + --exclude $SCRIPT_DIR/../app/frontend/** \ + --exclude $SCRIPT_DIR/../app/public/** \ + --exclude $SCRIPT_DIR/../app/vendor/** \ + +cd $SCRIPT_DIR/.. + +exit 0 diff --git a/.ci/phpmd/.gitignore b/.ci/phpmd/.gitignore new file mode 100644 index 0000000000..22d0d82f80 --- /dev/null +++ b/.ci/phpmd/.gitignore @@ -0,0 +1 @@ +vendor diff --git a/.ci/phpmd/composer.json b/.ci/phpmd/composer.json new file mode 100644 index 0000000000..0e8694ec56 --- /dev/null +++ b/.ci/phpmd/composer.json @@ -0,0 +1,5 @@ +{ + "require-dev": { + "phpmd/phpmd": "^2.13" + } +} diff --git a/.ci/phpmd/composer.lock b/.ci/phpmd/composer.lock new file mode 100644 index 0000000000..0d2f0c7ba9 --- /dev/null +++ b/.ci/phpmd/composer.lock @@ -0,0 +1,1012 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "655b6c5b599fb9b1f4cb2779854c0510", + "packages": [], + "packages-dev": [ + { + "name": "composer/pcre", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.1.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-11-17T09:50:14+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "ced299686f41dce890debac69273b47ffe98a40c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-02-25T21:32:43+00:00" + }, + { + "name": "pdepend/pdepend", + "version": "2.14.0", + "source": { + "type": "git", + "url": "https://github.com/pdepend/pdepend.git", + "reference": "1121d4b04af06e33e9659bac3a6741b91cab1de1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/1121d4b04af06e33e9659bac3a6741b91cab1de1", + "reference": "1121d4b04af06e33e9659bac3a6741b91cab1de1", + "shasum": "" + }, + "require": { + "php": ">=5.3.7", + "symfony/config": "^2.3.0|^3|^4|^5|^6.0", + "symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0", + "symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0" + }, + "require-dev": { + "easy-doc/easy-doc": "0.0.0|^1.2.3", + "gregwar/rst": "^1.0", + "phpunit/phpunit": "^4.8.36|^5.7.27", + "squizlabs/php_codesniffer": "^2.0.0" + }, + "bin": [ + "src/bin/pdepend" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "PDepend\\": "src/main/php/PDepend" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Official version of pdepend to be handled with Composer", + "keywords": [ + "PHP Depend", + "PHP_Depend", + "dev", + "pdepend" + ], + "support": { + "issues": "https://github.com/pdepend/pdepend/issues", + "source": "https://github.com/pdepend/pdepend/tree/2.14.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/pdepend/pdepend", + "type": "tidelift" + } + ], + "time": "2023-05-26T13:15:18+00:00" + }, + { + "name": "phpmd/phpmd", + "version": "2.13.0", + "source": { + "type": "git", + "url": "https://github.com/phpmd/phpmd.git", + "reference": "dad0228156856b3ad959992f9748514fa943f3e3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/dad0228156856b3ad959992f9748514fa943f3e3", + "reference": "dad0228156856b3ad959992f9748514fa943f3e3", + "shasum": "" + }, + "require": { + "composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0", + "ext-xml": "*", + "pdepend/pdepend": "^2.12.1", + "php": ">=5.3.9" + }, + "require-dev": { + "easy-doc/easy-doc": "0.0.0 || ^1.3.2", + "ext-json": "*", + "ext-simplexml": "*", + "gregwar/rst": "^1.0", + "mikey179/vfsstream": "^1.6.8", + "phpunit/phpunit": "^4.8.36 || ^5.7.27", + "squizlabs/php_codesniffer": "^2.0" + }, + "bin": [ + "src/bin/phpmd" + ], + "type": "library", + "autoload": { + "psr-0": { + "PHPMD\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Manuel Pichler", + "email": "github@manuel-pichler.de", + "homepage": "https://github.com/manuelpichler", + "role": "Project Founder" + }, + { + "name": "Marc Würth", + "email": "ravage@bluewin.ch", + "homepage": "https://github.com/ravage84", + "role": "Project Maintainer" + }, + { + "name": "Other contributors", + "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", + "role": "Contributors" + } + ], + "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", + "homepage": "https://phpmd.org/", + "keywords": [ + "mess detection", + "mess detector", + "pdepend", + "phpmd", + "pmd" + ], + "support": { + "irc": "irc://irc.freenode.org/phpmd", + "issues": "https://github.com/phpmd/phpmd/issues", + "source": "https://github.com/phpmd/phpmd/tree/2.13.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/phpmd/phpmd", + "type": "tidelift" + } + ], + "time": "2022-09-10T08:44:15+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "symfony/config", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "a5e00dec161b08c946a2c16eed02adbeedf827ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/a5e00dec161b08c946a2c16eed02adbeedf827ae", + "reference": "a5e00dec161b08c946a2c16eed02adbeedf827ae", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^5.4|^6.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "require-dev": { + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/messenger": "^5.4|^6.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-04-25T10:46:17+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "ebf5f9c5bb5c21d75ab74995ce5e26c3fbbda44d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ebf5f9c5bb5c21d75ab74995ce5e26c3fbbda44d", + "reference": "ebf5f9c5bb5c21d75ab74995ce5e26c3fbbda44d", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.2.10" + }, + "conflict": { + "ext-psr": "<1.1|>=2", + "symfony/config": "<6.1", + "symfony/finder": "<5.4", + "symfony/proxy-manager-bridge": "<6.3", + "symfony/yaml": "<5.4" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "symfony/service-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "symfony/config": "^6.1", + "symfony/expression-language": "^5.4|^6.0", + "symfony/yaml": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows you to standardize and centralize the way objects are constructed in your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-30T17:12:32+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "97b698e1d77d356304def77a8d0cd73090b359ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/97b698e1d77d356304def77a8d0cd73090b359ea", + "reference": "97b698e1d77d356304def77a8d0cd73090b359ea", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-30T17:12:32+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "db5416d04269f2827d8c54331ba4cfa42620d350" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/db5416d04269f2827d8c54331ba4cfa42620d350", + "reference": "db5416d04269f2827d8c54331ba4cfa42620d350", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/var-dumper": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-04-21T08:48:44+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/.ci/phpmd/phpmd.xml b/.ci/phpmd/phpmd.xml new file mode 100644 index 0000000000..791de491ec --- /dev/null +++ b/.ci/phpmd/phpmd.xml @@ -0,0 +1,52 @@ + + + Bla bla + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.env.example b/.env.example index 71dd938bf4..a634e37ac0 100644 --- a/.env.example +++ b/.env.example @@ -143,6 +143,7 @@ MAIL_FROM=changeme@example.com MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null +MAIL_SENDMAIL_COMMAND= # Other mail drivers: # If you use Docker or similar, you can set these variables from a file by appending them with _FILE diff --git a/.github/code_of_conduct.md b/.github/code_of_conduct.md index 61940de18d..fda4ed7d13 100644 --- a/.github/code_of_conduct.md +++ b/.github/code_of_conduct.md @@ -2,7 +2,10 @@ ## Our Pledge -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making +participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, +disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, +religion, or sexual identity and orientation. ## Our Standards @@ -24,23 +27,35 @@ Examples of unacceptable behavior by participants include: ## Our Responsibilities -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take +appropriate and fair corrective action in response to any instances of unacceptable behavior. -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, +issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the +project or its community. Examples of representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed representative at an online or offline +event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at james@firefly-iii.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at +james@firefly-iii.org. The project team will review and investigate all complaints, and will respond in a way that it +deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the +reporter of an incident. Further details of specific enforcement policies may be posted separately. -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent +repercussions as determined by other members of the project's leadership. ## Attribution -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available +at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org + [version]: http://contributor-covenant.org/version/1/4/ diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 557d6df1e7..50269b374b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,7 +5,7 @@ updates: - package-ecosystem: "composer" directory: "/" # Location of package manifests target-branch: develop - labels: ["bug"] + labels: [ "bug" ] versioning-strategy: increase schedule: interval: "weekly" @@ -14,15 +14,15 @@ updates: - package-ecosystem: "npm" directory: "/" target-branch: develop - labels: ["bug"] + labels: [ "bug" ] versioning-strategy: increase schedule: interval: "weekly" - package-ecosystem: "github-actions" - directory: "/" + directory: "/" target-branch: develop - labels: ["bug"] + labels: [ "bug" ] versioning-strategy: increase schedule: interval: "weekly" diff --git a/.github/its_you_not_me.md b/.github/its_you_not_me.md index e9fc163ce4..67ffa425c1 100644 --- a/.github/its_you_not_me.md +++ b/.github/its_you_not_me.md @@ -2,9 +2,11 @@ Sometimes bugs reported to Firefly III are configuration and system problems on the user's side. -If you run into any of the following problems, there's a good chance it's not a Firefly III issue, but a configuration issue. +If you run into any of the following problems, there's a good chance it's not a Firefly III issue, but a configuration +issue. -- ⚠️ Firefly III can't connect to the database when starting or the password is wrong, even though you're sure it's correct. +- ⚠️ Firefly III can't connect to the database when starting or the password is wrong, even though you're sure it's + correct. - ⚠️ Errors about a missing `APP_KEY` or other encryption/hash problems - ⚠️ You can't login due to `419` errors (page expired) - ⚠️ Any `500` error when starting Firefly III @@ -13,4 +15,6 @@ If you run into any of the following problems, there's a good chance it's not a - ⚠️ Firefly III does not work behind your reverse proxy - ⚠️ You can't connect to the Data Importer due to 404's or authentication issues. -If you run into an issue like this, please start a [discussion](https://github.com/firefly-iii/firefly-iii/discussions) or chat on [Gitter.im](https://gitter.im/firefly-iii/firefly-iii). There's a good chance it's not a bug but something we can fix rather quickly :+1: +If you run into an issue like this, please start a [discussion](https://github.com/firefly-iii/firefly-iii/discussions) +or chat on [Gitter.im](https://gitter.im/firefly-iii/firefly-iii). There's a good chance it's not a bug but something we +can fix rather quickly :+1: diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4fa394e86e..4ffd6e4395 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -11,8 +11,8 @@ Fixes issue # (if relevant) Changes in this pull request: -- -- -- +- +- +- @JC5 diff --git a/.github/support.md b/.github/support.md index 24296ab50c..80e4b99ad8 100644 --- a/.github/support.md +++ b/.github/support.md @@ -4,12 +4,13 @@ ## Reporting an issue -First of all: thank you for reporting a bug instead of ditching the tool altogether. Bugs have a lot of priority! +First of all: thank you for reporting a bug instead of ditching the tool altogether. Bugs have a lot of priority! 1. Open bugs will have open issues, so search for one first. 2. If your feature request is already there, vote on it with :+1: or :-1: reactions. 3. Do NOT hijack old issues with the bug you found, open your own issue. -4. If relevant, take the time and see if the [demo site](https://demo.firefly-iii.org/) is also suffering from your issue. +4. If relevant, take the time and see if the [demo site](https://demo.firefly-iii.org/) is also suffering from your + issue. 5. If relevant, read the [documentation](https://docs.firefly-iii.org/). Please follow these guidelines when opening new issues: @@ -25,7 +26,8 @@ Only then [create a new issue](https://github.com/firefly-iii/firefly-iii/issues ## Issue closure and abandonment policy - Issues can be converted into discussions if it's not a bug or feature request. -- Features that won't be implemented will be labelled "wontfix". [This isn't personal](https://docs.firefly-iii.org/firefly-iii/about-firefly-iii/what-its-not/). +- Features that won't be implemented will be labelled " + wontfix". [This isn't personal](https://docs.firefly-iii.org/firefly-iii/about-firefly-iii/what-its-not/). - Issues can be closed if they're duplicates of other issues. - Issues can be closed if the answer is in the FAQ. - Issues will be closed automatically after 14 days. diff --git a/.github/workflows/closed-issues.yml b/.github/workflows/closed-issues.yml index 6e803648c2..8decb5667a 100644 --- a/.github/workflows/closed-issues.yml +++ b/.github/workflows/closed-issues.yml @@ -7,17 +7,16 @@ jobs: auto_comment: runs-on: ubuntu-latest steps: - - - uses: aws-actions/closed-issue-message@v1 + - uses: aws-actions/closed-issue-message@v1 with: message: | - Hi there! This is an automatic reply. `Share and enjoy` - - This issue is now 🔒 closed. Please be aware that closed issues are **not** watched. - - - If the original bug is not actually fixed, please feel free to open [a new issue](https://github.com/firefly-iii/firefly-iii/issues/new/choose). Please refer to this issue for clarity. - - Follow-up questions must be posted in a new [discussion](https://github.com/firefly-iii/firefly-iii/discussions/) - - Further replies to this issue will get **no response**. - - Thank you for your contributions. + Hi there! This is an automatic reply. `Share and enjoy` + + This issue is now 🔒 closed. Please be aware that closed issues are **not** watched. + + - If the original bug is not actually fixed, please feel free to open [a new issue](https://github.com/firefly-iii/firefly-iii/issues/new/choose). Please refer to this issue for clarity. + - Follow-up questions must be posted in a new [discussion](https://github.com/firefly-iii/firefly-iii/discussions/) + - Further replies to this issue will get **no response**. + + Thank you for your contributions. repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/depsreview.yaml b/.github/workflows/depsreview.yaml index da99d0c548..d5ed859514 100644 --- a/.github/workflows/depsreview.yaml +++ b/.github/workflows/depsreview.yaml @@ -1,5 +1,5 @@ name: 'Dependency Review' -on: [pull_request] +on: [ pull_request ] permissions: contents: read diff --git a/app/Api/V1/Controllers/Autocomplete/AccountController.php b/app/Api/V1/Controllers/Autocomplete/AccountController.php index 07ec75799c..8847b8ff4b 100644 --- a/app/Api/V1/Controllers/Autocomplete/AccountController.php +++ b/app/Api/V1/Controllers/Autocomplete/AccountController.php @@ -67,7 +67,7 @@ class AccountController extends Controller * Documentation for this endpoint: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getAccountsAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse * @throws JsonException diff --git a/app/Api/V1/Controllers/Autocomplete/BillController.php b/app/Api/V1/Controllers/Autocomplete/BillController.php index b9e0894fec..88656746d8 100644 --- a/app/Api/V1/Controllers/Autocomplete/BillController.php +++ b/app/Api/V1/Controllers/Autocomplete/BillController.php @@ -60,7 +60,7 @@ class BillController extends Controller * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getBillsAC * TODO expand API to add active field. * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Autocomplete/BudgetController.php b/app/Api/V1/Controllers/Autocomplete/BudgetController.php index db69b6e4ee..61bb6a82b9 100644 --- a/app/Api/V1/Controllers/Autocomplete/BudgetController.php +++ b/app/Api/V1/Controllers/Autocomplete/BudgetController.php @@ -59,7 +59,7 @@ class BudgetController extends Controller * Documentation for this endpoint is at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getBudgetsAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Autocomplete/CategoryController.php b/app/Api/V1/Controllers/Autocomplete/CategoryController.php index 957ec7fd14..1abd086dac 100644 --- a/app/Api/V1/Controllers/Autocomplete/CategoryController.php +++ b/app/Api/V1/Controllers/Autocomplete/CategoryController.php @@ -59,7 +59,7 @@ class CategoryController extends Controller * Documentation for this endpoint is at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getCategoriesAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Autocomplete/CurrencyController.php b/app/Api/V1/Controllers/Autocomplete/CurrencyController.php index c287191a23..e46a477034 100644 --- a/app/Api/V1/Controllers/Autocomplete/CurrencyController.php +++ b/app/Api/V1/Controllers/Autocomplete/CurrencyController.php @@ -59,7 +59,7 @@ class CurrencyController extends Controller * Documentation for this endpoint is at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getCurrenciesAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ @@ -87,7 +87,7 @@ class CurrencyController extends Controller * Documentation for this endpoint is at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getCurrenciesCodeAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse * @deprecated diff --git a/app/Api/V1/Controllers/Autocomplete/ObjectGroupController.php b/app/Api/V1/Controllers/Autocomplete/ObjectGroupController.php index f0a206e4a7..6ad068c28d 100644 --- a/app/Api/V1/Controllers/Autocomplete/ObjectGroupController.php +++ b/app/Api/V1/Controllers/Autocomplete/ObjectGroupController.php @@ -59,7 +59,7 @@ class ObjectGroupController extends Controller * Documentation for this endpoint is at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getObjectGroupsAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php b/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php index 2cfeb90ac0..8bcbc216c8 100644 --- a/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php +++ b/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php @@ -63,7 +63,7 @@ class PiggyBankController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getPiggiesAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ @@ -98,7 +98,7 @@ class PiggyBankController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getPiggiesBalanceAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Autocomplete/RecurrenceController.php b/app/Api/V1/Controllers/Autocomplete/RecurrenceController.php index 1065b9ea1a..a209d6934c 100644 --- a/app/Api/V1/Controllers/Autocomplete/RecurrenceController.php +++ b/app/Api/V1/Controllers/Autocomplete/RecurrenceController.php @@ -57,7 +57,7 @@ class RecurrenceController extends Controller * This endpoint is documented at: * * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getRecurringAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Autocomplete/RuleController.php b/app/Api/V1/Controllers/Autocomplete/RuleController.php index 4a8c503d10..2cc3acd57b 100644 --- a/app/Api/V1/Controllers/Autocomplete/RuleController.php +++ b/app/Api/V1/Controllers/Autocomplete/RuleController.php @@ -56,7 +56,7 @@ class RuleController extends Controller * This endpoint is documented at: * * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getRulesAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Autocomplete/RuleGroupController.php b/app/Api/V1/Controllers/Autocomplete/RuleGroupController.php index 249c971faa..f5e69f793a 100644 --- a/app/Api/V1/Controllers/Autocomplete/RuleGroupController.php +++ b/app/Api/V1/Controllers/Autocomplete/RuleGroupController.php @@ -56,7 +56,7 @@ class RuleGroupController extends Controller * This endpoint is documented at: * * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getRuleGroupsAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Autocomplete/TagController.php b/app/Api/V1/Controllers/Autocomplete/TagController.php index 4e80ce5531..8b2a442de8 100644 --- a/app/Api/V1/Controllers/Autocomplete/TagController.php +++ b/app/Api/V1/Controllers/Autocomplete/TagController.php @@ -59,7 +59,7 @@ class TagController extends Controller * This endpoint is documented at: * * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTagAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Autocomplete/TransactionController.php b/app/Api/V1/Controllers/Autocomplete/TransactionController.php index fe8a5a2099..5d5cb94daf 100644 --- a/app/Api/V1/Controllers/Autocomplete/TransactionController.php +++ b/app/Api/V1/Controllers/Autocomplete/TransactionController.php @@ -64,7 +64,7 @@ class TransactionController extends Controller * This endpoint is documented at: * * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTransactionsAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ @@ -94,7 +94,7 @@ class TransactionController extends Controller * This endpoint is documented at: * * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTransactionsIDAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Autocomplete/TransactionTypeController.php b/app/Api/V1/Controllers/Autocomplete/TransactionTypeController.php index 84b7efc5e4..88d636c905 100644 --- a/app/Api/V1/Controllers/Autocomplete/TransactionTypeController.php +++ b/app/Api/V1/Controllers/Autocomplete/TransactionTypeController.php @@ -55,7 +55,7 @@ class TransactionTypeController extends Controller * This endpoint is documented at * * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTransactionTypesAC * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Chart/AccountController.php b/app/Api/V1/Controllers/Chart/AccountController.php index c14ee1843b..5c554c17f2 100644 --- a/app/Api/V1/Controllers/Chart/AccountController.php +++ b/app/Api/V1/Controllers/Chart/AccountController.php @@ -76,7 +76,7 @@ class AccountController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/charts/getChartAccountOverview * - * @param DateRequest $request + * @param DateRequest $request * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Controller.php b/app/Api/V1/Controllers/Controller.php index d0c534b167..e3cb350469 100644 --- a/app/Api/V1/Controllers/Controller.php +++ b/app/Api/V1/Controllers/Controller.php @@ -74,42 +74,6 @@ abstract class Controller extends BaseController ); } - /** - * Method to help build URL's. - * - * @return string - */ - final protected function buildParams(): string - { - $return = '?'; - $params = []; - foreach ($this->parameters as $key => $value) { - if ('page' === $key) { - continue; - } - if ($value instanceof Carbon) { - $params[$key] = $value->format('Y-m-d'); - continue; - } - $params[$key] = $value; - } - - return $return.http_build_query($params); - } - - /** - * @return Manager - */ - final protected function getManager(): Manager - { - // create some objects: - $manager = new Manager(); - $baseUrl = request()->getSchemeAndHttpHost().'/api/v1'; - $manager->setSerializer(new JsonApiSerializer($baseUrl)); - - return $manager; - } - /** * Method to grab all parameters from the URL. * @@ -144,7 +108,7 @@ abstract class Controller extends BaseController if (null !== $date) { try { $obj = Carbon::parse($date); - } catch (InvalidDateException|InvalidFormatException $e) { + } catch (InvalidDateException | InvalidFormatException $e) { // don't care app('log')->warning( sprintf( @@ -178,7 +142,7 @@ abstract class Controller extends BaseController } /** - * @param ParameterBag $bag + * @param ParameterBag $bag * * @return ParameterBag */ @@ -211,4 +175,40 @@ abstract class Controller extends BaseController return $bag; } + + /** + * Method to help build URL's. + * + * @return string + */ + final protected function buildParams(): string + { + $return = '?'; + $params = []; + foreach ($this->parameters as $key => $value) { + if ('page' === $key) { + continue; + } + if ($value instanceof Carbon) { + $params[$key] = $value->format('Y-m-d'); + continue; + } + $params[$key] = $value; + } + + return $return . http_build_query($params); + } + + /** + * @return Manager + */ + final protected function getManager(): Manager + { + // create some objects: + $manager = new Manager(); + $baseUrl = request()->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + + return $manager; + } } diff --git a/app/Api/V1/Controllers/Data/Bulk/TransactionController.php b/app/Api/V1/Controllers/Data/Bulk/TransactionController.php index ff4528fe82..56afbde1cd 100644 --- a/app/Api/V1/Controllers/Data/Bulk/TransactionController.php +++ b/app/Api/V1/Controllers/Data/Bulk/TransactionController.php @@ -64,7 +64,7 @@ class TransactionController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/bulkUpdateTransactions * - * @param TransactionRequest $request + * @param TransactionRequest $request * * @return JsonResponse */ @@ -89,7 +89,7 @@ class TransactionController extends Controller } /** - * @param array $params + * @param array $params * * @return bool */ diff --git a/app/Api/V1/Controllers/Data/DestroyController.php b/app/Api/V1/Controllers/Data/DestroyController.php index b5dda35ef6..fa4ced9fb3 100644 --- a/app/Api/V1/Controllers/Data/DestroyController.php +++ b/app/Api/V1/Controllers/Data/DestroyController.php @@ -58,7 +58,7 @@ class DestroyController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/destroyData * - * @param DestroyRequest $request + * @param DestroyRequest $request * * @return JsonResponse * @throws FireflyException @@ -202,7 +202,92 @@ class DestroyController extends Controller } /** - * @param array $types + * + */ + private function destroyBudgets(): void + { + /** @var AvailableBudgetRepositoryInterface $abRepository */ + $abRepository = app(AvailableBudgetRepositoryInterface::class); + $abRepository->destroyAll(); + + /** @var BudgetLimitRepositoryInterface $blRepository */ + $blRepository = app(BudgetLimitRepositoryInterface::class); + $blRepository->destroyAll(); + + /** @var BudgetRepositoryInterface $budgetRepository */ + $budgetRepository = app(BudgetRepositoryInterface::class); + $budgetRepository->destroyAll(); + } + + /** + * + */ + private function destroyBills(): void + { + /** @var BillRepositoryInterface $repository */ + $repository = app(BillRepositoryInterface::class); + $repository->destroyAll(); + } + + /** + * + */ + private function destroyPiggyBanks(): void + { + /** @var PiggyBankRepositoryInterface $repository */ + $repository = app(PiggyBankRepositoryInterface::class); + $repository->destroyAll(); + } + + /** + * + */ + private function destroyRules(): void + { + /** @var RuleGroupRepositoryInterface $repository */ + $repository = app(RuleGroupRepositoryInterface::class); + $repository->destroyAll(); + } + + /** + * + */ + private function destroyRecurringTransactions(): void + { + /** @var RecurringRepositoryInterface $repository */ + $repository = app(RecurringRepositoryInterface::class); + $repository->destroyAll(); + } + + /** + * + */ + private function destroyCategories(): void + { + /** @var CategoryRepositoryInterface $categoryRepos */ + $categoryRepos = app(CategoryRepositoryInterface::class); + $categoryRepos->destroyAll(); + } + + /** + * + */ + private function destroyTags(): void + { + /** @var TagRepositoryInterface $tagRepository */ + $tagRepository = app(TagRepositoryInterface::class); + $tagRepository->destroyAll(); + } + + private function destroyObjectGroups(): void + { + /** @var ObjectGroupRepositoryInterface $repository */ + $repository = app(ObjectGroupRepositoryInterface::class); + $repository->deleteAll(); + } + + /** + * @param array $types */ private function destroyAccounts(array $types): void { @@ -227,92 +312,7 @@ class DestroyController extends Controller } /** - * - */ - private function destroyBills(): void - { - /** @var BillRepositoryInterface $repository */ - $repository = app(BillRepositoryInterface::class); - $repository->destroyAll(); - } - - /** - * - */ - private function destroyBudgets(): void - { - /** @var AvailableBudgetRepositoryInterface $abRepository */ - $abRepository = app(AvailableBudgetRepositoryInterface::class); - $abRepository->destroyAll(); - - /** @var BudgetLimitRepositoryInterface $blRepository */ - $blRepository = app(BudgetLimitRepositoryInterface::class); - $blRepository->destroyAll(); - - /** @var BudgetRepositoryInterface $budgetRepository */ - $budgetRepository = app(BudgetRepositoryInterface::class); - $budgetRepository->destroyAll(); - } - - /** - * - */ - private function destroyCategories(): void - { - /** @var CategoryRepositoryInterface $categoryRepos */ - $categoryRepos = app(CategoryRepositoryInterface::class); - $categoryRepos->destroyAll(); - } - - private function destroyObjectGroups(): void - { - /** @var ObjectGroupRepositoryInterface $repository */ - $repository = app(ObjectGroupRepositoryInterface::class); - $repository->deleteAll(); - } - - /** - * - */ - private function destroyPiggyBanks(): void - { - /** @var PiggyBankRepositoryInterface $repository */ - $repository = app(PiggyBankRepositoryInterface::class); - $repository->destroyAll(); - } - - /** - * - */ - private function destroyRecurringTransactions(): void - { - /** @var RecurringRepositoryInterface $repository */ - $repository = app(RecurringRepositoryInterface::class); - $repository->destroyAll(); - } - - /** - * - */ - private function destroyRules(): void - { - /** @var RuleGroupRepositoryInterface $repository */ - $repository = app(RuleGroupRepositoryInterface::class); - $repository->destroyAll(); - } - - /** - * - */ - private function destroyTags(): void - { - /** @var TagRepositoryInterface $tagRepository */ - $tagRepository = app(TagRepositoryInterface::class); - $tagRepository->destroyAll(); - } - - /** - * @param array $types + * @param array $types */ private function destroyTransactions(array $types): void { diff --git a/app/Api/V1/Controllers/Data/Export/ExportController.php b/app/Api/V1/Controllers/Data/Export/ExportController.php index 2949be621d..ce36ca292f 100644 --- a/app/Api/V1/Controllers/Data/Export/ExportController.php +++ b/app/Api/V1/Controllers/Data/Export/ExportController.php @@ -57,7 +57,7 @@ class ExportController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportAccounts * - * @param ExportRequest $request + * @param ExportRequest $request * * @return LaravelResponse * @throws FireflyException @@ -70,139 +70,7 @@ class ExportController extends Controller } /** - * This endpoint is documented at: - * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportBills - * - * @param ExportRequest $request - * - * @return LaravelResponse - * @throws FireflyException - */ - public function bills(ExportRequest $request): LaravelResponse - { - $this->exporter->setExportBills(true); - - return $this->returnExport('bills'); - } - - /** - * This endpoint is documented at: - * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportBudgets - * - * @param ExportRequest $request - * - * @return LaravelResponse - * @throws FireflyException - */ - public function budgets(ExportRequest $request): LaravelResponse - { - $this->exporter->setExportBudgets(true); - - return $this->returnExport('budgets'); - } - - /** - * This endpoint is documented at: - * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportCategories - * - * @param ExportRequest $request - * - * @return LaravelResponse - * @throws FireflyException - */ - public function categories(ExportRequest $request): LaravelResponse - { - $this->exporter->setExportCategories(true); - - return $this->returnExport('categories'); - } - - /** - * This endpoint is documented at: - * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportPiggies - * - * @param ExportRequest $request - * - * @return LaravelResponse - * @throws FireflyException - */ - public function piggyBanks(ExportRequest $request): LaravelResponse - { - $this->exporter->setExportPiggies(true); - - return $this->returnExport('piggies'); - } - - /** - * This endpoint is documented at: - * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportRecurring - * - * @param ExportRequest $request - * - * @return LaravelResponse - * @throws FireflyException - */ - public function recurring(ExportRequest $request): LaravelResponse - { - $this->exporter->setExportRecurring(true); - - return $this->returnExport('recurrences'); - } - - /** - * This endpoint is documented at: - * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportRules - * - * @param ExportRequest $request - * - * @return LaravelResponse - * @throws FireflyException - */ - public function rules(ExportRequest $request): LaravelResponse - { - $this->exporter->setExportRules(true); - - return $this->returnExport('rules'); - } - - /** - * This endpoint is documented at: - * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportTags - * - * @param ExportRequest $request - * - * @return LaravelResponse - * @throws FireflyException - */ - public function tags(ExportRequest $request): LaravelResponse - { - $this->exporter->setExportTags(true); - - return $this->returnExport('tags'); - } - - /** - * This endpoint is documented at: - * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportTransactions - * - * @param ExportRequest $request - * - * @return LaravelResponse - * @throws FireflyException - */ - public function transactions(ExportRequest $request): LaravelResponse - { - $params = $request->getAll(); - $this->exporter->setStart($params['start']); - $this->exporter->setEnd($params['end']); - $this->exporter->setAccounts($params['accounts']); - $this->exporter->setExportTransactions(true); - - return $this->returnExport('transactions'); - } - - /** - * @param string $key + * @param string $key * * @return LaravelResponse * @throws FireflyException @@ -218,7 +86,7 @@ class ExportController extends Controller $response ->header('Content-Description', 'File Transfer') ->header('Content-Type', 'application/octet-stream') - ->header('Content-Disposition', 'attachment; filename='.$fileName) + ->header('Content-Disposition', 'attachment; filename=' . $fileName) ->header('Content-Transfer-Encoding', 'binary') ->header('Connection', 'Keep-Alive') ->header('Expires', '0') @@ -228,4 +96,136 @@ class ExportController extends Controller return $response; } + + /** + * This endpoint is documented at: + * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportBills + * + * @param ExportRequest $request + * + * @return LaravelResponse + * @throws FireflyException + */ + public function bills(ExportRequest $request): LaravelResponse + { + $this->exporter->setExportBills(true); + + return $this->returnExport('bills'); + } + + /** + * This endpoint is documented at: + * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportBudgets + * + * @param ExportRequest $request + * + * @return LaravelResponse + * @throws FireflyException + */ + public function budgets(ExportRequest $request): LaravelResponse + { + $this->exporter->setExportBudgets(true); + + return $this->returnExport('budgets'); + } + + /** + * This endpoint is documented at: + * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportCategories + * + * @param ExportRequest $request + * + * @return LaravelResponse + * @throws FireflyException + */ + public function categories(ExportRequest $request): LaravelResponse + { + $this->exporter->setExportCategories(true); + + return $this->returnExport('categories'); + } + + /** + * This endpoint is documented at: + * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportPiggies + * + * @param ExportRequest $request + * + * @return LaravelResponse + * @throws FireflyException + */ + public function piggyBanks(ExportRequest $request): LaravelResponse + { + $this->exporter->setExportPiggies(true); + + return $this->returnExport('piggies'); + } + + /** + * This endpoint is documented at: + * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportRecurring + * + * @param ExportRequest $request + * + * @return LaravelResponse + * @throws FireflyException + */ + public function recurring(ExportRequest $request): LaravelResponse + { + $this->exporter->setExportRecurring(true); + + return $this->returnExport('recurrences'); + } + + /** + * This endpoint is documented at: + * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportRules + * + * @param ExportRequest $request + * + * @return LaravelResponse + * @throws FireflyException + */ + public function rules(ExportRequest $request): LaravelResponse + { + $this->exporter->setExportRules(true); + + return $this->returnExport('rules'); + } + + /** + * This endpoint is documented at: + * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportTags + * + * @param ExportRequest $request + * + * @return LaravelResponse + * @throws FireflyException + */ + public function tags(ExportRequest $request): LaravelResponse + { + $this->exporter->setExportTags(true); + + return $this->returnExport('tags'); + } + + /** + * This endpoint is documented at: + * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportTransactions + * + * @param ExportRequest $request + * + * @return LaravelResponse + * @throws FireflyException + */ + public function transactions(ExportRequest $request): LaravelResponse + { + $params = $request->getAll(); + $this->exporter->setStart($params['start']); + $this->exporter->setEnd($params['end']); + $this->exporter->setAccounts($params['accounts']); + $this->exporter->setExportTransactions(true); + + return $this->returnExport('transactions'); + } } diff --git a/app/Api/V1/Controllers/Insight/Expense/AccountController.php b/app/Api/V1/Controllers/Insight/Expense/AccountController.php index 12621a0f3a..ad9d660d5e 100644 --- a/app/Api/V1/Controllers/Insight/Expense/AccountController.php +++ b/app/Api/V1/Controllers/Insight/Expense/AccountController.php @@ -76,7 +76,7 @@ class AccountController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseAsset * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ @@ -107,7 +107,7 @@ class AccountController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseExpense * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Insight/Expense/BillController.php b/app/Api/V1/Controllers/Insight/Expense/BillController.php index 37e53893de..a584c55913 100644 --- a/app/Api/V1/Controllers/Insight/Expense/BillController.php +++ b/app/Api/V1/Controllers/Insight/Expense/BillController.php @@ -61,7 +61,7 @@ class BillController extends Controller * * Expenses per bill, possibly filtered by bill and account. * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ @@ -124,7 +124,7 @@ class BillController extends Controller * * Expenses for no bill filtered by account. * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Insight/Expense/BudgetController.php b/app/Api/V1/Controllers/Insight/Expense/BudgetController.php index 698c54470c..27e600482b 100644 --- a/app/Api/V1/Controllers/Insight/Expense/BudgetController.php +++ b/app/Api/V1/Controllers/Insight/Expense/BudgetController.php @@ -68,7 +68,7 @@ class BudgetController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseBudget * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ @@ -105,7 +105,7 @@ class BudgetController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseNoBudget * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Insight/Expense/CategoryController.php b/app/Api/V1/Controllers/Insight/Expense/CategoryController.php index 2f17ffe12e..b7972097f7 100644 --- a/app/Api/V1/Controllers/Insight/Expense/CategoryController.php +++ b/app/Api/V1/Controllers/Insight/Expense/CategoryController.php @@ -69,7 +69,7 @@ class CategoryController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferCategory * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ @@ -106,7 +106,7 @@ class CategoryController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferNoCategory * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Insight/Expense/PeriodController.php b/app/Api/V1/Controllers/Insight/Expense/PeriodController.php index 0814a1467c..eb583d0693 100644 --- a/app/Api/V1/Controllers/Insight/Expense/PeriodController.php +++ b/app/Api/V1/Controllers/Insight/Expense/PeriodController.php @@ -38,7 +38,7 @@ class PeriodController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseTotal * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Insight/Expense/TagController.php b/app/Api/V1/Controllers/Insight/Expense/TagController.php index 4101391089..9068f402f6 100644 --- a/app/Api/V1/Controllers/Insight/Expense/TagController.php +++ b/app/Api/V1/Controllers/Insight/Expense/TagController.php @@ -60,7 +60,7 @@ class TagController extends Controller * * Expenses for no tag filtered by account. * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ @@ -113,7 +113,7 @@ class TagController extends Controller * * Expenses per tag, possibly filtered by tag and account. * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Insight/Income/AccountController.php b/app/Api/V1/Controllers/Insight/Income/AccountController.php index 7b96bc9488..5d8aabc7f3 100644 --- a/app/Api/V1/Controllers/Insight/Income/AccountController.php +++ b/app/Api/V1/Controllers/Insight/Income/AccountController.php @@ -76,7 +76,7 @@ class AccountController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeAsset * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ @@ -106,7 +106,7 @@ class AccountController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeRevenue * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Insight/Income/CategoryController.php b/app/Api/V1/Controllers/Insight/Income/CategoryController.php index 762f2f5f84..f992540f1b 100644 --- a/app/Api/V1/Controllers/Insight/Income/CategoryController.php +++ b/app/Api/V1/Controllers/Insight/Income/CategoryController.php @@ -69,7 +69,7 @@ class CategoryController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeCategory * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ @@ -106,7 +106,7 @@ class CategoryController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeNoCategory * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Insight/Income/PeriodController.php b/app/Api/V1/Controllers/Insight/Income/PeriodController.php index 11f9ac967b..cff22e7cbb 100644 --- a/app/Api/V1/Controllers/Insight/Income/PeriodController.php +++ b/app/Api/V1/Controllers/Insight/Income/PeriodController.php @@ -38,7 +38,7 @@ class PeriodController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeTotal * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Insight/Income/TagController.php b/app/Api/V1/Controllers/Insight/Income/TagController.php index cad86cb2fb..87cb0bb4b3 100644 --- a/app/Api/V1/Controllers/Insight/Income/TagController.php +++ b/app/Api/V1/Controllers/Insight/Income/TagController.php @@ -61,7 +61,7 @@ class TagController extends Controller * * Expenses for no tag filtered by account. * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ @@ -117,7 +117,7 @@ class TagController extends Controller * * Expenses per tag, possibly filtered by tag and account. * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Insight/Transfer/AccountController.php b/app/Api/V1/Controllers/Insight/Transfer/AccountController.php index 3ce3081a2e..09d1fc2b8b 100644 --- a/app/Api/V1/Controllers/Insight/Transfer/AccountController.php +++ b/app/Api/V1/Controllers/Insight/Transfer/AccountController.php @@ -61,7 +61,7 @@ class AccountController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransfers * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Insight/Transfer/CategoryController.php b/app/Api/V1/Controllers/Insight/Transfer/CategoryController.php index 1071db8b1b..f88bb8dd75 100644 --- a/app/Api/V1/Controllers/Insight/Transfer/CategoryController.php +++ b/app/Api/V1/Controllers/Insight/Transfer/CategoryController.php @@ -68,7 +68,7 @@ class CategoryController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferCategory * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ @@ -105,7 +105,7 @@ class CategoryController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferNoCategory * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Insight/Transfer/PeriodController.php b/app/Api/V1/Controllers/Insight/Transfer/PeriodController.php index 6a0167296c..fc4a35a196 100644 --- a/app/Api/V1/Controllers/Insight/Transfer/PeriodController.php +++ b/app/Api/V1/Controllers/Insight/Transfer/PeriodController.php @@ -38,7 +38,7 @@ class PeriodController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferTotal * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Insight/Transfer/TagController.php b/app/Api/V1/Controllers/Insight/Transfer/TagController.php index 50f977f3fc..e880067197 100644 --- a/app/Api/V1/Controllers/Insight/Transfer/TagController.php +++ b/app/Api/V1/Controllers/Insight/Transfer/TagController.php @@ -58,7 +58,7 @@ class TagController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferNoTag * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ @@ -114,7 +114,7 @@ class TagController extends Controller * * Transfers per tag, possibly filtered by tag and account. * - * @param GenericRequest $request + * @param GenericRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Account/DestroyController.php b/app/Api/V1/Controllers/Models/Account/DestroyController.php index a665b0ac50..b157b011fd 100644 --- a/app/Api/V1/Controllers/Models/Account/DestroyController.php +++ b/app/Api/V1/Controllers/Models/Account/DestroyController.php @@ -61,7 +61,7 @@ class DestroyController extends Controller * * Remove the specified resource from storage. * - * @param Account $account + * @param Account $account * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Account/ListController.php b/app/Api/V1/Controllers/Models/Account/ListController.php index 859138c306..562b9c8d95 100644 --- a/app/Api/V1/Controllers/Models/Account/ListController.php +++ b/app/Api/V1/Controllers/Models/Account/ListController.php @@ -73,7 +73,7 @@ class ListController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/listAttachmentByAccount * - * @param Account $account + * @param Account $account * * @return JsonResponse * @throws FireflyException @@ -89,7 +89,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.accounts.attachments', [$account->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.accounts.attachments', [$account->id]) . $this->buildParams()); /** @var AttachmentTransformer $transformer */ $transformer = app(AttachmentTransformer::class); @@ -105,7 +105,7 @@ class ListController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/listPiggyBankByAccount * - * @param Account $account + * @param Account $account * * @return JsonResponse * @throws FireflyException @@ -125,7 +125,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.accounts.piggy-banks', [$account->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.accounts.piggy-banks', [$account->id]) . $this->buildParams()); /** @var PiggyBankTransformer $transformer */ $transformer = app(PiggyBankTransformer::class); @@ -144,8 +144,8 @@ class ListController extends Controller * Show all transaction groups related to the account. * * - * @param Request $request - * @param Account $account + * @param Request $request + * @param Account $account * * @return JsonResponse * @throws FireflyException @@ -177,7 +177,7 @@ class ListController extends Controller } $paginator = $collector->getPaginatedGroups(); - $paginator->setPath(route('api.v1.accounts.transactions', [$account->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.accounts.transactions', [$account->id]) . $this->buildParams()); $groups = $paginator->getCollection(); /** @var TransactionGroupTransformer $transformer */ diff --git a/app/Api/V1/Controllers/Models/Account/ShowController.php b/app/Api/V1/Controllers/Models/Account/ShowController.php index 31dea2c0a2..b3e7d75942 100644 --- a/app/Api/V1/Controllers/Models/Account/ShowController.php +++ b/app/Api/V1/Controllers/Models/Account/ShowController.php @@ -71,7 +71,7 @@ class ShowController extends Controller * * Display a listing of the resource. * - * @param Request $request + * @param Request $request * * @return JsonResponse * @throws FireflyException @@ -98,7 +98,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.accounts.index').$this->buildParams()); + $paginator->setPath(route('api.v1.accounts.index') . $this->buildParams()); /** @var AccountTransformer $transformer */ $transformer = app(AccountTransformer::class); @@ -116,7 +116,7 @@ class ShowController extends Controller * * Show single instance. * - * @param Account $account + * @param Account $account * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Account/StoreController.php b/app/Api/V1/Controllers/Models/Account/StoreController.php index 2ccdb5c267..cb49ece28f 100644 --- a/app/Api/V1/Controllers/Models/Account/StoreController.php +++ b/app/Api/V1/Controllers/Models/Account/StoreController.php @@ -63,7 +63,7 @@ class StoreController extends Controller * * Store a new instance. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Account/UpdateController.php b/app/Api/V1/Controllers/Models/Account/UpdateController.php index c80093adfe..1be3f42970 100644 --- a/app/Api/V1/Controllers/Models/Account/UpdateController.php +++ b/app/Api/V1/Controllers/Models/Account/UpdateController.php @@ -66,8 +66,8 @@ class UpdateController extends Controller * * Update account. * - * @param UpdateRequest $request - * @param Account $account + * @param UpdateRequest $request + * @param Account $account * * @return JsonResponse */ @@ -75,7 +75,7 @@ class UpdateController extends Controller { Log::debug(sprintf('Now in %s', __METHOD__)); $data = $request->getUpdateData(); - $data['type'] = config('firefly.shortNamesByFullName.'.$account->accountType->type); + $data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type); $account = $this->repository->update($account, $data); $manager = $this->getManager(); $account->refresh(); diff --git a/app/Api/V1/Controllers/Models/Attachment/DestroyController.php b/app/Api/V1/Controllers/Models/Attachment/DestroyController.php index 6037ce9a3f..ba81be4ecf 100644 --- a/app/Api/V1/Controllers/Models/Attachment/DestroyController.php +++ b/app/Api/V1/Controllers/Models/Attachment/DestroyController.php @@ -65,7 +65,7 @@ class DestroyController extends Controller * Remove the specified resource from storage. * * - * @param Attachment $attachment + * @param Attachment $attachment * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Attachment/ShowController.php b/app/Api/V1/Controllers/Models/Attachment/ShowController.php index 99ab07dc49..31dc2bfd93 100644 --- a/app/Api/V1/Controllers/Models/Attachment/ShowController.php +++ b/app/Api/V1/Controllers/Models/Attachment/ShowController.php @@ -71,7 +71,7 @@ class ShowController extends Controller * * Download an attachment. * - * @param Attachment $attachment + * @param Attachment $attachment * * @return LaravelResponse * @throws FireflyException @@ -96,7 +96,7 @@ class ShowController extends Controller $response ->header('Content-Description', 'File Transfer') ->header('Content-Type', 'application/octet-stream') - ->header('Content-Disposition', 'attachment; filename='.$quoted) + ->header('Content-Disposition', 'attachment; filename=' . $quoted) ->header('Content-Transfer-Encoding', 'binary') ->header('Connection', 'Keep-Alive') ->header('Expires', '0') @@ -132,7 +132,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.attachments.index').$this->buildParams()); + $paginator->setPath(route('api.v1.attachments.index') . $this->buildParams()); /** @var AttachmentTransformer $transformer */ $transformer = app(AttachmentTransformer::class); @@ -150,7 +150,7 @@ class ShowController extends Controller * * Display the specified resource. * - * @param Attachment $attachment + * @param Attachment $attachment * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Attachment/StoreController.php b/app/Api/V1/Controllers/Models/Attachment/StoreController.php index 6c56d46565..6eeb9160c6 100644 --- a/app/Api/V1/Controllers/Models/Attachment/StoreController.php +++ b/app/Api/V1/Controllers/Models/Attachment/StoreController.php @@ -71,7 +71,7 @@ class StoreController extends Controller * * Store a newly created resource in storage. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse * @throws FireflyException @@ -96,8 +96,8 @@ class StoreController extends Controller * Upload an attachment. * * - * @param Request $request - * @param Attachment $attachment + * @param Request $request + * @param Attachment $attachment * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Attachment/UpdateController.php b/app/Api/V1/Controllers/Models/Attachment/UpdateController.php index 2a9c6afdab..e50ce2cc80 100644 --- a/app/Api/V1/Controllers/Models/Attachment/UpdateController.php +++ b/app/Api/V1/Controllers/Models/Attachment/UpdateController.php @@ -67,8 +67,8 @@ class UpdateController extends Controller * * Update the specified resource in storage. * - * @param UpdateRequest $request - * @param Attachment $attachment + * @param UpdateRequest $request + * @param Attachment $attachment * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php b/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php index 69ad50f904..d122321e71 100644 --- a/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php +++ b/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php @@ -88,7 +88,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.available-budgets.index').$this->buildParams()); + $paginator->setPath(route('api.v1.available-budgets.index') . $this->buildParams()); /** @var AvailableBudgetTransformer $transformer */ $transformer = app(AvailableBudgetTransformer::class); @@ -106,7 +106,7 @@ class ShowController extends Controller * * Display the specified resource. * - * @param AvailableBudget $availableBudget + * @param AvailableBudget $availableBudget * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Bill/DestroyController.php b/app/Api/V1/Controllers/Models/Bill/DestroyController.php index 7fed9a0d6e..befa62ddc1 100644 --- a/app/Api/V1/Controllers/Models/Bill/DestroyController.php +++ b/app/Api/V1/Controllers/Models/Bill/DestroyController.php @@ -59,7 +59,7 @@ class DestroyController extends Controller * * Remove the specified resource from storage. * - * @param Bill $bill + * @param Bill $bill * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Bill/ListController.php b/app/Api/V1/Controllers/Models/Bill/ListController.php index d4a9702d29..1000ec433e 100644 --- a/app/Api/V1/Controllers/Models/Bill/ListController.php +++ b/app/Api/V1/Controllers/Models/Bill/ListController.php @@ -72,7 +72,7 @@ class ListController extends Controller * * Display a listing of the resource. * - * @param Bill $bill + * @param Bill $bill * * @return JsonResponse * @throws FireflyException @@ -88,7 +88,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.bills.attachments', [$bill->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.bills.attachments', [$bill->id]) . $this->buildParams()); /** @var AttachmentTransformer $transformer */ $transformer = app(AttachmentTransformer::class); @@ -106,7 +106,7 @@ class ListController extends Controller * * List all of them. * - * @param Bill $bill + * @param Bill $bill * * @return JsonResponse * @throws FireflyException @@ -125,7 +125,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.bills.rules', [$bill->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.bills.rules', [$bill->id]) . $this->buildParams()); /** @var RuleTransformer $transformer */ $transformer = app(RuleTransformer::class); @@ -142,9 +142,9 @@ class ListController extends Controller * * Show all transactions. * - * @param Request $request + * @param Request $request * - * @param Bill $bill + * @param Bill $bill * * @return JsonResponse * @throws FireflyException @@ -184,7 +184,7 @@ class ListController extends Controller // get paginator. $paginator = $collector->getPaginatedGroups(); - $paginator->setPath(route('api.v1.bills.transactions', [$bill->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.bills.transactions', [$bill->id]) . $this->buildParams()); $transactions = $paginator->getCollection(); /** @var TransactionGroupTransformer $transformer */ diff --git a/app/Api/V1/Controllers/Models/Bill/ShowController.php b/app/Api/V1/Controllers/Models/Bill/ShowController.php index f2d68fcdc8..a5bc503eed 100644 --- a/app/Api/V1/Controllers/Models/Bill/ShowController.php +++ b/app/Api/V1/Controllers/Models/Bill/ShowController.php @@ -94,7 +94,7 @@ class ShowController extends Controller * * Show the specified bill. * - * @param Bill $bill + * @param Bill $bill * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Bill/StoreController.php b/app/Api/V1/Controllers/Models/Bill/StoreController.php index 373f49851e..2a819f8912 100644 --- a/app/Api/V1/Controllers/Models/Bill/StoreController.php +++ b/app/Api/V1/Controllers/Models/Bill/StoreController.php @@ -65,7 +65,7 @@ class StoreController extends Controller * * Store a bill. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/Bill/UpdateController.php b/app/Api/V1/Controllers/Models/Bill/UpdateController.php index e249231510..e17e2945f9 100644 --- a/app/Api/V1/Controllers/Models/Bill/UpdateController.php +++ b/app/Api/V1/Controllers/Models/Bill/UpdateController.php @@ -62,8 +62,8 @@ class UpdateController extends Controller * * Update a bill. * - * @param UpdateRequest $request - * @param Bill $bill + * @param UpdateRequest $request + * @param Bill $bill * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Budget/DestroyController.php b/app/Api/V1/Controllers/Models/Budget/DestroyController.php index 30c3349e3a..8f6847aee9 100644 --- a/app/Api/V1/Controllers/Models/Budget/DestroyController.php +++ b/app/Api/V1/Controllers/Models/Budget/DestroyController.php @@ -59,7 +59,7 @@ class DestroyController extends Controller * * Remove the specified resource from storage. * - * @param Budget $budget + * @param Budget $budget * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Budget/ListController.php b/app/Api/V1/Controllers/Models/Budget/ListController.php index 9ee4c5a335..6f5ba252a8 100644 --- a/app/Api/V1/Controllers/Models/Budget/ListController.php +++ b/app/Api/V1/Controllers/Models/Budget/ListController.php @@ -74,7 +74,7 @@ class ListController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listAttachmentByBudget * - * @param Budget $budget + * @param Budget $budget * * @return JsonResponse * @throws FireflyException @@ -90,7 +90,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.budgets.attachments', [$budget->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.budgets.attachments', [$budget->id]) . $this->buildParams()); /** @var AttachmentTransformer $transformer */ $transformer = app(AttachmentTransformer::class); @@ -108,7 +108,7 @@ class ListController extends Controller * * Display a listing of the resource. * - * @param Budget $budget + * @param Budget $budget * * @return JsonResponse * @throws FireflyException @@ -122,7 +122,7 @@ class ListController extends Controller $count = $collection->count(); $budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); $paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.budgets.budget-limits', [$budget->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.budgets.budget-limits', [$budget->id]) . $this->buildParams()); /** @var BudgetLimitTransformer $transformer */ $transformer = app(BudgetLimitTransformer::class); @@ -139,9 +139,9 @@ class ListController extends Controller * * Show all transactions. * - * @param Request $request + * @param Request $request * - * @param Budget $budget + * @param Budget $budget * * @return JsonResponse * @throws FireflyException @@ -186,7 +186,7 @@ class ListController extends Controller } $paginator = $collector->getPaginatedGroups(); - $paginator->setPath(route('api.v1.budgets.transactions', [$budget->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.budgets.transactions', [$budget->id]) . $this->buildParams()); $transactions = $paginator->getCollection(); /** @var TransactionGroupTransformer $transformer */ @@ -204,7 +204,7 @@ class ListController extends Controller * * Show all transactions. * - * @param Request $request + * @param Request $request * * @return JsonResponse * @throws FireflyException @@ -249,7 +249,7 @@ class ListController extends Controller } $paginator = $collector->getPaginatedGroups(); - $paginator->setPath(route('api.v1.budgets.without-budget').$this->buildParams()); + $paginator->setPath(route('api.v1.budgets.without-budget') . $this->buildParams()); $transactions = $paginator->getCollection(); /** @var TransactionGroupTransformer $transformer */ diff --git a/app/Api/V1/Controllers/Models/Budget/ShowController.php b/app/Api/V1/Controllers/Models/Budget/ShowController.php index 0dd71f0518..02252caf35 100644 --- a/app/Api/V1/Controllers/Models/Budget/ShowController.php +++ b/app/Api/V1/Controllers/Models/Budget/ShowController.php @@ -86,7 +86,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($budgets, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.budgets.index').$this->buildParams()); + $paginator->setPath(route('api.v1.budgets.index') . $this->buildParams()); /** @var BudgetTransformer $transformer */ $transformer = app(BudgetTransformer::class); @@ -101,7 +101,7 @@ class ShowController extends Controller /** * Show a budget. * - * @param Budget $budget + * @param Budget $budget * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Budget/StoreController.php b/app/Api/V1/Controllers/Models/Budget/StoreController.php index cc413fc3d2..a70f823a9b 100644 --- a/app/Api/V1/Controllers/Models/Budget/StoreController.php +++ b/app/Api/V1/Controllers/Models/Budget/StoreController.php @@ -62,7 +62,7 @@ class StoreController extends Controller * * Store a budget. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/Budget/UpdateController.php b/app/Api/V1/Controllers/Models/Budget/UpdateController.php index c9e97f6dea..5836be33f1 100644 --- a/app/Api/V1/Controllers/Models/Budget/UpdateController.php +++ b/app/Api/V1/Controllers/Models/Budget/UpdateController.php @@ -62,8 +62,8 @@ class UpdateController extends Controller * * Update a budget. * - * @param UpdateRequest $request - * @param Budget $budget + * @param UpdateRequest $request + * @param Budget $budget * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/BudgetLimit/DestroyController.php b/app/Api/V1/Controllers/Models/BudgetLimit/DestroyController.php index 8d71493396..c459b1cee3 100644 --- a/app/Api/V1/Controllers/Models/BudgetLimit/DestroyController.php +++ b/app/Api/V1/Controllers/Models/BudgetLimit/DestroyController.php @@ -64,8 +64,8 @@ class DestroyController extends Controller * * Remove the specified resource from storage. * - * @param Budget $budget - * @param BudgetLimit $budgetLimit + * @param Budget $budget + * @param BudgetLimit $budgetLimit * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/BudgetLimit/ListController.php b/app/Api/V1/Controllers/Models/BudgetLimit/ListController.php index 58041013be..e006c95d7b 100644 --- a/app/Api/V1/Controllers/Models/BudgetLimit/ListController.php +++ b/app/Api/V1/Controllers/Models/BudgetLimit/ListController.php @@ -71,9 +71,9 @@ class ListController extends Controller * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listTransactionByBudgetLimit * Show all transactions. * - * @param Request $request - * @param Budget $budget - * @param BudgetLimit $budgetLimit + * @param Request $request + * @param Budget $budget + * @param BudgetLimit $budgetLimit * * @return JsonResponse * @throws FireflyException @@ -109,7 +109,7 @@ class ListController extends Controller $collector->setRange($budgetLimit->start_date, $budgetLimit->end_date); $collector->setTypes($types); $paginator = $collector->getPaginatedGroups(); - $paginator->setPath(route('api.v1.budgets.limits.transactions', [$budget->id, $budgetLimit->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.budgets.limits.transactions', [$budget->id, $budgetLimit->id]) . $this->buildParams()); $transactions = $paginator->getCollection(); /** @var TransactionGroupTransformer $transformer */ diff --git a/app/Api/V1/Controllers/Models/BudgetLimit/ShowController.php b/app/Api/V1/Controllers/Models/BudgetLimit/ShowController.php index 9ce3fcb602..365bc19dcd 100644 --- a/app/Api/V1/Controllers/Models/BudgetLimit/ShowController.php +++ b/app/Api/V1/Controllers/Models/BudgetLimit/ShowController.php @@ -75,8 +75,8 @@ class ShowController extends Controller * * Display a listing of the budget limits for this budget. * - * @param Request $request - * @param Budget $budget + * @param Request $request + * @param Budget $budget * * @return JsonResponse * @throws FireflyException @@ -90,7 +90,7 @@ class ShowController extends Controller $count = $collection->count(); $budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); $paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.budgets.limits.index', [$budget->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.budgets.limits.index', [$budget->id]) . $this->buildParams()); /** @var BudgetLimitTransformer $transformer */ $transformer = app(BudgetLimitTransformer::class); @@ -108,7 +108,7 @@ class ShowController extends Controller * * Display a listing of the budget limits for this budget. * - * @param SameDateRequest $request + * @param SameDateRequest $request * * @return JsonResponse * @throws FireflyException @@ -122,7 +122,7 @@ class ShowController extends Controller $count = $collection->count(); $budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); $paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.budget-limits.index').$this->buildParams()); + $paginator->setPath(route('api.v1.budget-limits.index') . $this->buildParams()); /** @var BudgetLimitTransformer $transformer */ $transformer = app(BudgetLimitTransformer::class); @@ -138,9 +138,9 @@ class ShowController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/getBudgetLimit * - * @param Request $request - * @param Budget $budget - * @param BudgetLimit $budgetLimit + * @param Request $request + * @param Budget $budget + * @param BudgetLimit $budgetLimit * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/BudgetLimit/StoreController.php b/app/Api/V1/Controllers/Models/BudgetLimit/StoreController.php index 8707b21ac7..3cb8d1858b 100644 --- a/app/Api/V1/Controllers/Models/BudgetLimit/StoreController.php +++ b/app/Api/V1/Controllers/Models/BudgetLimit/StoreController.php @@ -65,8 +65,8 @@ class StoreController extends Controller * * Store a newly created resource in storage. * - * @param StoreRequest $request - * @param Budget $budget + * @param StoreRequest $request + * @param Budget $budget * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/BudgetLimit/UpdateController.php b/app/Api/V1/Controllers/Models/BudgetLimit/UpdateController.php index 1ccbfbebbd..8cf724245d 100644 --- a/app/Api/V1/Controllers/Models/BudgetLimit/UpdateController.php +++ b/app/Api/V1/Controllers/Models/BudgetLimit/UpdateController.php @@ -69,9 +69,9 @@ class UpdateController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/updateBudgetLimit * - * @param UpdateRequest $request - * @param Budget $budget - * @param BudgetLimit $budgetLimit + * @param UpdateRequest $request + * @param Budget $budget + * @param BudgetLimit $budgetLimit * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/Category/DestroyController.php b/app/Api/V1/Controllers/Models/Category/DestroyController.php index 02952c8697..3e977e948d 100644 --- a/app/Api/V1/Controllers/Models/Category/DestroyController.php +++ b/app/Api/V1/Controllers/Models/Category/DestroyController.php @@ -59,7 +59,7 @@ class DestroyController extends Controller * * Remove the specified resource from storage. * - * @param Category $category + * @param Category $category * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Category/ListController.php b/app/Api/V1/Controllers/Models/Category/ListController.php index 1946f25a8d..16c2bfd4d2 100644 --- a/app/Api/V1/Controllers/Models/Category/ListController.php +++ b/app/Api/V1/Controllers/Models/Category/ListController.php @@ -69,7 +69,7 @@ class ListController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/categories/listAttachmentByCategory * - * @param Category $category + * @param Category $category * * @return JsonResponse * @throws FireflyException @@ -85,7 +85,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.categories.attachments', [$category->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.categories.attachments', [$category->id]) . $this->buildParams()); /** @var AttachmentTransformer $transformer */ $transformer = app(AttachmentTransformer::class); @@ -103,9 +103,9 @@ class ListController extends Controller * * Show all transactions. * - * @param Request $request + * @param Request $request * - * @param Category $category + * @param Category $category * * @return JsonResponse * @throws FireflyException @@ -143,7 +143,7 @@ class ListController extends Controller } $paginator = $collector->getPaginatedGroups(); - $paginator->setPath(route('api.v1.categories.transactions', [$category->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.categories.transactions', [$category->id]) . $this->buildParams()); $transactions = $paginator->getCollection(); /** @var TransactionGroupTransformer $transformer */ diff --git a/app/Api/V1/Controllers/Models/Category/ShowController.php b/app/Api/V1/Controllers/Models/Category/ShowController.php index 51ddcdbeec..01f328eff1 100644 --- a/app/Api/V1/Controllers/Models/Category/ShowController.php +++ b/app/Api/V1/Controllers/Models/Category/ShowController.php @@ -82,7 +82,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($categories, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.categories.index').$this->buildParams()); + $paginator->setPath(route('api.v1.categories.index') . $this->buildParams()); /** @var CategoryTransformer $transformer */ $transformer = app(CategoryTransformer::class); @@ -99,7 +99,7 @@ class ShowController extends Controller * * Show the category. * - * @param Category $category + * @param Category $category * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Category/StoreController.php b/app/Api/V1/Controllers/Models/Category/StoreController.php index 76d1b6b0e4..9ae15f6382 100644 --- a/app/Api/V1/Controllers/Models/Category/StoreController.php +++ b/app/Api/V1/Controllers/Models/Category/StoreController.php @@ -62,7 +62,7 @@ class StoreController extends Controller * * Store new category. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/Category/UpdateController.php b/app/Api/V1/Controllers/Models/Category/UpdateController.php index 95ce97598a..c5bf2f04f4 100644 --- a/app/Api/V1/Controllers/Models/Category/UpdateController.php +++ b/app/Api/V1/Controllers/Models/Category/UpdateController.php @@ -62,8 +62,8 @@ class UpdateController extends Controller * * Update the category. * - * @param UpdateRequest $request - * @param Category $category + * @param UpdateRequest $request + * @param Category $category * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/ObjectGroup/DestroyController.php b/app/Api/V1/Controllers/Models/ObjectGroup/DestroyController.php index fb31ca6d6d..d9da7ec3e9 100644 --- a/app/Api/V1/Controllers/Models/ObjectGroup/DestroyController.php +++ b/app/Api/V1/Controllers/Models/ObjectGroup/DestroyController.php @@ -62,7 +62,7 @@ class DestroyController extends Controller * * Remove the specified resource from storage. * - * @param ObjectGroup $objectGroup + * @param ObjectGroup $objectGroup * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/ObjectGroup/ListController.php b/app/Api/V1/Controllers/Models/ObjectGroup/ListController.php index 09e1e1b68d..10b96a4e93 100644 --- a/app/Api/V1/Controllers/Models/ObjectGroup/ListController.php +++ b/app/Api/V1/Controllers/Models/ObjectGroup/ListController.php @@ -68,7 +68,7 @@ class ListController extends Controller * * List all bills in this object group * - * @param ObjectGroup $objectGroup + * @param ObjectGroup $objectGroup * * @return JsonResponse * @throws FireflyException @@ -85,7 +85,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.currencies.bills', [$objectGroup->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.currencies.bills', [$objectGroup->id]) . $this->buildParams()); /** @var BillTransformer $transformer */ $transformer = app(BillTransformer::class); @@ -103,7 +103,7 @@ class ListController extends Controller * * List all piggies under the object group. * - * @param ObjectGroup $objectGroup + * @param ObjectGroup $objectGroup * * @return JsonResponse * @throws FireflyException @@ -123,7 +123,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.object-groups.piggy-banks', [$objectGroup->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.object-groups.piggy-banks', [$objectGroup->id]) . $this->buildParams()); /** @var PiggyBankTransformer $transformer */ $transformer = app(PiggyBankTransformer::class); diff --git a/app/Api/V1/Controllers/Models/ObjectGroup/ShowController.php b/app/Api/V1/Controllers/Models/ObjectGroup/ShowController.php index a6764b62b3..911f803b08 100644 --- a/app/Api/V1/Controllers/Models/ObjectGroup/ShowController.php +++ b/app/Api/V1/Controllers/Models/ObjectGroup/ShowController.php @@ -69,7 +69,7 @@ class ShowController extends Controller * * Display a listing of the resource. * - * @param Request $request + * @param Request $request * * @return JsonResponse * @throws FireflyException @@ -88,7 +88,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($objectGroups, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.object-groups.index').$this->buildParams()); + $paginator->setPath(route('api.v1.object-groups.index') . $this->buildParams()); /** @var ObjectGroupTransformer $transformer */ $transformer = app(ObjectGroupTransformer::class); @@ -106,7 +106,7 @@ class ShowController extends Controller * * Show single instance. * - * @param ObjectGroup $objectGroup + * @param ObjectGroup $objectGroup * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/ObjectGroup/UpdateController.php b/app/Api/V1/Controllers/Models/ObjectGroup/UpdateController.php index b1ba8f8cb7..21ebcbf6fc 100644 --- a/app/Api/V1/Controllers/Models/ObjectGroup/UpdateController.php +++ b/app/Api/V1/Controllers/Models/ObjectGroup/UpdateController.php @@ -63,8 +63,8 @@ class UpdateController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/object_groups/updateObjectGroup * - * @param UpdateRequest $request - * @param ObjectGroup $objectGroup + * @param UpdateRequest $request + * @param ObjectGroup $objectGroup * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/PiggyBank/DestroyController.php b/app/Api/V1/Controllers/Models/PiggyBank/DestroyController.php index d7995df2e4..6c1c4fd021 100644 --- a/app/Api/V1/Controllers/Models/PiggyBank/DestroyController.php +++ b/app/Api/V1/Controllers/Models/PiggyBank/DestroyController.php @@ -59,7 +59,7 @@ class DestroyController extends Controller * * Delete the resource. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/PiggyBank/ListController.php b/app/Api/V1/Controllers/Models/PiggyBank/ListController.php index 21bff011c3..8943791638 100644 --- a/app/Api/V1/Controllers/Models/PiggyBank/ListController.php +++ b/app/Api/V1/Controllers/Models/PiggyBank/ListController.php @@ -63,7 +63,7 @@ class ListController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listAttachmentByPiggyBank * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return JsonResponse * @throws FireflyException @@ -79,7 +79,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.piggy-banks.attachments', [$piggyBank->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.piggy-banks.attachments', [$piggyBank->id]) . $this->buildParams()); /** @var AttachmentTransformer $transformer */ $transformer = app(AttachmentTransformer::class); @@ -97,7 +97,7 @@ class ListController extends Controller * * List single resource. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return JsonResponse * @throws FireflyException @@ -114,7 +114,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($events, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.piggy-banks.events', [$piggyBank->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.piggy-banks.events', [$piggyBank->id]) . $this->buildParams()); /** @var PiggyBankEventTransformer $transformer */ $transformer = app(PiggyBankEventTransformer::class); diff --git a/app/Api/V1/Controllers/Models/PiggyBank/ShowController.php b/app/Api/V1/Controllers/Models/PiggyBank/ShowController.php index c2f72e1779..0c8e01e968 100644 --- a/app/Api/V1/Controllers/Models/PiggyBank/ShowController.php +++ b/app/Api/V1/Controllers/Models/PiggyBank/ShowController.php @@ -81,7 +81,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.piggy-banks.index').$this->buildParams()); + $paginator->setPath(route('api.v1.piggy-banks.index') . $this->buildParams()); /** @var PiggyBankTransformer $transformer */ $transformer = app(PiggyBankTransformer::class); @@ -99,7 +99,7 @@ class ShowController extends Controller * * List single resource. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/PiggyBank/StoreController.php b/app/Api/V1/Controllers/Models/PiggyBank/StoreController.php index 25850bb4d8..a29e0b03d8 100644 --- a/app/Api/V1/Controllers/Models/PiggyBank/StoreController.php +++ b/app/Api/V1/Controllers/Models/PiggyBank/StoreController.php @@ -62,7 +62,7 @@ class StoreController extends Controller * * Store new object. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/PiggyBank/UpdateController.php b/app/Api/V1/Controllers/Models/PiggyBank/UpdateController.php index 08ff2fe971..9e7e841ee9 100644 --- a/app/Api/V1/Controllers/Models/PiggyBank/UpdateController.php +++ b/app/Api/V1/Controllers/Models/PiggyBank/UpdateController.php @@ -62,8 +62,8 @@ class UpdateController extends Controller * * Update piggy bank. * - * @param UpdateRequest $request - * @param PiggyBank $piggyBank + * @param UpdateRequest $request + * @param PiggyBank $piggyBank * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Recurrence/DestroyController.php b/app/Api/V1/Controllers/Models/Recurrence/DestroyController.php index 48df6cf188..41018c5403 100644 --- a/app/Api/V1/Controllers/Models/Recurrence/DestroyController.php +++ b/app/Api/V1/Controllers/Models/Recurrence/DestroyController.php @@ -59,7 +59,7 @@ class DestroyController extends Controller * * Delete the resource. * - * @param Recurrence $recurrence + * @param Recurrence $recurrence * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Recurrence/ListController.php b/app/Api/V1/Controllers/Models/Recurrence/ListController.php index 0643229545..9e017818db 100644 --- a/app/Api/V1/Controllers/Models/Recurrence/ListController.php +++ b/app/Api/V1/Controllers/Models/Recurrence/ListController.php @@ -69,8 +69,8 @@ class ListController extends Controller * * Show transactions for this recurrence. * - * @param Request $request - * @param Recurrence $recurrence + * @param Request $request + * @param Recurrence $recurrence * * @return JsonResponse * @throws FireflyException @@ -109,7 +109,7 @@ class ListController extends Controller $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); } $paginator = $collector->getPaginatedGroups(); - $paginator->setPath(route('api.v1.transactions.index').$this->buildParams()); + $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); $transactions = $paginator->getCollection(); /** @var TransactionGroupTransformer $transformer */ diff --git a/app/Api/V1/Controllers/Models/Recurrence/ShowController.php b/app/Api/V1/Controllers/Models/Recurrence/ShowController.php index 91887a75f4..99ed67b074 100644 --- a/app/Api/V1/Controllers/Models/Recurrence/ShowController.php +++ b/app/Api/V1/Controllers/Models/Recurrence/ShowController.php @@ -82,7 +82,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.recurrences.index').$this->buildParams()); + $paginator->setPath(route('api.v1.recurrences.index') . $this->buildParams()); /** @var RecurrenceTransformer $transformer */ $transformer = app(RecurrenceTransformer::class); @@ -100,7 +100,7 @@ class ShowController extends Controller * * List single resource. * - * @param Recurrence $recurrence + * @param Recurrence $recurrence * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Recurrence/StoreController.php b/app/Api/V1/Controllers/Models/Recurrence/StoreController.php index 18fe32772e..e213ce03ea 100644 --- a/app/Api/V1/Controllers/Models/Recurrence/StoreController.php +++ b/app/Api/V1/Controllers/Models/Recurrence/StoreController.php @@ -62,7 +62,7 @@ class StoreController extends Controller * * Store new object. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/Recurrence/UpdateController.php b/app/Api/V1/Controllers/Models/Recurrence/UpdateController.php index 74b0b21001..04a1a92a19 100644 --- a/app/Api/V1/Controllers/Models/Recurrence/UpdateController.php +++ b/app/Api/V1/Controllers/Models/Recurrence/UpdateController.php @@ -62,8 +62,8 @@ class UpdateController extends Controller * * Update single recurrence. * - * @param UpdateRequest $request - * @param Recurrence $recurrence + * @param UpdateRequest $request + * @param Recurrence $recurrence * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Rule/DestroyController.php b/app/Api/V1/Controllers/Models/Rule/DestroyController.php index 2b7e606e1a..20e035f882 100644 --- a/app/Api/V1/Controllers/Models/Rule/DestroyController.php +++ b/app/Api/V1/Controllers/Models/Rule/DestroyController.php @@ -63,7 +63,7 @@ class DestroyController extends Controller * * Delete the resource. * - * @param Rule $rule + * @param Rule $rule * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Rule/ShowController.php b/app/Api/V1/Controllers/Models/Rule/ShowController.php index f11bf6199b..ff8ed98044 100644 --- a/app/Api/V1/Controllers/Models/Rule/ShowController.php +++ b/app/Api/V1/Controllers/Models/Rule/ShowController.php @@ -86,7 +86,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.rules.index').$this->buildParams()); + $paginator->setPath(route('api.v1.rules.index') . $this->buildParams()); /** @var RuleTransformer $transformer */ $transformer = app(RuleTransformer::class); @@ -104,7 +104,7 @@ class ShowController extends Controller * * List single resource. * - * @param Rule $rule + * @param Rule $rule * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Rule/StoreController.php b/app/Api/V1/Controllers/Models/Rule/StoreController.php index c94c250579..1d5e7ac89c 100644 --- a/app/Api/V1/Controllers/Models/Rule/StoreController.php +++ b/app/Api/V1/Controllers/Models/Rule/StoreController.php @@ -65,7 +65,7 @@ class StoreController extends Controller * * Store new object. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Rule/TriggerController.php b/app/Api/V1/Controllers/Models/Rule/TriggerController.php index 90dff0e13f..1f409a592d 100644 --- a/app/Api/V1/Controllers/Models/Rule/TriggerController.php +++ b/app/Api/V1/Controllers/Models/Rule/TriggerController.php @@ -69,8 +69,8 @@ class TriggerController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rules/testRule * - * @param TestRequest $request - * @param Rule $rule + * @param TestRequest $request + * @param Rule $rule * * @return JsonResponse */ @@ -102,7 +102,7 @@ class TriggerController extends Controller $count = $transactions->count(); $paginator = new LengthAwarePaginator($transactions, $count, 31337, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.rules.test', [$rule->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.rules.test', [$rule->id]) . $this->buildParams()); // resulting list is presented as JSON thing. $manager = $this->getManager(); @@ -122,8 +122,8 @@ class TriggerController extends Controller * * Execute the given rule group on a set of existing transactions. * - * @param TriggerRequest $request - * @param Rule $rule + * @param TriggerRequest $request + * @param Rule $rule * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Rule/UpdateController.php b/app/Api/V1/Controllers/Models/Rule/UpdateController.php index 7aef0ed6e4..f4b1f1a8a5 100644 --- a/app/Api/V1/Controllers/Models/Rule/UpdateController.php +++ b/app/Api/V1/Controllers/Models/Rule/UpdateController.php @@ -66,8 +66,8 @@ class UpdateController extends Controller * * Update a rule. * - * @param UpdateRequest $request - * @param Rule $rule + * @param UpdateRequest $request + * @param Rule $rule * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/RuleGroup/DestroyController.php b/app/Api/V1/Controllers/Models/RuleGroup/DestroyController.php index d53f488102..62f390aef4 100644 --- a/app/Api/V1/Controllers/Models/RuleGroup/DestroyController.php +++ b/app/Api/V1/Controllers/Models/RuleGroup/DestroyController.php @@ -63,7 +63,7 @@ class DestroyController extends Controller * * Delete the resource. * - * @param RuleGroup $ruleGroup + * @param RuleGroup $ruleGroup * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/RuleGroup/ListController.php b/app/Api/V1/Controllers/Models/RuleGroup/ListController.php index d549bc841b..0e3f7cbab4 100644 --- a/app/Api/V1/Controllers/Models/RuleGroup/ListController.php +++ b/app/Api/V1/Controllers/Models/RuleGroup/ListController.php @@ -66,7 +66,7 @@ class ListController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rule_groups/listRuleByGroup * - * @param RuleGroup $group + * @param RuleGroup $group * * @return JsonResponse * @throws FireflyException @@ -84,7 +84,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.rule-groups.rules', [$group->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.rule-groups.rules', [$group->id]) . $this->buildParams()); /** @var RuleTransformer $transformer */ $transformer = app(RuleTransformer::class); diff --git a/app/Api/V1/Controllers/Models/RuleGroup/ShowController.php b/app/Api/V1/Controllers/Models/RuleGroup/ShowController.php index 6d648339ee..465ac40a5d 100644 --- a/app/Api/V1/Controllers/Models/RuleGroup/ShowController.php +++ b/app/Api/V1/Controllers/Models/RuleGroup/ShowController.php @@ -84,7 +84,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($ruleGroups, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.rule-groups.index').$this->buildParams()); + $paginator->setPath(route('api.v1.rule-groups.index') . $this->buildParams()); /** @var RuleGroupTransformer $transformer */ $transformer = app(RuleGroupTransformer::class); @@ -102,7 +102,7 @@ class ShowController extends Controller * * List single resource. * - * @param RuleGroup $ruleGroup + * @param RuleGroup $ruleGroup * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/RuleGroup/StoreController.php b/app/Api/V1/Controllers/Models/RuleGroup/StoreController.php index eaa7de0ee2..02e1433a6b 100644 --- a/app/Api/V1/Controllers/Models/RuleGroup/StoreController.php +++ b/app/Api/V1/Controllers/Models/RuleGroup/StoreController.php @@ -70,7 +70,7 @@ class StoreController extends Controller * * Store new object. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/RuleGroup/TriggerController.php b/app/Api/V1/Controllers/Models/RuleGroup/TriggerController.php index a174613ec3..cda13829b7 100644 --- a/app/Api/V1/Controllers/Models/RuleGroup/TriggerController.php +++ b/app/Api/V1/Controllers/Models/RuleGroup/TriggerController.php @@ -70,8 +70,8 @@ class TriggerController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rule_groups/testRuleGroup * - * @param TestRequest $request - * @param RuleGroup $group + * @param TestRequest $request + * @param RuleGroup $group * * @return JsonResponse * @throws FireflyException @@ -108,7 +108,7 @@ class TriggerController extends Controller $count = $transactions->count(); $paginator = new LengthAwarePaginator($transactions, $count, 31337, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.rule-groups.test', [$group->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.rule-groups.test', [$group->id]) . $this->buildParams()); // resulting list is presented as JSON thing. $manager = $this->getManager(); @@ -128,8 +128,8 @@ class TriggerController extends Controller * * Execute the given rule group on a set of existing transactions. * - * @param TriggerRequest $request - * @param RuleGroup $group + * @param TriggerRequest $request + * @param RuleGroup $group * * @return JsonResponse * @throws Exception diff --git a/app/Api/V1/Controllers/Models/RuleGroup/UpdateController.php b/app/Api/V1/Controllers/Models/RuleGroup/UpdateController.php index 28ebab8249..1d2b19b6ac 100644 --- a/app/Api/V1/Controllers/Models/RuleGroup/UpdateController.php +++ b/app/Api/V1/Controllers/Models/RuleGroup/UpdateController.php @@ -66,8 +66,8 @@ class UpdateController extends Controller * * Update a rule group. * - * @param UpdateRequest $request - * @param RuleGroup $ruleGroup + * @param UpdateRequest $request + * @param RuleGroup $ruleGroup * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Tag/DestroyController.php b/app/Api/V1/Controllers/Models/Tag/DestroyController.php index 0ed01b99b0..a0b7f2c3b9 100644 --- a/app/Api/V1/Controllers/Models/Tag/DestroyController.php +++ b/app/Api/V1/Controllers/Models/Tag/DestroyController.php @@ -63,7 +63,7 @@ class DestroyController extends Controller * * Delete the resource. * - * @param Tag $tag + * @param Tag $tag * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Tag/ListController.php b/app/Api/V1/Controllers/Models/Tag/ListController.php index 31c931a955..89bc31dee8 100644 --- a/app/Api/V1/Controllers/Models/Tag/ListController.php +++ b/app/Api/V1/Controllers/Models/Tag/ListController.php @@ -72,7 +72,7 @@ class ListController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/tags/listAttachmentByTag * - * @param Tag $tag + * @param Tag $tag * * @return JsonResponse * @throws FireflyException @@ -88,7 +88,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.tags.attachments', [$tag->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.tags.attachments', [$tag->id]) . $this->buildParams()); /** @var AttachmentTransformer $transformer */ $transformer = app(AttachmentTransformer::class); @@ -106,8 +106,8 @@ class ListController extends Controller * * Show all transactions. * - * @param Request $request - * @param Tag $tag + * @param Request $request + * @param Tag $tag * * @return JsonResponse * @throws FireflyException @@ -143,7 +143,7 @@ class ListController extends Controller $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); } $paginator = $collector->getPaginatedGroups(); - $paginator->setPath(route('api.v1.tags.transactions', [$tag->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.tags.transactions', [$tag->id]) . $this->buildParams()); $transactions = $paginator->getCollection(); /** @var TransactionGroupTransformer $transformer */ diff --git a/app/Api/V1/Controllers/Models/Tag/ShowController.php b/app/Api/V1/Controllers/Models/Tag/ShowController.php index d103698dae..068c266f95 100644 --- a/app/Api/V1/Controllers/Models/Tag/ShowController.php +++ b/app/Api/V1/Controllers/Models/Tag/ShowController.php @@ -85,7 +85,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.tags.index').$this->buildParams()); + $paginator->setPath(route('api.v1.tags.index') . $this->buildParams()); /** @var TagTransformer $transformer */ $transformer = app(TagTransformer::class); @@ -103,7 +103,7 @@ class ShowController extends Controller * * List single resource. * - * @param Tag $tag + * @param Tag $tag * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Tag/StoreController.php b/app/Api/V1/Controllers/Models/Tag/StoreController.php index 0417abe83a..309ee7a14b 100644 --- a/app/Api/V1/Controllers/Models/Tag/StoreController.php +++ b/app/Api/V1/Controllers/Models/Tag/StoreController.php @@ -65,7 +65,7 @@ class StoreController extends Controller * * Store new object. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Tag/UpdateController.php b/app/Api/V1/Controllers/Models/Tag/UpdateController.php index baa25fdcef..89c9eafa22 100644 --- a/app/Api/V1/Controllers/Models/Tag/UpdateController.php +++ b/app/Api/V1/Controllers/Models/Tag/UpdateController.php @@ -66,8 +66,8 @@ class UpdateController extends Controller * * Update a rule. * - * @param UpdateRequest $request - * @param Tag $tag + * @param UpdateRequest $request + * @param Tag $tag * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Transaction/DestroyController.php b/app/Api/V1/Controllers/Models/Transaction/DestroyController.php index 884c8e7e1c..a15a24ff33 100644 --- a/app/Api/V1/Controllers/Models/Transaction/DestroyController.php +++ b/app/Api/V1/Controllers/Models/Transaction/DestroyController.php @@ -73,7 +73,7 @@ class DestroyController extends Controller * * Remove the specified resource from storage. * - * @param TransactionGroup $transactionGroup + * @param TransactionGroup $transactionGroup * * @return JsonResponse */ @@ -113,7 +113,7 @@ class DestroyController extends Controller * * Remove the specified resource from storage. * - * @param TransactionJournal $transactionJournal + * @param TransactionJournal $transactionJournal * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/Transaction/ListController.php b/app/Api/V1/Controllers/Models/Transaction/ListController.php index 8d47934687..2a0266b798 100644 --- a/app/Api/V1/Controllers/Models/Transaction/ListController.php +++ b/app/Api/V1/Controllers/Models/Transaction/ListController.php @@ -70,7 +70,7 @@ class ListController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/listAttachmentByTransaction * - * @param TransactionGroup $transactionGroup + * @param TransactionGroup $transactionGroup * * @return JsonResponse * @throws FireflyException @@ -89,7 +89,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.transactions.attachments', [$transactionGroup->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.transactions.attachments', [$transactionGroup->id]) . $this->buildParams()); /** @var AttachmentTransformer $transformer */ $transformer = app(AttachmentTransformer::class); @@ -105,7 +105,7 @@ class ListController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/listEventByTransaction * - * @param TransactionGroup $transactionGroup + * @param TransactionGroup $transactionGroup * * @return JsonResponse * @throws FireflyException @@ -122,7 +122,7 @@ class ListController extends Controller $events = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); // make paginator: $paginator = new LengthAwarePaginator($events, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.transactions.piggy-bank-events', [$transactionGroup->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.transactions.piggy-bank-events', [$transactionGroup->id]) . $this->buildParams()); /** @var PiggyBankEventTransformer $transformer */ $transformer = app(PiggyBankEventTransformer::class); @@ -143,7 +143,7 @@ class ListController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/listLinksByJournal * - * @param TransactionJournal $transactionJournal + * @param TransactionJournal $transactionJournal * * @return JsonResponse * @throws FireflyException @@ -158,7 +158,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($journalLinks, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.transaction-journals.transaction-links', [$transactionJournal->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.transaction-journals.transaction-links', [$transactionJournal->id]) . $this->buildParams()); /** @var TransactionLinkTransformer $transformer */ $transformer = app(TransactionLinkTransformer::class); diff --git a/app/Api/V1/Controllers/Models/Transaction/ShowController.php b/app/Api/V1/Controllers/Models/Transaction/ShowController.php index 217ad9e53b..03749f831a 100644 --- a/app/Api/V1/Controllers/Models/Transaction/ShowController.php +++ b/app/Api/V1/Controllers/Models/Transaction/ShowController.php @@ -51,7 +51,7 @@ class ShowController extends Controller * * Show all transactions. * - * @param Request $request + * @param Request $request * * @return JsonResponse * @throws FireflyException @@ -84,7 +84,7 @@ class ShowController extends Controller $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); } $paginator = $collector->getPaginatedGroups(); - $paginator->setPath(route('api.v1.transactions.index').$this->buildParams()); + $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); $transactions = $paginator->getCollection(); /** @var TransactionGroupTransformer $transformer */ @@ -97,13 +97,28 @@ class ShowController extends Controller return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); } + /** + * This endpoint is documented at: + * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/getTransactionByJournal + * + * Show a single transaction, by transaction journal. + * + * @param TransactionJournal $transactionJournal + * + * @return JsonResponse + */ + public function showJournal(TransactionJournal $transactionJournal): JsonResponse + { + return $this->show($transactionJournal->transactionGroup); + } + /** * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/getTransaction * * Show a single transaction. * - * @param TransactionGroup $transactionGroup + * @param TransactionGroup $transactionGroup * * @return JsonResponse */ @@ -133,19 +148,4 @@ class ShowController extends Controller return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); } - - /** - * This endpoint is documented at: - * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/getTransactionByJournal - * - * Show a single transaction, by transaction journal. - * - * @param TransactionJournal $transactionJournal - * - * @return JsonResponse - */ - public function showJournal(TransactionJournal $transactionJournal): JsonResponse - { - return $this->show($transactionJournal->transactionGroup); - } } diff --git a/app/Api/V1/Controllers/Models/Transaction/StoreController.php b/app/Api/V1/Controllers/Models/Transaction/StoreController.php index 3134996e7d..29c4a262e8 100644 --- a/app/Api/V1/Controllers/Models/Transaction/StoreController.php +++ b/app/Api/V1/Controllers/Models/Transaction/StoreController.php @@ -76,7 +76,7 @@ class StoreController extends Controller * * Store a new transaction. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse * @throws FireflyException|ValidationException diff --git a/app/Api/V1/Controllers/Models/Transaction/UpdateController.php b/app/Api/V1/Controllers/Models/Transaction/UpdateController.php index 678c324850..ffe1a83c57 100644 --- a/app/Api/V1/Controllers/Models/Transaction/UpdateController.php +++ b/app/Api/V1/Controllers/Models/Transaction/UpdateController.php @@ -70,8 +70,8 @@ class UpdateController extends Controller * * Update a transaction. * - * @param UpdateRequest $request - * @param TransactionGroup $transactionGroup + * @param UpdateRequest $request + * @param TransactionGroup $transactionGroup * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/TransactionCurrency/DestroyController.php b/app/Api/V1/Controllers/Models/TransactionCurrency/DestroyController.php index a5b89d7738..1cfb07d391 100644 --- a/app/Api/V1/Controllers/Models/TransactionCurrency/DestroyController.php +++ b/app/Api/V1/Controllers/Models/TransactionCurrency/DestroyController.php @@ -66,7 +66,7 @@ class DestroyController extends Controller * * Remove the specified resource from storage. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/TransactionCurrency/ListController.php b/app/Api/V1/Controllers/Models/TransactionCurrency/ListController.php index bca8c01b2f..2404b9b54e 100644 --- a/app/Api/V1/Controllers/Models/TransactionCurrency/ListController.php +++ b/app/Api/V1/Controllers/Models/TransactionCurrency/ListController.php @@ -90,8 +90,8 @@ class ListController extends Controller * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/listAccountByCurrency * Display a list of accounts. * - * @param Request $request - * @param TransactionCurrency $currency + * @param Request $request + * @param TransactionCurrency $currency * * @return JsonResponse * @throws FireflyException @@ -127,7 +127,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.currencies.accounts', [$currency->code]).$this->buildParams()); + $paginator->setPath(route('api.v1.currencies.accounts', [$currency->code]) . $this->buildParams()); /** @var AccountTransformer $transformer */ $transformer = app(AccountTransformer::class); @@ -144,7 +144,7 @@ class ListController extends Controller * * Display a listing of the resource. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return JsonResponse * @throws FireflyException @@ -164,7 +164,7 @@ class ListController extends Controller $availableBudgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); // make paginator: $paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.currencies.available-budgets', [$currency->code]).$this->buildParams()); + $paginator->setPath(route('api.v1.currencies.available-budgets', [$currency->code]) . $this->buildParams()); /** @var AvailableBudgetTransformer $transformer */ $transformer = app(AvailableBudgetTransformer::class); @@ -182,7 +182,7 @@ class ListController extends Controller * * List all bills * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return JsonResponse * @throws FireflyException @@ -207,7 +207,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.currencies.bills', [$currency->code]).$this->buildParams()); + $paginator->setPath(route('api.v1.currencies.bills', [$currency->code]) . $this->buildParams()); /** @var BillTransformer $transformer */ $transformer = app(BillTransformer::class); @@ -225,7 +225,7 @@ class ListController extends Controller * * List all budget limits * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return JsonResponse * @throws FireflyException @@ -241,7 +241,7 @@ class ListController extends Controller $count = $collection->count(); $budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); $paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.currencies.budget-limits', [$currency->code]).$this->buildParams()); + $paginator->setPath(route('api.v1.currencies.budget-limits', [$currency->code]) . $this->buildParams()); /** @var BudgetLimitTransformer $transformer */ $transformer = app(BudgetLimitTransformer::class); @@ -259,7 +259,7 @@ class ListController extends Controller * * List all recurring transactions. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return JsonResponse * @throws FireflyException @@ -293,7 +293,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.currencies.recurrences', [$currency->code]).$this->buildParams()); + $paginator->setPath(route('api.v1.currencies.recurrences', [$currency->code]) . $this->buildParams()); /** @var RecurrenceTransformer $transformer */ $transformer = app(RecurrenceTransformer::class); @@ -311,7 +311,7 @@ class ListController extends Controller * * List all of them. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return JsonResponse * @throws FireflyException @@ -344,7 +344,7 @@ class ListController extends Controller // make paginator: $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.rules.index').$this->buildParams()); + $paginator->setPath(route('api.v1.rules.index') . $this->buildParams()); /** @var RuleTransformer $transformer */ $transformer = app(RuleTransformer::class); @@ -362,9 +362,9 @@ class ListController extends Controller * * Show all transactions. * - * @param Request $request + * @param Request $request * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return JsonResponse * @throws FireflyException @@ -400,7 +400,7 @@ class ListController extends Controller $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); } $paginator = $collector->getPaginatedGroups(); - $paginator->setPath(route('api.v1.currencies.transactions', [$currency->code]).$this->buildParams()); + $paginator->setPath(route('api.v1.currencies.transactions', [$currency->code]) . $this->buildParams()); $transactions = $paginator->getCollection(); /** @var TransactionGroupTransformer $transformer */ diff --git a/app/Api/V1/Controllers/Models/TransactionCurrency/ShowController.php b/app/Api/V1/Controllers/Models/TransactionCurrency/ShowController.php index c94e9cb35b..e9e21d722a 100644 --- a/app/Api/V1/Controllers/Models/TransactionCurrency/ShowController.php +++ b/app/Api/V1/Controllers/Models/TransactionCurrency/ShowController.php @@ -84,7 +84,7 @@ class ShowController extends Controller // slice them: $currencies = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); $paginator = new LengthAwarePaginator($currencies, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.currencies.index').$this->buildParams()); + $paginator->setPath(route('api.v1.currencies.index') . $this->buildParams()); $manager = $this->getManager(); $defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user()); $this->parameters->set('defaultCurrency', $defaultCurrency); @@ -105,7 +105,7 @@ class ShowController extends Controller * * Show a currency. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/TransactionCurrency/StoreController.php b/app/Api/V1/Controllers/Models/TransactionCurrency/StoreController.php index 6853c1be71..61a4c63d22 100644 --- a/app/Api/V1/Controllers/Models/TransactionCurrency/StoreController.php +++ b/app/Api/V1/Controllers/Models/TransactionCurrency/StoreController.php @@ -69,7 +69,7 @@ class StoreController extends Controller * * Store new currency. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/TransactionCurrency/UpdateController.php b/app/Api/V1/Controllers/Models/TransactionCurrency/UpdateController.php index c03a20aa56..e0f978c048 100644 --- a/app/Api/V1/Controllers/Models/TransactionCurrency/UpdateController.php +++ b/app/Api/V1/Controllers/Models/TransactionCurrency/UpdateController.php @@ -70,7 +70,7 @@ class UpdateController extends Controller * * Disable a currency. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return JsonResponse * @throws FireflyException @@ -97,42 +97,13 @@ class UpdateController extends Controller return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); } - /** - * This endpoint is documented at: - * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/enableCurrency - * - * Enable a currency. - * - * @param TransactionCurrency $currency - * - * @return JsonResponse - * @throws FireflyException - * @throws JsonException - */ - public function enable(TransactionCurrency $currency): JsonResponse - { - $this->repository->enable($currency); - $manager = $this->getManager(); - - $defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user()); - $this->parameters->set('defaultCurrency', $defaultCurrency); - - /** @var CurrencyTransformer $transformer */ - $transformer = app(CurrencyTransformer::class); - $transformer->setParameters($this->parameters); - - $resource = new Item($currency, $transformer, 'currencies'); - - return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); - } - /** * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/defaultCurrency * * Make the currency a default currency. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return JsonResponse * @throws FireflyException @@ -157,14 +128,43 @@ class UpdateController extends Controller return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); } + /** + * This endpoint is documented at: + * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/enableCurrency + * + * Enable a currency. + * + * @param TransactionCurrency $currency + * + * @return JsonResponse + * @throws FireflyException + * @throws JsonException + */ + public function enable(TransactionCurrency $currency): JsonResponse + { + $this->repository->enable($currency); + $manager = $this->getManager(); + + $defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user()); + $this->parameters->set('defaultCurrency', $defaultCurrency); + + /** @var CurrencyTransformer $transformer */ + $transformer = app(CurrencyTransformer::class); + $transformer->setParameters($this->parameters); + + $resource = new Item($currency, $transformer, 'currencies'); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); + } + /** * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/updateCurrency * * Update a currency. * - * @param UpdateRequest $request - * @param TransactionCurrency $currency + * @param UpdateRequest $request + * @param TransactionCurrency $currency * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/TransactionLink/DestroyController.php b/app/Api/V1/Controllers/Models/TransactionLink/DestroyController.php index cbc4b1bf40..2c0026e31a 100644 --- a/app/Api/V1/Controllers/Models/TransactionLink/DestroyController.php +++ b/app/Api/V1/Controllers/Models/TransactionLink/DestroyController.php @@ -62,7 +62,7 @@ class DestroyController extends Controller * * Delete the resource. * - * @param TransactionJournalLink $link + * @param TransactionJournalLink $link * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/TransactionLink/ShowController.php b/app/Api/V1/Controllers/Models/TransactionLink/ShowController.php index 8c69c1d8eb..4efa2b7ede 100644 --- a/app/Api/V1/Controllers/Models/TransactionLink/ShowController.php +++ b/app/Api/V1/Controllers/Models/TransactionLink/ShowController.php @@ -69,7 +69,7 @@ class ShowController extends Controller * * List all transaction links there are. * - * @param Request $request + * @param Request $request * * @return JsonResponse * @throws FireflyException @@ -92,7 +92,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($journalLinks, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.transaction-links.index').$this->buildParams()); + $paginator->setPath(route('api.v1.transaction-links.index') . $this->buildParams()); /** @var TransactionLinkTransformer $transformer */ $transformer = app(TransactionLinkTransformer::class); @@ -110,7 +110,7 @@ class ShowController extends Controller * * List single resource. * - * @param TransactionJournalLink $journalLink + * @param TransactionJournalLink $journalLink * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/TransactionLink/StoreController.php b/app/Api/V1/Controllers/Models/TransactionLink/StoreController.php index c8c94d0300..ecae44f712 100644 --- a/app/Api/V1/Controllers/Models/TransactionLink/StoreController.php +++ b/app/Api/V1/Controllers/Models/TransactionLink/StoreController.php @@ -72,7 +72,7 @@ class StoreController extends Controller * * Store new object. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/TransactionLink/UpdateController.php b/app/Api/V1/Controllers/Models/TransactionLink/UpdateController.php index ba3af64ecf..34b20841be 100644 --- a/app/Api/V1/Controllers/Models/TransactionLink/UpdateController.php +++ b/app/Api/V1/Controllers/Models/TransactionLink/UpdateController.php @@ -69,8 +69,8 @@ class UpdateController extends Controller * * Update object. * - * @param UpdateRequest $request - * @param TransactionJournalLink $journalLink + * @param UpdateRequest $request + * @param TransactionJournalLink $journalLink * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/TransactionLinkType/DestroyController.php b/app/Api/V1/Controllers/Models/TransactionLinkType/DestroyController.php index 48f3f57dc0..4eca004d35 100644 --- a/app/Api/V1/Controllers/Models/TransactionLinkType/DestroyController.php +++ b/app/Api/V1/Controllers/Models/TransactionLinkType/DestroyController.php @@ -67,7 +67,7 @@ class DestroyController extends Controller * * Delete the resource. * - * @param LinkType $linkType + * @param LinkType $linkType * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/TransactionLinkType/ListController.php b/app/Api/V1/Controllers/Models/TransactionLinkType/ListController.php index 7891f4709f..b34e702b77 100644 --- a/app/Api/V1/Controllers/Models/TransactionLinkType/ListController.php +++ b/app/Api/V1/Controllers/Models/TransactionLinkType/ListController.php @@ -70,8 +70,8 @@ class ListController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/links/listTransactionByLinkType * - * @param Request $request - * @param LinkType $linkType + * @param Request $request + * @param LinkType $linkType * * @return JsonResponse * @throws FireflyException @@ -110,7 +110,7 @@ class ListController extends Controller $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); } $paginator = $collector->getPaginatedGroups(); - $paginator->setPath(route('api.v1.transactions.index').$this->buildParams()); + $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); $transactions = $paginator->getCollection(); /** @var TransactionGroupTransformer $transformer */ diff --git a/app/Api/V1/Controllers/Models/TransactionLinkType/ShowController.php b/app/Api/V1/Controllers/Models/TransactionLinkType/ShowController.php index aa011d8d46..49f19afd4e 100644 --- a/app/Api/V1/Controllers/Models/TransactionLinkType/ShowController.php +++ b/app/Api/V1/Controllers/Models/TransactionLinkType/ShowController.php @@ -87,7 +87,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($linkTypes, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.link-types.index').$this->buildParams()); + $paginator->setPath(route('api.v1.link-types.index') . $this->buildParams()); /** @var LinkTypeTransformer $transformer */ $transformer = app(LinkTypeTransformer::class); @@ -105,7 +105,7 @@ class ShowController extends Controller * * List single resource. * - * @param LinkType $linkType + * @param LinkType $linkType * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Models/TransactionLinkType/StoreController.php b/app/Api/V1/Controllers/Models/TransactionLinkType/StoreController.php index 1694e03c85..e42f5d74c2 100644 --- a/app/Api/V1/Controllers/Models/TransactionLinkType/StoreController.php +++ b/app/Api/V1/Controllers/Models/TransactionLinkType/StoreController.php @@ -73,7 +73,7 @@ class StoreController extends Controller * * Store new object. * - * @param StoreRequest $request + * @param StoreRequest $request * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Models/TransactionLinkType/UpdateController.php b/app/Api/V1/Controllers/Models/TransactionLinkType/UpdateController.php index 74778b8509..60bab00568 100644 --- a/app/Api/V1/Controllers/Models/TransactionLinkType/UpdateController.php +++ b/app/Api/V1/Controllers/Models/TransactionLinkType/UpdateController.php @@ -74,8 +74,8 @@ class UpdateController extends Controller * * Update object. * - * @param UpdateRequest $request - * @param LinkType $linkType + * @param UpdateRequest $request + * @param LinkType $linkType * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Search/AccountController.php b/app/Api/V1/Controllers/Search/AccountController.php index c4214547db..2da3d3a254 100644 --- a/app/Api/V1/Controllers/Search/AccountController.php +++ b/app/Api/V1/Controllers/Search/AccountController.php @@ -33,7 +33,6 @@ use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Support\Facades\Log; -use JsonException; use League\Fractal\Pagination\IlluminatePaginatorAdapter; use League\Fractal\Resource\Collection as FractalCollection; @@ -62,11 +61,11 @@ class AccountController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/search/searchAccounts * - * @param Request $request + * @param Request $request * * @return JsonResponse|Response */ - public function search(Request $request): JsonResponse|Response + public function search(Request $request): JsonResponse | Response { Log::debug('Now in account search()'); $manager = $this->getManager(); diff --git a/app/Api/V1/Controllers/Search/TransactionController.php b/app/Api/V1/Controllers/Search/TransactionController.php index f4fbe86782..7fc503d201 100644 --- a/app/Api/V1/Controllers/Search/TransactionController.php +++ b/app/Api/V1/Controllers/Search/TransactionController.php @@ -42,8 +42,8 @@ class TransactionController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/search/searchTransactions * - * @param Request $request - * @param SearchInterface $searcher + * @param Request $request + * @param SearchInterface $searcher * * @return JsonResponse * @throws FireflyException @@ -60,7 +60,7 @@ class TransactionController extends Controller $searcher->setLimit($pageSize); $groups = $searcher->searchTransactions(); $parameters = ['search' => $fullQuery]; - $url = route('api.v1.search.transactions').'?'.http_build_query($parameters); + $url = route('api.v1.search.transactions') . '?' . http_build_query($parameters); $groups->setPath($url); $transactions = $groups->getCollection(); diff --git a/app/Api/V1/Controllers/Summary/BasicController.php b/app/Api/V1/Controllers/Summary/BasicController.php index bc0ba94eb5..72734fd361 100644 --- a/app/Api/V1/Controllers/Summary/BasicController.php +++ b/app/Api/V1/Controllers/Summary/BasicController.php @@ -90,7 +90,7 @@ class BasicController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/summary/getBasicSummary * - * @param DateRequest $request + * @param DateRequest $request * * @return JsonResponse * @throws Exception @@ -122,32 +122,8 @@ class BasicController extends Controller } /** - * Check if date is outside session range. - * - * @param Carbon $date - * - * @param Carbon $start - * @param Carbon $end - * - * @return bool - */ - protected function notInDateRange(Carbon $date, Carbon $start, Carbon $end): bool // Validate a preference - { - $result = false; - if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) { - $result = true; - } - // start and end in the past? use $end - if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) { - $result = true; - } - - return $result; - } - - /** - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -220,8 +196,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), @@ -253,8 +229,8 @@ class BasicController extends Controller } /** - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -310,8 +286,8 @@ class BasicController extends Controller } /** - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return array * @throws Exception @@ -364,8 +340,8 @@ class BasicController extends Controller } /** - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -422,4 +398,28 @@ class BasicController extends Controller return $return; } + + /** + * Check if date is outside session range. + * + * @param Carbon $date + * + * @param Carbon $start + * @param Carbon $end + * + * @return bool + */ + protected function notInDateRange(Carbon $date, Carbon $start, Carbon $end): bool // Validate a preference + { + $result = false; + if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) { + $result = true; + } + // start and end in the past? use $end + if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) { + $result = true; + } + + return $result; + } } diff --git a/app/Api/V1/Controllers/System/ConfigurationController.php b/app/Api/V1/Controllers/System/ConfigurationController.php index 727660c2af..475502620a 100644 --- a/app/Api/V1/Controllers/System/ConfigurationController.php +++ b/app/Api/V1/Controllers/System/ConfigurationController.php @@ -94,11 +94,47 @@ class ConfigurationController extends Controller return response()->json($return); } + /** + * Get all config values. + * + * @return array + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + private function getDynamicConfiguration(): array + { + $isDemoSite = app('fireflyconfig')->get('is_demo_site'); + $updateCheck = app('fireflyconfig')->get('permission_update_check'); + $lastCheck = app('fireflyconfig')->get('last_update_check'); + $singleUser = app('fireflyconfig')->get('single_user_mode'); + + return [ + 'is_demo_site' => $isDemoSite?->data, + 'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data, + 'last_update_check' => null === $lastCheck ? null : (int)$lastCheck->data, + 'single_user_mode' => $singleUser?->data, + ]; + } + + /** + * @return array + */ + private function getStaticConfiguration(): array + { + $list = EitherConfigKey::$static; + $return = []; + foreach ($list as $key) { + $return[$key] = config($key); + } + + return $return; + } + /** * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/configuration/getSingleConfiguration * - * @param string $configKey + * @param string $configKey * * @return JsonResponse * @throws ContainerExceptionInterface @@ -134,8 +170,8 @@ class ConfigurationController extends Controller * * Update the configuration. * - * @param UpdateRequest $request - * @param string $name + * @param UpdateRequest $request + * @param string $name * * @return JsonResponse * @throws ContainerExceptionInterface @@ -164,40 +200,4 @@ class ConfigurationController extends Controller return response()->json(['data' => $data])->header('Content-Type', self::CONTENT_TYPE); } - - /** - * Get all config values. - * - * @return array - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - private function getDynamicConfiguration(): array - { - $isDemoSite = app('fireflyconfig')->get('is_demo_site'); - $updateCheck = app('fireflyconfig')->get('permission_update_check'); - $lastCheck = app('fireflyconfig')->get('last_update_check'); - $singleUser = app('fireflyconfig')->get('single_user_mode'); - - return [ - 'is_demo_site' => $isDemoSite?->data, - 'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data, - 'last_update_check' => null === $lastCheck ? null : (int)$lastCheck->data, - 'single_user_mode' => $singleUser?->data, - ]; - } - - /** - * @return array - */ - private function getStaticConfiguration(): array - { - $list = EitherConfigKey::$static; - $return = []; - foreach ($list as $key) { - $return[$key] = config($key); - } - - return $return; - } } diff --git a/app/Api/V1/Controllers/System/CronController.php b/app/Api/V1/Controllers/System/CronController.php index fbe211dc9c..c75f2db102 100644 --- a/app/Api/V1/Controllers/System/CronController.php +++ b/app/Api/V1/Controllers/System/CronController.php @@ -40,8 +40,8 @@ class CronController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/about/getCron * - * @param CronRequest $request - * @param string $token + * @param CronRequest $request + * @param string $token * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/System/UserController.php b/app/Api/V1/Controllers/System/UserController.php index 3c0f84b369..413bf3a037 100644 --- a/app/Api/V1/Controllers/System/UserController.php +++ b/app/Api/V1/Controllers/System/UserController.php @@ -68,7 +68,7 @@ class UserController extends Controller * * Remove the specified resource from storage. * - * @param User $user + * @param User $user * * @return JsonResponse * @throws FireflyException @@ -111,7 +111,7 @@ class UserController extends Controller // make paginator: $paginator = new LengthAwarePaginator($users, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.users.index').$this->buildParams()); + $paginator->setPath(route('api.v1.users.index') . $this->buildParams()); // make resource /** @var UserTransformer $transformer */ @@ -130,7 +130,7 @@ class UserController extends Controller * * Show a single user. * - * @param User $user + * @param User $user * * @return JsonResponse */ @@ -154,7 +154,7 @@ class UserController extends Controller * * Store a new user. * - * @param UserStoreRequest $request + * @param UserStoreRequest $request * * @return JsonResponse */ @@ -181,8 +181,8 @@ class UserController extends Controller * * Update a user. * - * @param UserUpdateRequest $request - * @param User $user + * @param UserUpdateRequest $request + * @param User $user * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/User/PreferencesController.php b/app/Api/V1/Controllers/User/PreferencesController.php index 0934b3982f..6d618fc86c 100644 --- a/app/Api/V1/Controllers/User/PreferencesController.php +++ b/app/Api/V1/Controllers/User/PreferencesController.php @@ -63,7 +63,7 @@ class PreferencesController extends Controller // make paginator: $paginator = new LengthAwarePaginator($preferences, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.preferences.index').$this->buildParams()); + $paginator->setPath(route('api.v1.preferences.index') . $this->buildParams()); /** @var PreferenceTransformer $transformer */ $transformer = app(PreferenceTransformer::class); @@ -81,7 +81,7 @@ class PreferencesController extends Controller * * Return a single preference by name. * - * @param Preference $preference + * @param Preference $preference * * @return JsonResponse */ @@ -101,7 +101,7 @@ class PreferencesController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/preferences/storePreference * - * @param PreferenceStoreRequest $request + * @param PreferenceStoreRequest $request * * @return JsonResponse * @throws FireflyException @@ -125,8 +125,8 @@ class PreferencesController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/preferences/updatePreference * - * @param PreferenceUpdateRequest $request - * @param Preference $preference + * @param PreferenceUpdateRequest $request + * @param Preference $preference * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Webhook/AttemptController.php b/app/Api/V1/Controllers/Webhook/AttemptController.php index 226416512a..a64066da1f 100644 --- a/app/Api/V1/Controllers/Webhook/AttemptController.php +++ b/app/Api/V1/Controllers/Webhook/AttemptController.php @@ -63,8 +63,8 @@ class AttemptController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/getWebhookMessageAttempts * - * @param Webhook $webhook - * @param WebhookMessage $message + * @param Webhook $webhook + * @param WebhookMessage $message * * @return JsonResponse * @throws FireflyException @@ -83,7 +83,7 @@ class AttemptController extends Controller // make paginator: $paginator = new LengthAwarePaginator($attempts, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.webhooks.attempts.index', [$webhook->id, $message->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.webhooks.attempts.index', [$webhook->id, $message->id]) . $this->buildParams()); /** @var WebhookAttemptTransformer $transformer */ $transformer = app(WebhookAttemptTransformer::class); @@ -101,9 +101,9 @@ class AttemptController extends Controller * * Show single instance. * - * @param Webhook $webhook - * @param WebhookMessage $message - * @param WebhookAttempt $attempt + * @param Webhook $webhook + * @param WebhookMessage $message + * @param WebhookAttempt $attempt * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Webhook/DestroyController.php b/app/Api/V1/Controllers/Webhook/DestroyController.php index 13bb023c95..da914b57d4 100644 --- a/app/Api/V1/Controllers/Webhook/DestroyController.php +++ b/app/Api/V1/Controllers/Webhook/DestroyController.php @@ -60,7 +60,7 @@ class DestroyController extends Controller * * Remove the specified resource from storage. * - * @param Webhook $webhook + * @param Webhook $webhook * * @return JsonResponse */ @@ -78,9 +78,9 @@ class DestroyController extends Controller * * Remove the specified resource from storage. * - * @param Webhook $webhook - * @param WebhookMessage $message - * @param WebhookAttempt $attempt + * @param Webhook $webhook + * @param WebhookMessage $message + * @param WebhookAttempt $attempt * * @return JsonResponse * @throws FireflyException @@ -106,8 +106,8 @@ class DestroyController extends Controller * * Remove the specified resource from storage. * - * @param Webhook $webhook - * @param WebhookMessage $message + * @param Webhook $webhook + * @param WebhookMessage $message * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Webhook/MessageController.php b/app/Api/V1/Controllers/Webhook/MessageController.php index 2560bf7437..74aba2e64d 100644 --- a/app/Api/V1/Controllers/Webhook/MessageController.php +++ b/app/Api/V1/Controllers/Webhook/MessageController.php @@ -59,7 +59,7 @@ class MessageController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/getWebhookMessages * - * @param Webhook $webhook + * @param Webhook $webhook * * @return JsonResponse * @throws FireflyException @@ -75,7 +75,7 @@ class MessageController extends Controller // make paginator: $paginator = new LengthAwarePaginator($messages, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.webhooks.messages.index', [$webhook->id]).$this->buildParams()); + $paginator->setPath(route('api.v1.webhooks.messages.index', [$webhook->id]) . $this->buildParams()); /** @var WebhookMessageTransformer $transformer */ $transformer = app(WebhookMessageTransformer::class); @@ -93,8 +93,8 @@ class MessageController extends Controller * * Show single instance. * - * @param Webhook $webhook - * @param WebhookMessage $message + * @param Webhook $webhook + * @param WebhookMessage $message * * @return JsonResponse * @throws FireflyException diff --git a/app/Api/V1/Controllers/Webhook/ShowController.php b/app/Api/V1/Controllers/Webhook/ShowController.php index 0fc63fccab..d9f2db1530 100644 --- a/app/Api/V1/Controllers/Webhook/ShowController.php +++ b/app/Api/V1/Controllers/Webhook/ShowController.php @@ -80,7 +80,7 @@ class ShowController extends Controller // make paginator: $paginator = new LengthAwarePaginator($webhooks, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.webhooks.index').$this->buildParams()); + $paginator->setPath(route('api.v1.webhooks.index') . $this->buildParams()); /** @var WebhookTransformer $transformer */ $transformer = app(WebhookTransformer::class); @@ -98,7 +98,7 @@ class ShowController extends Controller * * Show single instance. * - * @param Webhook $webhook + * @param Webhook $webhook * * @return JsonResponse */ @@ -120,8 +120,8 @@ class ShowController extends Controller * * This method recycles part of the code of the StoredGroupEventHandler. * - * @param Webhook $webhook - * @param TransactionGroup $group + * @param Webhook $webhook + * @param TransactionGroup $group * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Webhook/StoreController.php b/app/Api/V1/Controllers/Webhook/StoreController.php index 4df638d557..6c573a7929 100644 --- a/app/Api/V1/Controllers/Webhook/StoreController.php +++ b/app/Api/V1/Controllers/Webhook/StoreController.php @@ -57,7 +57,7 @@ class StoreController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/storeWebhook * - * @param CreateRequest $request + * @param CreateRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Webhook/SubmitController.php b/app/Api/V1/Controllers/Webhook/SubmitController.php index 96db2dc3a2..bf325fdbb4 100644 --- a/app/Api/V1/Controllers/Webhook/SubmitController.php +++ b/app/Api/V1/Controllers/Webhook/SubmitController.php @@ -55,7 +55,7 @@ class SubmitController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/submitWebook * - * @param Webhook $webhook + * @param Webhook $webhook * * @return JsonResponse */ diff --git a/app/Api/V1/Controllers/Webhook/UpdateController.php b/app/Api/V1/Controllers/Webhook/UpdateController.php index b5443cdc31..658412801b 100644 --- a/app/Api/V1/Controllers/Webhook/UpdateController.php +++ b/app/Api/V1/Controllers/Webhook/UpdateController.php @@ -57,8 +57,8 @@ class UpdateController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/updateWebhook * - * @param Webhook $webhook - * @param UpdateRequest $request + * @param Webhook $webhook + * @param UpdateRequest $request * * @return JsonResponse */ diff --git a/app/Api/V1/Middleware/ApiDemoUser.php b/app/Api/V1/Middleware/ApiDemoUser.php index 2573ee939d..02553d67f0 100644 --- a/app/Api/V1/Middleware/ApiDemoUser.php +++ b/app/Api/V1/Middleware/ApiDemoUser.php @@ -35,8 +35,8 @@ class ApiDemoUser /** * Handle an incoming request. * - * @param Request $request - * @param Closure $next + * @param Request $request + * @param Closure $next * * @return mixed */ diff --git a/app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php b/app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php index dfba30b9bc..59df3d2678 100644 --- a/app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php +++ b/app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php @@ -63,7 +63,7 @@ class MoveTransactionsRequest extends FormRequest /** * Configure the validator instance with special rules for after the basic validation rules. * - * @param Validator $validator + * @param Validator $validator * TODO this is duplicate. * * @return void @@ -82,7 +82,7 @@ class MoveTransactionsRequest extends FormRequest } /** - * @param Validator $validator + * @param Validator $validator * * @return void */ diff --git a/app/Api/V1/Requests/Data/Bulk/TransactionRequest.php b/app/Api/V1/Requests/Data/Bulk/TransactionRequest.php index 926b51e308..07b29a7a60 100644 --- a/app/Api/V1/Requests/Data/Bulk/TransactionRequest.php +++ b/app/Api/V1/Requests/Data/Bulk/TransactionRequest.php @@ -72,7 +72,7 @@ class TransactionRequest extends FormRequest } /** - * @param Validator $validator + * @param Validator $validator * * @return void */ diff --git a/app/Api/V1/Requests/Data/DestroyRequest.php b/app/Api/V1/Requests/Data/DestroyRequest.php index 0f186ffd4e..ea96e92c26 100644 --- a/app/Api/V1/Requests/Data/DestroyRequest.php +++ b/app/Api/V1/Requests/Data/DestroyRequest.php @@ -52,8 +52,8 @@ 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'. + $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 [ diff --git a/app/Api/V1/Requests/Insight/GenericRequest.php b/app/Api/V1/Requests/Insight/GenericRequest.php index 2ca1f8a58b..0eb22bc584 100644 --- a/app/Api/V1/Requests/Insight/GenericRequest.php +++ b/app/Api/V1/Requests/Insight/GenericRequest.php @@ -82,6 +82,28 @@ class GenericRequest extends FormRequest return $return; } + /** + * + */ + private function parseAccounts(): void + { + if (0 !== $this->accounts->count()) { + return; + } + $repository = app(AccountRepositoryInterface::class); + $repository->setUser(auth()->user()); + $array = $this->get('accounts'); + if (is_array($array)) { + foreach ($array as $accountId) { + $accountId = (int)$accountId; + $account = $repository->find($accountId); + if (null !== $account) { + $this->accounts->push($account); + } + } + } + } + /** * @return Collection */ @@ -92,6 +114,28 @@ class GenericRequest extends FormRequest return $this->bills; } + /** + * + */ + private function parseBills(): void + { + if (0 !== $this->bills->count()) { + return; + } + $repository = app(BillRepositoryInterface::class); + $repository->setUser(auth()->user()); + $array = $this->get('bills'); + if (is_array($array)) { + foreach ($array as $billId) { + $billId = (int)$billId; + $bill = $repository->find($billId); + if (null !== $bill) { + $this->bills->push($bill); + } + } + } + } + /** * @return Collection */ @@ -102,6 +146,28 @@ class GenericRequest extends FormRequest return $this->budgets; } + /** + * + */ + private function parseBudgets(): void + { + if (0 !== $this->budgets->count()) { + return; + } + $repository = app(BudgetRepositoryInterface::class); + $repository->setUser(auth()->user()); + $array = $this->get('budgets'); + if (is_array($array)) { + foreach ($array as $budgetId) { + $budgetId = (int)$budgetId; + $budget = $repository->find($budgetId); + if (null !== $budget) { + $this->budgets->push($budget); + } + } + } + } + /** * @return Collection */ @@ -112,6 +178,28 @@ class GenericRequest extends FormRequest return $this->categories; } + /** + * + */ + private function parseCategories(): void + { + if (0 !== $this->categories->count()) { + return; + } + $repository = app(CategoryRepositoryInterface::class); + $repository->setUser(auth()->user()); + $array = $this->get('categories'); + if (is_array($array)) { + foreach ($array as $categoryId) { + $categoryId = (int)$categoryId; + $category = $repository->find($categoryId); + if (null !== $category) { + $this->categories->push($category); + } + } + } + } + /** * @return Carbon */ @@ -180,114 +268,6 @@ class GenericRequest extends FormRequest return $this->tags; } - /** - * The rules that the incoming request must be matched against. - * - * @return array - */ - public function rules(): array - { - // this is cheating, but it works to initialize the collections. - $this->accounts = new Collection(); - $this->budgets = new Collection(); - $this->categories = new Collection(); - $this->bills = new Collection(); - $this->tags = new Collection(); - - return [ - 'start' => 'required|date', - 'end' => 'required|date|after_or_equal:start', - ]; - } - - /** - * - */ - private function parseAccounts(): void - { - if (0 !== $this->accounts->count()) { - return; - } - $repository = app(AccountRepositoryInterface::class); - $repository->setUser(auth()->user()); - $array = $this->get('accounts'); - if (is_array($array)) { - foreach ($array as $accountId) { - $accountId = (int)$accountId; - $account = $repository->find($accountId); - if (null !== $account) { - $this->accounts->push($account); - } - } - } - } - - /** - * - */ - private function parseBills(): void - { - if (0 !== $this->bills->count()) { - return; - } - $repository = app(BillRepositoryInterface::class); - $repository->setUser(auth()->user()); - $array = $this->get('bills'); - if (is_array($array)) { - foreach ($array as $billId) { - $billId = (int)$billId; - $bill = $repository->find($billId); - if (null !== $bill) { - $this->bills->push($bill); - } - } - } - } - - /** - * - */ - private function parseBudgets(): void - { - if (0 !== $this->budgets->count()) { - return; - } - $repository = app(BudgetRepositoryInterface::class); - $repository->setUser(auth()->user()); - $array = $this->get('budgets'); - if (is_array($array)) { - foreach ($array as $budgetId) { - $budgetId = (int)$budgetId; - $budget = $repository->find($budgetId); - if (null !== $budget) { - $this->budgets->push($budget); - } - } - } - } - - /** - * - */ - private function parseCategories(): void - { - if (0 !== $this->categories->count()) { - return; - } - $repository = app(CategoryRepositoryInterface::class); - $repository->setUser(auth()->user()); - $array = $this->get('categories'); - if (is_array($array)) { - foreach ($array as $categoryId) { - $categoryId = (int)$categoryId; - $category = $repository->find($categoryId); - if (null !== $category) { - $this->categories->push($category); - } - } - } - } - /** * */ @@ -309,4 +289,24 @@ class GenericRequest extends FormRequest } } } + + /** + * The rules that the incoming request must be matched against. + * + * @return array + */ + public function rules(): array + { + // this is cheating, but it works to initialize the collections. + $this->accounts = new Collection(); + $this->budgets = new Collection(); + $this->categories = new Collection(); + $this->bills = new Collection(); + $this->tags = new Collection(); + + return [ + 'start' => 'required|date', + 'end' => 'required|date|after_or_equal:start', + ]; + } } diff --git a/app/Api/V1/Requests/Models/Account/StoreRequest.php b/app/Api/V1/Requests/Models/Account/StoreRequest.php index 7be849258f..d46322bea9 100644 --- a/app/Api/V1/Requests/Models/Account/StoreRequest.php +++ b/app/Api/V1/Requests/Models/Account/StoreRequest.php @@ -104,7 +104,7 @@ class StoreRequest extends FormRequest $type = $this->convertString('type'); $rules = [ 'name' => 'required|max:1024|min:1|uniqueAccountForUser', - 'type' => 'required|max:1024|min:1|'.sprintf('in:%s', $types), + 'type' => 'required|max:1024|min:1|' . sprintf('in:%s', $types), 'iban' => ['iban', 'nullable', new UniqueIban(null, $type)], 'bic' => 'bic|nullable', 'account_number' => ['between:1,255', 'nullable', new UniqueAccountNumber(null, $type)], diff --git a/app/Api/V1/Requests/Models/Account/UpdateRequest.php b/app/Api/V1/Requests/Models/Account/UpdateRequest.php index 08ba545aa8..d50f9d10eb 100644 --- a/app/Api/V1/Requests/Models/Account/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/Account/UpdateRequest.php @@ -109,7 +109,7 @@ class UpdateRequest extends FormRequest 'include_net_worth' => [new IsBoolean()], 'account_role' => sprintf('in:%s|nullable|required_if:type,asset', $accountRoles), 'credit_card_type' => sprintf('in:%s|nullable|required_if:account_role,ccAsset', $ccPaymentTypes), - 'monthly_payment_date' => 'date'.'|nullable|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull', + 'monthly_payment_date' => 'date' . '|nullable|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull', 'liability_type' => 'required_if:type,liability|in:loan,debt,mortgage', 'liability_direction' => 'required_if:type,liability|in:credit,debit', 'interest' => 'required_if:type,liability|between:0,100|numeric', diff --git a/app/Api/V1/Requests/Models/AvailableBudget/Request.php b/app/Api/V1/Requests/Models/AvailableBudget/Request.php index 454ab77167..f92de0da5a 100644 --- a/app/Api/V1/Requests/Models/AvailableBudget/Request.php +++ b/app/Api/V1/Requests/Models/AvailableBudget/Request.php @@ -77,7 +77,7 @@ class Request extends FormRequest /** * Configure the validator instance with special rules for after the basic validation rules. * - * @param Validator $validator + * @param Validator $validator * * @return void */ diff --git a/app/Api/V1/Requests/Models/Bill/StoreRequest.php b/app/Api/V1/Requests/Models/Bill/StoreRequest.php index 8d3b990f7b..416d73ac99 100644 --- a/app/Api/V1/Requests/Models/Bill/StoreRequest.php +++ b/app/Api/V1/Requests/Models/Bill/StoreRequest.php @@ -96,7 +96,7 @@ class StoreRequest extends FormRequest /** * Configure the validator instance. * - * @param Validator $validator + * @param Validator $validator * * @return void */ diff --git a/app/Api/V1/Requests/Models/Bill/UpdateRequest.php b/app/Api/V1/Requests/Models/Bill/UpdateRequest.php index ded92b920c..25adeb2705 100644 --- a/app/Api/V1/Requests/Models/Bill/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/Bill/UpdateRequest.php @@ -98,7 +98,7 @@ class UpdateRequest extends FormRequest /** * Configure the validator instance. * - * @param Validator $validator + * @param Validator $validator * * @return void */ diff --git a/app/Api/V1/Requests/Models/Budget/StoreRequest.php b/app/Api/V1/Requests/Models/Budget/StoreRequest.php index d53e144fe9..78714bb474 100644 --- a/app/Api/V1/Requests/Models/Budget/StoreRequest.php +++ b/app/Api/V1/Requests/Models/Budget/StoreRequest.php @@ -88,7 +88,7 @@ class StoreRequest extends FormRequest /** * Configure the validator instance with special rules for after the basic validation rules. * - * @param Validator $validator + * @param Validator $validator * * @return void */ diff --git a/app/Api/V1/Requests/Models/Budget/UpdateRequest.php b/app/Api/V1/Requests/Models/Budget/UpdateRequest.php index f4de11b76b..2fd5e43560 100644 --- a/app/Api/V1/Requests/Models/Budget/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/Budget/UpdateRequest.php @@ -100,7 +100,7 @@ class UpdateRequest extends FormRequest /** * Configure the validator instance with special rules for after the basic validation rules. * - * @param Validator $validator + * @param Validator $validator * * @return void */ diff --git a/app/Api/V1/Requests/Models/BudgetLimit/UpdateRequest.php b/app/Api/V1/Requests/Models/BudgetLimit/UpdateRequest.php index d863916ae5..4df2b88936 100644 --- a/app/Api/V1/Requests/Models/BudgetLimit/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/BudgetLimit/UpdateRequest.php @@ -76,7 +76,7 @@ class UpdateRequest extends FormRequest /** * Configure the validator instance with special rules for after the basic validation rules. * - * @param Validator $validator + * @param Validator $validator * TODO duplicate code * * @return void diff --git a/app/Api/V1/Requests/Models/PiggyBank/UpdateRequest.php b/app/Api/V1/Requests/Models/PiggyBank/UpdateRequest.php index e12390f600..7eb4ae1dba 100644 --- a/app/Api/V1/Requests/Models/PiggyBank/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/PiggyBank/UpdateRequest.php @@ -74,7 +74,7 @@ class UpdateRequest extends FormRequest $piggyBank = $this->route()->parameter('piggyBank'); return [ - 'name' => 'between:1,255|uniquePiggyBankForUser:'.$piggyBank->id, + 'name' => 'between:1,255|uniquePiggyBankForUser:' . $piggyBank->id, 'current_amount' => ['numeric', 'gte:0', new LessThanPiggyTarget()], 'target_amount' => 'numeric|gte:0', 'start_date' => 'date|nullable', diff --git a/app/Api/V1/Requests/Models/Recurrence/StoreRequest.php b/app/Api/V1/Requests/Models/Recurrence/StoreRequest.php index 22502451f9..bfd273969d 100644 --- a/app/Api/V1/Requests/Models/Recurrence/StoreRequest.php +++ b/app/Api/V1/Requests/Models/Recurrence/StoreRequest.php @@ -73,6 +73,65 @@ class StoreRequest extends FormRequest ]; } + /** + * Returns the transaction data as it is found in the submitted data. It's a complex method according to code + * standards but it just has a lot of ??-statements because of the fields that may or may not exist. + * + * @return array + */ + private function getTransactionData(): array + { + $return = []; + // transaction data: + /** @var array|null $transactions */ + $transactions = $this->get('transactions'); + if (null === $transactions) { + return []; + } + /** @var array $transaction */ + foreach ($transactions as $transaction) { + $return[] = $this->getSingleTransactionData($transaction); + } + + return $return; + } + + /** + * Returns the repetition data as it is found in the submitted data. + * + * @return array + */ + private function getRepetitionData(): array + { + $return = []; + // repetition data: + /** @var array|null $repetitions */ + $repetitions = $this->get('repetitions'); + if (null === $repetitions) { + return []; + } + /** @var array $repetition */ + foreach ($repetitions as $repetition) { + $current = []; + if (array_key_exists('type', $repetition)) { + $current['type'] = $repetition['type']; + } + if (array_key_exists('moment', $repetition)) { + $current['moment'] = $repetition['moment']; + } + if (array_key_exists('skip', $repetition)) { + $current['skip'] = (int)$repetition['skip']; + } + if (array_key_exists('weekend', $repetition)) { + $current['weekend'] = (int)$repetition['weekend']; + } + + $return[] = $current; + } + + return $return; + } + /** * The rules that the incoming request must be matched against. * @@ -121,7 +180,7 @@ class StoreRequest extends FormRequest /** * Configure the validator instance. * - * @param Validator $validator + * @param Validator $validator * * @return void */ @@ -139,63 +198,4 @@ class StoreRequest extends FormRequest } ); } - - /** - * Returns the repetition data as it is found in the submitted data. - * - * @return array - */ - private function getRepetitionData(): array - { - $return = []; - // repetition data: - /** @var array|null $repetitions */ - $repetitions = $this->get('repetitions'); - if (null === $repetitions) { - return []; - } - /** @var array $repetition */ - foreach ($repetitions as $repetition) { - $current = []; - if (array_key_exists('type', $repetition)) { - $current['type'] = $repetition['type']; - } - if (array_key_exists('moment', $repetition)) { - $current['moment'] = $repetition['moment']; - } - if (array_key_exists('skip', $repetition)) { - $current['skip'] = (int)$repetition['skip']; - } - if (array_key_exists('weekend', $repetition)) { - $current['weekend'] = (int)$repetition['weekend']; - } - - $return[] = $current; - } - - return $return; - } - - /** - * Returns the transaction data as it is found in the submitted data. It's a complex method according to code - * standards but it just has a lot of ??-statements because of the fields that may or may not exist. - * - * @return array - */ - private function getTransactionData(): array - { - $return = []; - // transaction data: - /** @var array|null $transactions */ - $transactions = $this->get('transactions'); - if (null === $transactions) { - return []; - } - /** @var array $transaction */ - foreach ($transactions as $transaction) { - $return[] = $this->getSingleTransactionData($transaction); - } - - return $return; - } } diff --git a/app/Api/V1/Requests/Models/Recurrence/UpdateRequest.php b/app/Api/V1/Requests/Models/Recurrence/UpdateRequest.php index 71198089f2..8d5f790c4c 100644 --- a/app/Api/V1/Requests/Models/Recurrence/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/Recurrence/UpdateRequest.php @@ -80,80 +80,6 @@ class UpdateRequest extends FormRequest return $return; } - /** - * The rules that the incoming request must be matched against. - * - * @return array - */ - public function rules(): array - { - /** @var Recurrence $recurrence */ - $recurrence = $this->route()->parameter('recurrence'); - - return [ - 'title' => sprintf('between:1,255|uniqueObjectForUser:recurrences,title,%d', $recurrence->id), - 'description' => 'between:1,65000', - 'first_date' => 'date', - 'apply_rules' => [new IsBoolean()], - 'active' => [new IsBoolean()], - 'repeat_until' => 'nullable|date', - 'nr_of_repetitions' => 'nullable|numeric|between:1,31', - - 'repetitions.*.type' => 'in:daily,weekly,ndom,monthly,yearly', - 'repetitions.*.moment' => 'between:0,10', - 'repetitions.*.skip' => 'nullable|numeric|between:0,31', - 'repetitions.*.weekend' => 'nullable|numeric|min:1|max:4', - - 'transactions.*.description' => 'between:1,255', - 'transactions.*.amount' => 'numeric|gt:0', - 'transactions.*.foreign_amount' => 'nullable|numeric|gt:0', - 'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id', - 'transactions.*.currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code', - 'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id', - 'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code', - 'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()], - 'transactions.*.source_name' => 'between:1,255|nullable', - 'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()], - 'transactions.*.destination_name' => 'between:1,255|nullable', - - // new and updated fields: - 'transactions.*.budget_id' => ['nullable', 'mustExist:budgets,id', new BelongsUser()], - 'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()], - 'transactions.*.category_id' => ['nullable', 'mustExist:categories,id', new BelongsUser()], - 'transactions.*.category_name' => 'between:1,255|nullable', - 'transactions.*.piggy_bank_id' => ['nullable', 'numeric', 'mustExist:piggy_banks,id', new BelongsUser()], - 'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser()], - 'transactions.*.tags' => 'nullable|between:1,64000', - - ]; - } - - /** - * Configure the validator instance. - * - * @param Validator $validator - * - * @return void - */ - public function withValidator(Validator $validator): void - { - $validator->after( - function (Validator $validator) { - //$this->validateOneRecurrenceTransaction($validator); - //$this->validateOneRepetitionUpdate($validator); - - - /** @var Recurrence $recurrence */ - $recurrence = $this->route()->parameter('recurrence'); - $this->validateTransactionId($recurrence, $validator); - $this->validateRecurrenceRepetition($validator); - $this->validateRepetitionMoment($validator); - $this->validateForeignCurrencyInformation($validator); - $this->valUpdateAccountInfo($validator); - } - ); - } - /** * Returns the repetition data as it is found in the submitted data. * @@ -218,4 +144,78 @@ class UpdateRequest extends FormRequest return $return; } + /** + * The rules that the incoming request must be matched against. + * + * @return array + */ + public function rules(): array + { + /** @var Recurrence $recurrence */ + $recurrence = $this->route()->parameter('recurrence'); + + return [ + 'title' => sprintf('between:1,255|uniqueObjectForUser:recurrences,title,%d', $recurrence->id), + 'description' => 'between:1,65000', + 'first_date' => 'date', + 'apply_rules' => [new IsBoolean()], + 'active' => [new IsBoolean()], + 'repeat_until' => 'nullable|date', + 'nr_of_repetitions' => 'nullable|numeric|between:1,31', + + 'repetitions.*.type' => 'in:daily,weekly,ndom,monthly,yearly', + 'repetitions.*.moment' => 'between:0,10', + 'repetitions.*.skip' => 'nullable|numeric|between:0,31', + 'repetitions.*.weekend' => 'nullable|numeric|min:1|max:4', + + 'transactions.*.description' => 'between:1,255', + 'transactions.*.amount' => 'numeric|gt:0', + 'transactions.*.foreign_amount' => 'nullable|numeric|gt:0', + 'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id', + 'transactions.*.currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code', + 'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id', + 'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code', + 'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()], + 'transactions.*.source_name' => 'between:1,255|nullable', + 'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()], + 'transactions.*.destination_name' => 'between:1,255|nullable', + + // new and updated fields: + 'transactions.*.budget_id' => ['nullable', 'mustExist:budgets,id', new BelongsUser()], + 'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()], + 'transactions.*.category_id' => ['nullable', 'mustExist:categories,id', new BelongsUser()], + 'transactions.*.category_name' => 'between:1,255|nullable', + 'transactions.*.piggy_bank_id' => ['nullable', 'numeric', 'mustExist:piggy_banks,id', new BelongsUser()], + 'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser()], + 'transactions.*.tags' => 'nullable|between:1,64000', + + ]; + } + + /** + * Configure the validator instance. + * + * @param Validator $validator + * + * @return void + */ + public function withValidator(Validator $validator): void + { + $validator->after( + function (Validator $validator) { + //$this->validateOneRecurrenceTransaction($validator); + //$this->validateOneRepetitionUpdate($validator); + + + /** @var Recurrence $recurrence */ + $recurrence = $this->route()->parameter('recurrence'); + $this->validateTransactionId($recurrence, $validator); + $this->validateRecurrenceRepetition($validator); + $this->validateRepetitionMoment($validator); + $this->validateForeignCurrencyInformation($validator); + $this->valUpdateAccountInfo($validator); + } + ); + } + } diff --git a/app/Api/V1/Requests/Models/Rule/StoreRequest.php b/app/Api/V1/Requests/Models/Rule/StoreRequest.php index 578df69405..2b241f0e96 100644 --- a/app/Api/V1/Requests/Models/Rule/StoreRequest.php +++ b/app/Api/V1/Requests/Models/Rule/StoreRequest.php @@ -67,6 +67,48 @@ class StoreRequest extends FormRequest return $data; } + /** + * @return array + */ + private function getRuleTriggers(): array + { + $triggers = $this->get('triggers'); + $return = []; + if (is_array($triggers)) { + foreach ($triggers as $trigger) { + $return[] = [ + 'type' => $trigger['type'], + 'value' => $trigger['value'], + 'active' => $this->convertBoolean((string)($trigger['active'] ?? 'true')), + 'stop_processing' => $this->convertBoolean((string)($trigger['stop_processing'] ?? 'false')), + ]; + } + } + + return $return; + } + + /** + * @return array + */ + private function getRuleActions(): array + { + $actions = $this->get('actions'); + $return = []; + if (is_array($actions)) { + foreach ($actions as $action) { + $return[] = [ + 'type' => $action['type'], + 'value' => $action['value'], + 'active' => $this->convertBoolean((string)($action['active'] ?? 'true')), + 'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')), + ]; + } + } + + return $return; + } + /** * The rules that the incoming request must be matched against. * @@ -87,12 +129,12 @@ class StoreRequest extends FormRequest 'rule_group_id' => 'belongsToUser:rule_groups|required_without:rule_group_title', 'rule_group_title' => 'nullable|between:1,255|required_without:rule_group_id|belongsToUser:rule_groups,title', 'trigger' => 'required|in:store-journal,update-journal', - 'triggers.*.type' => 'required|in:'.implode(',', $validTriggers), - 'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024', + 'triggers.*.type' => 'required|in:' . implode(',', $validTriggers), + 'triggers.*.value' => 'required_if:actions.*.type,' . $contextTriggers . '|min:1|ruleTriggerValue|max:1024', 'triggers.*.stop_processing' => [new IsBoolean()], 'triggers.*.active' => [new IsBoolean()], - 'actions.*.type' => 'required|in:'.implode(',', $validActions), - 'actions.*.value' => 'required_if:actions.*.type,'.$contextActions.'|ruleActionValue', + 'actions.*.type' => 'required|in:' . implode(',', $validActions), + 'actions.*.value' => 'required_if:actions.*.type,' . $contextActions . '|ruleActionValue', 'actions.*.stop_processing' => [new IsBoolean()], 'actions.*.active' => [new IsBoolean()], 'strict' => [new IsBoolean()], @@ -104,7 +146,7 @@ class StoreRequest extends FormRequest /** * Configure the validator instance. * - * @param Validator $validator + * @param Validator $validator * * @return void */ @@ -120,10 +162,25 @@ class StoreRequest extends FormRequest ); } + /** + * Adds an error to the validator when there are no triggers in the array of data. + * + * @param Validator $validator + */ + protected function atLeastOneTrigger(Validator $validator): void + { + $data = $validator->getData(); + $triggers = $data['triggers'] ?? []; + // need at least one trigger + if (!is_countable($triggers) || 0 === count($triggers)) { + $validator->errors()->add('title', (string)trans('validation.at_least_one_trigger')); + } + } + /** * Adds an error to the validator when there are no repetitions in the array of data. * - * @param Validator $validator + * @param Validator $validator */ protected function atLeastOneAction(Validator $validator): void { @@ -135,39 +192,10 @@ class StoreRequest extends FormRequest } } - /** - * Adds an error to the validator when there are no ACTIVE actions in the array of data. - * - * @param Validator $validator - */ - protected function atLeastOneActiveAction(Validator $validator): void - { - $data = $validator->getData(); - $actions = $data['actions'] ?? []; - // need at least one trigger - if (!is_countable($actions) || 0 === count($actions)) { - return; - } - $allInactive = true; - $inactiveIndex = 0; - foreach ($actions as $index => $action) { - $active = array_key_exists('active', $action) ? $action['active'] : true; // assume true - if (true === $active) { - $allInactive = false; - } - if (false === $active) { - $inactiveIndex = $index; - } - } - if (true === $allInactive) { - $validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action')); - } - } - /** * Adds an error to the validator when there are no ACTIVE triggers in the array of data. * - * @param Validator $validator + * @param Validator $validator */ protected function atLeastOneActiveTrigger(Validator $validator): void { @@ -194,59 +222,31 @@ class StoreRequest extends FormRequest } /** - * Adds an error to the validator when there are no triggers in the array of data. + * Adds an error to the validator when there are no ACTIVE actions in the array of data. * - * @param Validator $validator + * @param Validator $validator */ - protected function atLeastOneTrigger(Validator $validator): void + protected function atLeastOneActiveAction(Validator $validator): void { - $data = $validator->getData(); - $triggers = $data['triggers'] ?? []; + $data = $validator->getData(); + $actions = $data['actions'] ?? []; // need at least one trigger - if (!is_countable($triggers) || 0 === count($triggers)) { - $validator->errors()->add('title', (string)trans('validation.at_least_one_trigger')); + if (!is_countable($actions) || 0 === count($actions)) { + return; } - } - - /** - * @return array - */ - private function getRuleActions(): array - { - $actions = $this->get('actions'); - $return = []; - if (is_array($actions)) { - foreach ($actions as $action) { - $return[] = [ - 'type' => $action['type'], - 'value' => $action['value'], - 'active' => $this->convertBoolean((string)($action['active'] ?? 'true')), - 'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')), - ]; + $allInactive = true; + $inactiveIndex = 0; + foreach ($actions as $index => $action) { + $active = array_key_exists('active', $action) ? $action['active'] : true; // assume true + if (true === $active) { + $allInactive = false; + } + if (false === $active) { + $inactiveIndex = $index; } } - - return $return; - } - - /** - * @return array - */ - private function getRuleTriggers(): array - { - $triggers = $this->get('triggers'); - $return = []; - if (is_array($triggers)) { - foreach ($triggers as $trigger) { - $return[] = [ - 'type' => $trigger['type'], - 'value' => $trigger['value'], - 'active' => $this->convertBoolean((string)($trigger['active'] ?? 'true')), - 'stop_processing' => $this->convertBoolean((string)($trigger['stop_processing'] ?? 'false')), - ]; - } + if (true === $allInactive) { + $validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action')); } - - return $return; } } diff --git a/app/Api/V1/Requests/Models/Rule/TestRequest.php b/app/Api/V1/Requests/Models/Rule/TestRequest.php index b392a370cb..331c4922c3 100644 --- a/app/Api/V1/Requests/Models/Rule/TestRequest.php +++ b/app/Api/V1/Requests/Models/Rule/TestRequest.php @@ -52,16 +52,21 @@ class TestRequest extends FormRequest } /** - * @return array + * @return int */ - public function rules(): array + private function getPage(): int { - return [ - 'start' => 'date', - 'end' => 'date|after_or_equal:start', - 'accounts' => '', - 'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts', - ]; + return 0 === (int)$this->query('page') ? 1 : (int)$this->query('page'); + } + + /** + * @param string $field + * + * @return Carbon|null + */ + private function getDate(string $field): ?Carbon + { + return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field)); } /** @@ -73,20 +78,15 @@ class TestRequest extends FormRequest } /** - * @param string $field - * - * @return Carbon|null + * @return array */ - private function getDate(string $field): ?Carbon + public function rules(): array { - return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field)); - } - - /** - * @return int - */ - private function getPage(): int - { - return 0 === (int)$this->query('page') ? 1 : (int)$this->query('page'); + return [ + 'start' => 'date', + 'end' => 'date|after_or_equal:start', + 'accounts' => '', + 'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts', + ]; } } diff --git a/app/Api/V1/Requests/Models/Rule/TriggerRequest.php b/app/Api/V1/Requests/Models/Rule/TriggerRequest.php index 88b39b02b7..12785842c1 100644 --- a/app/Api/V1/Requests/Models/Rule/TriggerRequest.php +++ b/app/Api/V1/Requests/Models/Rule/TriggerRequest.php @@ -50,16 +50,13 @@ class TriggerRequest extends FormRequest } /** - * @return array + * @param string $field + * + * @return Carbon|null */ - public function rules(): array + private function getDate(string $field): ?Carbon { - return [ - 'start' => 'date', - 'end' => 'date|after_or_equal:start', - 'accounts' => '', - 'accounts.*' => 'exists:accounts,id|belongsToUser:accounts', - ]; + return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($this->query($field), 0, 10)); } /** @@ -71,12 +68,15 @@ class TriggerRequest extends FormRequest } /** - * @param string $field - * - * @return Carbon|null + * @return array */ - private function getDate(string $field): ?Carbon + public function rules(): array { - return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($this->query($field), 0, 10)); + return [ + 'start' => 'date', + 'end' => 'date|after_or_equal:start', + 'accounts' => '', + 'accounts.*' => 'exists:accounts,id|belongsToUser:accounts', + ]; } } diff --git a/app/Api/V1/Requests/Models/Rule/UpdateRequest.php b/app/Api/V1/Requests/Models/Rule/UpdateRequest.php index ec951d8a7f..363dc7eef6 100644 --- a/app/Api/V1/Requests/Models/Rule/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/Rule/UpdateRequest.php @@ -74,149 +74,29 @@ class UpdateRequest extends FormRequest } /** - * The rules that the incoming request must be matched against. - * - * @return array + * @return array|null */ - public function rules(): array + private function getRuleTriggers(): ?array { - $validTriggers = $this->getTriggers(); - $validActions = array_keys(config('firefly.rule-actions')); - - /** @var Rule $rule */ - $rule = $this->route()->parameter('rule'); - - // some triggers and actions require text: - $contextTriggers = implode(',', $this->getTriggersWithContext()); - $contextActions = implode(',', config('firefly.context-rule-actions')); - - return [ - 'title' => sprintf('between:1,100|uniqueObjectForUser:rules,title,%d', $rule->id), - 'description' => 'between:1,5000|nullable', - 'rule_group_id' => 'belongsToUser:rule_groups', - 'rule_group_title' => 'nullable|between:1,255|belongsToUser:rule_groups,title', - 'trigger' => 'in:store-journal,update-journal', - 'triggers.*.type' => 'required|in:'.implode(',', $validTriggers), - 'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024', - 'triggers.*.stop_processing' => [new IsBoolean()], - 'triggers.*.active' => [new IsBoolean()], - 'actions.*.type' => 'required|in:'.implode(',', $validActions), - 'actions.*.value' => 'required_if:actions.*.type,'.$contextActions.'|ruleActionValue', - 'actions.*.stop_processing' => [new IsBoolean()], - 'actions.*.active' => [new IsBoolean()], - 'strict' => [new IsBoolean()], - 'stop_processing' => [new IsBoolean()], - 'active' => [new IsBoolean()], - 'order' => 'numeric|between:1,1337', - ]; - } - - /** - * Configure the validator instance. - * - * @param Validator $validator - * - * @return void - */ - public function withValidator(Validator $validator): void - { - $validator->after( - function (Validator $validator) { - $this->atLeastOneTrigger($validator); - $this->atLeastOneValidTrigger($validator); - $this->atLeastOneAction($validator); - $this->atLeastOneValidAction($validator); - } - ); - } - - /** - * Adds an error to the validator when there are no repetitions in the array of data. - * - * @param Validator $validator - */ - protected function atLeastOneAction(Validator $validator): void - { - $data = $validator->getData(); - $actions = $data['actions'] ?? null; - // need at least one action - if (is_array($actions) && 0 === count($actions)) { - $validator->errors()->add('title', (string)trans('validation.at_least_one_action')); + if (!$this->has('triggers')) { + return null; } - } - - /** - * Adds an error to the validator when there are no repetitions in the array of data. - * - * @param Validator $validator - */ - protected function atLeastOneTrigger(Validator $validator): void - { - $data = $validator->getData(); - $triggers = $data['triggers'] ?? null; - // need at least one trigger - if (is_array($triggers) && 0 === count($triggers)) { - $validator->errors()->add('title', (string)trans('validation.at_least_one_trigger')); - } - } - - /** - * Adds an error to the validator when there are no repetitions in the array of data. - * - * @param Validator $validator - */ - protected function atLeastOneValidAction(Validator $validator): void - { - $data = $validator->getData(); - $actions = $data['actions'] ?? []; - $allInactive = true; - $inactiveIndex = 0; - // need at least one action - if (is_array($actions) && 0 === count($actions)) { - return; - } - - foreach ($actions as $index => $action) { - $active = array_key_exists('active', $action) ? $action['active'] : true; // assume true - if (true === $active) { - $allInactive = false; - } - if (false === $active) { - $inactiveIndex = $index; + $triggers = $this->get('triggers'); + $return = []; + if (is_array($triggers)) { + foreach ($triggers as $trigger) { + $active = array_key_exists('active', $trigger) ? $trigger['active'] : true; + $stopProcessing = array_key_exists('stop_processing', $trigger) ? $trigger['stop_processing'] : false; + $return[] = [ + 'type' => $trigger['type'], + 'value' => $trigger['value'], + 'active' => $active, + 'stop_processing' => $stopProcessing, + ]; } } - if (true === $allInactive) { - $validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action')); - } - } - /** - * Adds an error to the validator when there are no repetitions in the array of data. - * - * @param Validator $validator - */ - protected function atLeastOneValidTrigger(Validator $validator): void - { - $data = $validator->getData(); - $triggers = $data['triggers'] ?? []; - $allInactive = true; - $inactiveIndex = 0; - // need at least one trigger - if (is_array($triggers) && 0 === count($triggers)) { - return; - } - foreach ($triggers as $index => $trigger) { - $active = array_key_exists('active', $trigger) ? $trigger['active'] : true; // assume true - if (true === $active) { - $allInactive = false; - } - if (false === $active) { - $inactiveIndex = $index; - } - } - if (true === $allInactive) { - $validator->errors()->add(sprintf('triggers.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_trigger')); - } + return $return; } /** @@ -244,28 +124,148 @@ class UpdateRequest extends FormRequest } /** - * @return array|null + * The rules that the incoming request must be matched against. + * + * @return array */ - private function getRuleTriggers(): ?array + public function rules(): array { - if (!$this->has('triggers')) { - return null; + $validTriggers = $this->getTriggers(); + $validActions = array_keys(config('firefly.rule-actions')); + + /** @var Rule $rule */ + $rule = $this->route()->parameter('rule'); + + // some triggers and actions require text: + $contextTriggers = implode(',', $this->getTriggersWithContext()); + $contextActions = implode(',', config('firefly.context-rule-actions')); + + return [ + 'title' => sprintf('between:1,100|uniqueObjectForUser:rules,title,%d', $rule->id), + 'description' => 'between:1,5000|nullable', + 'rule_group_id' => 'belongsToUser:rule_groups', + 'rule_group_title' => 'nullable|between:1,255|belongsToUser:rule_groups,title', + 'trigger' => 'in:store-journal,update-journal', + 'triggers.*.type' => 'required|in:' . implode(',', $validTriggers), + 'triggers.*.value' => 'required_if:actions.*.type,' . $contextTriggers . '|min:1|ruleTriggerValue|max:1024', + 'triggers.*.stop_processing' => [new IsBoolean()], + 'triggers.*.active' => [new IsBoolean()], + 'actions.*.type' => 'required|in:' . implode(',', $validActions), + 'actions.*.value' => 'required_if:actions.*.type,' . $contextActions . '|ruleActionValue', + 'actions.*.stop_processing' => [new IsBoolean()], + 'actions.*.active' => [new IsBoolean()], + 'strict' => [new IsBoolean()], + 'stop_processing' => [new IsBoolean()], + 'active' => [new IsBoolean()], + 'order' => 'numeric|between:1,1337', + ]; + } + + /** + * Configure the validator instance. + * + * @param Validator $validator + * + * @return void + */ + public function withValidator(Validator $validator): void + { + $validator->after( + function (Validator $validator) { + $this->atLeastOneTrigger($validator); + $this->atLeastOneValidTrigger($validator); + $this->atLeastOneAction($validator); + $this->atLeastOneValidAction($validator); + } + ); + } + + /** + * Adds an error to the validator when there are no repetitions in the array of data. + * + * @param Validator $validator + */ + protected function atLeastOneTrigger(Validator $validator): void + { + $data = $validator->getData(); + $triggers = $data['triggers'] ?? null; + // need at least one trigger + if (is_array($triggers) && 0 === count($triggers)) { + $validator->errors()->add('title', (string)trans('validation.at_least_one_trigger')); } - $triggers = $this->get('triggers'); - $return = []; - if (is_array($triggers)) { - foreach ($triggers as $trigger) { - $active = array_key_exists('active', $trigger) ? $trigger['active'] : true; - $stopProcessing = array_key_exists('stop_processing', $trigger) ? $trigger['stop_processing'] : false; - $return[] = [ - 'type' => $trigger['type'], - 'value' => $trigger['value'], - 'active' => $active, - 'stop_processing' => $stopProcessing, - ]; + } + + /** + * Adds an error to the validator when there are no repetitions in the array of data. + * + * @param Validator $validator + */ + protected function atLeastOneValidTrigger(Validator $validator): void + { + $data = $validator->getData(); + $triggers = $data['triggers'] ?? []; + $allInactive = true; + $inactiveIndex = 0; + // need at least one trigger + if (is_array($triggers) && 0 === count($triggers)) { + return; + } + foreach ($triggers as $index => $trigger) { + $active = array_key_exists('active', $trigger) ? $trigger['active'] : true; // assume true + if (true === $active) { + $allInactive = false; + } + if (false === $active) { + $inactiveIndex = $index; } } + if (true === $allInactive) { + $validator->errors()->add(sprintf('triggers.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_trigger')); + } + } - return $return; + /** + * Adds an error to the validator when there are no repetitions in the array of data. + * + * @param Validator $validator + */ + protected function atLeastOneAction(Validator $validator): void + { + $data = $validator->getData(); + $actions = $data['actions'] ?? null; + // need at least one action + if (is_array($actions) && 0 === count($actions)) { + $validator->errors()->add('title', (string)trans('validation.at_least_one_action')); + } + } + + /** + * Adds an error to the validator when there are no repetitions in the array of data. + * + * @param Validator $validator + */ + protected function atLeastOneValidAction(Validator $validator): void + { + $data = $validator->getData(); + $actions = $data['actions'] ?? []; + $allInactive = true; + $inactiveIndex = 0; + // need at least one action + if (is_array($actions) && 0 === count($actions)) { + return; + } + + foreach ($actions as $index => $action) { + $active = array_key_exists('active', $action) ? $action['active'] : true; // assume true + if (true === $active) { + $allInactive = false; + } + if (false === $active) { + $inactiveIndex = $index; + } + } + if (true === $allInactive) { + $validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action')); + } } } diff --git a/app/Api/V1/Requests/Models/RuleGroup/TestRequest.php b/app/Api/V1/Requests/Models/RuleGroup/TestRequest.php index 15837e5678..81226973b5 100644 --- a/app/Api/V1/Requests/Models/RuleGroup/TestRequest.php +++ b/app/Api/V1/Requests/Models/RuleGroup/TestRequest.php @@ -50,16 +50,13 @@ class TestRequest extends FormRequest } /** - * @return array + * @param string $field + * + * @return Carbon|null */ - public function rules(): array + private function getDate(string $field): ?Carbon { - return [ - 'start' => 'date', - 'end' => 'date|after_or_equal:start', - 'accounts' => '', - 'accounts.*' => 'exists:accounts,id|belongsToUser:accounts', - ]; + return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field)); } /** @@ -71,12 +68,15 @@ class TestRequest extends FormRequest } /** - * @param string $field - * - * @return Carbon|null + * @return array */ - private function getDate(string $field): ?Carbon + public function rules(): array { - return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field)); + return [ + 'start' => 'date', + 'end' => 'date|after_or_equal:start', + 'accounts' => '', + 'accounts.*' => 'exists:accounts,id|belongsToUser:accounts', + ]; } } diff --git a/app/Api/V1/Requests/Models/RuleGroup/TriggerRequest.php b/app/Api/V1/Requests/Models/RuleGroup/TriggerRequest.php index b057efc783..4d9514307a 100644 --- a/app/Api/V1/Requests/Models/RuleGroup/TriggerRequest.php +++ b/app/Api/V1/Requests/Models/RuleGroup/TriggerRequest.php @@ -50,14 +50,13 @@ class TriggerRequest extends FormRequest } /** - * @return array + * @param string $field + * + * @return Carbon|null */ - public function rules(): array + private function getDate(string $field): ?Carbon { - return [ - 'start' => 'date', - 'end' => 'date|after_or_equal:start', - ]; + return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field)); } /** @@ -69,12 +68,13 @@ class TriggerRequest extends FormRequest } /** - * @param string $field - * - * @return Carbon|null + * @return array */ - private function getDate(string $field): ?Carbon + public function rules(): array { - return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field)); + return [ + 'start' => 'date', + 'end' => 'date|after_or_equal:start', + ]; } } diff --git a/app/Api/V1/Requests/Models/RuleGroup/UpdateRequest.php b/app/Api/V1/Requests/Models/RuleGroup/UpdateRequest.php index 62d3f4061b..a417570bce 100644 --- a/app/Api/V1/Requests/Models/RuleGroup/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/RuleGroup/UpdateRequest.php @@ -66,7 +66,7 @@ class UpdateRequest extends FormRequest $ruleGroup = $this->route()->parameter('ruleGroup'); return [ - 'title' => 'between:1,100|uniqueObjectForUser:rule_groups,title,'.$ruleGroup->id, + 'title' => 'between:1,100|uniqueObjectForUser:rule_groups,title,' . $ruleGroup->id, 'description' => 'between:1,5000|nullable', 'active' => [new IsBoolean()], ]; diff --git a/app/Api/V1/Requests/Models/Tag/UpdateRequest.php b/app/Api/V1/Requests/Models/Tag/UpdateRequest.php index 03eb2d2573..d364e8605f 100644 --- a/app/Api/V1/Requests/Models/Tag/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/Tag/UpdateRequest.php @@ -71,7 +71,7 @@ class UpdateRequest extends FormRequest $tag = $this->route()->parameter('tagOrId'); // TODO check if uniqueObjectForUser is obsolete $rules = [ - 'tag' => 'min:1|max:1024|uniqueObjectForUser:tags,tag,'.$tag->id, + 'tag' => 'min:1|max:1024|uniqueObjectForUser:tags,tag,' . $tag->id, 'description' => 'min:1|nullable|max:65536', 'date' => 'date|nullable', ]; diff --git a/app/Api/V1/Requests/Models/Transaction/StoreRequest.php b/app/Api/V1/Requests/Models/Transaction/StoreRequest.php index e9ebda90f0..932d3061cf 100644 --- a/app/Api/V1/Requests/Models/Transaction/StoreRequest.php +++ b/app/Api/V1/Requests/Models/Transaction/StoreRequest.php @@ -69,135 +69,6 @@ class StoreRequest extends FormRequest // TODO include location and ability to process it. } - /** - * The rules that the incoming request must be matched against. - * - * @return array - */ - public function rules(): array - { - Log::debug('Collect rules of TransactionStoreRequest'); - - return [ - // basic fields for group: - 'group_title' => 'between:1,1000|nullable', - 'error_if_duplicate_hash' => [new IsBoolean()], - 'apply_rules' => [new IsBoolean()], - - // transaction rules (in array for splits): - 'transactions.*.type' => 'required|in:withdrawal,deposit,transfer,opening-balance,reconciliation', - 'transactions.*.date' => ['required', new IsDateOrTime()], - 'transactions.*.order' => 'numeric|min:0', - - // currency info - 'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable', - 'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable', - 'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id|nullable', - 'transactions.*.foreign_currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable', - - // amount - 'transactions.*.amount' => 'required|numeric|gt:0', - 'transactions.*.foreign_amount' => 'numeric', - - // description - 'transactions.*.description' => 'nullable|between:1,1000', - - // source of transaction - 'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()], - 'transactions.*.source_name' => 'between:1,255|nullable', - 'transactions.*.source_iban' => 'between:1,255|nullable|iban', - 'transactions.*.source_number' => 'between:1,255|nullable', - 'transactions.*.source_bic' => 'between:1,255|nullable|bic', - - // destination of transaction - 'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()], - 'transactions.*.destination_name' => 'between:1,255|nullable', - 'transactions.*.destination_iban' => 'between:1,255|nullable|iban', - 'transactions.*.destination_number' => 'between:1,255|nullable', - 'transactions.*.destination_bic' => 'between:1,255|nullable|bic', - - // budget, category, bill and piggy - 'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser()], - 'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()], - 'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'], - 'transactions.*.category_name' => 'between:1,255|nullable', - 'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()], - 'transactions.*.bill_name' => ['between:1,255', 'nullable', new BelongsUser()], - 'transactions.*.piggy_bank_id' => ['numeric', 'nullable', 'mustExist:piggy_banks,id', new BelongsUser()], - 'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser()], - - // other interesting fields - 'transactions.*.reconciled' => [new IsBoolean()], - 'transactions.*.notes' => 'min:1|max:50000|nullable', - 'transactions.*.tags' => 'between:0,255', - - // meta info fields - 'transactions.*.internal_reference' => 'min:1|max:255|nullable', - 'transactions.*.external_id' => 'min:1|max:255|nullable', - 'transactions.*.recurrence_id' => 'min:1|max:255|nullable', - 'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable', - 'transactions.*.external_url' => 'min:1|max:255|nullable|url', - - // SEPA fields: - 'transactions.*.sepa_cc' => 'min:1|max:255|nullable', - 'transactions.*.sepa_ct_op' => 'min:1|max:255|nullable', - 'transactions.*.sepa_ct_id' => 'min:1|max:255|nullable', - 'transactions.*.sepa_db' => 'min:1|max:255|nullable', - 'transactions.*.sepa_country' => 'min:1|max:255|nullable', - 'transactions.*.sepa_ep' => 'min:1|max:255|nullable', - 'transactions.*.sepa_ci' => 'min:1|max:255|nullable', - 'transactions.*.sepa_batch_id' => 'min:1|max:255|nullable', - - // dates - 'transactions.*.interest_date' => 'date|nullable', - 'transactions.*.book_date' => 'date|nullable', - 'transactions.*.process_date' => 'date|nullable', - 'transactions.*.due_date' => 'date|nullable', - 'transactions.*.payment_date' => 'date|nullable', - 'transactions.*.invoice_date' => 'date|nullable', - ]; - } - - /** - * Configure the validator instance. - * - * @param Validator $validator - * - * @return void - */ - public function withValidator(Validator $validator): void - { - $validator->after( - function (Validator $validator) { - // must be valid array. - $this->validateTransactionArray($validator); - - // must submit at least one transaction. - Log::debug('Now going to validateOneTransaction'); - $this->validateOneTransaction($validator); - Log::debug('Now done with validateOneTransaction'); - - // all journals must have a description - $this->validateDescriptions($validator); - - // all transaction types must be equal: - $this->validateTransactionTypes($validator); - - // validate foreign currency info - $this->validateForeignCurrencyInformation($validator); - - // validate all account info - $this->validateAccountInformation($validator); - - // validate source/destination is equal, depending on the transaction journal type. - $this->validateEqualAccounts($validator); - - // the group must have a description if > 1 journal. - $this->validateGroupDescription($validator); - } - ); - } - /** * Get transaction data. * @@ -294,4 +165,133 @@ class StoreRequest extends FormRequest return $return; } + + /** + * The rules that the incoming request must be matched against. + * + * @return array + */ + public function rules(): array + { + Log::debug('Collect rules of TransactionStoreRequest'); + + return [ + // basic fields for group: + 'group_title' => 'between:1,1000|nullable', + 'error_if_duplicate_hash' => [new IsBoolean()], + 'apply_rules' => [new IsBoolean()], + + // transaction rules (in array for splits): + 'transactions.*.type' => 'required|in:withdrawal,deposit,transfer,opening-balance,reconciliation', + 'transactions.*.date' => ['required', new IsDateOrTime()], + 'transactions.*.order' => 'numeric|min:0', + + // currency info + 'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable', + 'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable', + 'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id|nullable', + 'transactions.*.foreign_currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable', + + // amount + 'transactions.*.amount' => 'required|numeric|gt:0', + 'transactions.*.foreign_amount' => 'numeric', + + // description + 'transactions.*.description' => 'nullable|between:1,1000', + + // source of transaction + 'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()], + 'transactions.*.source_name' => 'between:1,255|nullable', + 'transactions.*.source_iban' => 'between:1,255|nullable|iban', + 'transactions.*.source_number' => 'between:1,255|nullable', + 'transactions.*.source_bic' => 'between:1,255|nullable|bic', + + // destination of transaction + 'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()], + 'transactions.*.destination_name' => 'between:1,255|nullable', + 'transactions.*.destination_iban' => 'between:1,255|nullable|iban', + 'transactions.*.destination_number' => 'between:1,255|nullable', + 'transactions.*.destination_bic' => 'between:1,255|nullable|bic', + + // budget, category, bill and piggy + 'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser()], + 'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()], + 'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'], + 'transactions.*.category_name' => 'between:1,255|nullable', + 'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()], + 'transactions.*.bill_name' => ['between:1,255', 'nullable', new BelongsUser()], + 'transactions.*.piggy_bank_id' => ['numeric', 'nullable', 'mustExist:piggy_banks,id', new BelongsUser()], + 'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser()], + + // other interesting fields + 'transactions.*.reconciled' => [new IsBoolean()], + 'transactions.*.notes' => 'min:1|max:50000|nullable', + 'transactions.*.tags' => 'between:0,255', + + // meta info fields + 'transactions.*.internal_reference' => 'min:1|max:255|nullable', + 'transactions.*.external_id' => 'min:1|max:255|nullable', + 'transactions.*.recurrence_id' => 'min:1|max:255|nullable', + 'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable', + 'transactions.*.external_url' => 'min:1|max:255|nullable|url', + + // SEPA fields: + 'transactions.*.sepa_cc' => 'min:1|max:255|nullable', + 'transactions.*.sepa_ct_op' => 'min:1|max:255|nullable', + 'transactions.*.sepa_ct_id' => 'min:1|max:255|nullable', + 'transactions.*.sepa_db' => 'min:1|max:255|nullable', + 'transactions.*.sepa_country' => 'min:1|max:255|nullable', + 'transactions.*.sepa_ep' => 'min:1|max:255|nullable', + 'transactions.*.sepa_ci' => 'min:1|max:255|nullable', + 'transactions.*.sepa_batch_id' => 'min:1|max:255|nullable', + + // dates + 'transactions.*.interest_date' => 'date|nullable', + 'transactions.*.book_date' => 'date|nullable', + 'transactions.*.process_date' => 'date|nullable', + 'transactions.*.due_date' => 'date|nullable', + 'transactions.*.payment_date' => 'date|nullable', + 'transactions.*.invoice_date' => 'date|nullable', + ]; + } + + /** + * Configure the validator instance. + * + * @param Validator $validator + * + * @return void + */ + public function withValidator(Validator $validator): void + { + $validator->after( + function (Validator $validator) { + // must be valid array. + $this->validateTransactionArray($validator); + + // must submit at least one transaction. + Log::debug('Now going to validateOneTransaction'); + $this->validateOneTransaction($validator); + Log::debug('Now done with validateOneTransaction'); + + // all journals must have a description + $this->validateDescriptions($validator); + + // all transaction types must be equal: + $this->validateTransactionTypes($validator); + + // validate foreign currency info + $this->validateForeignCurrencyInformation($validator); + + // validate all account info + $this->validateAccountInformation($validator); + + // validate source/destination is equal, depending on the transaction journal type. + $this->validateEqualAccounts($validator); + + // the group must have a description if > 1 journal. + $this->validateGroupDescription($validator); + } + ); + } } diff --git a/app/Api/V1/Requests/Models/Transaction/UpdateRequest.php b/app/Api/V1/Requests/Models/Transaction/UpdateRequest.php index 9fd68335dd..ca3ba78dc7 100644 --- a/app/Api/V1/Requests/Models/Transaction/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/Transaction/UpdateRequest.php @@ -185,8 +185,8 @@ class UpdateRequest extends FormRequest /** * For each field, add it to the array if a reference is present in the request: * - * @param array $current - * @param array $transaction + * @param array $current + * @param array $transaction * * @return array */ @@ -202,8 +202,8 @@ class UpdateRequest extends FormRequest } /** - * @param array $current - * @param array $transaction + * @param array $current + * @param array $transaction * * @return array */ @@ -219,8 +219,8 @@ class UpdateRequest extends FormRequest } /** - * @param array $current - * @param array $transaction + * @param array $current + * @param array $transaction * * @return array */ @@ -236,8 +236,8 @@ class UpdateRequest extends FormRequest } /** - * @param array $current - * @param array $transaction + * @param array $current + * @param array $transaction * * @return array */ @@ -255,8 +255,8 @@ class UpdateRequest extends FormRequest } /** - * @param array $current - * @param array $transaction + * @param array $current + * @param array $transaction * * @return array */ @@ -272,8 +272,8 @@ class UpdateRequest extends FormRequest } /** - * @param array $current - * @param array $transaction + * @param array $current + * @param array $transaction * * @return array */ @@ -289,8 +289,8 @@ class UpdateRequest extends FormRequest } /** - * @param array $current - * @param array $transaction + * @param array $current + * @param array $transaction * * @return array */ @@ -398,7 +398,7 @@ class UpdateRequest extends FormRequest /** * Configure the validator instance. * - * @param Validator $validator + * @param Validator $validator * * @return void */ diff --git a/app/Api/V1/Requests/Models/TransactionLink/StoreRequest.php b/app/Api/V1/Requests/Models/TransactionLink/StoreRequest.php index af57c23d31..dd97a2a4c1 100644 --- a/app/Api/V1/Requests/Models/TransactionLink/StoreRequest.php +++ b/app/Api/V1/Requests/Models/TransactionLink/StoreRequest.php @@ -74,7 +74,7 @@ class StoreRequest extends FormRequest /** * Configure the validator instance. * - * @param Validator $validator + * @param Validator $validator * * @return void */ @@ -88,7 +88,7 @@ class StoreRequest extends FormRequest } /** - * @param Validator $validator + * @param Validator $validator */ private function validateExistingLink(Validator $validator): void { diff --git a/app/Api/V1/Requests/Models/TransactionLink/UpdateRequest.php b/app/Api/V1/Requests/Models/TransactionLink/UpdateRequest.php index e63121c47b..92cc96c909 100644 --- a/app/Api/V1/Requests/Models/TransactionLink/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/TransactionLink/UpdateRequest.php @@ -74,7 +74,7 @@ class UpdateRequest extends FormRequest /** * Configure the validator instance. * - * @param Validator $validator + * @param Validator $validator * * @return void */ @@ -88,7 +88,7 @@ class UpdateRequest extends FormRequest } /** - * @param Validator $validator + * @param Validator $validator */ private function validateUpdate(Validator $validator): void { diff --git a/app/Api/V1/Requests/System/UserUpdateRequest.php b/app/Api/V1/Requests/System/UserUpdateRequest.php index a6a6292543..87013e88fd 100644 --- a/app/Api/V1/Requests/System/UserUpdateRequest.php +++ b/app/Api/V1/Requests/System/UserUpdateRequest.php @@ -90,7 +90,7 @@ class UserUpdateRequest extends FormRequest /** * Configure the validator instance. * - * @param Validator $validator + * @param Validator $validator * * @return void */ diff --git a/app/Api/V2/Controllers/Autocomplete/AccountController.php b/app/Api/V2/Controllers/Autocomplete/AccountController.php index 3c4f6ef2f6..393c5ce06c 100644 --- a/app/Api/V2/Controllers/Autocomplete/AccountController.php +++ b/app/Api/V2/Controllers/Autocomplete/AccountController.php @@ -32,7 +32,6 @@ use FireflyIII\Models\AccountType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface; use FireflyIII\Support\Http\Api\AccountFilter; -use FireflyIII\User; use Illuminate\Http\JsonResponse; use JsonException; @@ -68,7 +67,7 @@ class AccountController extends Controller * Documentation for this endpoint: * TODO endpoint is not documented. * - * @param AutocompleteRequest $request + * @param AutocompleteRequest $request * * @return JsonResponse * @throws JsonException diff --git a/app/Api/V2/Controllers/Chart/AccountController.php b/app/Api/V2/Controllers/Chart/AccountController.php index 7ae5182c25..1c342e1120 100644 --- a/app/Api/V2/Controllers/Chart/AccountController.php +++ b/app/Api/V2/Controllers/Chart/AccountController.php @@ -63,7 +63,7 @@ class AccountController extends Controller * This endpoint is documented at * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/charts/getChartAccountOverview * - * @param DateRequest $request + * @param DateRequest $request * * @return JsonResponse * @throws ContainerExceptionInterface diff --git a/app/Api/V2/Controllers/Controller.php b/app/Api/V2/Controllers/Controller.php index c00ad133b8..c3731acabe 100644 --- a/app/Api/V2/Controllers/Controller.php +++ b/app/Api/V2/Controllers/Controller.php @@ -64,54 +64,6 @@ class Controller extends BaseController } } - /** - * @param string $key - * @param LengthAwarePaginator $paginator - * @param AbstractTransformer $transformer - * - * @return array - */ - final protected function jsonApiList(string $key, LengthAwarePaginator $paginator, AbstractTransformer $transformer): array - { - $manager = new Manager(); - $baseUrl = request()->getSchemeAndHttpHost().'/api/v2'; - $manager->setSerializer(new JsonApiSerializer($baseUrl)); - - $objects = $paginator->getCollection(); - - // the transformer, at this point, needs to collect information that ALL items in the collection - // require, like meta data and stuff like that, and save it for later. - $transformer->collectMetaData($objects); - - $resource = new FractalCollection($objects, $transformer, $key); - $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); - - return $manager->createData($resource)->toArray(); - } - - /** - * Returns a JSON API object and returns it. - * - * @param string $key - * @param Model $object - * @param AbstractTransformer $transformer - * - * @return array - */ - final protected function jsonApiObject(string $key, Model $object, AbstractTransformer $transformer): array - { - // create some objects: - $manager = new Manager(); - $baseUrl = request()->getSchemeAndHttpHost().'/api/v2'; - $manager->setSerializer(new JsonApiSerializer($baseUrl)); - - $transformer->collectMetaData(new Collection([$object])); - - $resource = new Item($object, $transformer, $key); - - return $manager->createData($resource)->toArray(); - } - /** * TODO duplicate from V1 controller * Method to grab all parameters from the URL. @@ -123,7 +75,7 @@ class Controller extends BaseController $bag = new ParameterBag(); try { $page = (int)request()->get('page'); - } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) { + } catch (ContainerExceptionInterface | NotFoundExceptionInterface $e) { $page = 1; } @@ -152,7 +104,7 @@ class Controller extends BaseController if (null !== $date) { try { $obj = Carbon::parse($date); - } catch (InvalidDateException|InvalidFormatException $e) { + } catch (InvalidDateException | InvalidFormatException $e) { // don't care app('log')->warning(sprintf('Ignored invalid date "%s" in API v2 controller parameter check: %s', substr($date, 0, 20), $e->getMessage())); } @@ -179,4 +131,52 @@ class Controller extends BaseController return $bag; } + + /** + * @param string $key + * @param LengthAwarePaginator $paginator + * @param AbstractTransformer $transformer + * + * @return array + */ + final protected function jsonApiList(string $key, LengthAwarePaginator $paginator, AbstractTransformer $transformer): array + { + $manager = new Manager(); + $baseUrl = request()->getSchemeAndHttpHost() . '/api/v2'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + + $objects = $paginator->getCollection(); + + // the transformer, at this point, needs to collect information that ALL items in the collection + // require, like meta data and stuff like that, and save it for later. + $transformer->collectMetaData($objects); + + $resource = new FractalCollection($objects, $transformer, $key); + $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); + + return $manager->createData($resource)->toArray(); + } + + /** + * Returns a JSON API object and returns it. + * + * @param string $key + * @param Model $object + * @param AbstractTransformer $transformer + * + * @return array + */ + final protected function jsonApiObject(string $key, Model $object, AbstractTransformer $transformer): array + { + // create some objects: + $manager = new Manager(); + $baseUrl = request()->getSchemeAndHttpHost() . '/api/v2'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + + $transformer->collectMetaData(new Collection([$object])); + + $resource = new Item($object, $transformer, $key); + + return $manager->createData($resource)->toArray(); + } } diff --git a/app/Api/V2/Controllers/Model/Bill/SumController.php b/app/Api/V2/Controllers/Model/Bill/SumController.php index 879f501278..61456329b8 100644 --- a/app/Api/V2/Controllers/Model/Bill/SumController.php +++ b/app/Api/V2/Controllers/Model/Bill/SumController.php @@ -58,7 +58,7 @@ class SumController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/transactions-sum/getBillsPaidTrSum * - * @param DateRequest $request + * @param DateRequest $request * * @return JsonResponse */ @@ -76,7 +76,7 @@ class SumController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/transactions-sum/getBillsUnpaidTrSum * - * @param DateRequest $request + * @param DateRequest $request * * @return JsonResponse */ diff --git a/app/Api/V2/Controllers/Model/Budget/ListController.php b/app/Api/V2/Controllers/Model/Budget/ListController.php index 65a7836833..37b1a92e38 100644 --- a/app/Api/V2/Controllers/Model/Budget/ListController.php +++ b/app/Api/V2/Controllers/Model/Budget/ListController.php @@ -51,7 +51,7 @@ class ListController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/budgets/listBudgets * - * @param Request $request + * @param Request $request * * @return JsonResponse */ diff --git a/app/Api/V2/Controllers/Model/Budget/SumController.php b/app/Api/V2/Controllers/Model/Budget/SumController.php index 80c39ac5df..15de6ca665 100644 --- a/app/Api/V2/Controllers/Model/Budget/SumController.php +++ b/app/Api/V2/Controllers/Model/Budget/SumController.php @@ -58,7 +58,7 @@ class SumController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/budgets/getBudgetedForBudget * - * @param DateRequest $request + * @param DateRequest $request * * @return JsonResponse */ @@ -75,7 +75,7 @@ class SumController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/budgets/getSpentForBudget * - * @param DateRequest $request + * @param DateRequest $request * * @return JsonResponse */ diff --git a/app/Api/V2/Controllers/NetWorthController.php b/app/Api/V2/Controllers/NetWorthController.php index b842a9a744..1c7d196ef1 100644 --- a/app/Api/V2/Controllers/NetWorthController.php +++ b/app/Api/V2/Controllers/NetWorthController.php @@ -58,7 +58,7 @@ class NetWorthController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/net-worth/getNetWorth * - * @param SingleDateRequest $request + * @param SingleDateRequest $request * * @return JsonResponse */ diff --git a/app/Api/V2/Controllers/System/PreferencesController.php b/app/Api/V2/Controllers/System/PreferencesController.php index 64d8aaf967..915ab2ce3d 100644 --- a/app/Api/V2/Controllers/System/PreferencesController.php +++ b/app/Api/V2/Controllers/System/PreferencesController.php @@ -38,7 +38,7 @@ class PreferencesController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/preferences/getPreference * - * @param Preference $preference + * @param Preference $preference * * @return JsonResponse */ diff --git a/app/Api/V2/Controllers/Transaction/List/AccountController.php b/app/Api/V2/Controllers/Transaction/List/AccountController.php index 324f541c90..0d3ae2761a 100644 --- a/app/Api/V2/Controllers/Transaction/List/AccountController.php +++ b/app/Api/V2/Controllers/Transaction/List/AccountController.php @@ -44,8 +44,8 @@ class AccountController extends Controller * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/accounts/listTransactionByAccount * - * @param ListRequest $request - * @param Account $account + * @param ListRequest $request + * @param Account $account * * @return JsonResponse */ diff --git a/app/Api/V2/Request/Autocomplete/AutocompleteRequest.php b/app/Api/V2/Request/Autocomplete/AutocompleteRequest.php index 74d8eaf801..7bd383b8a1 100644 --- a/app/Api/V2/Request/Autocomplete/AutocompleteRequest.php +++ b/app/Api/V2/Request/Autocomplete/AutocompleteRequest.php @@ -83,7 +83,7 @@ class AutocompleteRequest extends FormRequest /** * Configure the validator instance with special rules for after the basic validation rules. * - * @param Validator $validator + * @param Validator $validator * * @return void */ diff --git a/app/Api/V2/Response/Sum/AutoSum.php b/app/Api/V2/Response/Sum/AutoSum.php index 691d3c3eff..5953c7ed71 100644 --- a/app/Api/V2/Response/Sum/AutoSum.php +++ b/app/Api/V2/Response/Sum/AutoSum.php @@ -38,9 +38,9 @@ use Illuminate\Support\Collection; class AutoSum { /** - * @param Collection $objects - * @param Closure $getCurrency - * @param Closure $getSum + * @param Collection $objects + * @param Closure $getCurrency + * @param Closure $getSum * * @return array * @throws FireflyException diff --git a/app/Console/Commands/Correction/CorrectAmounts.php b/app/Console/Commands/Correction/CorrectAmounts.php index e9199540a6..c2d53cd097 100644 --- a/app/Console/Commands/Correction/CorrectAmounts.php +++ b/app/Console/Commands/Correction/CorrectAmounts.php @@ -174,6 +174,26 @@ class CorrectAmounts extends Command $this->friendlyInfo(sprintf('Corrected %d currency exchange rate(s).', $count)); } + /** + * @return void + */ + private function fixRepetitions(): void + { + $set = PiggyBankRepetition::where('currentamount', '<', 0)->get(); + $count = $set->count(); + if (0 === $count) { + $this->friendlyPositive('All piggy bank repetition amounts are positive.'); + + return; + } + /** @var PiggyBankRepetition $item */ + foreach ($set as $item) { + $item->currentamount = app('steam')->positive((string)$item->currentamount); + $item->save(); + } + $this->friendlyInfo(sprintf('Corrected %d piggy bank repetition amount(s).', $count)); + } + /** * @return void */ @@ -217,26 +237,6 @@ class CorrectAmounts extends Command $this->friendlyInfo(sprintf('Corrected %d recurring transaction amount(s).', $count)); } - /** - * @return void - */ - private function fixRepetitions(): void - { - $set = PiggyBankRepetition::where('currentamount', '<', 0)->get(); - $count = $set->count(); - if (0 === $count) { - $this->friendlyPositive('All piggy bank repetition amounts are positive.'); - - return; - } - /** @var PiggyBankRepetition $item */ - foreach ($set as $item) { - $item->currentamount = app('steam')->positive((string)$item->currentamount); - $item->save(); - } - $this->friendlyInfo(sprintf('Corrected %d piggy bank repetition amount(s).', $count)); - } - /** * @return void */ diff --git a/app/Console/Commands/Correction/CorrectOpeningBalanceCurrencies.php b/app/Console/Commands/Correction/CorrectOpeningBalanceCurrencies.php index f82512adcf..5185be8789 100644 --- a/app/Console/Commands/Correction/CorrectOpeningBalanceCurrencies.php +++ b/app/Console/Commands/Correction/CorrectOpeningBalanceCurrencies.php @@ -72,7 +72,18 @@ class CorrectOpeningBalanceCurrencies extends Command } /** - * @param TransactionJournal $journal + * @return Collection + */ + private function getJournals(): Collection + { + /** @var Collection */ + return TransactionJournal::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') + ->whereNull('transaction_journals.deleted_at') + ->where('transaction_types.type', TransactionType::OPENING_BALANCE)->get(['transaction_journals.*']); + } + + /** + * @param TransactionJournal $journal * * @return int */ @@ -93,7 +104,7 @@ class CorrectOpeningBalanceCurrencies extends Command } /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return Account|null */ @@ -113,33 +124,8 @@ class CorrectOpeningBalanceCurrencies extends Command } /** - * @param Account $account - * - * @return TransactionCurrency - */ - private function getCurrency(Account $account): TransactionCurrency - { - /** @var AccountRepositoryInterface $repos */ - $repos = app(AccountRepositoryInterface::class); - $repos->setUser($account->user); - - return $repos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user); - } - - /** - * @return Collection - */ - private function getJournals(): Collection - { - /** @var Collection */ - return TransactionJournal::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') - ->whereNull('transaction_journals.deleted_at') - ->where('transaction_types.type', TransactionType::OPENING_BALANCE)->get(['transaction_journals.*']); - } - - /** - * @param Account $account - * @param TransactionJournal $journal + * @param Account $account + * @param TransactionJournal $journal * @return int */ private function setCorrectCurrency(Account $account, TransactionJournal $journal): int @@ -163,4 +149,18 @@ class CorrectOpeningBalanceCurrencies extends Command return $count; } + + /** + * @param Account $account + * + * @return TransactionCurrency + */ + private function getCurrency(Account $account): TransactionCurrency + { + /** @var AccountRepositoryInterface $repos */ + $repos = app(AccountRepositoryInterface::class); + $repos->setUser($account->user); + + return $repos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user); + } } diff --git a/app/Console/Commands/Correction/DeleteEmptyJournals.php b/app/Console/Commands/Correction/DeleteEmptyJournals.php index 681c583a67..bf10ef7ec2 100644 --- a/app/Console/Commands/Correction/DeleteEmptyJournals.php +++ b/app/Console/Commands/Correction/DeleteEmptyJournals.php @@ -64,30 +64,6 @@ class DeleteEmptyJournals extends Command return 0; } - private function deleteEmptyJournals(): void - { - $count = 0; - $set = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->groupBy('transaction_journals.id') - ->whereNull('transactions.transaction_journal_id') - ->get(['transaction_journals.id']); - - foreach ($set as $entry) { - try { - TransactionJournal::find($entry->id)->delete(); - } catch (QueryException $e) { - Log::info(sprintf('Could not delete entry: %s', $e->getMessage())); - } - - - $this->friendlyInfo(sprintf('Deleted empty transaction journal #%d', $entry->id)); - ++$count; - } - if (0 === $count) { - $this->friendlyPositive('No empty transaction journals.'); - } - } - /** * Delete transactions and their journals if they have an uneven number of transactions. */ @@ -120,4 +96,28 @@ class DeleteEmptyJournals extends Command $this->friendlyPositive('No uneven transaction journals.'); } } + + private function deleteEmptyJournals(): void + { + $count = 0; + $set = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->groupBy('transaction_journals.id') + ->whereNull('transactions.transaction_journal_id') + ->get(['transaction_journals.id']); + + foreach ($set as $entry) { + try { + TransactionJournal::find($entry->id)->delete(); + } catch (QueryException $e) { + Log::info(sprintf('Could not delete entry: %s', $e->getMessage())); + } + + + $this->friendlyInfo(sprintf('Deleted empty transaction journal #%d', $entry->id)); + ++$count; + } + if (0 === $count) { + $this->friendlyPositive('No empty transaction journals.'); + } + } } diff --git a/app/Console/Commands/Correction/DeleteOrphanedTransactions.php b/app/Console/Commands/Correction/DeleteOrphanedTransactions.php index fd5a2469ba..e8e6a55f9e 100644 --- a/app/Console/Commands/Correction/DeleteOrphanedTransactions.php +++ b/app/Console/Commands/Correction/DeleteOrphanedTransactions.php @@ -65,38 +65,6 @@ class DeleteOrphanedTransactions extends Command return 0; } - /** - * - */ - private function deleteFromOrphanedAccounts(): void - { - $set - = Transaction::leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id') - ->whereNotNull('accounts.deleted_at') - ->get(['transactions.*']); - $count = 0; - /** @var Transaction $transaction */ - foreach ($set as $transaction) { - // delete journals - $journal = TransactionJournal::find((int)$transaction->transaction_journal_id); - if ($journal) { - $journal->delete(); - } - Transaction::where('transaction_journal_id', (int)$transaction->transaction_journal_id)->delete(); - $this->friendlyWarning( - sprintf( - 'Deleted transaction journal #%d because account #%d was already deleted.', - $transaction->transaction_journal_id, - $transaction->account_id - ) - ); - $count++; - } - if (0 === $count) { - $this->friendlyPositive('No orphaned accounts.'); - } - } - private function deleteOrphanedJournals(): void { $set = TransactionJournal::leftJoin('transaction_groups', 'transaction_journals.transaction_group_id', 'transaction_groups.id') @@ -159,4 +127,36 @@ class DeleteOrphanedTransactions extends Command $this->friendlyPositive('No orphaned transactions.'); } } + + /** + * + */ + private function deleteFromOrphanedAccounts(): void + { + $set + = Transaction::leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id') + ->whereNotNull('accounts.deleted_at') + ->get(['transactions.*']); + $count = 0; + /** @var Transaction $transaction */ + foreach ($set as $transaction) { + // delete journals + $journal = TransactionJournal::find((int)$transaction->transaction_journal_id); + if ($journal) { + $journal->delete(); + } + Transaction::where('transaction_journal_id', (int)$transaction->transaction_journal_id)->delete(); + $this->friendlyWarning( + sprintf( + 'Deleted transaction journal #%d because account #%d was already deleted.', + $transaction->transaction_journal_id, + $transaction->account_id + ) + ); + $count++; + } + if (0 === $count) { + $this->friendlyPositive('No orphaned accounts.'); + } + } } diff --git a/app/Console/Commands/Correction/EnableCurrencies.php b/app/Console/Commands/Correction/EnableCurrencies.php index a47b2957a1..f2b2e094b5 100644 --- a/app/Console/Commands/Correction/EnableCurrencies.php +++ b/app/Console/Commands/Correction/EnableCurrencies.php @@ -31,7 +31,6 @@ use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionJournal; use Illuminate\Console\Command; use Illuminate\Support\Collection; -use Illuminate\Support\Facades\Log; /** * Class EnableCurrencies diff --git a/app/Console/Commands/Correction/FixAccountTypes.php b/app/Console/Commands/Correction/FixAccountTypes.php index f2b84ebc75..eadee90d4f 100644 --- a/app/Console/Commands/Correction/FixAccountTypes.php +++ b/app/Console/Commands/Correction/FixAccountTypes.php @@ -31,8 +31,8 @@ use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; use Illuminate\Console\Command; -use JsonException; use Illuminate\Support\Facades\Log; +use JsonException; /** * Class FixAccountTypes @@ -74,10 +74,83 @@ class FixAccountTypes extends Command } /** - * @param TransactionJournal $journal - * @param string $type - * @param Transaction $source - * @param Transaction $dest + * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is + * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should + * be called from the handle method instead of using the constructor to initialize the command. + * + + */ + private function stupidLaravel(): void + { + $this->count = 0; + } + + /** + * @param TransactionJournal $journal + * + * @throws FireflyException + */ + private function inspectJournal(TransactionJournal $journal): void + { + $transactions = $journal->transactions()->count(); + if (2 !== $transactions) { + Log::debug(sprintf('Journal has %d transactions, so can\'t fix.', $transactions)); + $this->friendlyError(sprintf('Cannot inspect transaction journal #%d because it has %d transaction(s) instead of 2.', $journal->id, $transactions)); + + return; + } + $type = $journal->transactionType->type; + $sourceTransaction = $this->getSourceTransaction($journal); + $destTransaction = $this->getDestinationTransaction($journal); + $sourceAccount = $sourceTransaction->account; + $sourceAccountType = $sourceAccount->accountType->type; + $destAccount = $destTransaction->account; + $destAccountType = $destAccount->accountType->type; + + if (!array_key_exists($type, $this->expected)) { + Log::info(sprintf('No source/destination info for transaction type %s.', $type)); + $this->friendlyError(sprintf('No source/destination info for transaction type %s.', $type)); + + return; + } + if (!array_key_exists($sourceAccountType, $this->expected[$type])) { + Log::debug(sprintf('Going to fix journal #%d', $journal->id)); + $this->fixJournal($journal, $type, $sourceTransaction, $destTransaction); + + return; + } + $expectedTypes = $this->expected[$type][$sourceAccountType]; + if (!in_array($destAccountType, $expectedTypes, true)) { + Log::debug(sprintf('Going to fix journal #%d', $journal->id)); + $this->fixJournal($journal, $type, $sourceTransaction, $destTransaction); + } + } + + /** + * @param TransactionJournal $journal + * + * @return Transaction + */ + private function getSourceTransaction(TransactionJournal $journal): Transaction + { + return $journal->transactions->firstWhere('amount', '<', 0); + } + + /** + * @param TransactionJournal $journal + * + * @return Transaction + */ + private function getDestinationTransaction(TransactionJournal $journal): Transaction + { + return $journal->transactions->firstWhere('amount', '>', 0); + } + + /** + * @param TransactionJournal $journal + * @param string $type + * @param Transaction $source + * @param Transaction $dest * * @throws FireflyException * @throws JsonException @@ -167,77 +240,4 @@ class FixAccountTypes extends Command break; } } - - /** - * @param TransactionJournal $journal - * - * @return Transaction - */ - private function getDestinationTransaction(TransactionJournal $journal): Transaction - { - return $journal->transactions->firstWhere('amount', '>', 0); - } - - /** - * @param TransactionJournal $journal - * - * @return Transaction - */ - private function getSourceTransaction(TransactionJournal $journal): Transaction - { - return $journal->transactions->firstWhere('amount', '<', 0); - } - - /** - * @param TransactionJournal $journal - * - * @throws FireflyException - */ - private function inspectJournal(TransactionJournal $journal): void - { - $transactions = $journal->transactions()->count(); - if (2 !== $transactions) { - Log::debug(sprintf('Journal has %d transactions, so can\'t fix.', $transactions)); - $this->friendlyError(sprintf('Cannot inspect transaction journal #%d because it has %d transaction(s) instead of 2.', $journal->id, $transactions)); - - return; - } - $type = $journal->transactionType->type; - $sourceTransaction = $this->getSourceTransaction($journal); - $destTransaction = $this->getDestinationTransaction($journal); - $sourceAccount = $sourceTransaction->account; - $sourceAccountType = $sourceAccount->accountType->type; - $destAccount = $destTransaction->account; - $destAccountType = $destAccount->accountType->type; - - if (!array_key_exists($type, $this->expected)) { - Log::info(sprintf('No source/destination info for transaction type %s.', $type)); - $this->friendlyError(sprintf('No source/destination info for transaction type %s.', $type)); - - return; - } - if (!array_key_exists($sourceAccountType, $this->expected[$type])) { - Log::debug(sprintf('Going to fix journal #%d', $journal->id)); - $this->fixJournal($journal, $type, $sourceTransaction, $destTransaction); - - return; - } - $expectedTypes = $this->expected[$type][$sourceAccountType]; - if (!in_array($destAccountType, $expectedTypes, true)) { - Log::debug(sprintf('Going to fix journal #%d', $journal->id)); - $this->fixJournal($journal, $type, $sourceTransaction, $destTransaction); - } - } - - /** - * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is - * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should - * be called from the handle method instead of using the constructor to initialize the command. - * - - */ - private function stupidLaravel(): void - { - $this->count = 0; - } } diff --git a/app/Console/Commands/Correction/FixFrontpageAccounts.php b/app/Console/Commands/Correction/FixFrontpageAccounts.php index ab336f09d8..884b4d43e1 100644 --- a/app/Console/Commands/Correction/FixFrontpageAccounts.php +++ b/app/Console/Commands/Correction/FixFrontpageAccounts.php @@ -63,7 +63,7 @@ class FixFrontpageAccounts extends Command } /** - * @param Preference $preference + * @param Preference $preference */ private function fixPreference(Preference $preference): void { diff --git a/app/Console/Commands/Correction/FixIbans.php b/app/Console/Commands/Correction/FixIbans.php index 893dcd45be..7afbd3c2cf 100644 --- a/app/Console/Commands/Correction/FixIbans.php +++ b/app/Console/Commands/Correction/FixIbans.php @@ -59,7 +59,29 @@ class FixIbans extends Command } /** - * @param Collection $accounts + * @param Collection $accounts + * + * @return void + */ + private function filterIbans(Collection $accounts): void + { + /** @var Account $account */ + foreach ($accounts as $account) { + $iban = $account->iban; + if (str_contains($iban, ' ')) { + $iban = app('steam')->filterSpaces((string)$account->iban); + if ('' !== $iban) { + $account->iban = $iban; + $account->save(); + $this->friendlyInfo(sprintf('Removed spaces from IBAN of account #%d', $account->id)); + $this->count++; + } + } + } + } + + /** + * @param Collection $accounts * * @return void */ @@ -105,26 +127,4 @@ class FixIbans extends Command } } } - - /** - * @param Collection $accounts - * - * @return void - */ - private function filterIbans(Collection $accounts): void - { - /** @var Account $account */ - foreach ($accounts as $account) { - $iban = $account->iban; - if (str_contains($iban, ' ')) { - $iban = app('steam')->filterSpaces((string)$account->iban); - if ('' !== $iban) { - $account->iban = $iban; - $account->save(); - $this->friendlyInfo(sprintf('Removed spaces from IBAN of account #%d', $account->id)); - $this->count++; - } - } - } - } } diff --git a/app/Console/Commands/Correction/FixRecurringTransactions.php b/app/Console/Commands/Correction/FixRecurringTransactions.php index af9ed0b1ce..ac2fc02cf8 100644 --- a/app/Console/Commands/Correction/FixRecurringTransactions.php +++ b/app/Console/Commands/Correction/FixRecurringTransactions.php @@ -62,6 +62,19 @@ class FixRecurringTransactions extends Command return 0; } + /** + * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is + * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should + * be called from the handle method instead of using the constructor to initialize the command. + * + + */ + private function stupidLaravel(): void + { + $this->recurringRepos = app(RecurringRepositoryInterface::class); + $this->userRepos = app(UserRepositoryInterface::class); + } + /** * */ @@ -75,7 +88,20 @@ class FixRecurringTransactions extends Command } /** - * @param Recurrence $recurrence + * @param User $user + */ + private function processUser(User $user): void + { + $this->recurringRepos->setUser($user); + $recurrences = $this->recurringRepos->get(); + /** @var Recurrence $recurrence */ + foreach ($recurrences as $recurrence) { + $this->processRecurrence($recurrence); + } + } + + /** + * @param Recurrence $recurrence */ private function processRecurrence(Recurrence $recurrence): void { @@ -86,8 +112,8 @@ class FixRecurringTransactions extends Command } /** - * @param Recurrence $recurrence - * @param RecurrenceTransaction $transaction + * @param Recurrence $recurrence + * @param RecurrenceTransaction $transaction */ private function processTransaction(Recurrence $recurrence, RecurrenceTransaction $transaction): void { @@ -107,30 +133,4 @@ class FixRecurringTransactions extends Command } } } - - /** - * @param User $user - */ - private function processUser(User $user): void - { - $this->recurringRepos->setUser($user); - $recurrences = $this->recurringRepos->get(); - /** @var Recurrence $recurrence */ - foreach ($recurrences as $recurrence) { - $this->processRecurrence($recurrence); - } - } - - /** - * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is - * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should - * be called from the handle method instead of using the constructor to initialize the command. - * - - */ - private function stupidLaravel(): void - { - $this->recurringRepos = app(RecurringRepositoryInterface::class); - $this->userRepos = app(UserRepositoryInterface::class); - } } diff --git a/app/Console/Commands/Correction/FixTransactionTypes.php b/app/Console/Commands/Correction/FixTransactionTypes.php index b4b88b18c4..9fbd8a42ce 100644 --- a/app/Console/Commands/Correction/FixTransactionTypes.php +++ b/app/Console/Commands/Correction/FixTransactionTypes.php @@ -69,19 +69,6 @@ class FixTransactionTypes extends Command return 0; } - /** - * @param TransactionJournal $journal - * @param string $expectedType - */ - private function changeJournal(TransactionJournal $journal, string $expectedType): void - { - $type = TransactionType::whereType($expectedType)->first(); - if (null !== $type) { - $journal->transaction_type_id = $type->id; - $journal->save(); - } - } - /** * Collect all transaction journals. * @@ -94,7 +81,7 @@ class FixTransactionTypes extends Command } /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return bool */ @@ -130,7 +117,37 @@ class FixTransactionTypes extends Command } /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal + * + * @return Account + * @throws FireflyException + */ + private function getSourceAccount(TransactionJournal $journal): Account + { + $collection = $journal->transactions->filter( + static function (Transaction $transaction) { + return $transaction->amount < 0; + } + ); + if (0 === $collection->count()) { + throw new FireflyException(sprintf('300001: Journal #%d has no source transaction.', $journal->id)); + } + if (1 !== $collection->count()) { + throw new FireflyException(sprintf('300002: Journal #%d has multiple source transactions.', $journal->id)); + } + /** @var Transaction $transaction */ + $transaction = $collection->first(); + /** @var Account|null $account */ + $account = $transaction->account; + if (null === $account) { + throw new FireflyException(sprintf('300003: Journal #%d, transaction #%d has no source account.', $journal->id, $transaction->id)); + } + + return $account; + } + + /** + * @param TransactionJournal $journal * * @return Account * @throws FireflyException @@ -160,32 +177,15 @@ class FixTransactionTypes extends Command } /** - * @param TransactionJournal $journal - * - * @return Account - * @throws FireflyException + * @param TransactionJournal $journal + * @param string $expectedType */ - private function getSourceAccount(TransactionJournal $journal): Account + private function changeJournal(TransactionJournal $journal, string $expectedType): void { - $collection = $journal->transactions->filter( - static function (Transaction $transaction) { - return $transaction->amount < 0; - } - ); - if (0 === $collection->count()) { - throw new FireflyException(sprintf('300001: Journal #%d has no source transaction.', $journal->id)); + $type = TransactionType::whereType($expectedType)->first(); + if (null !== $type) { + $journal->transaction_type_id = $type->id; + $journal->save(); } - if (1 !== $collection->count()) { - throw new FireflyException(sprintf('300002: Journal #%d has multiple source transactions.', $journal->id)); - } - /** @var Transaction $transaction */ - $transaction = $collection->first(); - /** @var Account|null $account */ - $account = $transaction->account; - if (null === $account) { - throw new FireflyException(sprintf('300003: Journal #%d, transaction #%d has no source account.', $journal->id, $transaction->id)); - } - - return $account; } } diff --git a/app/Console/Commands/Correction/FixUnevenAmount.php b/app/Console/Commands/Correction/FixUnevenAmount.php index 2e1b0bef4c..9b09734392 100644 --- a/app/Console/Commands/Correction/FixUnevenAmount.php +++ b/app/Console/Commands/Correction/FixUnevenAmount.php @@ -47,7 +47,7 @@ class FixUnevenAmount extends Command */ public function handle(): int { - $count = 0; + $count = 0; $journals = DB::table('transactions') ->groupBy('transaction_journal_id') ->whereNull('deleted_at') diff --git a/app/Console/Commands/Correction/RenameMetaFields.php b/app/Console/Commands/Correction/RenameMetaFields.php index 97da4e8692..1005114e61 100644 --- a/app/Console/Commands/Correction/RenameMetaFields.php +++ b/app/Console/Commands/Correction/RenameMetaFields.php @@ -75,8 +75,8 @@ class RenameMetaFields extends Command } /** - * @param string $original - * @param string $update + * @param string $original + * @param string $update */ private function rename(string $original, string $update): void { diff --git a/app/Console/Commands/Correction/TriggerCreditCalculation.php b/app/Console/Commands/Correction/TriggerCreditCalculation.php index bda570cf42..6b4ac9afd9 100644 --- a/app/Console/Commands/Correction/TriggerCreditCalculation.php +++ b/app/Console/Commands/Correction/TriggerCreditCalculation.php @@ -7,7 +7,6 @@ namespace FireflyIII\Console\Commands\Correction; use FireflyIII\Models\Account; use FireflyIII\Services\Internal\Support\CreditRecalculateService; use Illuminate\Console\Command; -use Illuminate\Support\Facades\Log; /** * Class CorrectionSkeleton @@ -30,8 +29,18 @@ class TriggerCreditCalculation extends Command return 0; } + private function processAccounts(): void + { + $accounts = Account::leftJoin('account_types', 'accounts.account_type_id', 'account_types.id') + ->whereIn('account_types.type', config('firefly.valid_liabilities')) + ->get(['accounts.*']); + foreach ($accounts as $account) { + $this->processAccount($account); + } + } + /** - * @param Account $account + * @param Account $account * * @return void */ @@ -42,14 +51,4 @@ class TriggerCreditCalculation extends Command $object->setAccount($account); $object->recalculate(); } - - private function processAccounts(): void - { - $accounts = Account::leftJoin('account_types', 'accounts.account_type_id', 'account_types.id') - ->whereIn('account_types.type', config('firefly.valid_liabilities')) - ->get(['accounts.*']); - foreach ($accounts as $account) { - $this->processAccount($account); - } - } } diff --git a/app/Console/Commands/Export/ExportData.php b/app/Console/Commands/Export/ExportData.php index 9c0ca5b840..a94dbd85bf 100644 --- a/app/Console/Commands/Export/ExportData.php +++ b/app/Console/Commands/Export/ExportData.php @@ -36,8 +36,8 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Support\Export\ExportDataGenerator; use Illuminate\Console\Command; use Illuminate\Support\Collection; -use InvalidArgumentException; use Illuminate\Support\Facades\Log; +use InvalidArgumentException; /** * Class ExportData @@ -141,61 +141,52 @@ class ExportData extends Command } /** - * @param array $options - * @param array $data + * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is + * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should + * be called from the handle method instead of using the constructor to initialize the command. * - * @throws FireflyException + */ - private function exportData(array $options, array $data): void + private function stupidLaravel(): void { - $date = date('Y_m_d'); - foreach ($data as $key => $content) { - $file = sprintf('%s%s_%s.csv', $options['directory'], $date, $key); - if (false === $options['force'] && file_exists($file)) { - throw new FireflyException(sprintf('File "%s" exists already. Use --force to overwrite.', $file)); - } - if (true === $options['force'] && file_exists($file)) { - $this->friendlyWarning(sprintf('File "%s" exists already but will be replaced.', $file)); - } - // continue to write to file. - file_put_contents($file, $content); - $this->friendlyPositive(sprintf('Wrote %s-export to file "%s".', $key, $file)); - } + $this->journalRepository = app(JournalRepositoryInterface::class); + $this->accountRepository = app(AccountRepositoryInterface::class); } /** - * @return Collection + * @return array * @throws FireflyException + * @throws Exception */ - private function getAccountsParameter(): Collection + private function parseOptions(): array { - $final = new Collection(); - $accounts = new Collection(); - $accountList = $this->option('accounts'); - $types = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]; - if (null !== $accountList && '' !== (string)$accountList) { - $accountIds = explode(',', $accountList); - $accounts = $this->accountRepository->getAccountsById($accountIds); - } - if (null === $accountList) { - $accounts = $this->accountRepository->getAccountsByType($types); - } - // filter accounts, - /** @var Account $account */ - foreach ($accounts as $account) { - if (in_array($account->accountType->type, $types, true)) { - $final->push($account); - } - } - if (0 === $final->count()) { - throw new FireflyException('300007: Ended up with zero valid accounts to export from.'); - } + $start = $this->getDateParameter('start'); + $end = $this->getDateParameter('end'); + $accounts = $this->getAccountsParameter(); + $export = $this->getExportDirectory(); - return $final; + return [ + 'export' => [ + 'transactions' => $this->option('export-transactions'), + 'accounts' => $this->option('export-accounts'), + 'budgets' => $this->option('export-budgets'), + 'categories' => $this->option('export-categories'), + 'tags' => $this->option('export-tags'), + 'recurring' => $this->option('export-recurring'), + 'rules' => $this->option('export-rules'), + 'bills' => $this->option('export-bills'), + 'piggies' => $this->option('export-piggies'), + ], + 'start' => $start, + 'end' => $end, + 'accounts' => $accounts, + 'directory' => $export, + 'force' => $this->option('force'), + ]; } /** - * @param string $field + * @param string $field * * @return Carbon * @throws Exception @@ -235,6 +226,37 @@ class ExportData extends Command return $date; } + /** + * @return Collection + * @throws FireflyException + */ + private function getAccountsParameter(): Collection + { + $final = new Collection(); + $accounts = new Collection(); + $accountList = $this->option('accounts'); + $types = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]; + if (null !== $accountList && '' !== (string)$accountList) { + $accountIds = explode(',', $accountList); + $accounts = $this->accountRepository->getAccountsById($accountIds); + } + if (null === $accountList) { + $accounts = $this->accountRepository->getAccountsByType($types); + } + // filter accounts, + /** @var Account $account */ + foreach ($accounts as $account) { + if (in_array($account->accountType->type, $types, true)) { + $final->push($account); + } + } + if (0 === $final->count()) { + throw new FireflyException('300007: Ended up with zero valid accounts to export from.'); + } + + return $final; + } + /** * @return string * @throws FireflyException @@ -254,47 +276,25 @@ class ExportData extends Command } /** - * @return array - * @throws FireflyException - * @throws Exception - */ - private function parseOptions(): array - { - $start = $this->getDateParameter('start'); - $end = $this->getDateParameter('end'); - $accounts = $this->getAccountsParameter(); - $export = $this->getExportDirectory(); - - return [ - 'export' => [ - 'transactions' => $this->option('export-transactions'), - 'accounts' => $this->option('export-accounts'), - 'budgets' => $this->option('export-budgets'), - 'categories' => $this->option('export-categories'), - 'tags' => $this->option('export-tags'), - 'recurring' => $this->option('export-recurring'), - 'rules' => $this->option('export-rules'), - 'bills' => $this->option('export-bills'), - 'piggies' => $this->option('export-piggies'), - ], - 'start' => $start, - 'end' => $end, - 'accounts' => $accounts, - 'directory' => $export, - 'force' => $this->option('force'), - ]; - } - - /** - * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is - * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should - * be called from the handle method instead of using the constructor to initialize the command. + * @param array $options + * @param array $data * - + * @throws FireflyException */ - private function stupidLaravel(): void + private function exportData(array $options, array $data): void { - $this->journalRepository = app(JournalRepositoryInterface::class); - $this->accountRepository = app(AccountRepositoryInterface::class); + $date = date('Y_m_d'); + foreach ($data as $key => $content) { + $file = sprintf('%s%s_%s.csv', $options['directory'], $date, $key); + if (false === $options['force'] && file_exists($file)) { + throw new FireflyException(sprintf('File "%s" exists already. Use --force to overwrite.', $file)); + } + if (true === $options['force'] && file_exists($file)) { + $this->friendlyWarning(sprintf('File "%s" exists already but will be replaced.', $file)); + } + // continue to write to file. + file_put_contents($file, $content); + $this->friendlyPositive(sprintf('Wrote %s-export to file "%s".', $key, $file)); + } } } diff --git a/app/Console/Commands/Integrity/CreateGroupMemberships.php b/app/Console/Commands/Integrity/CreateGroupMemberships.php index 4a621000b2..a883aca285 100644 --- a/app/Console/Commands/Integrity/CreateGroupMemberships.php +++ b/app/Console/Commands/Integrity/CreateGroupMemberships.php @@ -31,7 +31,6 @@ use FireflyIII\Models\UserGroup; use FireflyIII\Models\UserRole; use FireflyIII\User; use Illuminate\Console\Command; -use Illuminate\Support\Facades\Log; /** * Class CreateGroupMemberships @@ -44,10 +43,37 @@ class CreateGroupMemberships extends Command protected $description = 'Update group memberships'; protected $signature = 'firefly-iii:create-group-memberships'; + /** + * Execute the console command. + * + * @return int + * @throws FireflyException + */ + public function handle(): int + { + $this->createGroupMemberships(); + $this->friendlyPositive('Validated group memberships'); + + return 0; + } + + /** + * + * @throws FireflyException + */ + private function createGroupMemberships(): void + { + $users = User::get(); + /** @var User $user */ + foreach ($users as $user) { + self::createGroupMembership($user); + } + } + /** * TODO move to helper. * - * @param User $user + * @param User $user * * @throws FireflyException */ @@ -81,31 +107,4 @@ class CreateGroupMemberships extends Command $user->save(); } } - - /** - * Execute the console command. - * - * @return int - * @throws FireflyException - */ - public function handle(): int - { - $this->createGroupMemberships(); - $this->friendlyPositive('Validated group memberships'); - - return 0; - } - - /** - * - * @throws FireflyException - */ - private function createGroupMemberships(): void - { - $users = User::get(); - /** @var User $user */ - foreach ($users as $user) { - self::createGroupMembership($user); - } - } } diff --git a/app/Console/Commands/Integrity/ReportEmptyObjects.php b/app/Console/Commands/Integrity/ReportEmptyObjects.php index 85762f45c9..2152694ed8 100644 --- a/app/Console/Commands/Integrity/ReportEmptyObjects.php +++ b/app/Console/Commands/Integrity/ReportEmptyObjects.php @@ -67,51 +67,6 @@ class ReportEmptyObjects extends Command return 0; } - /** - * Reports on accounts with no transactions. - */ - private function reportAccounts(): void - { - $set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id') - ->leftJoin('users', 'accounts.user_id', '=', 'users.id') - ->groupBy(['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email']) - ->whereNull('transactions.account_id') - ->get( - ['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email'] - ); - - /** @var stdClass $entry */ - foreach ($set as $entry) { - $line = 'User #%d (%s) has account #%d ("%s") which has no transactions.'; - $line = sprintf($line, $entry->user_id, $entry->email, $entry->id, $entry->name); - $this->friendlyWarning($line); - } - } - - /** - * Reports on budgets with no budget limits (which makes them pointless). - */ - private function reportBudgetLimits(): void - { - $set = Budget::leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id') - ->leftJoin('users', 'budgets.user_id', '=', 'users.id') - ->groupBy(['budgets.id', 'budgets.name', 'budgets.encrypted', 'budgets.user_id', 'users.email']) - ->whereNull('budget_limits.id') - ->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'budgets.encrypted', 'users.email']); - - /** @var Budget $entry */ - foreach ($set as $entry) { - $line = sprintf( - 'User #%d (%s) has budget #%d ("%s") which has no budget limits.', - $entry->user_id, - $entry->email, - $entry->id, - $entry->name - ); - $this->friendlyWarning($line); - } - } - /** * Report on budgets with no transactions or journals. */ @@ -186,4 +141,49 @@ class ReportEmptyObjects extends Command $this->friendlyWarning($line); } } + + /** + * Reports on accounts with no transactions. + */ + private function reportAccounts(): void + { + $set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id') + ->leftJoin('users', 'accounts.user_id', '=', 'users.id') + ->groupBy(['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email']) + ->whereNull('transactions.account_id') + ->get( + ['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email'] + ); + + /** @var stdClass $entry */ + foreach ($set as $entry) { + $line = 'User #%d (%s) has account #%d ("%s") which has no transactions.'; + $line = sprintf($line, $entry->user_id, $entry->email, $entry->id, $entry->name); + $this->friendlyWarning($line); + } + } + + /** + * Reports on budgets with no budget limits (which makes them pointless). + */ + private function reportBudgetLimits(): void + { + $set = Budget::leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id') + ->leftJoin('users', 'budgets.user_id', '=', 'users.id') + ->groupBy(['budgets.id', 'budgets.name', 'budgets.encrypted', 'budgets.user_id', 'users.email']) + ->whereNull('budget_limits.id') + ->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'budgets.encrypted', 'users.email']); + + /** @var Budget $entry */ + foreach ($set as $entry) { + $line = sprintf( + 'User #%d (%s) has budget #%d ("%s") which has no budget limits.', + $entry->user_id, + $entry->email, + $entry->id, + $entry->name + ); + $this->friendlyWarning($line); + } + } } diff --git a/app/Console/Commands/Integrity/RestoreOAuthKeys.php b/app/Console/Commands/Integrity/RestoreOAuthKeys.php index d9c3ecd859..463b270c91 100644 --- a/app/Console/Commands/Integrity/RestoreOAuthKeys.php +++ b/app/Console/Commands/Integrity/RestoreOAuthKeys.php @@ -50,38 +50,6 @@ class RestoreOAuthKeys extends Command return 0; } - /** - * - */ - private function generateKeys(): void - { - OAuthKeys::generateKeys(); - } - - /** - * @return bool - */ - private function keysInDatabase(): bool - { - return OAuthKeys::keysInDatabase(); - } - - /** - * @return bool - */ - private function keysOnDrive(): bool - { - return OAuthKeys::hasKeyFiles(); - } - - /** - * - */ - private function restoreKeysFromDB(): bool - { - return OAuthKeys::restoreKeysFromDB(); - } - /** * */ @@ -116,6 +84,30 @@ class RestoreOAuthKeys extends Command $this->friendlyPositive('OAuth keys are OK'); } + /** + * @return bool + */ + private function keysInDatabase(): bool + { + return OAuthKeys::keysInDatabase(); + } + + /** + * @return bool + */ + private function keysOnDrive(): bool + { + return OAuthKeys::hasKeyFiles(); + } + + /** + * + */ + private function generateKeys(): void + { + OAuthKeys::generateKeys(); + } + /** * */ @@ -123,4 +115,12 @@ class RestoreOAuthKeys extends Command { OAuthKeys::storeKeysInDB(); } + + /** + * + */ + private function restoreKeysFromDB(): bool + { + return OAuthKeys::restoreKeysFromDB(); + } } diff --git a/app/Console/Commands/Integrity/UpdateGroupInformation.php b/app/Console/Commands/Integrity/UpdateGroupInformation.php index 75b8c1b6a1..b94c33b4b4 100644 --- a/app/Console/Commands/Integrity/UpdateGroupInformation.php +++ b/app/Console/Commands/Integrity/UpdateGroupInformation.php @@ -103,9 +103,9 @@ class UpdateGroupInformation extends Command } /** - * @param User $user - * @param UserGroup $group - * @param string $className + * @param User $user + * @param UserGroup $group + * @param string $className * * @return void */ diff --git a/app/Console/Commands/ShowsFriendlyMessages.php b/app/Console/Commands/ShowsFriendlyMessages.php index ea6640b5b0..ea3edd4c17 100644 --- a/app/Console/Commands/ShowsFriendlyMessages.php +++ b/app/Console/Commands/ShowsFriendlyMessages.php @@ -29,7 +29,7 @@ namespace FireflyIII\Console\Commands; trait ShowsFriendlyMessages { /** - * @param string $message + * @param string $message * @return void */ public function friendlyError(string $message): void @@ -38,7 +38,7 @@ trait ShowsFriendlyMessages } /** - * @param string $message + * @param string $message * @return void */ public function friendlyInfo(string $message): void @@ -47,16 +47,7 @@ trait ShowsFriendlyMessages } /** - * @param string $message - * @return void - */ - public function friendlyLine(string $message): void - { - $this->line(sprintf(' %s', trim($message))); - } - - /** - * @param string $message + * @param string $message * @return void */ public function friendlyNeutral(string $message): void @@ -65,7 +56,16 @@ trait ShowsFriendlyMessages } /** - * @param string $message + * @param string $message + * @return void + */ + public function friendlyLine(string $message): void + { + $this->line(sprintf(' %s', trim($message))); + } + + /** + * @param string $message * @return void */ public function friendlyPositive(string $message): void @@ -74,7 +74,7 @@ trait ShowsFriendlyMessages } /** - * @param string $message + * @param string $message * @return void */ public function friendlyWarning(string $message): void diff --git a/app/Console/Commands/System/ForceDecimalSize.php b/app/Console/Commands/System/ForceDecimalSize.php index d38c1405b9..3def35e188 100644 --- a/app/Console/Commands/System/ForceDecimalSize.php +++ b/app/Console/Commands/System/ForceDecimalSize.php @@ -110,52 +110,19 @@ class ForceDecimalSize extends Command return 0; } - /** - * This method loops over all accounts and validates the amounts. - * - * @param TransactionCurrency $currency - * @param array $fields - * - * @return void - */ - private function correctAccountAmounts(TransactionCurrency $currency, array $fields): void + private function determineDatabaseType(): void { - $operator = $this->operator; - $cast = $this->cast; - $regularExpression = $this->regularExpression; - - /** @var Builder $query */ - $query = Account::leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id') - ->where('account_meta.name', 'currency_id') - ->where('account_meta.data', json_encode((string)$currency->id)); - $query->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression) { - foreach ($fields as $field) { - $q->orWhere( - DB::raw(sprintf('CAST(accounts.%s AS %s)', $field, $cast)), - $operator, - DB::raw(sprintf($regularExpression, $currency->decimal_places)) - ); - } - }); - $result = $query->get(['accounts.*']); - if (0 === $result->count()) { - $this->friendlyPositive(sprintf('All accounts in %s are OK', $currency->code)); - - return; + // switch stuff based on database connection: + $this->operator = 'REGEXP'; + $this->regularExpression = '\'\\\\.[\\\\d]{%d}[1-9]+\''; + $this->cast = 'CHAR'; + if ('pgsql' === config('database.default')) { + $this->operator = 'SIMILAR TO'; + $this->regularExpression = '\'%%\.[\d]{%d}[1-9]+%%\''; + $this->cast = 'TEXT'; } - /** @var Account $account */ - foreach ($result as $account) { - foreach ($fields as $field) { - $value = $account->$field; - if (null === $value) { - continue; - } - // fix $field by rounding it down correctly. - $pow = pow(10, (int)$currency->decimal_places); - $correct = bcdiv((string)round($value * $pow), (string)$pow, 12); - $this->friendlyInfo(sprintf('Account #%d has %s with value "%s", this has been corrected to "%s".', $account->id, $field, $value, $correct)); - Account::find($account->id)->update([$field => $correct]); - } + if ('sqlite' === config('database.default')) { + $this->regularExpression = '"\\.[\d]{%d}[1-9]+"'; } } @@ -202,7 +169,7 @@ class ForceDecimalSize extends Command /** * This method loops the available tables that may need fixing, and calls for the right method that can fix them. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return void * @throws FireflyException @@ -211,7 +178,7 @@ class ForceDecimalSize extends Command { /** * @var string $name - * @var array $fields + * @var array $fields */ foreach ($this->tables as $name => $fields) { switch ($name) { @@ -249,11 +216,60 @@ class ForceDecimalSize extends Command } } + /** + * This method loops over all accounts and validates the amounts. + * + * @param TransactionCurrency $currency + * @param array $fields + * + * @return void + */ + private function correctAccountAmounts(TransactionCurrency $currency, array $fields): void + { + $operator = $this->operator; + $cast = $this->cast; + $regularExpression = $this->regularExpression; + + /** @var Builder $query */ + $query = Account::leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id') + ->where('account_meta.name', 'currency_id') + ->where('account_meta.data', json_encode((string)$currency->id)); + $query->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression) { + foreach ($fields as $field) { + $q->orWhere( + DB::raw(sprintf('CAST(accounts.%s AS %s)', $field, $cast)), + $operator, + DB::raw(sprintf($regularExpression, $currency->decimal_places)) + ); + } + }); + $result = $query->get(['accounts.*']); + if (0 === $result->count()) { + $this->friendlyPositive(sprintf('All accounts in %s are OK', $currency->code)); + + return; + } + /** @var Account $account */ + foreach ($result as $account) { + foreach ($fields as $field) { + $value = $account->$field; + if (null === $value) { + continue; + } + // fix $field by rounding it down correctly. + $pow = pow(10, (int)$currency->decimal_places); + $correct = bcdiv((string)round($value * $pow), (string)$pow, 12); + $this->friendlyInfo(sprintf('Account #%d has %s with value "%s", this has been corrected to "%s".', $account->id, $field, $value, $correct)); + Account::find($account->id)->update([$field => $correct]); + } + } + } + /** * This method fixes all auto budgets in currency $currency. * - * @param TransactionCurrency $currency - * @param string $table + * @param TransactionCurrency $currency + * @param string $table * * @return void */ @@ -300,62 +316,11 @@ class ForceDecimalSize extends Command } } - /** - * This method fixes all piggy banks in currency $currency. - * - * @param TransactionCurrency $currency - * @param array $fields - * - * @return void - */ - private function correctPiggyAmounts(TransactionCurrency $currency, array $fields): void - { - $operator = $this->operator; - $cast = $this->cast; - $regularExpression = $this->regularExpression; - - /** @var Builder $query */ - $query = PiggyBank::leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id') - ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id') - ->where('account_meta.name', 'currency_id') - ->where('account_meta.data', json_encode((string)$currency->id)) - ->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression) { - foreach ($fields as $field) { - $q->orWhere( - DB::raw(sprintf('CAST(piggy_banks.%s AS %s)', $field, $cast)), - $operator, - DB::raw(sprintf($regularExpression, $currency->decimal_places)) - ); - } - }); - - $result = $query->get(['piggy_banks.*']); - if (0 === $result->count()) { - $this->friendlyPositive(sprintf('All piggy banks in %s are OK', $currency->code)); - - return; - } - /** @var PiggyBank $item */ - foreach ($result as $item) { - foreach ($fields as $field) { - $value = $item->$field; - if (null === $value) { - continue; - } - // fix $field by rounding it down correctly. - $pow = pow(10, (int)$currency->decimal_places); - $correct = bcdiv((string)round($value * $pow), (string)$pow, 12); - $this->friendlyWarning(sprintf('Piggy bank #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct)); - PiggyBank::find($item->id)->update([$field => $correct]); - } - } - } - /** * This method fixes all piggy bank events in currency $currency. * - * @param TransactionCurrency $currency - * @param array $fields + * @param TransactionCurrency $currency + * @param array $fields * * @return void */ @@ -408,8 +373,8 @@ class ForceDecimalSize extends Command /** * This method fixes all piggy bank repetitions in currency $currency. * - * @param TransactionCurrency $currency - * @param array $fields + * @param TransactionCurrency $currency + * @param array $fields * * @return void */ @@ -459,10 +424,61 @@ class ForceDecimalSize extends Command } } + /** + * This method fixes all piggy banks in currency $currency. + * + * @param TransactionCurrency $currency + * @param array $fields + * + * @return void + */ + private function correctPiggyAmounts(TransactionCurrency $currency, array $fields): void + { + $operator = $this->operator; + $cast = $this->cast; + $regularExpression = $this->regularExpression; + + /** @var Builder $query */ + $query = PiggyBank::leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id') + ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id') + ->where('account_meta.name', 'currency_id') + ->where('account_meta.data', json_encode((string)$currency->id)) + ->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression) { + foreach ($fields as $field) { + $q->orWhere( + DB::raw(sprintf('CAST(piggy_banks.%s AS %s)', $field, $cast)), + $operator, + DB::raw(sprintf($regularExpression, $currency->decimal_places)) + ); + } + }); + + $result = $query->get(['piggy_banks.*']); + if (0 === $result->count()) { + $this->friendlyPositive(sprintf('All piggy banks in %s are OK', $currency->code)); + + return; + } + /** @var PiggyBank $item */ + foreach ($result as $item) { + foreach ($fields as $field) { + $value = $item->$field; + if (null === $value) { + continue; + } + // fix $field by rounding it down correctly. + $pow = pow(10, (int)$currency->decimal_places); + $correct = bcdiv((string)round($value * $pow), (string)$pow, 12); + $this->friendlyWarning(sprintf('Piggy bank #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct)); + PiggyBank::find($item->id)->update([$field => $correct]); + } + } + } + /** * This method fixes all transactions in currency $currency. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return void */ @@ -524,22 +540,6 @@ class ForceDecimalSize extends Command } } - private function determineDatabaseType(): void - { - // switch stuff based on database connection: - $this->operator = 'REGEXP'; - $this->regularExpression = '\'\\\\.[\\\\d]{%d}[1-9]+\''; - $this->cast = 'CHAR'; - if ('pgsql' === config('database.default')) { - $this->operator = 'SIMILAR TO'; - $this->regularExpression = '\'%%\.[\d]{%d}[1-9]+%%\''; - $this->cast = 'TEXT'; - } - if ('sqlite' === config('database.default')) { - $this->regularExpression = '"\\.[\d]{%d}[1-9]+"'; - } - } - /** * @return void */ @@ -550,7 +550,7 @@ class ForceDecimalSize extends Command /** * @var string $name - * @var array $fields + * @var array $fields */ foreach ($this->tables as $name => $fields) { /** @var string $field */ diff --git a/app/Console/Commands/System/UpgradeFireflyInstructions.php b/app/Console/Commands/System/UpgradeFireflyInstructions.php index a977153b0d..3623a42956 100644 --- a/app/Console/Commands/System/UpgradeFireflyInstructions.php +++ b/app/Console/Commands/System/UpgradeFireflyInstructions.php @@ -66,29 +66,116 @@ class UpgradeFireflyInstructions extends Command return 0; } + /** + * Render upgrade instructions. + */ + private function updateInstructions(): void + { + /** @var string $version */ + $version = config('firefly.version'); + $config = config('upgrade.text.upgrade'); + $text = ''; + foreach (array_keys($config) as $compare) { + // if string starts with: + if (\str_starts_with($version, $compare)) { + $text = $config[$compare]; + } + } + + $this->newLine(); + $this->showLogo(); + $this->newLine(); + $this->showLine(); + + $this->boxed(''); + if (null === $text || '' === $text) { + $this->boxed(sprintf('Thank you for updating to Firefly III, v%s', $version)); + $this->boxedInfo('There are no extra upgrade instructions.'); + $this->boxed('Firefly III should be ready for use.'); + $this->boxed(''); + $this->showLine(); + + return; + } + + $this->boxed(sprintf('Thank you for updating to Firefly III, v%s!', $version)); + $this->boxedInfo($text); + $this->boxed(''); + $this->showLine(); + } + + /** + * The logo takes up 8 lines of code. So 8 colors can be used. + * + * @return void + */ + private function showLogo(): void + { + $today = date('m-d'); + $month = date('m'); + // variation in colors and effects just because I can! + // default is Ukraine flag: + $colors = ['blue', 'blue', 'blue', 'yellow', 'yellow', 'yellow', 'default', 'default']; + + // 5th of May is Dutch liberation day and 29th of April is Dutch King's Day and September 17 is my birthday. + if ('05-01' === $today || '04-29' === $today || '09-17' === $today) { + $colors = ['red', 'red', 'red', 'white', 'white', 'blue', 'blue', 'blue']; + } + + // National Coming Out Day, International Day Against Homophobia, Biphobia and Transphobia and Pride Month + if ('10-11' === $today || '05-17' === $today || '06' === $month) { + $colors = ['red', 'bright-red', 'yellow', 'green', 'blue', 'magenta', 'default', 'default']; + } + + // International Transgender Day of Visibility + if ('03-31' === $today) { + $colors = ['bright-blue', 'bright-red', 'white', 'white', 'bright-red', 'bright-blue', 'default', 'default']; + } + + $this->line(sprintf(' ______ _ __ _ _____ _____ _____ ', $colors[0])); + $this->line(sprintf(' | ____(_) / _| | |_ _|_ _|_ _| ', $colors[1])); + $this->line(sprintf(' | |__ _ _ __ ___| |_| |_ _ | | | | | | ', $colors[2])); + $this->line(sprintf(' | __| | | \'__/ _ \ _| | | | | | | | | | | ', $colors[3])); + $this->line(sprintf(' | | | | | | __/ | | | |_| | _| |_ _| |_ _| |_ ', $colors[4])); + $this->line(sprintf(' |_| |_|_| \___|_| |_|\__, | |_____|_____|_____| ', $colors[5])); + $this->line(sprintf(' __/ | ', $colors[6])); + $this->line(sprintf(' |___/ ', $colors[7])); + } + + /** + * Show a line. + */ + private function showLine(): void + { + $line = '+'; + $line .= str_repeat('-', 78); + $line .= '+'; + $this->line($line); + } + /** * Show a nice box. * - * @param string $text + * @param string $text */ private function boxed(string $text): void { $parts = explode("\n", wordwrap($text)); foreach ($parts as $string) { - $this->line('| '.sprintf('%-77s', $string).'|'); + $this->line('| ' . sprintf('%-77s', $string) . '|'); } } /** * Show a nice info box. * - * @param string $text + * @param string $text */ private function boxedInfo(string $text): void { $parts = explode("\n", wordwrap($text)); foreach ($parts as $string) { - $this->info('| '.sprintf('%-77s', $string).'|'); + $this->info('| ' . sprintf('%-77s', $string) . '|'); } } @@ -127,90 +214,4 @@ class UpgradeFireflyInstructions extends Command $this->boxed(''); $this->showLine(); } - - /** - * Show a line. - */ - private function showLine(): void - { - $line = '+'; - $line .= str_repeat('-', 78); - $line .= '+'; - $this->line($line); - } - - /** - * The logo takes up 8 lines of code. So 8 colors can be used. - * @return void - */ - private function showLogo(): void - { - $today = date('m-d'); - $month = date('m'); - // variation in colors and effects just because I can! - // default is Ukraine flag: - $colors = ['blue', 'blue', 'blue', 'yellow', 'yellow', 'yellow', 'default', 'default']; - - // 5th of May is Dutch liberation day and 29th of April is Dutch King's Day and September 17 is my birthday. - if ('05-01' === $today || '04-29' === $today || '09-17' === $today) { - $colors = ['red', 'red', 'red', 'white', 'white', 'blue', 'blue', 'blue']; - } - - // National Coming Out Day, International Day Against Homophobia, Biphobia and Transphobia and Pride Month - if ('10-11' === $today || '05-17' === $today || '06' === $month) { - $colors = ['red', 'bright-red', 'yellow', 'green', 'blue', 'magenta', 'default', 'default']; - } - - // International Transgender Day of Visibility - if ('03-31' === $today) { - $colors = ['bright-blue', 'bright-red', 'white', 'white', 'bright-red', 'bright-blue', 'default', 'default']; - } - - $this->line(sprintf(' ______ _ __ _ _____ _____ _____ ', $colors[0])); - $this->line(sprintf(' | ____(_) / _| | |_ _|_ _|_ _| ', $colors[1])); - $this->line(sprintf(' | |__ _ _ __ ___| |_| |_ _ | | | | | | ', $colors[2])); - $this->line(sprintf(' | __| | | \'__/ _ \ _| | | | | | | | | | | ', $colors[3])); - $this->line(sprintf(' | | | | | | __/ | | | |_| | _| |_ _| |_ _| |_ ', $colors[4])); - $this->line(sprintf(' |_| |_|_| \___|_| |_|\__, | |_____|_____|_____| ', $colors[5])); - $this->line(sprintf(' __/ | ', $colors[6])); - $this->line(sprintf(' |___/ ', $colors[7])); - } - - /** - * Render upgrade instructions. - */ - private function updateInstructions(): void - { - /** @var string $version */ - $version = config('firefly.version'); - $config = config('upgrade.text.upgrade'); - $text = ''; - foreach (array_keys($config) as $compare) { - // if string starts with: - if (\str_starts_with($version, $compare)) { - $text = $config[$compare]; - } - } - - $this->newLine(); - $this->showLogo(); - $this->newLine(); - $this->showLine(); - - $this->boxed(''); - if (null === $text || '' === $text) { - $this->boxed(sprintf('Thank you for updating to Firefly III, v%s', $version)); - $this->boxedInfo('There are no extra upgrade instructions.'); - $this->boxed('Firefly III should be ready for use.'); - $this->boxed(''); - $this->showLine(); - - return; - } - - $this->boxed(sprintf('Thank you for updating to Firefly III, v%s!', $version)); - $this->boxedInfo($text); - $this->boxed(''); - $this->showLine(); - } } diff --git a/app/Console/Commands/System/VerifySecurityAlerts.php b/app/Console/Commands/System/VerifySecurityAlerts.php index 54d37c5b87..3c82bb45bd 100644 --- a/app/Console/Commands/System/VerifySecurityAlerts.php +++ b/app/Console/Commands/System/VerifySecurityAlerts.php @@ -126,7 +126,7 @@ class VerifySecurityAlerts extends Command } /** - * @param array $array + * @param array $array * * @return void */ diff --git a/app/Console/Commands/Tools/ApplyRules.php b/app/Console/Commands/Tools/ApplyRules.php index 9ee2545e0a..97b8b526b1 100644 --- a/app/Console/Commands/Tools/ApplyRules.php +++ b/app/Console/Commands/Tools/ApplyRules.php @@ -153,49 +153,6 @@ class ApplyRules extends Command return 0; } - /** - * @return Collection - */ - private function getRulesToApply(): Collection - { - $rulesToApply = new Collection(); - /** @var RuleGroup $group */ - foreach ($this->groups as $group) { - $rules = $this->ruleGroupRepository->getActiveStoreRules($group); - /** @var Rule $rule */ - foreach ($rules as $rule) { - // if in rule selection, or group in selection or all rules, it's included. - $test = $this->includeRule($rule, $group); - if (true === $test) { - Log::debug(sprintf('Will include rule #%d "%s"', $rule->id, $rule->title)); - $rulesToApply->push($rule); - } - } - } - - return $rulesToApply; - } - - /** - */ - private function grabAllRules(): void - { - $this->groups = $this->ruleGroupRepository->getActiveGroups(); - } - - /** - * @param Rule $rule - * @param RuleGroup $group - * - * @return bool - */ - private function includeRule(Rule $rule, RuleGroup $group): bool - { - return in_array($group->id, $this->ruleGroupSelection, true) - || in_array($rule->id, $this->ruleSelection, true) - || $this->allRules; - } - /** * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should @@ -274,42 +231,6 @@ class ApplyRules extends Command return true; } - /** - * @throws FireflyException - */ - private function verifyInputDates(): void - { - // parse start date. - $inputStart = today(config('app.timezone'))->startOfMonth(); - $startString = $this->option('start_date'); - if (null === $startString) { - /** @var JournalRepositoryInterface $repository */ - $repository = app(JournalRepositoryInterface::class); - $repository->setUser($this->getUser()); - $first = $repository->firstNull(); - if (null !== $first) { - $inputStart = $first->date; - } - } - if (null !== $startString && '' !== $startString) { - $inputStart = Carbon::createFromFormat('Y-m-d', $startString); - } - - // parse end date - $inputEnd = today(config('app.timezone')); - $endString = $this->option('end_date'); - if (null !== $endString && '' !== $endString) { - $inputEnd = Carbon::createFromFormat('Y-m-d', $endString); - } - - if ($inputStart > $inputEnd) { - [$inputEnd, $inputStart] = [$inputStart, $inputEnd]; - } - - $this->startDate = $inputStart; - $this->endDate = $inputEnd; - } - /** * @return bool */ @@ -356,4 +277,83 @@ class ApplyRules extends Command return true; } + + /** + * @throws FireflyException + */ + private function verifyInputDates(): void + { + // parse start date. + $inputStart = today(config('app.timezone'))->startOfMonth(); + $startString = $this->option('start_date'); + if (null === $startString) { + /** @var JournalRepositoryInterface $repository */ + $repository = app(JournalRepositoryInterface::class); + $repository->setUser($this->getUser()); + $first = $repository->firstNull(); + if (null !== $first) { + $inputStart = $first->date; + } + } + if (null !== $startString && '' !== $startString) { + $inputStart = Carbon::createFromFormat('Y-m-d', $startString); + } + + // parse end date + $inputEnd = today(config('app.timezone')); + $endString = $this->option('end_date'); + if (null !== $endString && '' !== $endString) { + $inputEnd = Carbon::createFromFormat('Y-m-d', $endString); + } + + if ($inputStart > $inputEnd) { + [$inputEnd, $inputStart] = [$inputStart, $inputEnd]; + } + + $this->startDate = $inputStart; + $this->endDate = $inputEnd; + } + + /** + */ + private function grabAllRules(): void + { + $this->groups = $this->ruleGroupRepository->getActiveGroups(); + } + + /** + * @return Collection + */ + private function getRulesToApply(): Collection + { + $rulesToApply = new Collection(); + /** @var RuleGroup $group */ + foreach ($this->groups as $group) { + $rules = $this->ruleGroupRepository->getActiveStoreRules($group); + /** @var Rule $rule */ + foreach ($rules as $rule) { + // if in rule selection, or group in selection or all rules, it's included. + $test = $this->includeRule($rule, $group); + if (true === $test) { + Log::debug(sprintf('Will include rule #%d "%s"', $rule->id, $rule->title)); + $rulesToApply->push($rule); + } + } + } + + return $rulesToApply; + } + + /** + * @param Rule $rule + * @param RuleGroup $group + * + * @return bool + */ + private function includeRule(Rule $rule, RuleGroup $group): bool + { + return in_array($group->id, $this->ruleGroupSelection, true) + || in_array($rule->id, $this->ruleSelection, true) + || $this->allRules; + } } diff --git a/app/Console/Commands/Tools/Cron.php b/app/Console/Commands/Tools/Cron.php index ce211b4191..c4526d72fd 100644 --- a/app/Console/Commands/Tools/Cron.php +++ b/app/Console/Commands/Tools/Cron.php @@ -127,65 +127,8 @@ class Cron extends Command } /** - * @param bool $force - * @param Carbon|null $date - * - */ - private function autoBudgetCronJob(bool $force, ?Carbon $date): void - { - $autoBudget = new AutoBudgetCronjob(); - $autoBudget->setForce($force); - // set date in cron job: - if (null !== $date) { - $autoBudget->setDate($date); - } - - $autoBudget->fire(); - - if ($autoBudget->jobErrored) { - $this->friendlyError(sprintf('Error in "create auto budgets" cron: %s', $autoBudget->message)); - } - if ($autoBudget->jobFired) { - $this->friendlyInfo(sprintf('"Create auto budgets" cron fired: %s', $autoBudget->message)); - } - if ($autoBudget->jobSucceeded) { - $this->friendlyPositive(sprintf('"Create auto budgets" cron ran with success: %s', $autoBudget->message)); - } - } - - /** - * @param bool $force - * @param Carbon|null $date - * - * @throws FireflyException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - private function billWarningCronJob(bool $force, ?Carbon $date): void - { - $autoBudget = new BillWarningCronjob(); - $autoBudget->setForce($force); - // set date in cron job: - if (null !== $date) { - $autoBudget->setDate($date); - } - - $autoBudget->fire(); - - if ($autoBudget->jobErrored) { - $this->friendlyError(sprintf('Error in "bill warnings" cron: %s', $autoBudget->message)); - } - if ($autoBudget->jobFired) { - $this->friendlyInfo(sprintf('"Send bill warnings" cron fired: %s', $autoBudget->message)); - } - if ($autoBudget->jobSucceeded) { - $this->friendlyPositive(sprintf('"Send bill warnings" cron ran with success: %s', $autoBudget->message)); - } - } - - /** - * @param bool $force - * @param Carbon|null $date + * @param bool $force + * @param Carbon|null $date */ private function exchangeRatesCronJob(bool $force, ?Carbon $date): void { @@ -210,8 +153,8 @@ class Cron extends Command } /** - * @param bool $force - * @param Carbon|null $date + * @param bool $force + * @param Carbon|null $date * * @throws ContainerExceptionInterface * @throws FireflyException @@ -238,4 +181,61 @@ class Cron extends Command $this->friendlyPositive(sprintf('"Create recurring transactions" cron ran with success: %s', $recurring->message)); } } + + /** + * @param bool $force + * @param Carbon|null $date + * + */ + private function autoBudgetCronJob(bool $force, ?Carbon $date): void + { + $autoBudget = new AutoBudgetCronjob(); + $autoBudget->setForce($force); + // set date in cron job: + if (null !== $date) { + $autoBudget->setDate($date); + } + + $autoBudget->fire(); + + if ($autoBudget->jobErrored) { + $this->friendlyError(sprintf('Error in "create auto budgets" cron: %s', $autoBudget->message)); + } + if ($autoBudget->jobFired) { + $this->friendlyInfo(sprintf('"Create auto budgets" cron fired: %s', $autoBudget->message)); + } + if ($autoBudget->jobSucceeded) { + $this->friendlyPositive(sprintf('"Create auto budgets" cron ran with success: %s', $autoBudget->message)); + } + } + + /** + * @param bool $force + * @param Carbon|null $date + * + * @throws FireflyException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + private function billWarningCronJob(bool $force, ?Carbon $date): void + { + $autoBudget = new BillWarningCronjob(); + $autoBudget->setForce($force); + // set date in cron job: + if (null !== $date) { + $autoBudget->setDate($date); + } + + $autoBudget->fire(); + + if ($autoBudget->jobErrored) { + $this->friendlyError(sprintf('Error in "bill warnings" cron: %s', $autoBudget->message)); + } + if ($autoBudget->jobFired) { + $this->friendlyInfo(sprintf('"Send bill warnings" cron fired: %s', $autoBudget->message)); + } + if ($autoBudget->jobSucceeded) { + $this->friendlyPositive(sprintf('"Send bill warnings" cron ran with success: %s', $autoBudget->message)); + } + } } diff --git a/app/Console/Commands/Upgrade/AccountCurrencies.php b/app/Console/Commands/Upgrade/AccountCurrencies.php index d72c26f3f0..c03d26b2f2 100644 --- a/app/Console/Commands/Upgrade/AccountCurrencies.php +++ b/app/Console/Commands/Upgrade/AccountCurrencies.php @@ -35,8 +35,6 @@ use FireflyIII\Repositories\User\UserRepositoryInterface; use FireflyIII\User; use Illuminate\Console\Command; use Illuminate\Support\Facades\Log; -use Psr\Container\ContainerExceptionInterface; -use Psr\Container\NotFoundExceptionInterface; /** * Class AccountCurrencies @@ -54,7 +52,8 @@ class AccountCurrencies extends Command private UserRepositoryInterface $userRepos; /** - * Each (asset) account must have a reference to a preferred currency. If the account does not have one, it's forced upon the account. + * Each (asset) account must have a reference to a preferred currency. If the account does not have one, it's + * forced upon the account. * * @return int */ @@ -80,23 +79,6 @@ class AccountCurrencies extends Command return 0; } - /** - * @return bool - */ - private function isExecuted(): bool - { - $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); - return (bool)$configVar?->data; - } - - /** - * - */ - private function markAsExecuted(): void - { - app('fireflyconfig')->set(self::CONFIG_NAME, true); - } - /** * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should @@ -111,8 +93,62 @@ class AccountCurrencies extends Command } /** - * @param Account $account - * @param TransactionCurrency $currency + * @return bool + */ + private function isExecuted(): bool + { + $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); + return (bool)$configVar?->data; + } + + /** + * + */ + private function updateAccountCurrencies(): void + { + $users = $this->userRepos->all(); + $defaultCurrencyCode = (string)config('firefly.default_currency', 'EUR'); + foreach ($users as $user) { + $this->updateCurrenciesForUser($user, $defaultCurrencyCode); + } + } + + /** + * @param User $user + * @param string $systemCurrencyCode + * + * @throws FireflyException + */ + private function updateCurrenciesForUser(User $user, string $systemCurrencyCode): void + { + $this->accountRepos->setUser($user); + $accounts = $this->accountRepos->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]); + + // get user's currency preference: + $defaultCurrencyCode = app('preferences')->getForUser($user, 'currencyPreference', $systemCurrencyCode)->data; + if (!is_string($defaultCurrencyCode)) { + $defaultCurrencyCode = $systemCurrencyCode; + } + + /** @var TransactionCurrency|null $defaultCurrency */ + $defaultCurrency = TransactionCurrency::where('code', $defaultCurrencyCode)->first(); + + if (null === $defaultCurrency) { + Log::error(sprintf('Users currency pref "%s" does not exist!', $defaultCurrencyCode)); + $this->friendlyError(sprintf('User has a preference for "%s", but this currency does not exist.', $defaultCurrencyCode)); + + return; + } + + /** @var Account $account */ + foreach ($accounts as $account) { + $this->updateAccount($account, $defaultCurrency); + } + } + + /** + * @param Account $account + * @param TransactionCurrency $currency */ private function updateAccount(Account $account, TransactionCurrency $currency): void { @@ -158,45 +194,8 @@ class AccountCurrencies extends Command /** * */ - private function updateAccountCurrencies(): void + private function markAsExecuted(): void { - $users = $this->userRepos->all(); - $defaultCurrencyCode = (string)config('firefly.default_currency', 'EUR'); - foreach ($users as $user) { - $this->updateCurrenciesForUser($user, $defaultCurrencyCode); - } - } - - /** - * @param User $user - * @param string $systemCurrencyCode - * - * @throws FireflyException - */ - private function updateCurrenciesForUser(User $user, string $systemCurrencyCode): void - { - $this->accountRepos->setUser($user); - $accounts = $this->accountRepos->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]); - - // get user's currency preference: - $defaultCurrencyCode = app('preferences')->getForUser($user, 'currencyPreference', $systemCurrencyCode)->data; - if (!is_string($defaultCurrencyCode)) { - $defaultCurrencyCode = $systemCurrencyCode; - } - - /** @var TransactionCurrency|null $defaultCurrency */ - $defaultCurrency = TransactionCurrency::where('code', $defaultCurrencyCode)->first(); - - if (null === $defaultCurrency) { - Log::error(sprintf('Users currency pref "%s" does not exist!', $defaultCurrencyCode)); - $this->friendlyError(sprintf('User has a preference for "%s", but this currency does not exist.', $defaultCurrencyCode)); - - return; - } - - /** @var Account $account */ - foreach ($accounts as $account) { - $this->updateAccount($account, $defaultCurrency); - } + app('fireflyconfig')->set(self::CONFIG_NAME, true); } } diff --git a/app/Console/Commands/Upgrade/AppendBudgetLimitPeriods.php b/app/Console/Commands/Upgrade/AppendBudgetLimitPeriods.php index aa9ac93630..81727a9f1c 100644 --- a/app/Console/Commands/Upgrade/AppendBudgetLimitPeriods.php +++ b/app/Console/Commands/Upgrade/AppendBudgetLimitPeriods.php @@ -72,7 +72,31 @@ class AppendBudgetLimitPeriods extends Command } /** - * @param BudgetLimit $limit + * @return bool + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + private function isExecuted(): bool + { + $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); + + return (bool)$configVar->data; + } + + /** + * + */ + private function theresNoLimit(): void + { + $limits = BudgetLimit::whereNull('period')->get(); + /** @var BudgetLimit $limit */ + foreach ($limits as $limit) { + $this->fixLimit($limit); + } + } + + /** + * @param BudgetLimit $limit */ private function fixLimit(BudgetLimit $limit) { @@ -104,7 +128,7 @@ class AppendBudgetLimitPeriods extends Command } /** - * @param BudgetLimit $limit + * @param BudgetLimit $limit * * @return string|null */ @@ -156,18 +180,6 @@ class AppendBudgetLimitPeriods extends Command return null; } - /** - * @return bool - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - private function isExecuted(): bool - { - $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); - - return (bool)$configVar->data; - } - /** * */ @@ -175,16 +187,4 @@ class AppendBudgetLimitPeriods extends Command { app('fireflyconfig')->set(self::CONFIG_NAME, true); } - - /** - * - */ - private function theresNoLimit(): void - { - $limits = BudgetLimit::whereNull('period')->get(); - /** @var BudgetLimit $limit */ - foreach ($limits as $limit) { - $this->fixLimit($limit); - } - } } diff --git a/app/Console/Commands/Upgrade/BackToJournals.php b/app/Console/Commands/Upgrade/BackToJournals.php index 869cc449d0..3cfbd6c7e4 100644 --- a/app/Console/Commands/Upgrade/BackToJournals.php +++ b/app/Console/Commands/Upgrade/BackToJournals.php @@ -32,7 +32,6 @@ use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use Illuminate\Console\Command; use Illuminate\Support\Collection; -use Illuminate\Support\Facades\Log; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; @@ -87,54 +86,6 @@ class BackToJournals extends Command return 0; } - /** - * @return array - */ - private function getIdsForBudgets(): array - { - $transactions = DB::table('budget_transaction')->distinct()->pluck('transaction_id')->toArray(); - $array = []; - $chunks = array_chunk($transactions, 500); - - foreach ($chunks as $chunk) { - $set = DB::table('transactions')->whereIn('transactions.id', $chunk)->pluck('transaction_journal_id')->toArray(); - $array = array_merge($array, $set); - } - - return $array; - } - - /** - * @return array - */ - private function getIdsForCategories(): array - { - $transactions = DB::table('category_transaction')->distinct()->pluck('transaction_id')->toArray(); - $array = []; - $chunks = array_chunk($transactions, 500); - - foreach ($chunks as $chunk) { - $set = DB::table('transactions') - ->whereIn('transactions.id', $chunk) - ->pluck('transaction_journal_id')->toArray(); - $array = array_merge($array, $set); - } - - return $array; - } - - /** - * @return bool - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - private function isExecuted(): bool - { - $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); - - return (bool)$configVar->data; - } - /** * @return bool * @throws ContainerExceptionInterface @@ -148,11 +99,15 @@ class BackToJournals extends Command } /** - * + * @return bool + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface */ - private function markAsExecuted(): void + private function isExecuted(): bool { - app('fireflyconfig')->set(self::CONFIG_NAME, true); + $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); + + return (bool)$configVar->data; } /** @@ -187,7 +142,24 @@ class BackToJournals extends Command } /** - * @param TransactionJournal $journal + * @return array + */ + private function getIdsForBudgets(): array + { + $transactions = DB::table('budget_transaction')->distinct()->pluck('transaction_id')->toArray(); + $array = []; + $chunks = array_chunk($transactions, 500); + + foreach ($chunks as $chunk) { + $set = DB::table('transactions')->whereIn('transactions.id', $chunk)->pluck('transaction_journal_id')->toArray(); + $array = array_merge($array, $set); + } + + return $array; + } + + /** + * @param TransactionJournal $journal */ private function migrateBudgetsForJournal(TransactionJournal $journal): void { @@ -240,7 +212,26 @@ class BackToJournals extends Command } /** - * @param TransactionJournal $journal + * @return array + */ + private function getIdsForCategories(): array + { + $transactions = DB::table('category_transaction')->distinct()->pluck('transaction_id')->toArray(); + $array = []; + $chunks = array_chunk($transactions, 500); + + foreach ($chunks as $chunk) { + $set = DB::table('transactions') + ->whereIn('transactions.id', $chunk) + ->pluck('transaction_journal_id')->toArray(); + $array = array_merge($array, $set); + } + + return $array; + } + + /** + * @param TransactionJournal $journal */ private function migrateCategoriesForJournal(TransactionJournal $journal): void { @@ -268,4 +259,12 @@ class BackToJournals extends Command $journal->categories()->sync([(int)$category->id]); } } + + /** + * + */ + private function markAsExecuted(): void + { + app('fireflyconfig')->set(self::CONFIG_NAME, true); + } } diff --git a/app/Console/Commands/Upgrade/DecryptDatabase.php b/app/Console/Commands/Upgrade/DecryptDatabase.php index 54ab4f91cf..be6dd577f2 100644 --- a/app/Console/Commands/Upgrade/DecryptDatabase.php +++ b/app/Console/Commands/Upgrade/DecryptDatabase.php @@ -69,7 +69,7 @@ class DecryptDatabase extends Command ]; /** * @var string $table - * @var array $fields + * @var array $fields */ foreach ($tables as $table => $fields) { $this->decryptTable($table, $fields); @@ -78,8 +78,54 @@ class DecryptDatabase extends Command } /** - * @param string $table - * @param string $field + * @param string $table + * @param array $fields + * + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + private function decryptTable(string $table, array $fields): void + { + if ($this->isDecrypted($table)) { + $this->friendlyInfo(sprintf('No decryption required for table "%s".', $table)); + + return; + } + foreach ($fields as $field) { + $this->decryptField($table, $field); + } + $this->friendlyPositive(sprintf('Decrypted the data in table "%s".', $table)); + // mark as decrypted: + $configName = sprintf('is_decrypted_%s', $table); + app('fireflyconfig')->set($configName, true); + } + + /** + * @param string $table + * + * @return bool + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + private function isDecrypted(string $table): bool + { + $configName = sprintf('is_decrypted_%s', $table); + $configVar = null; + try { + $configVar = app('fireflyconfig')->get($configName, false); + } catch (FireflyException $e) { + Log::error($e->getMessage()); + } + if (null !== $configVar) { + return (bool)$configVar->data; + } + + return false; + } + + /** + * @param string $table + * @param string $field */ private function decryptField(string $table, string $field): void { @@ -91,36 +137,9 @@ class DecryptDatabase extends Command } /** - * @param int $id - * @param string $value - */ - private function decryptPreferencesRow(int $id, string $value): void - { - // try to json_decrypt the value. - try { - $newValue = json_decode($value, true, 512, JSON_THROW_ON_ERROR) ?? $value; - } catch (JsonException $e) { - $message = sprintf('Could not JSON decode preference row #%d: %s. This does not have to be a problem.', $id, $e->getMessage()); - $this->friendlyError($message); - app('log')->warning($message); - app('log')->warning($value); - app('log')->warning($e->getTraceAsString()); - - return; - } - - /** @var Preference $object */ - $object = Preference::find((int)$id); - if (null !== $object) { - $object->data = $newValue; - $object->save(); - } - } - - /** - * @param string $table - * @param string $field - * @param stdClass $row + * @param string $table + * @param string $field + * @param stdClass $row */ private function decryptRow(string $table, string $field, stdClass $row): void { @@ -152,56 +171,10 @@ class DecryptDatabase extends Command } } - /** - * @param string $table - * @param array $fields - * - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - private function decryptTable(string $table, array $fields): void - { - if ($this->isDecrypted($table)) { - $this->friendlyInfo(sprintf('No decryption required for table "%s".', $table)); - - return; - } - foreach ($fields as $field) { - $this->decryptField($table, $field); - } - $this->friendlyPositive(sprintf('Decrypted the data in table "%s".', $table)); - // mark as decrypted: - $configName = sprintf('is_decrypted_%s', $table); - app('fireflyconfig')->set($configName, true); - } - - /** - * @param string $table - * - * @return bool - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - private function isDecrypted(string $table): bool - { - $configName = sprintf('is_decrypted_%s', $table); - $configVar = null; - try { - $configVar = app('fireflyconfig')->get($configName, false); - } catch (FireflyException $e) { - Log::error($e->getMessage()); - } - if (null !== $configVar) { - return (bool)$configVar->data; - } - - return false; - } - /** * Tries to decrypt data. Will only throw an exception when the MAC is invalid. * - * @param mixed $value + * @param mixed $value * * @return string * @throws FireflyException @@ -218,4 +191,31 @@ class DecryptDatabase extends Command return $value; } + + /** + * @param int $id + * @param string $value + */ + private function decryptPreferencesRow(int $id, string $value): void + { + // try to json_decrypt the value. + try { + $newValue = json_decode($value, true, 512, JSON_THROW_ON_ERROR) ?? $value; + } catch (JsonException $e) { + $message = sprintf('Could not JSON decode preference row #%d: %s. This does not have to be a problem.', $id, $e->getMessage()); + $this->friendlyError($message); + app('log')->warning($message); + app('log')->warning($value); + app('log')->warning($e->getTraceAsString()); + + return; + } + + /** @var Preference $object */ + $object = Preference::find((int)$id); + if (null !== $object) { + $object->data = $newValue; + $object->save(); + } + } } diff --git a/app/Console/Commands/Upgrade/MigrateRecurrenceMeta.php b/app/Console/Commands/Upgrade/MigrateRecurrenceMeta.php index 7ed84eec42..425383f7b1 100644 --- a/app/Console/Commands/Upgrade/MigrateRecurrenceMeta.php +++ b/app/Console/Commands/Upgrade/MigrateRecurrenceMeta.php @@ -101,15 +101,24 @@ class MigrateRecurrenceMeta extends Command } /** - * + * @return int + * @throws JsonException */ - private function markAsExecuted(): void + private function migrateMetaData(): int { - app('fireflyconfig')->set(self::CONFIG_NAME, true); + $count = 0; + // get all recurrence meta data: + $collection = RecurrenceMeta::with('recurrence')->get(); + /** @var RecurrenceMeta $meta */ + foreach ($collection as $meta) { + $count += $this->migrateEntry($meta); + } + + return $count; } /** - * @param RecurrenceMeta $meta + * @param RecurrenceMeta $meta * * @return int * @throws JsonException @@ -145,19 +154,10 @@ class MigrateRecurrenceMeta extends Command } /** - * @return int - * @throws JsonException + * */ - private function migrateMetaData(): int + private function markAsExecuted(): void { - $count = 0; - // get all recurrence meta data: - $collection = RecurrenceMeta::with('recurrence')->get(); - /** @var RecurrenceMeta $meta */ - foreach ($collection as $meta) { - $count += $this->migrateEntry($meta); - } - - return $count; + app('fireflyconfig')->set(self::CONFIG_NAME, true); } } diff --git a/app/Console/Commands/Upgrade/MigrateRecurrenceType.php b/app/Console/Commands/Upgrade/MigrateRecurrenceType.php index 11e3424c8d..9d2d4887c4 100644 --- a/app/Console/Commands/Upgrade/MigrateRecurrenceType.php +++ b/app/Console/Commands/Upgrade/MigrateRecurrenceType.php @@ -77,14 +77,6 @@ class MigrateRecurrenceType extends Command return 0; } - /** - * - */ - private function getInvalidType(): TransactionType - { - return TransactionType::whereType(TransactionType::INVALID)->firstOrCreate(['type' => TransactionType::INVALID]); - } - /** * @return bool * @throws ContainerExceptionInterface @@ -99,13 +91,19 @@ class MigrateRecurrenceType extends Command /** * */ - private function markAsExecuted(): void + private function migrateTypes(): void { - app('fireflyconfig')->set(self::CONFIG_NAME, true); + $set = Recurrence::get(); + /** @var Recurrence $recurrence */ + foreach ($set as $recurrence) { + if ($recurrence->transactionType->type !== TransactionType::INVALID) { + $this->migrateRecurrence($recurrence); + } + } } /** - * @param Recurrence $recurrence + * @param Recurrence $recurrence * @return void */ private function migrateRecurrence(Recurrence $recurrence): void @@ -125,14 +123,16 @@ class MigrateRecurrenceType extends Command /** * */ - private function migrateTypes(): void + private function getInvalidType(): TransactionType { - $set = Recurrence::get(); - /** @var Recurrence $recurrence */ - foreach ($set as $recurrence) { - if ($recurrence->transactionType->type !== TransactionType::INVALID) { - $this->migrateRecurrence($recurrence); - } - } + return TransactionType::whereType(TransactionType::INVALID)->firstOrCreate(['type' => TransactionType::INVALID]); + } + + /** + * + */ + private function markAsExecuted(): void + { + app('fireflyconfig')->set(self::CONFIG_NAME, true); } } diff --git a/app/Console/Commands/Upgrade/MigrateTagLocations.php b/app/Console/Commands/Upgrade/MigrateTagLocations.php index 18dc8cc7ae..b91ab3822b 100644 --- a/app/Console/Commands/Upgrade/MigrateTagLocations.php +++ b/app/Console/Commands/Upgrade/MigrateTagLocations.php @@ -74,16 +74,6 @@ class MigrateTagLocations extends Command return 0; } - /** - * @param Tag $tag - * - * @return bool - */ - private function hasLocationDetails(Tag $tag): bool - { - return null !== $tag->latitude && null !== $tag->longitude && null !== $tag->zoomLevel; - } - /** * @return bool * @throws ContainerExceptionInterface @@ -99,16 +89,29 @@ class MigrateTagLocations extends Command return false; } - /** - * - */ - private function markAsExecuted(): void + private function migrateTagLocations(): void { - app('fireflyconfig')->set(self::CONFIG_NAME, true); + $tags = Tag::get(); + /** @var Tag $tag */ + foreach ($tags as $tag) { + if ($this->hasLocationDetails($tag)) { + $this->migrateLocationDetails($tag); + } + } } /** - * @param Tag $tag + * @param Tag $tag + * + * @return bool + */ + private function hasLocationDetails(Tag $tag): bool + { + return null !== $tag->latitude && null !== $tag->longitude && null !== $tag->zoomLevel; + } + + /** + * @param Tag $tag */ private function migrateLocationDetails(Tag $tag): void { @@ -125,14 +128,11 @@ class MigrateTagLocations extends Command $tag->save(); } - private function migrateTagLocations(): void + /** + * + */ + private function markAsExecuted(): void { - $tags = Tag::get(); - /** @var Tag $tag */ - foreach ($tags as $tag) { - if ($this->hasLocationDetails($tag)) { - $this->migrateLocationDetails($tag); - } - } + app('fireflyconfig')->set(self::CONFIG_NAME, true); } } diff --git a/app/Console/Commands/Upgrade/MigrateToGroups.php b/app/Console/Commands/Upgrade/MigrateToGroups.php index a6d12e5fa2..ca6fafa9f1 100644 --- a/app/Console/Commands/Upgrade/MigrateToGroups.php +++ b/app/Console/Commands/Upgrade/MigrateToGroups.php @@ -26,7 +26,6 @@ namespace FireflyIII\Console\Commands\Upgrade; use DB; use Exception; use FireflyIII\Console\Commands\ShowsFriendlyMessages; -use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\TransactionGroupFactory; use FireflyIII\Models\Budget; use FireflyIII\Models\Category; @@ -96,122 +95,19 @@ class MigrateToGroups extends Command } /** - * @param TransactionJournal $journal - * @param Transaction $transaction + * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is + * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should + * be called from the handle method instead of using the constructor to initialize the command. * - * @return Transaction|null + */ - private function findOpposingTransaction(TransactionJournal $journal, Transaction $transaction): ?Transaction + private function stupidLaravel(): void { - $set = $journal->transactions->filter( - static function (Transaction $subject) use ($transaction) { - $amount = (float)$transaction->amount * -1 === (float)$subject->amount; // intentional float - $identifier = $transaction->identifier === $subject->identifier; - Log::debug(sprintf('Amount the same? %s', var_export($amount, true))); - Log::debug(sprintf('ID the same? %s', var_export($identifier, true))); - - return $amount && $identifier; - } - ); - - return $set->first(); - } - - /** - * @param TransactionJournal $journal - * - * @return Collection - */ - private function getDestinationTransactions(TransactionJournal $journal): Collection - { - return $journal->transactions->filter( - static function (Transaction $transaction) { - return $transaction->amount > 0; - } - ); - } - - /** - * @param Transaction $left - * @param Transaction $right - * - * @return int|null - */ - private function getTransactionBudget(Transaction $left, Transaction $right): ?int - { - Log::debug('Now in getTransactionBudget()'); - - // try to get a budget ID from the left transaction: - /** @var Budget|null $budget */ - $budget = $left->budgets()->first(); - if (null !== $budget) { - Log::debug(sprintf('Return budget #%d, from transaction #%d', $budget->id, $left->id)); - - return (int)$budget->id; - } - - // try to get a budget ID from the right transaction: - /** @var Budget|null $budget */ - $budget = $right->budgets()->first(); - if (null !== $budget) { - Log::debug(sprintf('Return budget #%d, from transaction #%d', $budget->id, $right->id)); - - return (int)$budget->id; - } - Log::debug('Neither left or right have a budget, return NULL'); - - // if all fails, return NULL. - return null; - } - - /** - * @param Transaction $left - * @param Transaction $right - * - * @return int|null - */ - private function getTransactionCategory(Transaction $left, Transaction $right): ?int - { - Log::debug('Now in getTransactionCategory()'); - - // try to get a category ID from the left transaction: - /** @var Category|null $category */ - $category = $left->categories()->first(); - if (null !== $category) { - Log::debug(sprintf('Return category #%d, from transaction #%d', $category->id, $left->id)); - - return (int)$category->id; - } - - // try to get a category ID from the left transaction: - /** @var Category|null $category */ - $category = $right->categories()->first(); - if (null !== $category) { - Log::debug(sprintf('Return category #%d, from transaction #%d', $category->id, $category->id)); - - return (int)$category->id; - } - Log::debug('Neither left or right have a category, return NULL'); - - // if all fails, return NULL. - return null; - } - - /** - * @param array $array - */ - private function giveGroup(array $array): void - { - $groupId = DB::table('transaction_groups')->insertGetId( - [ - 'created_at' => date('Y-m-d H:i:s'), - 'updated_at' => date('Y-m-d H:i:s'), - 'title' => null, - 'user_id' => $array['user_id'], - ] - ); - DB::table('transaction_journals')->where('id', $array['id'])->update(['transaction_group_id' => $groupId]); - $this->count++; + $this->count = 0; + $this->journalRepository = app(JournalRepositoryInterface::class); + $this->service = app(JournalDestroyService::class); + $this->groupFactory = app(TransactionGroupFactory::class); + $this->cliRepository = app(JournalCLIRepositoryInterface::class); } /** @@ -229,26 +125,6 @@ class MigrateToGroups extends Command return false; } - /** - * Gives all journals without a group a group. - */ - private function makeGroupsFromAll(): void - { - $orphanedJournals = $this->cliRepository->getJournalsWithoutGroup(); - $total = count($orphanedJournals); - if ($total > 0) { - Log::debug(sprintf('Going to convert %d transaction journals. Please hold..', $total)); - $this->friendlyInfo(sprintf('Going to convert %d transaction journals. Please hold..', $total)); - /** @var array $array */ - foreach ($orphanedJournals as $array) { - $this->giveGroup($array); - } - } - if (0 === $total) { - $this->friendlyPositive('No need to convert transaction journals.'); - } - } - /** * @throws Exception */ @@ -265,7 +141,7 @@ class MigrateToGroups extends Command } /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @throws Exception */ @@ -406,6 +282,145 @@ class MigrateToGroups extends Command ); } + /** + * @param TransactionJournal $journal + * + * @return Collection + */ + private function getDestinationTransactions(TransactionJournal $journal): Collection + { + return $journal->transactions->filter( + static function (Transaction $transaction) { + return $transaction->amount > 0; + } + ); + } + + /** + * @param TransactionJournal $journal + * @param Transaction $transaction + * + * @return Transaction|null + */ + private function findOpposingTransaction(TransactionJournal $journal, Transaction $transaction): ?Transaction + { + $set = $journal->transactions->filter( + static function (Transaction $subject) use ($transaction) { + $amount = (float)$transaction->amount * -1 === (float)$subject->amount; // intentional float + $identifier = $transaction->identifier === $subject->identifier; + Log::debug(sprintf('Amount the same? %s', var_export($amount, true))); + Log::debug(sprintf('ID the same? %s', var_export($identifier, true))); + + return $amount && $identifier; + } + ); + + return $set->first(); + } + + /** + * @param Transaction $left + * @param Transaction $right + * + * @return int|null + */ + private function getTransactionBudget(Transaction $left, Transaction $right): ?int + { + Log::debug('Now in getTransactionBudget()'); + + // try to get a budget ID from the left transaction: + /** @var Budget|null $budget */ + $budget = $left->budgets()->first(); + if (null !== $budget) { + Log::debug(sprintf('Return budget #%d, from transaction #%d', $budget->id, $left->id)); + + return (int)$budget->id; + } + + // try to get a budget ID from the right transaction: + /** @var Budget|null $budget */ + $budget = $right->budgets()->first(); + if (null !== $budget) { + Log::debug(sprintf('Return budget #%d, from transaction #%d', $budget->id, $right->id)); + + return (int)$budget->id; + } + Log::debug('Neither left or right have a budget, return NULL'); + + // if all fails, return NULL. + return null; + } + + /** + * @param Transaction $left + * @param Transaction $right + * + * @return int|null + */ + private function getTransactionCategory(Transaction $left, Transaction $right): ?int + { + Log::debug('Now in getTransactionCategory()'); + + // try to get a category ID from the left transaction: + /** @var Category|null $category */ + $category = $left->categories()->first(); + if (null !== $category) { + Log::debug(sprintf('Return category #%d, from transaction #%d', $category->id, $left->id)); + + return (int)$category->id; + } + + // try to get a category ID from the left transaction: + /** @var Category|null $category */ + $category = $right->categories()->first(); + if (null !== $category) { + Log::debug(sprintf('Return category #%d, from transaction #%d', $category->id, $category->id)); + + return (int)$category->id; + } + Log::debug('Neither left or right have a category, return NULL'); + + // if all fails, return NULL. + return null; + } + + /** + * Gives all journals without a group a group. + */ + private function makeGroupsFromAll(): void + { + $orphanedJournals = $this->cliRepository->getJournalsWithoutGroup(); + $total = count($orphanedJournals); + if ($total > 0) { + Log::debug(sprintf('Going to convert %d transaction journals. Please hold..', $total)); + $this->friendlyInfo(sprintf('Going to convert %d transaction journals. Please hold..', $total)); + /** @var array $array */ + foreach ($orphanedJournals as $array) { + $this->giveGroup($array); + } + } + if (0 === $total) { + $this->friendlyPositive('No need to convert transaction journals.'); + } + } + + /** + * @param array $array + */ + private function giveGroup(array $array): void + { + $groupId = DB::table('transaction_groups')->insertGetId( + [ + 'created_at' => date('Y-m-d H:i:s'), + 'updated_at' => date('Y-m-d H:i:s'), + 'title' => null, + 'user_id' => $array['user_id'], + ] + ); + DB::table('transaction_journals')->where('id', $array['id'])->update(['transaction_group_id' => $groupId]); + $this->count++; + } + /** * */ @@ -413,20 +428,4 @@ class MigrateToGroups extends Command { app('fireflyconfig')->set(self::CONFIG_NAME, true); } - - /** - * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is - * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should - * be called from the handle method instead of using the constructor to initialize the command. - * - - */ - private function stupidLaravel(): void - { - $this->count = 0; - $this->journalRepository = app(JournalRepositoryInterface::class); - $this->service = app(JournalDestroyService::class); - $this->groupFactory = app(TransactionGroupFactory::class); - $this->cliRepository = app(JournalCLIRepositoryInterface::class); - } } diff --git a/app/Console/Commands/Upgrade/MigrateToRules.php b/app/Console/Commands/Upgrade/MigrateToRules.php index 96a3b2575f..6e8c804894 100644 --- a/app/Console/Commands/Upgrade/MigrateToRules.php +++ b/app/Console/Commands/Upgrade/MigrateToRules.php @@ -104,6 +104,22 @@ class MigrateToRules extends Command return 0; } + /** + * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is + * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should + * be called from the handle method instead of using the constructor to initialize the command. + * + + */ + private function stupidLaravel(): void + { + $this->count = 0; + $this->userRepository = app(UserRepositoryInterface::class); + $this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class); + $this->billRepository = app(BillRepositoryInterface::class); + $this->ruleRepository = app(RuleRepositoryInterface::class); + } + /** * @return bool * @throws ContainerExceptionInterface @@ -120,17 +136,44 @@ class MigrateToRules extends Command } /** + * Migrate bills to new rule structure for a specific user. * + * @param User $user + * + * @throws FireflyException */ - private function markAsExecuted(): void + private function migrateUser(User $user): void { - app('fireflyconfig')->set(self::CONFIG_NAME, true); + $this->ruleGroupRepository->setUser($user); + $this->billRepository->setUser($user); + $this->ruleRepository->setUser($user); + + /** @var Preference $lang */ + $lang = app('preferences')->getForUser($user, 'language', 'en_US'); + $groupTitle = (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data); + $ruleGroup = $this->ruleGroupRepository->findByTitle($groupTitle); + + if (null === $ruleGroup) { + $ruleGroup = $this->ruleGroupRepository->store( + [ + 'title' => (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data), + 'description' => (string)trans('firefly.rulegroup_for_bills_description', [], $lang->data), + 'active' => true, + ] + ); + } + $bills = $this->billRepository->getBills(); + + /** @var Bill $bill */ + foreach ($bills as $bill) { + $this->migrateBill($ruleGroup, $bill, $lang); + } } /** - * @param RuleGroup $ruleGroup - * @param Bill $bill - * @param Preference $language + * @param RuleGroup $ruleGroup + * @param Bill $bill + * @param Preference $language */ private function migrateBill(RuleGroup $ruleGroup, Bill $bill, Preference $language): void { @@ -199,53 +242,10 @@ class MigrateToRules extends Command } /** - * Migrate bills to new rule structure for a specific user. * - * @param User $user - * - * @throws FireflyException */ - private function migrateUser(User $user): void + private function markAsExecuted(): void { - $this->ruleGroupRepository->setUser($user); - $this->billRepository->setUser($user); - $this->ruleRepository->setUser($user); - - /** @var Preference $lang */ - $lang = app('preferences')->getForUser($user, 'language', 'en_US'); - $groupTitle = (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data); - $ruleGroup = $this->ruleGroupRepository->findByTitle($groupTitle); - - if (null === $ruleGroup) { - $ruleGroup = $this->ruleGroupRepository->store( - [ - 'title' => (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data), - 'description' => (string)trans('firefly.rulegroup_for_bills_description', [], $lang->data), - 'active' => true, - ] - ); - } - $bills = $this->billRepository->getBills(); - - /** @var Bill $bill */ - foreach ($bills as $bill) { - $this->migrateBill($ruleGroup, $bill, $lang); - } - } - - /** - * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is - * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should - * be called from the handle method instead of using the constructor to initialize the command. - * - - */ - private function stupidLaravel(): void - { - $this->count = 0; - $this->userRepository = app(UserRepositoryInterface::class); - $this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class); - $this->billRepository = app(BillRepositoryInterface::class); - $this->ruleRepository = app(RuleRepositoryInterface::class); + app('fireflyconfig')->set(self::CONFIG_NAME, true); } } diff --git a/app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php b/app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php index a9ea6e4aee..4d86755989 100644 --- a/app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php +++ b/app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php @@ -84,72 +84,20 @@ class OtherCurrenciesCorrections extends Command } /** - * @param Account $account + * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is + * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should + * be called from the handle method instead of using the constructor to initialize the command. * - * @return TransactionCurrency|null + */ - private function getCurrency(Account $account): ?TransactionCurrency + private function stupidLaravel(): void { - $accountId = $account->id; - if (array_key_exists($accountId, $this->accountCurrencies) && 0 === $this->accountCurrencies[$accountId]) { - return null; - } - if (array_key_exists($accountId, $this->accountCurrencies) && $this->accountCurrencies[$accountId] instanceof TransactionCurrency) { - return $this->accountCurrencies[$accountId]; - } - $currency = $this->accountRepos->getAccountCurrency($account); - if (null === $currency) { - $this->accountCurrencies[$accountId] = 0; - - return null; - } - $this->accountCurrencies[$accountId] = $currency; - - return $currency; - } - - /** - * Gets the transaction that determines the transaction that "leads" and will determine - * the currency to be used by all transactions, and the journal itself. - * - * @param TransactionJournal $journal - * - * @return Transaction|null - */ - private function getLeadTransaction(TransactionJournal $journal): ?Transaction - { - /** @var Transaction $lead */ - $lead = null; - switch ($journal->transactionType->type) { - default: - break; - case TransactionType::WITHDRAWAL: - $lead = $journal->transactions()->where('amount', '<', 0)->first(); - break; - case TransactionType::DEPOSIT: - $lead = $journal->transactions()->where('amount', '>', 0)->first(); - break; - case TransactionType::OPENING_BALANCE: - // whichever isn't an initial balance account: - $lead = $journal->transactions()->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')->leftJoin( - 'account_types', - 'accounts.account_type_id', - '=', - 'account_types.id' - )->where('account_types.type', '!=', AccountType::INITIAL_BALANCE)->first(['transactions.*']); - break; - case TransactionType::RECONCILIATION: - // whichever isn't the reconciliation account: - $lead = $journal->transactions()->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')->leftJoin( - 'account_types', - 'accounts.account_type_id', - '=', - 'account_types.id' - )->where('account_types.type', '!=', AccountType::RECONCILIATION)->first(['transactions.*']); - break; - } - - return $lead; + $this->count = 0; + $this->accountCurrencies = []; + $this->accountRepos = app(AccountRepositoryInterface::class); + $this->currencyRepos = app(CurrencyRepositoryInterface::class); + $this->journalRepos = app(JournalRepositoryInterface::class); + $this->cliRepos = app(JournalCLIRepositoryInterface::class); } /** @@ -168,32 +116,25 @@ class OtherCurrenciesCorrections extends Command } /** - * + * This routine verifies that withdrawals, deposits and opening balances have the correct currency settings for + * the accounts they are linked to. + * Both source and destination must match the respective currency preference of the related asset account. + * So FF3 must verify all transactions. */ - private function markAsExecuted(): void + private function updateOtherJournalsCurrencies(): void { - app('fireflyconfig')->set(self::CONFIG_NAME, true); + $set = $this->cliRepos->getAllJournals( + [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,] + ); + + /** @var TransactionJournal $journal */ + foreach ($set as $journal) { + $this->updateJournalCurrency($journal); + } } /** - * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is - * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should - * be called from the handle method instead of using the constructor to initialize the command. - * - - */ - private function stupidLaravel(): void - { - $this->count = 0; - $this->accountCurrencies = []; - $this->accountRepos = app(AccountRepositoryInterface::class); - $this->currencyRepos = app(CurrencyRepositoryInterface::class); - $this->journalRepos = app(JournalRepositoryInterface::class); - $this->cliRepos = app(JournalCLIRepositoryInterface::class); - } - - /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal */ private function updateJournalCurrency(TransactionJournal $journal): void { @@ -249,20 +190,79 @@ class OtherCurrenciesCorrections extends Command } /** - * This routine verifies that withdrawals, deposits and opening balances have the correct currency settings for - * the accounts they are linked to. - * Both source and destination must match the respective currency preference of the related asset account. - * So FF3 must verify all transactions. + * Gets the transaction that determines the transaction that "leads" and will determine + * the currency to be used by all transactions, and the journal itself. + * + * @param TransactionJournal $journal + * + * @return Transaction|null */ - private function updateOtherJournalsCurrencies(): void + private function getLeadTransaction(TransactionJournal $journal): ?Transaction { - $set = $this->cliRepos->getAllJournals( - [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,] - ); - - /** @var TransactionJournal $journal */ - foreach ($set as $journal) { - $this->updateJournalCurrency($journal); + /** @var Transaction $lead */ + $lead = null; + switch ($journal->transactionType->type) { + default: + break; + case TransactionType::WITHDRAWAL: + $lead = $journal->transactions()->where('amount', '<', 0)->first(); + break; + case TransactionType::DEPOSIT: + $lead = $journal->transactions()->where('amount', '>', 0)->first(); + break; + case TransactionType::OPENING_BALANCE: + // whichever isn't an initial balance account: + $lead = $journal->transactions()->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')->leftJoin( + 'account_types', + 'accounts.account_type_id', + '=', + 'account_types.id' + )->where('account_types.type', '!=', AccountType::INITIAL_BALANCE)->first(['transactions.*']); + break; + case TransactionType::RECONCILIATION: + // whichever isn't the reconciliation account: + $lead = $journal->transactions()->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')->leftJoin( + 'account_types', + 'accounts.account_type_id', + '=', + 'account_types.id' + )->where('account_types.type', '!=', AccountType::RECONCILIATION)->first(['transactions.*']); + break; } + + return $lead; + } + + /** + * @param Account $account + * + * @return TransactionCurrency|null + */ + private function getCurrency(Account $account): ?TransactionCurrency + { + $accountId = $account->id; + if (array_key_exists($accountId, $this->accountCurrencies) && 0 === $this->accountCurrencies[$accountId]) { + return null; + } + if (array_key_exists($accountId, $this->accountCurrencies) && $this->accountCurrencies[$accountId] instanceof TransactionCurrency) { + return $this->accountCurrencies[$accountId]; + } + $currency = $this->accountRepos->getAccountCurrency($account); + if (null === $currency) { + $this->accountCurrencies[$accountId] = 0; + + return null; + } + $this->accountCurrencies[$accountId] = $currency; + + return $currency; + } + + /** + * + */ + private function markAsExecuted(): void + { + app('fireflyconfig')->set(self::CONFIG_NAME, true); } } diff --git a/app/Console/Commands/Upgrade/TransactionIdentifier.php b/app/Console/Commands/Upgrade/TransactionIdentifier.php index f8260370fa..4f27a372ca 100644 --- a/app/Console/Commands/Upgrade/TransactionIdentifier.php +++ b/app/Console/Commands/Upgrade/TransactionIdentifier.php @@ -49,13 +49,14 @@ class TransactionIdentifier extends Command private int $count; /** - * This method gives all transactions which are part of a split journal (so more than 2) a sort of "order" so they are easier - * to easier to match to their counterpart. When a journal is split, it has two or three transactions: -3, -4 and -5 for example. + * This method gives all transactions which are part of a split journal (so more than 2) a sort of "order" so they + * are easier to easier to match to their counterpart. When a journal is split, it has two or three transactions: + * -3, -4 and -5 for example. * * In the database this is reflected as 6 transactions: -3/+3, -4/+4, -5/+5. * - * When either of these are the same amount, FF3 can't keep them apart: +3/-3, +3/-3, +3/-3. This happens more often than you would - * think. So each set gets a number (1,2,3) to keep them apart. + * When either of these are the same amount, FF3 can't keep them apart: +3/-3, +3/-3, +3/-3. This happens more + * often than you would think. So each set gets a number (1,2,3) to keep them apart. * * @return int * @throws ContainerExceptionInterface @@ -96,8 +97,65 @@ class TransactionIdentifier extends Command } /** - * @param Transaction $transaction - * @param array $exclude + * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is + * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should + * be called from the handle method instead of using the constructor to initialize the command. + * + + */ + private function stupidLaravel(): void + { + $this->cliRepository = app(JournalCLIRepositoryInterface::class); + $this->count = 0; + } + + /** + * @return bool + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + private function isExecuted(): bool + { + $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); + if (null !== $configVar) { + return (bool)$configVar->data; + } + + return false; + } + + /** + * Grab all positive transactions from this journal that are not deleted. for each one, grab the negative opposing + * one which has 0 as an identifier and give it the same identifier. + * + * @param TransactionJournal $transactionJournal + */ + private function updateJournalIdentifiers(TransactionJournal $transactionJournal): void + { + $identifier = 0; + $exclude = []; // transactions already processed. + $transactions = $transactionJournal->transactions()->where('amount', '>', 0)->get(); + + /** @var Transaction $transaction */ + foreach ($transactions as $transaction) { + $opposing = $this->findOpposing($transaction, $exclude); + if (null !== $opposing) { + // give both a new identifier: + $transaction->identifier = $identifier; + $opposing->identifier = $identifier; + $transaction->save(); + $opposing->save(); + $exclude[] = $transaction->id; + $exclude[] = $opposing->id; + $this->count++; + } + ++$identifier; + } + } + + /** + * @param Transaction $transaction + * @param array $exclude * * @return Transaction|null */ @@ -125,21 +183,6 @@ class TransactionIdentifier extends Command return $opposing; } - /** - * @return bool - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - private function isExecuted(): bool - { - $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); - if (null !== $configVar) { - return (bool)$configVar->data; - } - - return false; - } - /** * */ @@ -147,46 +190,4 @@ class TransactionIdentifier extends Command { app('fireflyconfig')->set(self::CONFIG_NAME, true); } - - /** - * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is - * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should - * be called from the handle method instead of using the constructor to initialize the command. - * - - */ - private function stupidLaravel(): void - { - $this->cliRepository = app(JournalCLIRepositoryInterface::class); - $this->count = 0; - } - - /** - * Grab all positive transactions from this journal that are not deleted. for each one, grab the negative opposing one - * which has 0 as an identifier and give it the same identifier. - * - * @param TransactionJournal $transactionJournal - */ - private function updateJournalIdentifiers(TransactionJournal $transactionJournal): void - { - $identifier = 0; - $exclude = []; // transactions already processed. - $transactions = $transactionJournal->transactions()->where('amount', '>', 0)->get(); - - /** @var Transaction $transaction */ - foreach ($transactions as $transaction) { - $opposing = $this->findOpposing($transaction, $exclude); - if (null !== $opposing) { - // give both a new identifier: - $transaction->identifier = $identifier; - $opposing->identifier = $identifier; - $transaction->save(); - $opposing->save(); - $exclude[] = $transaction->id; - $exclude[] = $opposing->id; - $this->count++; - } - ++$identifier; - } - } } diff --git a/app/Console/Commands/Upgrade/TransferCurrenciesCorrections.php b/app/Console/Commands/Upgrade/TransferCurrenciesCorrections.php index f97a5b3183..26414d04a4 100644 --- a/app/Console/Commands/Upgrade/TransferCurrenciesCorrections.php +++ b/app/Console/Commands/Upgrade/TransferCurrenciesCorrections.php @@ -86,6 +86,304 @@ class TransferCurrenciesCorrections extends Command return 0; } + /** + * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is + * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should + * be called from the handle method instead of using the constructor to initialize the command. + * + + */ + private function stupidLaravel(): void + { + $this->count = 0; + $this->accountRepos = app(AccountRepositoryInterface::class); + $this->cliRepos = app(JournalCLIRepositoryInterface::class); + $this->accountCurrencies = []; + $this->resetInformation(); + } + + /** + * Reset all the class fields for the current transfer. + * + + */ + private function resetInformation(): void + { + $this->sourceTransaction = null; + $this->sourceAccount = null; + $this->sourceCurrency = null; + $this->destinationTransaction = null; + $this->destinationAccount = null; + $this->destinationCurrency = null; + } + + /** + * @return bool + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + private function isExecuted(): bool + { + $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); + if (null !== $configVar) { + return (bool)$configVar->data; + } + + return false; + } + + /** + * This routine verifies that transfers have the correct currency settings for the accounts they are linked to. + * For transfers, this is can be a destructive routine since we FORCE them into a currency setting whether they + * like it or not. Previous routines MUST have set the currency setting for both accounts for this to work. + * + * Both source and destination must match the respective currency preference. So FF3 must verify ALL + * transactions. + */ + private function startUpdateRoutine(): void + { + $set = $this->cliRepos->getAllJournals([TransactionType::TRANSFER]); + /** @var TransactionJournal $journal */ + foreach ($set as $journal) { + $this->updateTransferCurrency($journal); + } + } + + /** + * @param TransactionJournal $transfer + */ + private function updateTransferCurrency(TransactionJournal $transfer): void + { + $this->resetInformation(); + + + if ($this->isSplitJournal($transfer)) { + $this->friendlyWarning(sprintf('Transaction journal #%d is a split journal. Cannot continue.', $transfer->id)); + + return; + } + + + $this->getSourceInformation($transfer); + $this->getDestinationInformation($transfer); + + // unexpectedly, either one is null: + + if ($this->isEmptyTransactions()) { + $this->friendlyError(sprintf('Source or destination information for transaction journal #%d is null. Cannot fix this one.', $transfer->id)); + + return; + } + + // both accounts must have currency preference: + + if ($this->isNoCurrencyPresent()) { + $this->friendlyError( + sprintf('Source or destination accounts for transaction journal #%d have no currency information. Cannot fix this one.', $transfer->id) + ); + + return; + } + + + // fix source transaction having no currency. + $this->fixSourceNoCurrency(); + + // fix source transaction having bad currency. + $this->fixSourceUnmatchedCurrency(); + + // fix destination transaction having no currency. + $this->fixDestNoCurrency(); + + // fix destination transaction having bad currency. + $this->fixDestinationUnmatchedCurrency(); + + // remove foreign currency information if not necessary. + $this->fixInvalidForeignCurrency(); + // correct foreign currency info if necessary. + $this->fixMismatchedForeignCurrency(); + + // restore missing foreign currency amount. + $this->fixSourceNullForeignAmount(); + + $this->fixDestNullForeignAmount(); + + // fix journal itself: + $this->fixTransactionJournalCurrency($transfer); + } + + /** + * Is this a split transaction journal? + * + * @param TransactionJournal $transfer + * + * @return bool + */ + private function isSplitJournal(TransactionJournal $transfer): bool + { + return $transfer->transactions->count() > 2; + } + + /** + * Extract source transaction, source account + source account currency from the journal. + * + * @param TransactionJournal $journal + * + + */ + private function getSourceInformation(TransactionJournal $journal): void + { + $this->sourceTransaction = $this->getSourceTransaction($journal); + $this->sourceAccount = $this->sourceTransaction?->account; + $this->sourceCurrency = null === $this->sourceAccount ? null : $this->getCurrency($this->sourceAccount); + } + + /** + * @param TransactionJournal $transfer + * + * @return Transaction|null + */ + private function getSourceTransaction(TransactionJournal $transfer): ?Transaction + { + return $transfer->transactions()->where('amount', '<', 0)->first(); + } + + /** + * @param Account $account + * + * @return TransactionCurrency|null + */ + private function getCurrency(Account $account): ?TransactionCurrency + { + $accountId = $account->id; + if (array_key_exists($accountId, $this->accountCurrencies) && 0 === $this->accountCurrencies[$accountId]) { + return null; + } + if (array_key_exists($accountId, $this->accountCurrencies) && $this->accountCurrencies[$accountId] instanceof TransactionCurrency) { + return $this->accountCurrencies[$accountId]; + } + $currency = $this->accountRepos->getAccountCurrency($account); + if (null === $currency) { + $this->accountCurrencies[$accountId] = 0; + + return null; + } + $this->accountCurrencies[$accountId] = $currency; + + return $currency; + } + + /** + * Extract destination transaction, destination account + destination account currency from the journal. + * + * @param TransactionJournal $journal + * + + */ + private function getDestinationInformation(TransactionJournal $journal): void + { + $this->destinationTransaction = $this->getDestinationTransaction($journal); + $this->destinationAccount = $this->destinationTransaction?->account; + $this->destinationCurrency = null === $this->destinationAccount ? null : $this->getCurrency($this->destinationAccount); + } + + /** + * @param TransactionJournal $transfer + * + * @return Transaction|null + */ + private function getDestinationTransaction(TransactionJournal $transfer): ?Transaction + { + return $transfer->transactions()->where('amount', '>', 0)->first(); + } + + /** + * Is either the source or destination transaction NULL? + * + * @return bool + */ + private function isEmptyTransactions(): bool + { + return null === $this->sourceTransaction || null === $this->destinationTransaction + || null === $this->sourceAccount + || null === $this->destinationAccount; + } + + /** + * @return bool + */ + private function isNoCurrencyPresent(): bool + { + // source account must have a currency preference. + if (null === $this->sourceCurrency) { + $message = sprintf('Account #%d ("%s") must have currency preference but has none.', $this->sourceAccount->id, $this->sourceAccount->name); + Log::error($message); + $this->friendlyError($message); + + return true; + } + + // destination account must have a currency preference. + if (null === $this->destinationCurrency) { + $message = sprintf( + 'Account #%d ("%s") must have currency preference but has none.', + $this->destinationAccount->id, + $this->destinationAccount->name + ); + Log::error($message); + $this->friendlyError($message); + + return true; + } + + return false; + } + + /** + * The source transaction must have a currency. If not, it will be added by + * taking it from the source account's preference. + */ + private function fixSourceNoCurrency(): void + { + if (null === $this->sourceTransaction->transaction_currency_id && null !== $this->sourceCurrency) { + $this->sourceTransaction + ->transaction_currency_id + = (int)$this->sourceCurrency->id; + $message = sprintf( + 'Transaction #%d has no currency setting, now set to %s.', + $this->sourceTransaction->id, + $this->sourceCurrency->code + ); + $this->friendlyInfo($message); + $this->count++; + $this->sourceTransaction->save(); + } + } + + /** + * The source transaction must have the correct currency. If not, it will be set by + * taking it from the source account's preference. + */ + private function fixSourceUnmatchedCurrency(): void + { + if (null !== $this->sourceCurrency + && null === $this->sourceTransaction->foreign_amount + && (int)$this->sourceTransaction->transaction_currency_id !== (int)$this->sourceCurrency->id + ) { + $message = sprintf( + 'Transaction #%d has a currency setting #%d that should be #%d. Amount remains %s, currency is changed.', + $this->sourceTransaction->id, + $this->sourceTransaction->transaction_currency_id, + $this->sourceAccount->id, + $this->sourceTransaction->amount + ); + $this->friendlyWarning($message); + $this->count++; + $this->sourceTransaction->transaction_currency_id = (int)$this->sourceCurrency->id; + $this->sourceTransaction->save(); + } + } + /** * The destination transaction must have a currency. If not, it will be added by * taking it from the destination account's preference. @@ -107,26 +405,6 @@ class TransferCurrenciesCorrections extends Command } } - /** - * If the foreign amount of the destination transaction is null, but that of the other isn't, use this piece of code - * to restore it. - */ - private function fixDestNullForeignAmount(): void - { - if (null === $this->destinationTransaction->foreign_amount && null !== $this->sourceTransaction->foreign_amount) { - $this->destinationTransaction->foreign_amount = bcmul((string)$this->sourceTransaction->foreign_amount, '-1'); - $this->destinationTransaction->save(); - $this->count++; - $this->friendlyInfo( - sprintf( - 'Restored foreign amount of destination transaction #%d to %s', - $this->destinationTransaction->id, - $this->destinationTransaction->foreign_amount - ) - ); - } - } - /** * The destination transaction must have the correct currency. If not, it will be set by * taking it from the destination account's preference. @@ -193,27 +471,6 @@ class TransferCurrenciesCorrections extends Command } } - /** - * The source transaction must have a currency. If not, it will be added by - * taking it from the source account's preference. - */ - private function fixSourceNoCurrency(): void - { - if (null === $this->sourceTransaction->transaction_currency_id && null !== $this->sourceCurrency) { - $this->sourceTransaction - ->transaction_currency_id - = (int)$this->sourceCurrency->id; - $message = sprintf( - 'Transaction #%d has no currency setting, now set to %s.', - $this->sourceTransaction->id, - $this->sourceCurrency->code - ); - $this->friendlyInfo($message); - $this->count++; - $this->sourceTransaction->save(); - } - } - /** * If the foreign amount of the source transaction is null, but that of the other isn't, use this piece of code * to restore it. @@ -235,33 +492,29 @@ class TransferCurrenciesCorrections extends Command } /** - * The source transaction must have the correct currency. If not, it will be set by - * taking it from the source account's preference. + * If the foreign amount of the destination transaction is null, but that of the other isn't, use this piece of code + * to restore it. */ - private function fixSourceUnmatchedCurrency(): void + private function fixDestNullForeignAmount(): void { - if (null !== $this->sourceCurrency - && null === $this->sourceTransaction->foreign_amount - && (int)$this->sourceTransaction->transaction_currency_id !== (int)$this->sourceCurrency->id - ) { - $message = sprintf( - 'Transaction #%d has a currency setting #%d that should be #%d. Amount remains %s, currency is changed.', - $this->sourceTransaction->id, - $this->sourceTransaction->transaction_currency_id, - $this->sourceAccount->id, - $this->sourceTransaction->amount - ); - $this->friendlyWarning($message); + if (null === $this->destinationTransaction->foreign_amount && null !== $this->sourceTransaction->foreign_amount) { + $this->destinationTransaction->foreign_amount = bcmul((string)$this->sourceTransaction->foreign_amount, '-1'); + $this->destinationTransaction->save(); $this->count++; - $this->sourceTransaction->transaction_currency_id = (int)$this->sourceCurrency->id; - $this->sourceTransaction->save(); + $this->friendlyInfo( + sprintf( + 'Restored foreign amount of destination transaction #%d to %s', + $this->destinationTransaction->id, + $this->destinationTransaction->foreign_amount + ) + ); } } /** * This method makes sure that the transaction journal uses the currency given in the source transaction. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal */ private function fixTransactionJournalCurrency(TransactionJournal $journal): void { @@ -281,148 +534,6 @@ class TransferCurrenciesCorrections extends Command } } - /** - * @param Account $account - * - * @return TransactionCurrency|null - */ - private function getCurrency(Account $account): ?TransactionCurrency - { - $accountId = $account->id; - if (array_key_exists($accountId, $this->accountCurrencies) && 0 === $this->accountCurrencies[$accountId]) { - return null; - } - if (array_key_exists($accountId, $this->accountCurrencies) && $this->accountCurrencies[$accountId] instanceof TransactionCurrency) { - return $this->accountCurrencies[$accountId]; - } - $currency = $this->accountRepos->getAccountCurrency($account); - if (null === $currency) { - $this->accountCurrencies[$accountId] = 0; - - return null; - } - $this->accountCurrencies[$accountId] = $currency; - - return $currency; - } - - /** - * Extract destination transaction, destination account + destination account currency from the journal. - * - * @param TransactionJournal $journal - * - - */ - private function getDestinationInformation(TransactionJournal $journal): void - { - $this->destinationTransaction = $this->getDestinationTransaction($journal); - $this->destinationAccount = $this->destinationTransaction?->account; - $this->destinationCurrency = null === $this->destinationAccount ? null : $this->getCurrency($this->destinationAccount); - } - - /** - * @param TransactionJournal $transfer - * - * @return Transaction|null - */ - private function getDestinationTransaction(TransactionJournal $transfer): ?Transaction - { - return $transfer->transactions()->where('amount', '>', 0)->first(); - } - - /** - * Extract source transaction, source account + source account currency from the journal. - * - * @param TransactionJournal $journal - * - - */ - private function getSourceInformation(TransactionJournal $journal): void - { - $this->sourceTransaction = $this->getSourceTransaction($journal); - $this->sourceAccount = $this->sourceTransaction?->account; - $this->sourceCurrency = null === $this->sourceAccount ? null : $this->getCurrency($this->sourceAccount); - } - - /** - * @param TransactionJournal $transfer - * - * @return Transaction|null - */ - private function getSourceTransaction(TransactionJournal $transfer): ?Transaction - { - return $transfer->transactions()->where('amount', '<', 0)->first(); - } - - /** - * Is either the source or destination transaction NULL? - * - * @return bool - */ - private function isEmptyTransactions(): bool - { - return null === $this->sourceTransaction || null === $this->destinationTransaction - || null === $this->sourceAccount - || null === $this->destinationAccount; - } - - /** - * @return bool - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - private function isExecuted(): bool - { - $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); - if (null !== $configVar) { - return (bool)$configVar->data; - } - - return false; - } - - /** - * @return bool - */ - private function isNoCurrencyPresent(): bool - { - // source account must have a currency preference. - if (null === $this->sourceCurrency) { - $message = sprintf('Account #%d ("%s") must have currency preference but has none.', $this->sourceAccount->id, $this->sourceAccount->name); - Log::error($message); - $this->friendlyError($message); - - return true; - } - - // destination account must have a currency preference. - if (null === $this->destinationCurrency) { - $message = sprintf( - 'Account #%d ("%s") must have currency preference but has none.', - $this->destinationAccount->id, - $this->destinationAccount->name - ); - Log::error($message); - $this->friendlyError($message); - - return true; - } - - return false; - } - - /** - * Is this a split transaction journal? - * - * @param TransactionJournal $transfer - * - * @return bool - */ - private function isSplitJournal(TransactionJournal $transfer): bool - { - return $transfer->transactions->count() > 2; - } - /** * */ @@ -430,115 +541,4 @@ class TransferCurrenciesCorrections extends Command { app('fireflyconfig')->set(self::CONFIG_NAME, true); } - - /** - * Reset all the class fields for the current transfer. - * - - */ - private function resetInformation(): void - { - $this->sourceTransaction = null; - $this->sourceAccount = null; - $this->sourceCurrency = null; - $this->destinationTransaction = null; - $this->destinationAccount = null; - $this->destinationCurrency = null; - } - - /** - * This routine verifies that transfers have the correct currency settings for the accounts they are linked to. - * For transfers, this is can be a destructive routine since we FORCE them into a currency setting whether they - * like it or not. Previous routines MUST have set the currency setting for both accounts for this to work. - * - * Both source and destination must match the respective currency preference. So FF3 must verify ALL - * transactions. - */ - private function startUpdateRoutine(): void - { - $set = $this->cliRepos->getAllJournals([TransactionType::TRANSFER]); - /** @var TransactionJournal $journal */ - foreach ($set as $journal) { - $this->updateTransferCurrency($journal); - } - } - - /** - * Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is - * executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should - * be called from the handle method instead of using the constructor to initialize the command. - * - - */ - private function stupidLaravel(): void - { - $this->count = 0; - $this->accountRepos = app(AccountRepositoryInterface::class); - $this->cliRepos = app(JournalCLIRepositoryInterface::class); - $this->accountCurrencies = []; - $this->resetInformation(); - } - - /** - * @param TransactionJournal $transfer - */ - private function updateTransferCurrency(TransactionJournal $transfer): void - { - $this->resetInformation(); - - - if ($this->isSplitJournal($transfer)) { - $this->friendlyWarning(sprintf('Transaction journal #%d is a split journal. Cannot continue.', $transfer->id)); - - return; - } - - - $this->getSourceInformation($transfer); - $this->getDestinationInformation($transfer); - - // unexpectedly, either one is null: - - if ($this->isEmptyTransactions()) { - $this->friendlyError(sprintf('Source or destination information for transaction journal #%d is null. Cannot fix this one.', $transfer->id)); - - return; - } - - // both accounts must have currency preference: - - if ($this->isNoCurrencyPresent()) { - $this->friendlyError( - sprintf('Source or destination accounts for transaction journal #%d have no currency information. Cannot fix this one.', $transfer->id) - ); - - return; - } - - - // fix source transaction having no currency. - $this->fixSourceNoCurrency(); - - // fix source transaction having bad currency. - $this->fixSourceUnmatchedCurrency(); - - // fix destination transaction having no currency. - $this->fixDestNoCurrency(); - - // fix destination transaction having bad currency. - $this->fixDestinationUnmatchedCurrency(); - - // remove foreign currency information if not necessary. - $this->fixInvalidForeignCurrency(); - // correct foreign currency info if necessary. - $this->fixMismatchedForeignCurrency(); - - // restore missing foreign currency amount. - $this->fixSourceNullForeignAmount(); - - $this->fixDestNullForeignAmount(); - - // fix journal itself: - $this->fixTransactionJournalCurrency($transfer); - } } diff --git a/app/Console/Commands/Upgrade/UpgradeLiabilities.php b/app/Console/Commands/Upgrade/UpgradeLiabilities.php index 213a300b3e..37c357e86d 100644 --- a/app/Console/Commands/Upgrade/UpgradeLiabilities.php +++ b/app/Console/Commands/Upgrade/UpgradeLiabilities.php @@ -34,7 +34,6 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Services\Internal\Support\CreditRecalculateService; use FireflyIII\User; use Illuminate\Console\Command; -use Illuminate\Support\Facades\Log; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; @@ -70,48 +69,6 @@ class UpgradeLiabilities extends Command return 0; } - /** - * @param Account $account - * @param TransactionJournal $openingBalance - */ - private function correctOpeningBalance(Account $account, TransactionJournal $openingBalance): void - { - $source = $this->getSourceTransaction($openingBalance); - $destination = $this->getDestinationTransaction($openingBalance); - if (null === $source || null === $destination) { - return; - } - // source MUST be the liability. - if ((int)$destination->account_id === (int)$account->id) { - // so if not, switch things around: - $sourceAccountId = (int)$source->account_id; - $source->account_id = $destination->account_id; - $destination->account_id = $sourceAccountId; - $source->save(); - $destination->save(); - } - } - - /** - * @param TransactionJournal $journal - * - * @return Transaction|null - */ - private function getDestinationTransaction(TransactionJournal $journal): ?Transaction - { - return $journal->transactions()->where('amount', '>', 0)->first(); - } - - /** - * @param TransactionJournal $journal - * - * @return Transaction|null - */ - private function getSourceTransaction(TransactionJournal $journal): ?Transaction - { - return $journal->transactions()->where('amount', '<', 0)->first(); - } - /** * @return bool * @throws ContainerExceptionInterface @@ -130,13 +87,17 @@ class UpgradeLiabilities extends Command /** * */ - private function markAsExecuted(): void + private function upgradeLiabilities(): void { - app('fireflyconfig')->set(self::CONFIG_NAME, true); + $users = User::get(); + /** @var User $user */ + foreach ($users as $user) { + $this->upgradeForUser($user); + } } /** - * @param User $user + * @param User $user */ private function upgradeForUser(User $user): void { @@ -154,19 +115,7 @@ class UpgradeLiabilities extends Command } /** - * - */ - private function upgradeLiabilities(): void - { - $users = User::get(); - /** @var User $user */ - foreach ($users as $user) { - $this->upgradeForUser($user); - } - } - - /** - * @param Account $account + * @param Account $account */ private function upgradeLiability(Account $account): void { @@ -189,4 +138,54 @@ class UpgradeLiabilities extends Command $factory->crud($account, 'liability_direction', 'debit'); } } + + /** + * @param Account $account + * @param TransactionJournal $openingBalance + */ + private function correctOpeningBalance(Account $account, TransactionJournal $openingBalance): void + { + $source = $this->getSourceTransaction($openingBalance); + $destination = $this->getDestinationTransaction($openingBalance); + if (null === $source || null === $destination) { + return; + } + // source MUST be the liability. + if ((int)$destination->account_id === (int)$account->id) { + // so if not, switch things around: + $sourceAccountId = (int)$source->account_id; + $source->account_id = $destination->account_id; + $destination->account_id = $sourceAccountId; + $source->save(); + $destination->save(); + } + } + + /** + * @param TransactionJournal $journal + * + * @return Transaction|null + */ + private function getSourceTransaction(TransactionJournal $journal): ?Transaction + { + return $journal->transactions()->where('amount', '<', 0)->first(); + } + + /** + * @param TransactionJournal $journal + * + * @return Transaction|null + */ + private function getDestinationTransaction(TransactionJournal $journal): ?Transaction + { + return $journal->transactions()->where('amount', '>', 0)->first(); + } + + /** + * + */ + private function markAsExecuted(): void + { + app('fireflyconfig')->set(self::CONFIG_NAME, true); + } } diff --git a/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php b/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php index c177fb9a59..4e15e9cd02 100644 --- a/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php +++ b/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php @@ -73,7 +73,105 @@ class UpgradeLiabilitiesEight extends Command } /** - * @param Account $account + * @return bool + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + private function isExecuted(): bool + { + $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); + if (null !== $configVar) { + return (bool)$configVar->data; + } + + return false; + } + + /** + * + */ + private function upgradeLiabilities(): void + { + $users = User::get(); + /** @var User $user */ + foreach ($users as $user) { + $this->upgradeForUser($user); + } + } + + /** + * @param User $user + */ + private function upgradeForUser(User $user): void + { + $accounts = $user->accounts() + ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') + ->whereIn('account_types.type', config('firefly.valid_liabilities')) + ->get(['accounts.*']); + /** @var Account $account */ + foreach ($accounts as $account) { + $this->upgradeLiability($account); + $service = app(CreditRecalculateService::class); + $service->setAccount($account); + $service->recalculate(); + } + } + + /** + * @param Account $account + */ + private function upgradeLiability(Account $account): void + { + /** @var AccountRepositoryInterface $repository */ + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($account->user); + + $direction = $repository->getMetaValue($account, 'liability_direction'); + if ('credit' === $direction && $this->hasBadOpening($account)) { + $this->deleteCreditTransaction($account); + $this->reverseOpeningBalance($account); + $this->friendlyInfo(sprintf('Corrected opening balance for liability #%d ("%s")', $account->id, $account->name)); + } + if ('credit' === $direction) { + $count = $this->deleteTransactions($account); + if ($count > 0) { + $this->friendlyInfo(sprintf('Removed %d old format transaction(s) for liability #%d ("%s")', $count, $account->id, $account->name)); + } + } + } + + /** + * @param Account $account + * + * @return bool + */ + private function hasBadOpening(Account $account): bool + { + $openingBalanceType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first(); + $liabilityType = TransactionType::whereType(TransactionType::LIABILITY_CREDIT)->first(); + $openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transactions.account_id', $account->id) + ->where('transaction_journals.transaction_type_id', $openingBalanceType->id) + ->first(['transaction_journals.*']); + if (null === $openingJournal) { + return false; + } + $liabilityJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transactions.account_id', $account->id) + ->where('transaction_journals.transaction_type_id', $liabilityType->id) + ->first(['transaction_journals.*']); + if (null === $liabilityJournal) { + return false; + } + if (!$openingJournal->date->isSameDay($liabilityJournal->date)) { + return false; + } + + return true; + } + + /** + * @param Account $account * * @return void */ @@ -93,6 +191,36 @@ class UpgradeLiabilitiesEight extends Command } } + /** + * @param Account $account + * + * @return void + */ + private function reverseOpeningBalance(Account $account): void + { + $openingBalanceType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first(); + /** @var TransactionJournal $openingJournal */ + $openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transactions.account_id', $account->id) + ->where('transaction_journals.transaction_type_id', $openingBalanceType->id) + ->first(['transaction_journals.*']); + /** @var Transaction|null $source */ + $source = $openingJournal->transactions()->where('amount', '<', 0)->first(); + /** @var Transaction|null $dest */ + $dest = $openingJournal->transactions()->where('amount', '>', 0)->first(); + if ($source && $dest) { + $sourceId = $source->account_id; + $destId = $dest->account_id; + $dest->account_id = $sourceId; + $source->account_id = $destId; + $source->save(); + $dest->save(); + + return; + } + Log::warning('Did not find opening balance.'); + } + /** * @param $account * @@ -134,51 +262,6 @@ class UpgradeLiabilitiesEight extends Command return $count; } - /** - * @param Account $account - * - * @return bool - */ - private function hasBadOpening(Account $account): bool - { - $openingBalanceType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first(); - $liabilityType = TransactionType::whereType(TransactionType::LIABILITY_CREDIT)->first(); - $openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transactions.account_id', $account->id) - ->where('transaction_journals.transaction_type_id', $openingBalanceType->id) - ->first(['transaction_journals.*']); - if (null === $openingJournal) { - return false; - } - $liabilityJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transactions.account_id', $account->id) - ->where('transaction_journals.transaction_type_id', $liabilityType->id) - ->first(['transaction_journals.*']); - if (null === $liabilityJournal) { - return false; - } - if (!$openingJournal->date->isSameDay($liabilityJournal->date)) { - return false; - } - - return true; - } - - /** - * @return bool - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - private function isExecuted(): bool - { - $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); - if (null !== $configVar) { - return (bool)$configVar->data; - } - - return false; - } - /** * */ @@ -186,87 +269,4 @@ class UpgradeLiabilitiesEight extends Command { app('fireflyconfig')->set(self::CONFIG_NAME, true); } - - /** - * @param Account $account - * - * @return void - */ - private function reverseOpeningBalance(Account $account): void - { - $openingBalanceType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first(); - /** @var TransactionJournal $openingJournal */ - $openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transactions.account_id', $account->id) - ->where('transaction_journals.transaction_type_id', $openingBalanceType->id) - ->first(['transaction_journals.*']); - /** @var Transaction|null $source */ - $source = $openingJournal->transactions()->where('amount', '<', 0)->first(); - /** @var Transaction|null $dest */ - $dest = $openingJournal->transactions()->where('amount', '>', 0)->first(); - if ($source && $dest) { - $sourceId = $source->account_id; - $destId = $dest->account_id; - $dest->account_id = $sourceId; - $source->account_id = $destId; - $source->save(); - $dest->save(); - - return; - } - Log::warning('Did not find opening balance.'); - } - - /** - * @param User $user - */ - private function upgradeForUser(User $user): void - { - $accounts = $user->accounts() - ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') - ->whereIn('account_types.type', config('firefly.valid_liabilities')) - ->get(['accounts.*']); - /** @var Account $account */ - foreach ($accounts as $account) { - $this->upgradeLiability($account); - $service = app(CreditRecalculateService::class); - $service->setAccount($account); - $service->recalculate(); - } - } - - /** - * - */ - private function upgradeLiabilities(): void - { - $users = User::get(); - /** @var User $user */ - foreach ($users as $user) { - $this->upgradeForUser($user); - } - } - - /** - * @param Account $account - */ - private function upgradeLiability(Account $account): void - { - /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class); - $repository->setUser($account->user); - - $direction = $repository->getMetaValue($account, 'liability_direction'); - if ('credit' === $direction && $this->hasBadOpening($account)) { - $this->deleteCreditTransaction($account); - $this->reverseOpeningBalance($account); - $this->friendlyInfo(sprintf('Corrected opening balance for liability #%d ("%s")', $account->id, $account->name)); - } - if ('credit' === $direction) { - $count = $this->deleteTransactions($account); - if ($count > 0) { - $this->friendlyInfo(sprintf('Removed %d old format transaction(s) for liability #%d ("%s")', $count, $account->id, $account->name)); - } - } - } } diff --git a/app/Console/Commands/VerifiesAccessToken.php b/app/Console/Commands/VerifiesAccessToken.php index dfcc1ce2f2..d6c45610c3 100644 --- a/app/Console/Commands/VerifiesAccessToken.php +++ b/app/Console/Commands/VerifiesAccessToken.php @@ -57,7 +57,7 @@ trait VerifiesAccessToken /** * Abstract method to make sure trait knows about method "option". * - * @param string|null $key + * @param string|null $key * * @return mixed */ diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 42c0151d67..3282712a95 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -40,7 +40,7 @@ class Kernel extends ConsoleKernel */ protected function commands(): void { - $this->load(__DIR__.'/Commands'); + $this->load(__DIR__ . '/Commands'); require base_path('routes/console.php'); } @@ -48,7 +48,7 @@ class Kernel extends ConsoleKernel /** * Define the application's command schedule. * - * @param Schedule $schedule + * @param Schedule $schedule */ protected function schedule(Schedule $schedule): void { diff --git a/app/Enums/AccountTypeEnum.php b/app/Enums/AccountTypeEnum.php index e14aaf7d3c..1a178d2101 100644 --- a/app/Enums/AccountTypeEnum.php +++ b/app/Enums/AccountTypeEnum.php @@ -29,18 +29,18 @@ namespace FireflyIII\Enums; */ enum AccountTypeEnum: string { - case ASSET = 'Asset account'; - case BENEFICIARY = 'Beneficiary account'; - case CASH = 'Cash account'; - case CREDITCARD = 'Credit card'; - case DEBT = 'Debt'; - case DEFAULT = 'Default account'; - case EXPENSE = 'Expense account'; - case IMPORT = 'Import account'; - case INITIAL_BALANCE = 'Initial balance account'; + case ASSET = 'Asset account'; + case BENEFICIARY = 'Beneficiary account'; + case CASH = 'Cash account'; + case CREDITCARD = 'Credit card'; + case DEBT = 'Debt'; + case DEFAULT = 'Default account'; + case EXPENSE = 'Expense account'; + case IMPORT = 'Import account'; + case INITIAL_BALANCE = 'Initial balance account'; case LIABILITY_CREDIT = 'Liability credit account'; - case LOAN = 'Loan'; - case MORTGAGE = 'Mortgage'; - case RECONCILIATION = 'Reconciliation account'; - case REVENUE = 'Revenue account'; + case LOAN = 'Loan'; + case MORTGAGE = 'Mortgage'; + case RECONCILIATION = 'Reconciliation account'; + case REVENUE = 'Revenue account'; } diff --git a/app/Enums/AutoBudgetType.php b/app/Enums/AutoBudgetType.php index ac8341a212..6d2a327a65 100644 --- a/app/Enums/AutoBudgetType.php +++ b/app/Enums/AutoBudgetType.php @@ -29,7 +29,7 @@ namespace FireflyIII\Enums; */ enum AutoBudgetType: int { - case AUTO_BUDGET_RESET = 1; + case AUTO_BUDGET_RESET = 1; case AUTO_BUDGET_ROLLOVER = 2; case AUTO_BUDGET_ADJUSTED = 3; } diff --git a/app/Enums/RecurrenceRepetitionWeekend.php b/app/Enums/RecurrenceRepetitionWeekend.php index f647b7b9e6..d19d7e541b 100644 --- a/app/Enums/RecurrenceRepetitionWeekend.php +++ b/app/Enums/RecurrenceRepetitionWeekend.php @@ -26,8 +26,8 @@ namespace FireflyIII\Enums; enum RecurrenceRepetitionWeekend: int { - case WEEKEND_DO_NOTHING = 1; + case WEEKEND_DO_NOTHING = 1; case WEEKEND_SKIP_CREATION = 2; - case WEEKEND_TO_FRIDAY = 3; - case WEEKEND_TO_MONDAY = 4; + case WEEKEND_TO_FRIDAY = 3; + case WEEKEND_TO_MONDAY = 4; } diff --git a/app/Enums/TransactionTypeEnum.php b/app/Enums/TransactionTypeEnum.php index 039a117bb7..0df01e348a 100644 --- a/app/Enums/TransactionTypeEnum.php +++ b/app/Enums/TransactionTypeEnum.php @@ -29,11 +29,11 @@ namespace FireflyIII\Enums; */ enum TransactionTypeEnum: string { - case DEPOSIT = 'Deposit'; - case INVALID = 'Invalid'; + case DEPOSIT = 'Deposit'; + case INVALID = 'Invalid'; case LIABILITY_CREDIT = 'Liability credit'; - case OPENING_BALANCE = 'Opening balance'; - case RECONCILIATION = 'Reconciliation'; - case TRANSFER = 'Transfer'; - case WITHDRAWAL = 'Withdrawal'; + case OPENING_BALANCE = 'Opening balance'; + case RECONCILIATION = 'Reconciliation'; + case TRANSFER = 'Transfer'; + case WITHDRAWAL = 'Withdrawal'; } diff --git a/app/Enums/UserRoleEnum.php b/app/Enums/UserRoleEnum.php index e053bf5ae8..e1d6ceb228 100644 --- a/app/Enums/UserRoleEnum.php +++ b/app/Enums/UserRoleEnum.php @@ -26,12 +26,12 @@ namespace FireflyIII\Enums; enum UserRoleEnum: string { - case CHANGE_PIGGY_BANKS = 'change_piggies'; - case CHANGE_REPETITIONS = 'change_reps'; - case CHANGE_RULES = 'change_rules'; + case CHANGE_PIGGY_BANKS = 'change_piggies'; + case CHANGE_REPETITIONS = 'change_reps'; + case CHANGE_RULES = 'change_rules'; case CHANGE_TRANSACTIONS = 'change_tx'; - case FULL = 'full'; - case OWNER = 'owner'; - case READ_ONLY = 'ro'; - case VIEW_REPORTS = 'view_reports'; + case FULL = 'full'; + case OWNER = 'owner'; + case READ_ONLY = 'ro'; + case VIEW_REPORTS = 'view_reports'; } diff --git a/app/Enums/WebhookResponse.php b/app/Enums/WebhookResponse.php index ca7057f468..6d47af0255 100644 --- a/app/Enums/WebhookResponse.php +++ b/app/Enums/WebhookResponse.php @@ -27,6 +27,6 @@ namespace FireflyIII\Enums; enum WebhookResponse: int { case TRANSACTIONS = 200; - case ACCOUNTS = 210; - case NONE = 220; + case ACCOUNTS = 210; + case NONE = 220; } diff --git a/app/Events/ActuallyLoggedIn.php b/app/Events/ActuallyLoggedIn.php index 6f0d07e691..557dad3b38 100644 --- a/app/Events/ActuallyLoggedIn.php +++ b/app/Events/ActuallyLoggedIn.php @@ -37,7 +37,7 @@ class ActuallyLoggedIn extends Event public User $user; /** - * @param User $user + * @param User $user */ public function __construct(User $user) { diff --git a/app/Events/Admin/InvitationCreated.php b/app/Events/Admin/InvitationCreated.php index 37fab9cbd2..3df959e956 100644 --- a/app/Events/Admin/InvitationCreated.php +++ b/app/Events/Admin/InvitationCreated.php @@ -43,7 +43,7 @@ class InvitationCreated extends Event /** * Create a new event instance. * - * @param InvitedUser $invitee + * @param InvitedUser $invitee */ public function __construct(InvitedUser $invitee) { diff --git a/app/Events/AdminRequestedTestMessage.php b/app/Events/AdminRequestedTestMessage.php index 23e03750f4..1c8d0fa1de 100644 --- a/app/Events/AdminRequestedTestMessage.php +++ b/app/Events/AdminRequestedTestMessage.php @@ -42,7 +42,7 @@ class AdminRequestedTestMessage extends Event /** * Create a new event instance. * - * @param User $user + * @param User $user */ public function __construct(User $user) { diff --git a/app/Events/ChangedPiggyBankAmount.php b/app/Events/ChangedPiggyBankAmount.php index 9434224d39..c1f6a7b689 100644 --- a/app/Events/ChangedPiggyBankAmount.php +++ b/app/Events/ChangedPiggyBankAmount.php @@ -45,10 +45,10 @@ class ChangedPiggyBankAmount extends Event /** * Create a new event instance. * - * @param PiggyBank $piggyBank - * @param string $amount - * @param TransactionJournal|null $transactionJournal - * @param TransactionGroup|null $transactionGroup + * @param PiggyBank $piggyBank + * @param string $amount + * @param TransactionJournal|null $transactionJournal + * @param TransactionGroup|null $transactionGroup */ public function __construct(PiggyBank $piggyBank, string $amount, ?TransactionJournal $transactionJournal, ?TransactionGroup $transactionGroup) { diff --git a/app/Events/DestroyedTransactionGroup.php b/app/Events/DestroyedTransactionGroup.php index 3fee8983c9..febad99260 100644 --- a/app/Events/DestroyedTransactionGroup.php +++ b/app/Events/DestroyedTransactionGroup.php @@ -42,7 +42,7 @@ class DestroyedTransactionGroup extends Event /** * Create a new event instance. * - * @param TransactionGroup $transactionGroup + * @param TransactionGroup $transactionGroup */ public function __construct(TransactionGroup $transactionGroup) { diff --git a/app/Events/DestroyedTransactionLink.php b/app/Events/DestroyedTransactionLink.php index b795515e72..fee5c47c9e 100644 --- a/app/Events/DestroyedTransactionLink.php +++ b/app/Events/DestroyedTransactionLink.php @@ -38,7 +38,7 @@ class DestroyedTransactionLink extends Event /** * DestroyedTransactionLink constructor. * - * @param TransactionJournalLink $link + * @param TransactionJournalLink $link */ public function __construct(TransactionJournalLink $link) { diff --git a/app/Events/DetectedNewIPAddress.php b/app/Events/DetectedNewIPAddress.php index 2e8de8ebbf..567bba32cc 100644 --- a/app/Events/DetectedNewIPAddress.php +++ b/app/Events/DetectedNewIPAddress.php @@ -39,8 +39,8 @@ class DetectedNewIPAddress extends Event /** * Create a new event instance. This event is triggered when a new user registers. * - * @param User $user - * @param string $ipAddress + * @param User $user + * @param string $ipAddress */ public function __construct(User $user, string $ipAddress) { diff --git a/app/Events/Model/BudgetLimit/Created.php b/app/Events/Model/BudgetLimit/Created.php index 95b84f0523..af97f21164 100644 --- a/app/Events/Model/BudgetLimit/Created.php +++ b/app/Events/Model/BudgetLimit/Created.php @@ -37,7 +37,7 @@ class Created extends Event public BudgetLimit $budgetLimit; /** - * @param BudgetLimit $budgetLimit + * @param BudgetLimit $budgetLimit */ public function __construct(BudgetLimit $budgetLimit) { diff --git a/app/Events/Model/BudgetLimit/Deleted.php b/app/Events/Model/BudgetLimit/Deleted.php index 9792d5c4e7..e999af1cc1 100644 --- a/app/Events/Model/BudgetLimit/Deleted.php +++ b/app/Events/Model/BudgetLimit/Deleted.php @@ -37,7 +37,7 @@ class Deleted extends Event public BudgetLimit $budgetLimit; /** - * @param BudgetLimit $budgetLimit + * @param BudgetLimit $budgetLimit */ public function __construct(BudgetLimit $budgetLimit) { diff --git a/app/Events/Model/BudgetLimit/Updated.php b/app/Events/Model/BudgetLimit/Updated.php index bbf36f3aae..047ab751ee 100644 --- a/app/Events/Model/BudgetLimit/Updated.php +++ b/app/Events/Model/BudgetLimit/Updated.php @@ -37,7 +37,7 @@ class Updated extends Event public BudgetLimit $budgetLimit; /** - * @param BudgetLimit $budgetLimit + * @param BudgetLimit $budgetLimit */ public function __construct(BudgetLimit $budgetLimit) { diff --git a/app/Events/NewVersionAvailable.php b/app/Events/NewVersionAvailable.php index 358441d766..28193ae6af 100644 --- a/app/Events/NewVersionAvailable.php +++ b/app/Events/NewVersionAvailable.php @@ -35,7 +35,7 @@ class NewVersionAvailable extends Event /** * Create a new event instance. This event is triggered when a new version is available. * - * @param string $message + * @param string $message */ public function __construct(string $message) { diff --git a/app/Events/RegisteredUser.php b/app/Events/RegisteredUser.php index 02b4aff53d..16e29abfd2 100644 --- a/app/Events/RegisteredUser.php +++ b/app/Events/RegisteredUser.php @@ -40,7 +40,8 @@ class RegisteredUser extends Event /** * Create a new event instance. This event is triggered when a new user registers. - * @param User $user + * + * @param User $user */ public function __construct(User $user) { diff --git a/app/Events/RequestedNewPassword.php b/app/Events/RequestedNewPassword.php index e983fda7bd..5967426dcd 100644 --- a/app/Events/RequestedNewPassword.php +++ b/app/Events/RequestedNewPassword.php @@ -46,9 +46,9 @@ class RequestedNewPassword extends Event /** * Create a new event instance. This event is triggered when a users tries to reset his or her password. * - * @param User $user - * @param string $token - * @param string $ipAddress + * @param User $user + * @param string $token + * @param string $ipAddress */ public function __construct(User $user, string $token, string $ipAddress) { diff --git a/app/Events/RequestedReportOnJournals.php b/app/Events/RequestedReportOnJournals.php index 1ff2a620fc..8b9edbd7eb 100644 --- a/app/Events/RequestedReportOnJournals.php +++ b/app/Events/RequestedReportOnJournals.php @@ -48,8 +48,8 @@ class RequestedReportOnJournals /** * Create a new event instance. * - * @param int $userId - * @param Collection $groups + * @param int $userId + * @param Collection $groups */ public function __construct(int $userId, Collection $groups) { diff --git a/app/Events/RequestedVersionCheckStatus.php b/app/Events/RequestedVersionCheckStatus.php index b4c37c32ac..9379beacb3 100644 --- a/app/Events/RequestedVersionCheckStatus.php +++ b/app/Events/RequestedVersionCheckStatus.php @@ -43,7 +43,7 @@ class RequestedVersionCheckStatus extends Event * Create a new event instance. This event is triggered when Firefly III wants to know * what the deal is with the version checker. * - * @param User $user + * @param User $user */ public function __construct(User $user) { diff --git a/app/Events/StoredAccount.php b/app/Events/StoredAccount.php index 9ccbe3a56d..d126dd3468 100644 --- a/app/Events/StoredAccount.php +++ b/app/Events/StoredAccount.php @@ -39,7 +39,7 @@ class StoredAccount extends Event /** * Create a new event instance. * - * @param Account $account + * @param Account $account */ public function __construct(Account $account) { diff --git a/app/Events/StoredTransactionGroup.php b/app/Events/StoredTransactionGroup.php index d399253077..40d65bf776 100644 --- a/app/Events/StoredTransactionGroup.php +++ b/app/Events/StoredTransactionGroup.php @@ -43,9 +43,9 @@ class StoredTransactionGroup extends Event /** * Create a new event instance. * - * @param TransactionGroup $transactionGroup - * @param bool $applyRules - * @param bool $fireWebhooks + * @param TransactionGroup $transactionGroup + * @param bool $applyRules + * @param bool $fireWebhooks */ public function __construct(TransactionGroup $transactionGroup, bool $applyRules, bool $fireWebhooks) { diff --git a/app/Events/UpdatedAccount.php b/app/Events/UpdatedAccount.php index 05f107a5d4..66640720b2 100644 --- a/app/Events/UpdatedAccount.php +++ b/app/Events/UpdatedAccount.php @@ -39,7 +39,7 @@ class UpdatedAccount extends Event /** * Create a new event instance. * - * @param Account $account + * @param Account $account */ public function __construct(Account $account) { diff --git a/app/Events/UpdatedTransactionGroup.php b/app/Events/UpdatedTransactionGroup.php index af7d481bc7..b3a79a56f2 100644 --- a/app/Events/UpdatedTransactionGroup.php +++ b/app/Events/UpdatedTransactionGroup.php @@ -43,9 +43,9 @@ class UpdatedTransactionGroup extends Event /** * Create a new event instance. * - * @param TransactionGroup $transactionGroup - * @param bool $applyRules - * @param bool $fireWebhooks + * @param TransactionGroup $transactionGroup + * @param bool $applyRules + * @param bool $fireWebhooks */ public function __construct(TransactionGroup $transactionGroup, bool $applyRules, bool $fireWebhooks) { diff --git a/app/Events/UserChangedEmail.php b/app/Events/UserChangedEmail.php index 3d695fb487..a71a4b7580 100644 --- a/app/Events/UserChangedEmail.php +++ b/app/Events/UserChangedEmail.php @@ -43,9 +43,9 @@ class UserChangedEmail extends Event /** * UserChangedEmail constructor. * - * @param User $user - * @param string $newEmail - * @param string $oldEmail + * @param User $user + * @param string $newEmail + * @param string $oldEmail */ public function __construct(User $user, string $newEmail, string $oldEmail) { diff --git a/app/Events/WarnUserAboutBill.php b/app/Events/WarnUserAboutBill.php index e101444ef5..d0673f5755 100644 --- a/app/Events/WarnUserAboutBill.php +++ b/app/Events/WarnUserAboutBill.php @@ -41,9 +41,9 @@ class WarnUserAboutBill extends Event public string $field; /** - * @param Bill $bill - * @param string $field - * @param int $diff + * @param Bill $bill + * @param string $field + * @param int $diff */ public function __construct(Bill $bill, string $field, int $diff) { diff --git a/app/Exceptions/GracefulNotFoundHandler.php b/app/Exceptions/GracefulNotFoundHandler.php index cd78d542cd..94ba81ec38 100644 --- a/app/Exceptions/GracefulNotFoundHandler.php +++ b/app/Exceptions/GracefulNotFoundHandler.php @@ -48,8 +48,8 @@ class GracefulNotFoundHandler extends ExceptionHandler /** * Render an exception into an HTTP response. * - * @param Request $request - * @param Throwable $e + * @param Request $request + * @param Throwable $e * * @return Application|JsonResponse|\Illuminate\Http\Response|Redirector|RedirectResponse|Response * @throws Throwable @@ -135,8 +135,8 @@ class GracefulNotFoundHandler extends ExceptionHandler } /** - * @param Request $request - * @param Throwable $exception + * @param Request $request + * @param Throwable $exception * * @return Response * @throws Throwable @@ -169,8 +169,47 @@ class GracefulNotFoundHandler extends ExceptionHandler } /** - * @param Request $request - * @param Throwable $exception + * @param Request $request + * @param Throwable $exception + * + * @return Response + * @throws Throwable + */ + private function handleGroup(Request $request, Throwable $exception) + { + Log::debug('404 page is probably a deleted group. Redirect to overview of group types.'); + /** @var User $user */ + $user = auth()->user(); + $route = $request->route(); + $groupId = (int)$route->parameter('transactionGroup'); + + /** @var TransactionGroup|null $group */ + $group = $user->transactionGroups()->withTrashed()->find($groupId); + if (null === $group) { + Log::error(sprintf('Could not find group %d, so give big fat error.', $groupId)); + + return parent::render($request, $exception); + } + /** @var TransactionJournal|null $journal */ + $journal = $group->transactionJournals()->withTrashed()->first(); + if (null === $journal) { + Log::error(sprintf('Could not find journal for group %d, so give big fat error.', $groupId)); + + return parent::render($request, $exception); + } + $type = $journal->transactionType->type; + $request->session()->reflash(); + + if (TransactionType::RECONCILIATION === $type) { + return redirect(route('accounts.index', ['asset'])); + } + + return redirect(route('transactions.index', [strtolower($type)])); + } + + /** + * @param Request $request + * @param Throwable $exception * * @return Response * @throws Throwable @@ -211,43 +250,4 @@ class GracefulNotFoundHandler extends ExceptionHandler return parent::render($request, $exception); } - - /** - * @param Request $request - * @param Throwable $exception - * - * @return Response - * @throws Throwable - */ - private function handleGroup(Request $request, Throwable $exception) - { - Log::debug('404 page is probably a deleted group. Redirect to overview of group types.'); - /** @var User $user */ - $user = auth()->user(); - $route = $request->route(); - $groupId = (int)$route->parameter('transactionGroup'); - - /** @var TransactionGroup|null $group */ - $group = $user->transactionGroups()->withTrashed()->find($groupId); - if (null === $group) { - Log::error(sprintf('Could not find group %d, so give big fat error.', $groupId)); - - return parent::render($request, $exception); - } - /** @var TransactionJournal|null $journal */ - $journal = $group->transactionJournals()->withTrashed()->first(); - if (null === $journal) { - Log::error(sprintf('Could not find journal for group %d, so give big fat error.', $groupId)); - - return parent::render($request, $exception); - } - $type = $journal->transactionType->type; - $request->session()->reflash(); - - if (TransactionType::RECONCILIATION === $type) { - return redirect(route('accounts.index', ['asset'])); - } - - return redirect(route('transactions.index', [strtolower($type)])); - } } diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 43ce8627ed..b9bf1e6a36 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -72,8 +72,8 @@ class Handler extends ExceptionHandler /** * Render an exception into an HTTP response. * - * @param Request $request - * @param Throwable $e + * @param Request $request + * @param Throwable $e * * @return mixed * @throws Throwable @@ -176,7 +176,7 @@ class Handler extends ExceptionHandler /** * Report or log an exception. * - * @param Throwable $e + * @param Throwable $e * * @return void * @throws Throwable @@ -225,15 +225,32 @@ class Handler extends ExceptionHandler parent::report($e); } + /** + * @param Throwable $e + * + * @return bool + */ + private function shouldntReportLocal(Throwable $e): bool + { + return !is_null( + Arr::first( + $this->dontReport, + function ($type) use ($e) { + return $e instanceof $type; + } + ) + ); + } + /** * Convert a validation exception into a response. * - * @param Request $request - * @param LaravelValidationException $exception + * @param Request $request + * @param LaravelValidationException $exception * * @return Application|RedirectResponse|Redirector */ - protected function invalid($request, LaravelValidationException $exception): Application|RedirectResponse|Redirector + protected function invalid($request, LaravelValidationException $exception): Application | RedirectResponse | Redirector { // protect against open redirect when submitting invalid forms. $previous = app('steam')->getSafePreviousUrl(); @@ -247,7 +264,7 @@ class Handler extends ExceptionHandler /** * Only return the redirectTo property from the exception if it is a valid URL. Return NULL otherwise. * - * @param LaravelValidationException $exception + * @param LaravelValidationException $exception * * @return string|null */ @@ -263,21 +280,4 @@ class Handler extends ExceptionHandler return null !== $previousHost && $previousHost === $safeHost ? $previous : $safe; } - - /** - * @param Throwable $e - * - * @return bool - */ - private function shouldntReportLocal(Throwable $e): bool - { - return !is_null( - Arr::first( - $this->dontReport, - function ($type) use ($e) { - return $e instanceof $type; - } - ) - ); - } } diff --git a/app/Factory/AccountFactory.php b/app/Factory/AccountFactory.php index a57c8068aa..ca8b583b20 100644 --- a/app/Factory/AccountFactory.php +++ b/app/Factory/AccountFactory.php @@ -70,50 +70,8 @@ class AccountFactory } /** - * @param array $data - * - * @return Account - * @throws FireflyException - * @throws JsonException - */ - public function create(array $data): Account - { - Log::debug('Now in AccountFactory::create()'); - $type = $this->getAccountType($data); - $data['iban'] = $this->filterIban($data['iban'] ?? null); - - // account may exist already: - $return = $this->find($data['name'], $type->type); - - if (null !== $return) { - return $return; - } - - $return = $this->createAccount($type, $data); - - event(new StoredAccount($return)); - - return $return; - } - - /** - * @param string $accountName - * @param string $accountType - * - * @return Account|null - */ - public function find(string $accountName, string $accountType): ?Account - { - Log::debug(sprintf('Now in AccountFactory::find("%s", "%s")', $accountName, $accountType)); - $type = AccountType::whereType($accountType)->first(); - - /** @var Account|null */ - return $this->user->accounts()->where('account_type_id', $type->id)->where('name', $accountName)->first(); - } - - /** - * @param string $accountName - * @param string $accountType + * @param string $accountName + * @param string $accountType * * @return Account * @throws FireflyException @@ -148,16 +106,34 @@ class AccountFactory } /** - * @param User $user + * @param array $data + * + * @return Account + * @throws FireflyException + * @throws JsonException */ - public function setUser(User $user): void + public function create(array $data): Account { - $this->user = $user; - $this->accountRepository->setUser($user); + Log::debug('Now in AccountFactory::create()'); + $type = $this->getAccountType($data); + $data['iban'] = $this->filterIban($data['iban'] ?? null); + + // account may exist already: + $return = $this->find($data['name'], $type->type); + + if (null !== $return) { + return $return; + } + + $return = $this->createAccount($type, $data); + + event(new StoredAccount($return)); + + return $return; } /** - * @param array $data + * @param array $data * * @return AccountType|null * @throws FireflyException @@ -192,37 +168,23 @@ class AccountFactory } /** - * @param Account $account - * @param array $data + * @param string $accountName + * @param string $accountType * - * @return array - * @throws FireflyException - * @throws JsonException + * @return Account|null */ - private function cleanMetaDataArray(Account $account, array $data): array + public function find(string $accountName, string $accountType): ?Account { - $currencyId = array_key_exists('currency_id', $data) ? (int)$data['currency_id'] : 0; - $currencyCode = array_key_exists('currency_code', $data) ? (string)$data['currency_code'] : ''; - $accountRole = array_key_exists('account_role', $data) ? (string)$data['account_role'] : null; - $currency = $this->getCurrency($currencyId, $currencyCode); + Log::debug(sprintf('Now in AccountFactory::find("%s", "%s")', $accountName, $accountType)); + $type = AccountType::whereType($accountType)->first(); - // only asset account may have a role: - if ($account->accountType->type !== AccountType::ASSET) { - $accountRole = ''; - } - // only liability may have direction: - if (array_key_exists('liability_direction', $data) && !in_array($account->accountType->type, config('firefly.valid_liabilities'), true)) { - $data['liability_direction'] = null; - } - $data['account_role'] = $accountRole; - $data['currency_id'] = $currency->id; - - return $data; + /** @var Account|null */ + return $this->user->accounts()->where('account_type_id', $type->id)->where('name', $accountName)->first(); } /** - * @param AccountType $type - * @param array $data + * @param AccountType $type + * @param array $data * * @return Account * @throws FireflyException @@ -290,37 +252,37 @@ class AccountFactory } /** - * @param Account $account - * @param array $data + * @param Account $account + * @param array $data * + * @return array * @throws FireflyException + * @throws JsonException */ - private function storeCreditLiability(Account $account, array $data): void + private function cleanMetaDataArray(Account $account, array $data): array { - Log::debug('storeCreditLiability'); - $account->refresh(); - $accountType = $account->accountType->type; - $direction = $this->accountRepository->getMetaValue($account, 'liability_direction'); - $valid = config('firefly.valid_liabilities'); - if (in_array($accountType, $valid, true)) { - Log::debug('Is a liability with credit ("i am owed") direction.'); - if ($this->validOBData($data)) { - Log::debug('Has valid CL data.'); - $openingBalance = $data['opening_balance']; - $openingBalanceDate = $data['opening_balance_date']; - // store credit transaction. - $this->updateCreditTransaction($account, $direction, $openingBalance, $openingBalanceDate); - } - if (!$this->validOBData($data)) { - Log::debug('Does NOT have valid CL data, deletr any CL transaction.'); - $this->deleteCreditTransaction($account); - } + $currencyId = array_key_exists('currency_id', $data) ? (int)$data['currency_id'] : 0; + $currencyCode = array_key_exists('currency_code', $data) ? (string)$data['currency_code'] : ''; + $accountRole = array_key_exists('account_role', $data) ? (string)$data['account_role'] : null; + $currency = $this->getCurrency($currencyId, $currencyCode); + + // only asset account may have a role: + if ($account->accountType->type !== AccountType::ASSET) { + $accountRole = ''; } + // only liability may have direction: + if (array_key_exists('liability_direction', $data) && !in_array($account->accountType->type, config('firefly.valid_liabilities'), true)) { + $data['liability_direction'] = null; + } + $data['account_role'] = $accountRole; + $data['currency_id'] = $currency->id; + + return $data; } /** - * @param Account $account - * @param array $data + * @param Account $account + * @param array $data */ private function storeMetaData(Account $account, array $data): void { @@ -362,8 +324,8 @@ class AccountFactory } /** - * @param Account $account - * @param array $data + * @param Account $account + * @param array $data * * @throws FireflyException */ @@ -384,8 +346,37 @@ class AccountFactory } /** - * @param Account $account - * @param array $data + * @param Account $account + * @param array $data + * + * @throws FireflyException + */ + private function storeCreditLiability(Account $account, array $data): void + { + Log::debug('storeCreditLiability'); + $account->refresh(); + $accountType = $account->accountType->type; + $direction = $this->accountRepository->getMetaValue($account, 'liability_direction'); + $valid = config('firefly.valid_liabilities'); + if (in_array($accountType, $valid, true)) { + Log::debug('Is a liability with credit ("i am owed") direction.'); + if ($this->validOBData($data)) { + Log::debug('Has valid CL data.'); + $openingBalance = $data['opening_balance']; + $openingBalanceDate = $data['opening_balance_date']; + // store credit transaction. + $this->updateCreditTransaction($account, $direction, $openingBalance, $openingBalanceDate); + } + if (!$this->validOBData($data)) { + Log::debug('Does NOT have valid CL data, deletr any CL transaction.'); + $this->deleteCreditTransaction($account); + } + } + } + + /** + * @param Account $account + * @param array $data * * @throws FireflyException */ @@ -406,4 +397,13 @@ class AccountFactory $updateService->setUser($account->user); $updateService->update($account, ['order' => $order]); } + + /** + * @param User $user + */ + public function setUser(User $user): void + { + $this->user = $user; + $this->accountRepository->setUser($user); + } } diff --git a/app/Factory/AccountMetaFactory.php b/app/Factory/AccountMetaFactory.php index a5d4031098..46f1d013b1 100644 --- a/app/Factory/AccountMetaFactory.php +++ b/app/Factory/AccountMetaFactory.php @@ -26,29 +26,18 @@ namespace FireflyIII\Factory; use FireflyIII\Models\Account; use FireflyIII\Models\AccountMeta; -use Illuminate\Support\Facades\Log; /** * Class AccountMetaFactory */ class AccountMetaFactory { - /** - * @param array $data - * - * @return AccountMeta|null - */ - public function create(array $data): ?AccountMeta - { - return AccountMeta::create($data); - } - /** * Create update or delete meta data. * - * @param Account $account - * @param string $field - * @param string $value + * @param Account $account + * @param string $field + * @param string $value * * @return AccountMeta|null */ @@ -75,4 +64,14 @@ class AccountMetaFactory return $entry; } + + /** + * @param array $data + * + * @return AccountMeta|null + */ + public function create(array $data): ?AccountMeta + { + return AccountMeta::create($data); + } } diff --git a/app/Factory/AttachmentFactory.php b/app/Factory/AttachmentFactory.php index 54402dde9d..bf4f63da5a 100644 --- a/app/Factory/AttachmentFactory.php +++ b/app/Factory/AttachmentFactory.php @@ -38,7 +38,7 @@ class AttachmentFactory private User $user; /** - * @param array $data + * @param array $data * * @return Attachment|null * @throws FireflyException @@ -87,7 +87,7 @@ class AttachmentFactory } /** - * @param User $user + * @param User $user */ public function setUser(User $user): void { diff --git a/app/Factory/BillFactory.php b/app/Factory/BillFactory.php index 2028795ddb..cff8187735 100644 --- a/app/Factory/BillFactory.php +++ b/app/Factory/BillFactory.php @@ -44,7 +44,7 @@ class BillFactory private User $user; /** - * @param array $data + * @param array $data * * @return Bill|null * @throws FireflyException @@ -109,8 +109,8 @@ class BillFactory } /** - * @param int|null $billId - * @param null|string $billName + * @param int|null $billId + * @param null|string $billName * * @return Bill|null */ @@ -134,7 +134,7 @@ class BillFactory } /** - * @param string $name + * @param string $name * * @return Bill|null */ @@ -144,7 +144,7 @@ class BillFactory } /** - * @param User $user + * @param User $user */ public function setUser(User $user): void { diff --git a/app/Factory/BudgetFactory.php b/app/Factory/BudgetFactory.php index 87b5a4fe9e..728f69c51f 100644 --- a/app/Factory/BudgetFactory.php +++ b/app/Factory/BudgetFactory.php @@ -34,8 +34,8 @@ class BudgetFactory private User $user; /** - * @param int|null $budgetId - * @param null|string $budgetName + * @param int|null $budgetId + * @param null|string $budgetName * * @return Budget|null */ @@ -68,7 +68,7 @@ class BudgetFactory } /** - * @param string $name + * @param string $name * * @return Budget|null */ @@ -78,7 +78,7 @@ class BudgetFactory } /** - * @param User $user + * @param User $user */ public function setUser(User $user): void { diff --git a/app/Factory/CategoryFactory.php b/app/Factory/CategoryFactory.php index 728d1c9d1a..2695b0edf1 100644 --- a/app/Factory/CategoryFactory.php +++ b/app/Factory/CategoryFactory.php @@ -37,18 +37,8 @@ class CategoryFactory private User $user; /** - * @param string $name - * - * @return Category|null - */ - public function findByName(string $name): ?Category - { - return $this->user->categories()->where('name', $name)->first(); - } - - /** - * @param int|null $categoryId - * @param null|string $categoryName + * @param int|null $categoryId + * @param null|string $categoryName * * @return Category|null * @throws FireflyException @@ -94,7 +84,17 @@ class CategoryFactory } /** - * @param User $user + * @param string $name + * + * @return Category|null + */ + public function findByName(string $name): ?Category + { + return $this->user->categories()->where('name', $name)->first(); + } + + /** + * @param User $user */ public function setUser(User $user): void { diff --git a/app/Factory/PiggyBankEventFactory.php b/app/Factory/PiggyBankEventFactory.php index 0851dd912c..3489ef96ec 100644 --- a/app/Factory/PiggyBankEventFactory.php +++ b/app/Factory/PiggyBankEventFactory.php @@ -36,8 +36,8 @@ use Illuminate\Support\Facades\Log; class PiggyBankEventFactory { /** - * @param TransactionJournal $journal - * @param PiggyBank|null $piggyBank + * @param TransactionJournal $journal + * @param PiggyBank|null $piggyBank */ public function create(TransactionJournal $journal, ?PiggyBank $piggyBank): void { diff --git a/app/Factory/PiggyBankFactory.php b/app/Factory/PiggyBankFactory.php index 0bcd6a367e..7d6d85fe2d 100644 --- a/app/Factory/PiggyBankFactory.php +++ b/app/Factory/PiggyBankFactory.php @@ -34,8 +34,8 @@ class PiggyBankFactory private User $user; /** - * @param int|null $piggyBankId - * @param null|string $piggyBankName + * @param int|null $piggyBankId + * @param null|string $piggyBankName * * @return PiggyBank|null */ @@ -68,7 +68,7 @@ class PiggyBankFactory } /** - * @param string $name + * @param string $name * * @return PiggyBank|null */ @@ -78,7 +78,7 @@ class PiggyBankFactory } /** - * @param User $user + * @param User $user */ public function setUser(User $user): void { diff --git a/app/Factory/RecurrenceFactory.php b/app/Factory/RecurrenceFactory.php index 0514f3c8fc..2b6b86653f 100644 --- a/app/Factory/RecurrenceFactory.php +++ b/app/Factory/RecurrenceFactory.php @@ -55,7 +55,7 @@ class RecurrenceFactory } /** - * @param array $data + * @param array $data * * @return Recurrence * @throws FireflyException @@ -148,7 +148,7 @@ class RecurrenceFactory } /** - * @param User $user + * @param User $user */ public function setUser(User $user): void { diff --git a/app/Factory/TagFactory.php b/app/Factory/TagFactory.php index 7b7d379a19..0c12f37348 100644 --- a/app/Factory/TagFactory.php +++ b/app/Factory/TagFactory.php @@ -36,41 +36,7 @@ class TagFactory private User $user; /** - * @param array $data - * - * @return Tag|null - */ - public function create(array $data): ?Tag - { - $zoomLevel = 0 === (int)$data['zoom_level'] ? null : (int)$data['zoom_level']; - $latitude = 0.0 === (float)$data['latitude'] ? null : (float)$data['latitude']; // intentional float - $longitude = 0.0 === (float)$data['longitude'] ? null : (float)$data['longitude']; // intentional float - $array = [ - 'user_id' => $this->user->id, - 'tag' => trim($data['tag']), - 'tagMode' => 'nothing', - 'date' => $data['date'], - 'description' => $data['description'], - 'latitude' => null, - 'longitude' => null, - 'zoomLevel' => null, - ]; - $tag = Tag::create($array); - if (null !== $tag && null !== $latitude && null !== $longitude) { - // create location object. - $location = new Location(); - $location->latitude = $latitude; - $location->longitude = $longitude; - $location->zoom_level = $zoomLevel; - $location->locatable()->associate($tag); - $location->save(); - } - - return $tag; - } - - /** - * @param string $tag + * @param string $tag * * @return Tag|null */ @@ -107,7 +73,41 @@ class TagFactory } /** - * @param User $user + * @param array $data + * + * @return Tag|null + */ + public function create(array $data): ?Tag + { + $zoomLevel = 0 === (int)$data['zoom_level'] ? null : (int)$data['zoom_level']; + $latitude = 0.0 === (float)$data['latitude'] ? null : (float)$data['latitude']; // intentional float + $longitude = 0.0 === (float)$data['longitude'] ? null : (float)$data['longitude']; // intentional float + $array = [ + 'user_id' => $this->user->id, + 'tag' => trim($data['tag']), + 'tagMode' => 'nothing', + 'date' => $data['date'], + 'description' => $data['description'], + 'latitude' => null, + 'longitude' => null, + 'zoomLevel' => null, + ]; + $tag = Tag::create($array); + if (null !== $tag && null !== $latitude && null !== $longitude) { + // create location object. + $location = new Location(); + $location->latitude = $latitude; + $location->longitude = $longitude; + $location->zoom_level = $zoomLevel; + $location->locatable()->associate($tag); + $location->save(); + } + + return $tag; + } + + /** + * @param User $user */ public function setUser(User $user): void { diff --git a/app/Factory/TransactionCurrencyFactory.php b/app/Factory/TransactionCurrencyFactory.php index 5a9b54d470..7d056ab1aa 100644 --- a/app/Factory/TransactionCurrencyFactory.php +++ b/app/Factory/TransactionCurrencyFactory.php @@ -34,7 +34,7 @@ use Illuminate\Support\Facades\Log; class TransactionCurrencyFactory { /** - * @param array $data + * @param array $data * * @return TransactionCurrency * @throws FireflyException @@ -76,8 +76,8 @@ class TransactionCurrencyFactory } /** - * @param int|null $currencyId - * @param null|string $currencyCode + * @param int|null $currencyId + * @param null|string $currencyCode * * @return TransactionCurrency|null */ diff --git a/app/Factory/TransactionFactory.php b/app/Factory/TransactionFactory.php index 6c3f3d4b47..2a364528f9 100644 --- a/app/Factory/TransactionFactory.php +++ b/app/Factory/TransactionFactory.php @@ -62,8 +62,8 @@ class TransactionFactory /** * Create transaction with negative amount (for source accounts). * - * @param string $amount - * @param string|null $foreignAmount + * @param string $amount + * @param string|null $foreignAmount * * @return Transaction * @throws FireflyException @@ -81,97 +81,8 @@ class TransactionFactory } /** - * Create transaction with positive amount (for destination accounts). - * - * @param string $amount - * @param string|null $foreignAmount - * - * @return Transaction - * @throws FireflyException - */ - public function createPositive(string $amount, ?string $foreignAmount): Transaction - { - if ('' === $foreignAmount) { - $foreignAmount = null; - } - if (null !== $foreignAmount) { - $foreignAmount = app('steam')->positive($foreignAmount); - } - - return $this->create(app('steam')->positive($amount), $foreignAmount); - } - - /** - * @param Account $account - * - - */ - public function setAccount(Account $account): void - { - $this->account = $account; - } - - /** - * @param array $accountInformation - */ - public function setAccountInformation(array $accountInformation): void - { - $this->accountInformation = $accountInformation; - } - - /** - * @param TransactionCurrency $currency - * - - */ - public function setCurrency(TransactionCurrency $currency): void - { - $this->currency = $currency; - } - - /** - * @param TransactionCurrency|null $foreignCurrency |null - * - - */ - public function setForeignCurrency(?TransactionCurrency $foreignCurrency): void - { - $this->foreignCurrency = $foreignCurrency; - } - - /** - * @param TransactionJournal $journal - * - - */ - public function setJournal(TransactionJournal $journal): void - { - $this->journal = $journal; - } - - /** - * @param bool $reconciled - * - - */ - public function setReconciled(bool $reconciled): void - { - $this->reconciled = $reconciled; - } - - /** - * @param User $user - * - - */ - public function setUser(User $user): void - { - // empty function. - } - - /** - * @param string $amount - * @param string|null $foreignAmount + * @param string $amount + * @param string|null $foreignAmount * * @return Transaction * @throws FireflyException @@ -260,4 +171,93 @@ class TransactionFactory $service = app(AccountUpdateService::class); $service->update($this->account, ['iban' => $this->accountInformation['iban']]); } + + /** + * Create transaction with positive amount (for destination accounts). + * + * @param string $amount + * @param string|null $foreignAmount + * + * @return Transaction + * @throws FireflyException + */ + public function createPositive(string $amount, ?string $foreignAmount): Transaction + { + if ('' === $foreignAmount) { + $foreignAmount = null; + } + if (null !== $foreignAmount) { + $foreignAmount = app('steam')->positive($foreignAmount); + } + + return $this->create(app('steam')->positive($amount), $foreignAmount); + } + + /** + * @param Account $account + * + + */ + public function setAccount(Account $account): void + { + $this->account = $account; + } + + /** + * @param array $accountInformation + */ + public function setAccountInformation(array $accountInformation): void + { + $this->accountInformation = $accountInformation; + } + + /** + * @param TransactionCurrency $currency + * + + */ + public function setCurrency(TransactionCurrency $currency): void + { + $this->currency = $currency; + } + + /** + * @param TransactionCurrency|null $foreignCurrency |null + * + + */ + public function setForeignCurrency(?TransactionCurrency $foreignCurrency): void + { + $this->foreignCurrency = $foreignCurrency; + } + + /** + * @param TransactionJournal $journal + * + + */ + public function setJournal(TransactionJournal $journal): void + { + $this->journal = $journal; + } + + /** + * @param bool $reconciled + * + + */ + public function setReconciled(bool $reconciled): void + { + $this->reconciled = $reconciled; + } + + /** + * @param User $user + * + + */ + public function setUser(User $user): void + { + // empty function. + } } diff --git a/app/Factory/TransactionGroupFactory.php b/app/Factory/TransactionGroupFactory.php index 3731f1a4e6..ea505122fe 100644 --- a/app/Factory/TransactionGroupFactory.php +++ b/app/Factory/TransactionGroupFactory.php @@ -51,7 +51,7 @@ class TransactionGroupFactory /** * Store a new transaction journal. * - * @param array $data + * @param array $data * * @return TransactionGroup * @throws DuplicateTransactionException @@ -92,7 +92,7 @@ class TransactionGroupFactory /** * Set the user. * - * @param User $user + * @param User $user */ public function setUser(User $user): void { diff --git a/app/Factory/TransactionJournalFactory.php b/app/Factory/TransactionJournalFactory.php index 389b15dc30..340f81b4a6 100644 --- a/app/Factory/TransactionJournalFactory.php +++ b/app/Factory/TransactionJournalFactory.php @@ -93,7 +93,7 @@ class TransactionJournalFactory /** * Store a new (set of) transaction journals. * - * @param array $data + * @param array $data * * @return Collection * @throws DuplicateTransactionException @@ -144,80 +144,7 @@ class TransactionJournalFactory } /** - * @param bool $errorOnHash - */ - public function setErrorOnHash(bool $errorOnHash): void - { - $this->errorOnHash = $errorOnHash; - if (true === $errorOnHash) { - Log::info('Will trigger duplication alert for this journal.'); - } - } - - /** - * Set the user. - * - * @param User $user - */ - public function setUser(User $user): void - { - $this->user = $user; - $this->currencyRepository->setUser($this->user); - $this->tagFactory->setUser($user); - $this->billRepository->setUser($this->user); - $this->budgetRepository->setUser($this->user); - $this->categoryRepository->setUser($this->user); - $this->piggyRepository->setUser($this->user); - $this->accountRepository->setUser($this->user); - } - - /** - * @param TransactionJournal $journal - * @param NullArrayObject $data - * @param string $field - */ - protected function storeMeta(TransactionJournal $journal, NullArrayObject $data, string $field): void - { - $set = [ - 'journal' => $journal, - 'name' => $field, - 'data' => (string)($data[$field] ?? ''), - ]; - if ($data[$field] instanceof Carbon) { - $data[$field]->setTimezone(config('app.timezone')); - Log::debug(sprintf('%s Date: %s (%s)', $field, $data[$field], $data[$field]->timezone->getName())); - $set['data'] = $data[$field]->format('Y-m-d H:i:s'); - } - - Log::debug(sprintf('Going to store meta-field "%s", with value "%s".', $set['name'], $set['data'])); - - /** @var TransactionJournalMetaFactory $factory */ - $factory = app(TransactionJournalMetaFactory::class); - $factory->updateOrCreate($set); - } - - /** - * Set foreign currency to NULL if it's the same as the normal currency: - * - * @param TransactionCurrency|null $currency - * @param TransactionCurrency|null $foreignCurrency - * - * @return TransactionCurrency|null - */ - private function compareCurrencies(?TransactionCurrency $currency, ?TransactionCurrency $foreignCurrency): ?TransactionCurrency - { - if (null === $currency) { - return null; - } - if (null !== $foreignCurrency && $foreignCurrency->id === $currency->id) { - return null; - } - - return $foreignCurrency; - } - - /** - * @param NullArrayObject $row + * @param NullArrayObject $row * * @return TransactionJournal|null * @throws DuplicateTransactionException @@ -377,10 +304,28 @@ class TransactionJournalFactory return $journal; } + /** + * @param NullArrayObject $row + * + * @return string + * @throws JsonException + */ + private function hashArray(NullArrayObject $row): string + { + $dataRow = $row->getArrayCopy(); + + unset($dataRow['import_hash_v2'], $dataRow['original_source']); + $json = json_encode($dataRow, JSON_THROW_ON_ERROR); + $hash = hash('sha256', $json); + Log::debug(sprintf('The hash is: %s', $hash), $dataRow); + + return $hash; + } + /** * If this transaction already exists, throw an error. * - * @param string $hash + * @param string $hash * * @throws DuplicateTransactionException * @throws JsonException @@ -410,184 +355,7 @@ class TransactionJournalFactory } /** - * Force the deletion of an entire set of transaction journals and their meta object in case of - * an error creating a group. - * - * @param Collection $collection - */ - private function forceDeleteOnError(Collection $collection): void - { - Log::debug(sprintf('forceDeleteOnError on collection size %d item(s)', $collection->count())); - $service = app(JournalDestroyService::class); - /** @var TransactionJournal $journal */ - foreach ($collection as $journal) { - Log::debug(sprintf('forceDeleteOnError on journal #%d', $journal->id)); - $service->destroy($journal); - } - } - - /** - * @param Transaction $transaction - */ - private function forceTrDelete(Transaction $transaction): void - { - $transaction->delete(); - } - - /** - * @param TransactionCurrency|null $currency - * @param Account $account - * - * @return TransactionCurrency - * @throws FireflyException - * @throws JsonException - */ - private function getCurrency(?TransactionCurrency $currency, Account $account): TransactionCurrency - { - Log::debug('Now in getCurrency()'); - /** @var Preference|null $preference */ - $preference = $this->accountRepository->getAccountCurrency($account); - if (null === $preference && null === $currency) { - // return user's default: - return app('amount')->getDefaultCurrencyByUser($this->user); - } - $result = ($preference ?? $currency) ?? app('amount')->getSystemCurrency(); - Log::debug(sprintf('Currency is now #%d (%s) because of account #%d (%s)', $result->id, $result->code, $account->id, $account->name)); - - return $result; - } - - /** - * @param string $type - * @param TransactionCurrency|null $currency - * @param Account $source - * @param Account $destination - * - * @return TransactionCurrency - * @throws FireflyException - * @throws JsonException - */ - private function getCurrencyByAccount(string $type, ?TransactionCurrency $currency, Account $source, Account $destination): TransactionCurrency - { - Log::debug('Now in getCurrencyByAccount()'); - - return match ($type) { - default => $this->getCurrency($currency, $source), - TransactionType::DEPOSIT => $this->getCurrency($currency, $destination), - }; - } - - /** - * @param string $description - * - * @return string - */ - private function getDescription(string $description): string - { - $description = '' === $description ? '(empty description)' : $description; - - return substr($description, 0, 255); - } - - /** - * @param string $type - * @param TransactionCurrency|null $foreignCurrency - * @param Account $destination - * - * @return TransactionCurrency|null - * @throws FireflyException - * @throws JsonException - */ - private function getForeignByAccount(string $type, ?TransactionCurrency $foreignCurrency, Account $destination): ?TransactionCurrency - { - if (TransactionType::TRANSFER === $type) { - return $this->getCurrency($foreignCurrency, $destination); - } - - return $foreignCurrency; - } - - /** - * @param NullArrayObject $row - * - * @return string - * @throws JsonException - */ - private function hashArray(NullArrayObject $row): string - { - $dataRow = $row->getArrayCopy(); - - unset($dataRow['import_hash_v2'], $dataRow['original_source']); - $json = json_encode($dataRow, JSON_THROW_ON_ERROR); - $hash = hash('sha256', $json); - Log::debug(sprintf('The hash is: %s', $hash), $dataRow); - - return $hash; - } - - /** - * @param Account|null $sourceAccount - * @param Account|null $destinationAccount - * @return array - */ - private function reconciliationSanityCheck(?Account $sourceAccount, ?Account $destinationAccount): array - { - Log::debug(sprintf('Now in %s', __METHOD__)); - if (null !== $sourceAccount && null !== $destinationAccount) { - Log::debug('Both accounts exist, simply return them.'); - return [$sourceAccount, $destinationAccount]; - } - if (null !== $sourceAccount && null === $destinationAccount) { - Log::debug('Destination account is NULL, source account is not.'); - $account = $this->accountRepository->getReconciliation($sourceAccount); - Log::debug(sprintf('Will return account #%d ("%s") of type "%s"', $account->id, $account->name, $account->accountType->type)); - return [$sourceAccount, $account]; - } - - if (null === $sourceAccount && null !== $destinationAccount) { - Log::debug('Source account is NULL, destination account is not.'); - $account = $this->accountRepository->getReconciliation($destinationAccount); - Log::debug(sprintf('Will return account #%d ("%s") of type "%s"', $account->id, $account->name, $account->accountType->type)); - return [$account, $destinationAccount]; - } - Log::debug('Unused fallback'); - return [$sourceAccount, $destinationAccount]; - } - - /** - * @param TransactionJournal $journal - * @param NullArrayObject $transaction - */ - private function storeMetaFields(TransactionJournal $journal, NullArrayObject $transaction): void - { - foreach ($this->fields as $field) { - $this->storeMeta($journal, $transaction, $field); - } - } - - /** - * Link a piggy bank to this journal. - * - * @param TransactionJournal $journal - * @param NullArrayObject $data - */ - private function storePiggyEvent(TransactionJournal $journal, NullArrayObject $data): void - { - Log::debug('Will now store piggy event.'); - - $piggyBank = $this->piggyRepository->findPiggyBank((int)$data['piggy_bank_id'], $data['piggy_bank_name']); - - if (null !== $piggyBank) { - $this->piggyEventFactory->create($journal, $piggyBank); - Log::debug('Create piggy event.'); - - return; - } - Log::debug('Create no piggy event'); - } - - /** - * @param NullArrayObject $data + * @param NullArrayObject $data * * @throws FireflyException */ @@ -627,4 +395,236 @@ class TransactionJournalFactory throw new FireflyException(sprintf('Destination: %s', $this->accountValidator->destError)); } } + + /** + * Set the user. + * + * @param User $user + */ + public function setUser(User $user): void + { + $this->user = $user; + $this->currencyRepository->setUser($this->user); + $this->tagFactory->setUser($user); + $this->billRepository->setUser($this->user); + $this->budgetRepository->setUser($this->user); + $this->categoryRepository->setUser($this->user); + $this->piggyRepository->setUser($this->user); + $this->accountRepository->setUser($this->user); + } + + /** + * @param Account|null $sourceAccount + * @param Account|null $destinationAccount + * @return array + */ + private function reconciliationSanityCheck(?Account $sourceAccount, ?Account $destinationAccount): array + { + Log::debug(sprintf('Now in %s', __METHOD__)); + if (null !== $sourceAccount && null !== $destinationAccount) { + Log::debug('Both accounts exist, simply return them.'); + return [$sourceAccount, $destinationAccount]; + } + if (null !== $sourceAccount && null === $destinationAccount) { + Log::debug('Destination account is NULL, source account is not.'); + $account = $this->accountRepository->getReconciliation($sourceAccount); + Log::debug(sprintf('Will return account #%d ("%s") of type "%s"', $account->id, $account->name, $account->accountType->type)); + return [$sourceAccount, $account]; + } + + if (null === $sourceAccount && null !== $destinationAccount) { + Log::debug('Source account is NULL, destination account is not.'); + $account = $this->accountRepository->getReconciliation($destinationAccount); + Log::debug(sprintf('Will return account #%d ("%s") of type "%s"', $account->id, $account->name, $account->accountType->type)); + return [$account, $destinationAccount]; + } + Log::debug('Unused fallback'); + return [$sourceAccount, $destinationAccount]; + } + + /** + * @param string $type + * @param TransactionCurrency|null $currency + * @param Account $source + * @param Account $destination + * + * @return TransactionCurrency + * @throws FireflyException + * @throws JsonException + */ + private function getCurrencyByAccount(string $type, ?TransactionCurrency $currency, Account $source, Account $destination): TransactionCurrency + { + Log::debug('Now in getCurrencyByAccount()'); + + return match ($type) { + default => $this->getCurrency($currency, $source), + TransactionType::DEPOSIT => $this->getCurrency($currency, $destination), + }; + } + + /** + * @param TransactionCurrency|null $currency + * @param Account $account + * + * @return TransactionCurrency + * @throws FireflyException + * @throws JsonException + */ + private function getCurrency(?TransactionCurrency $currency, Account $account): TransactionCurrency + { + Log::debug('Now in getCurrency()'); + /** @var Preference|null $preference */ + $preference = $this->accountRepository->getAccountCurrency($account); + if (null === $preference && null === $currency) { + // return user's default: + return app('amount')->getDefaultCurrencyByUser($this->user); + } + $result = ($preference ?? $currency) ?? app('amount')->getSystemCurrency(); + Log::debug(sprintf('Currency is now #%d (%s) because of account #%d (%s)', $result->id, $result->code, $account->id, $account->name)); + + return $result; + } + + /** + * Set foreign currency to NULL if it's the same as the normal currency: + * + * @param TransactionCurrency|null $currency + * @param TransactionCurrency|null $foreignCurrency + * + * @return TransactionCurrency|null + */ + private function compareCurrencies(?TransactionCurrency $currency, ?TransactionCurrency $foreignCurrency): ?TransactionCurrency + { + if (null === $currency) { + return null; + } + if (null !== $foreignCurrency && $foreignCurrency->id === $currency->id) { + return null; + } + + return $foreignCurrency; + } + + /** + * @param string $type + * @param TransactionCurrency|null $foreignCurrency + * @param Account $destination + * + * @return TransactionCurrency|null + * @throws FireflyException + * @throws JsonException + */ + private function getForeignByAccount(string $type, ?TransactionCurrency $foreignCurrency, Account $destination): ?TransactionCurrency + { + if (TransactionType::TRANSFER === $type) { + return $this->getCurrency($foreignCurrency, $destination); + } + + return $foreignCurrency; + } + + /** + * @param string $description + * + * @return string + */ + private function getDescription(string $description): string + { + $description = '' === $description ? '(empty description)' : $description; + + return substr($description, 0, 255); + } + + /** + * Force the deletion of an entire set of transaction journals and their meta object in case of + * an error creating a group. + * + * @param Collection $collection + */ + private function forceDeleteOnError(Collection $collection): void + { + Log::debug(sprintf('forceDeleteOnError on collection size %d item(s)', $collection->count())); + $service = app(JournalDestroyService::class); + /** @var TransactionJournal $journal */ + foreach ($collection as $journal) { + Log::debug(sprintf('forceDeleteOnError on journal #%d', $journal->id)); + $service->destroy($journal); + } + } + + /** + * @param Transaction $transaction + */ + private function forceTrDelete(Transaction $transaction): void + { + $transaction->delete(); + } + + /** + * Link a piggy bank to this journal. + * + * @param TransactionJournal $journal + * @param NullArrayObject $data + */ + private function storePiggyEvent(TransactionJournal $journal, NullArrayObject $data): void + { + Log::debug('Will now store piggy event.'); + + $piggyBank = $this->piggyRepository->findPiggyBank((int)$data['piggy_bank_id'], $data['piggy_bank_name']); + + if (null !== $piggyBank) { + $this->piggyEventFactory->create($journal, $piggyBank); + Log::debug('Create piggy event.'); + + return; + } + Log::debug('Create no piggy event'); + } + + /** + * @param TransactionJournal $journal + * @param NullArrayObject $transaction + */ + private function storeMetaFields(TransactionJournal $journal, NullArrayObject $transaction): void + { + foreach ($this->fields as $field) { + $this->storeMeta($journal, $transaction, $field); + } + } + + /** + * @param TransactionJournal $journal + * @param NullArrayObject $data + * @param string $field + */ + protected function storeMeta(TransactionJournal $journal, NullArrayObject $data, string $field): void + { + $set = [ + 'journal' => $journal, + 'name' => $field, + 'data' => (string)($data[$field] ?? ''), + ]; + if ($data[$field] instanceof Carbon) { + $data[$field]->setTimezone(config('app.timezone')); + Log::debug(sprintf('%s Date: %s (%s)', $field, $data[$field], $data[$field]->timezone->getName())); + $set['data'] = $data[$field]->format('Y-m-d H:i:s'); + } + + Log::debug(sprintf('Going to store meta-field "%s", with value "%s".', $set['name'], $set['data'])); + + /** @var TransactionJournalMetaFactory $factory */ + $factory = app(TransactionJournalMetaFactory::class); + $factory->updateOrCreate($set); + } + + /** + * @param bool $errorOnHash + */ + public function setErrorOnHash(bool $errorOnHash): void + { + $this->errorOnHash = $errorOnHash; + if (true === $errorOnHash) { + Log::info('Will trigger duplication alert for this journal.'); + } + } } diff --git a/app/Factory/TransactionJournalMetaFactory.php b/app/Factory/TransactionJournalMetaFactory.php index 9c4ca07d63..41cfe13971 100644 --- a/app/Factory/TransactionJournalMetaFactory.php +++ b/app/Factory/TransactionJournalMetaFactory.php @@ -33,7 +33,7 @@ use Illuminate\Support\Facades\Log; class TransactionJournalMetaFactory { /** - * @param array $data + * @param array $data * * @return TransactionJournalMeta|null */ diff --git a/app/Factory/TransactionTypeFactory.php b/app/Factory/TransactionTypeFactory.php index 87b60c2b11..64294ef1ee 100644 --- a/app/Factory/TransactionTypeFactory.php +++ b/app/Factory/TransactionTypeFactory.php @@ -32,7 +32,7 @@ use FireflyIII\Models\TransactionType; class TransactionTypeFactory { /** - * @param string $type + * @param string $type * * @return TransactionType|null */ diff --git a/app/Generator/Chart/Basic/ChartJsGenerator.php b/app/Generator/Chart/Basic/ChartJsGenerator.php index f29a6f9391..0662b6200a 100644 --- a/app/Generator/Chart/Basic/ChartJsGenerator.php +++ b/app/Generator/Chart/Basic/ChartJsGenerator.php @@ -35,7 +35,7 @@ class ChartJsGenerator implements GeneratorInterface * * key => [value => x, 'currency_symbol' => 'x'] * - * @param array $data + * @param array $data * * @return array */ @@ -100,7 +100,7 @@ class ChartJsGenerator implements GeneratorInterface * * // it's five. * - * @param array $data + * @param array $data * * @return array */ @@ -149,7 +149,7 @@ class ChartJsGenerator implements GeneratorInterface * * key => value * - * @param array $data + * @param array $data * * @return array */ @@ -190,8 +190,8 @@ class ChartJsGenerator implements GeneratorInterface * * 'label-of-entry' => value * - * @param string $setLabel - * @param array $data + * @param string $setLabel + * @param array $data * * @return array */ diff --git a/app/Generator/Chart/Basic/GeneratorInterface.php b/app/Generator/Chart/Basic/GeneratorInterface.php index e2209ccee1..a43c85bba9 100644 --- a/app/Generator/Chart/Basic/GeneratorInterface.php +++ b/app/Generator/Chart/Basic/GeneratorInterface.php @@ -29,7 +29,7 @@ namespace FireflyIII\Generator\Chart\Basic; interface GeneratorInterface { /** - * @param array $data + * @param array $data * * @return array */ @@ -63,7 +63,7 @@ interface GeneratorInterface * * // it's five. * - * @param array $data + * @param array $data * * @return array */ @@ -74,7 +74,7 @@ interface GeneratorInterface * * key => value * - * @param array $data + * @param array $data * * @return array */ @@ -85,8 +85,8 @@ interface GeneratorInterface * * 'label-of-entry' => value * - * @param string $setLabel - * @param array $data + * @param string $setLabel + * @param array $data * * @return array */ diff --git a/app/Generator/Report/Account/MonthReportGenerator.php b/app/Generator/Report/Account/MonthReportGenerator.php index 97608c267d..8275835d8c 100644 --- a/app/Generator/Report/Account/MonthReportGenerator.php +++ b/app/Generator/Report/Account/MonthReportGenerator.php @@ -44,6 +44,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Generate the report. + * * @return string * @throws FireflyException */ @@ -68,10 +69,20 @@ class MonthReportGenerator implements ReportGeneratorInterface return $result; } + /** + * Return the preferred period. + * + * @return string + */ + protected function preferredPeriod(): string + { + return 'day'; + } + /** * Set accounts. * - * @param Collection $accounts + * @param Collection $accounts * * @return ReportGeneratorInterface */ @@ -85,7 +96,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set budgets. * - * @param Collection $budgets + * @param Collection $budgets * * @return ReportGeneratorInterface */ @@ -97,7 +108,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set categories. * - * @param Collection $categories + * @param Collection $categories * * @return ReportGeneratorInterface */ @@ -109,7 +120,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set end date. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -123,7 +134,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set expense collection. * - * @param Collection $expense + * @param Collection $expense * * @return ReportGeneratorInterface */ @@ -137,7 +148,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set start date. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -151,7 +162,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set collection of tags. * - * @param Collection $tags + * @param Collection $tags * * @return ReportGeneratorInterface */ @@ -159,14 +170,4 @@ class MonthReportGenerator implements ReportGeneratorInterface { return $this; } - - /** - * Return the preferred period. - * - * @return string - */ - protected function preferredPeriod(): string - { - return 'day'; - } } diff --git a/app/Generator/Report/Audit/MonthReportGenerator.php b/app/Generator/Report/Audit/MonthReportGenerator.php index 5f07c4f2f7..30f5c162c9 100644 --- a/app/Generator/Report/Audit/MonthReportGenerator.php +++ b/app/Generator/Report/Audit/MonthReportGenerator.php @@ -110,8 +110,8 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Get the audit report. * - * @param Account $account - * @param Carbon $date + * @param Account $account + * @param Carbon $date * * @return array * @throws FireflyException @@ -182,7 +182,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Account collection setter. * - * @param Collection $accounts + * @param Collection $accounts * * @return ReportGeneratorInterface */ @@ -196,7 +196,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Budget collection setter. * - * @param Collection $budgets + * @param Collection $budgets * * @return ReportGeneratorInterface */ @@ -208,7 +208,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Category collection setter. * - * @param Collection $categories + * @param Collection $categories * * @return ReportGeneratorInterface */ @@ -220,7 +220,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * End date setter. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -234,7 +234,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Expenses collection setter. * - * @param Collection $expense + * @param Collection $expense * * @return ReportGeneratorInterface */ @@ -247,7 +247,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Start date collection setter. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -261,7 +261,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Tags collection setter. * - * @param Collection $tags + * @param Collection $tags * * @return ReportGeneratorInterface */ diff --git a/app/Generator/Report/Budget/MonthReportGenerator.php b/app/Generator/Report/Budget/MonthReportGenerator.php index c40ffa54f4..50ba4e8694 100644 --- a/app/Generator/Report/Budget/MonthReportGenerator.php +++ b/app/Generator/Report/Budget/MonthReportGenerator.php @@ -82,38 +82,10 @@ class MonthReportGenerator implements ReportGeneratorInterface return $result; } - /** - * Set the involved accounts. - * - * @param Collection $accounts - * - * @return ReportGeneratorInterface - */ - public function setAccounts(Collection $accounts): ReportGeneratorInterface - { - $this->accounts = $accounts; - - return $this; - } - - /** - * Set the involved budgets. - * - * @param Collection $budgets - * - * @return ReportGeneratorInterface - */ - public function setBudgets(Collection $budgets): ReportGeneratorInterface - { - $this->budgets = $budgets; - - return $this; - } - /** * Unused category setter. * - * @param Collection $categories + * @param Collection $categories * * @return ReportGeneratorInterface */ @@ -125,7 +97,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set the end date of the report. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -139,7 +111,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Unused expense setter. * - * @param Collection $expense + * @param Collection $expense * * @return ReportGeneratorInterface */ @@ -151,7 +123,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set the start date of the report. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -165,7 +137,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Unused tags setter. * - * @param Collection $tags + * @param Collection $tags * * @return ReportGeneratorInterface */ @@ -200,4 +172,32 @@ class MonthReportGenerator implements ReportGeneratorInterface return $journals; } + + /** + * Set the involved budgets. + * + * @param Collection $budgets + * + * @return ReportGeneratorInterface + */ + public function setBudgets(Collection $budgets): ReportGeneratorInterface + { + $this->budgets = $budgets; + + return $this; + } + + /** + * Set the involved accounts. + * + * @param Collection $accounts + * + * @return ReportGeneratorInterface + */ + public function setAccounts(Collection $accounts): ReportGeneratorInterface + { + $this->accounts = $accounts; + + return $this; + } } diff --git a/app/Generator/Report/Category/MonthReportGenerator.php b/app/Generator/Report/Category/MonthReportGenerator.php index f3a8c2bbed..eae5ee812b 100644 --- a/app/Generator/Report/Category/MonthReportGenerator.php +++ b/app/Generator/Report/Category/MonthReportGenerator.php @@ -82,24 +82,10 @@ class MonthReportGenerator implements ReportGeneratorInterface } } - /** - * Set the involved accounts. - * - * @param Collection $accounts - * - * @return ReportGeneratorInterface - */ - public function setAccounts(Collection $accounts): ReportGeneratorInterface - { - $this->accounts = $accounts; - - return $this; - } - /** * Empty budget setter. * - * @param Collection $budgets + * @param Collection $budgets * * @return ReportGeneratorInterface */ @@ -108,24 +94,10 @@ class MonthReportGenerator implements ReportGeneratorInterface return $this; } - /** - * Set the categories involved in this report. - * - * @param Collection $categories - * - * @return ReportGeneratorInterface - */ - public function setCategories(Collection $categories): ReportGeneratorInterface - { - $this->categories = $categories; - - return $this; - } - /** * Set the end date for this report. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -139,7 +111,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set the expenses involved in this report. * - * @param Collection $expense + * @param Collection $expense * * @return ReportGeneratorInterface */ @@ -151,7 +123,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set the start date for this report. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -165,7 +137,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Unused tag setter. * - * @param Collection $tags + * @param Collection $tags * * @return ReportGeneratorInterface */ @@ -199,6 +171,34 @@ class MonthReportGenerator implements ReportGeneratorInterface return $transactions; } + /** + * Set the categories involved in this report. + * + * @param Collection $categories + * + * @return ReportGeneratorInterface + */ + public function setCategories(Collection $categories): ReportGeneratorInterface + { + $this->categories = $categories; + + return $this; + } + + /** + * Set the involved accounts. + * + * @param Collection $accounts + * + * @return ReportGeneratorInterface + */ + public function setAccounts(Collection $accounts): ReportGeneratorInterface + { + $this->accounts = $accounts; + + return $this; + } + /** * Get the income for this report. * diff --git a/app/Generator/Report/ReportGeneratorFactory.php b/app/Generator/Report/ReportGeneratorFactory.php index bc717a92fb..a577f8f076 100644 --- a/app/Generator/Report/ReportGeneratorFactory.php +++ b/app/Generator/Report/ReportGeneratorFactory.php @@ -36,9 +36,9 @@ class ReportGeneratorFactory /** * Static report generator class. * - * @param string $type - * @param Carbon $start - * @param Carbon $end + * @param string $type + * @param Carbon $start + * @param Carbon $end * * @return ReportGeneratorInterface * diff --git a/app/Generator/Report/ReportGeneratorInterface.php b/app/Generator/Report/ReportGeneratorInterface.php index 5d7b9a76e6..c56c71afbd 100644 --- a/app/Generator/Report/ReportGeneratorInterface.php +++ b/app/Generator/Report/ReportGeneratorInterface.php @@ -41,7 +41,7 @@ interface ReportGeneratorInterface /** * Set the involved accounts. * - * @param Collection $accounts + * @param Collection $accounts * * @return ReportGeneratorInterface */ @@ -50,7 +50,7 @@ interface ReportGeneratorInterface /** * Set the involved budgets. * - * @param Collection $budgets + * @param Collection $budgets * * @return ReportGeneratorInterface */ @@ -59,7 +59,7 @@ interface ReportGeneratorInterface /** * Set the involved categories. * - * @param Collection $categories + * @param Collection $categories * * @return ReportGeneratorInterface */ @@ -68,7 +68,7 @@ interface ReportGeneratorInterface /** * Set the end date. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -77,7 +77,7 @@ interface ReportGeneratorInterface /** * Set the expense accounts. * - * @param Collection $expense + * @param Collection $expense * * @return ReportGeneratorInterface */ @@ -86,7 +86,7 @@ interface ReportGeneratorInterface /** * Set the start date. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -95,7 +95,7 @@ interface ReportGeneratorInterface /** * Set the tags. * - * @param Collection $tags + * @param Collection $tags * * @return ReportGeneratorInterface */ diff --git a/app/Generator/Report/Standard/MonthReportGenerator.php b/app/Generator/Report/Standard/MonthReportGenerator.php index 2b4d0cde41..0161787a0c 100644 --- a/app/Generator/Report/Standard/MonthReportGenerator.php +++ b/app/Generator/Report/Standard/MonthReportGenerator.php @@ -67,7 +67,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Sets the accounts involved in the report. * - * @param Collection $accounts + * @param Collection $accounts * * @return ReportGeneratorInterface */ @@ -81,7 +81,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Unused budget setter. * - * @param Collection $budgets + * @param Collection $budgets * * @return ReportGeneratorInterface */ @@ -93,7 +93,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Unused category setter. * - * @param Collection $categories + * @param Collection $categories * * @return ReportGeneratorInterface */ @@ -105,7 +105,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set the end date of the report. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -119,7 +119,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set the expenses used in this report. * - * @param Collection $expense + * @param Collection $expense * * @return ReportGeneratorInterface */ @@ -131,7 +131,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set the start date of this report. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -145,7 +145,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set the tags used in this report. * - * @param Collection $tags + * @param Collection $tags * * @return ReportGeneratorInterface */ diff --git a/app/Generator/Report/Standard/MultiYearReportGenerator.php b/app/Generator/Report/Standard/MultiYearReportGenerator.php index 23430c0904..177a578038 100644 --- a/app/Generator/Report/Standard/MultiYearReportGenerator.php +++ b/app/Generator/Report/Standard/MultiYearReportGenerator.php @@ -71,7 +71,7 @@ class MultiYearReportGenerator implements ReportGeneratorInterface /** * Sets the accounts used in the report. * - * @param Collection $accounts + * @param Collection $accounts * * @return ReportGeneratorInterface */ @@ -85,7 +85,7 @@ class MultiYearReportGenerator implements ReportGeneratorInterface /** * Sets the budgets used in the report. * - * @param Collection $budgets + * @param Collection $budgets * * @return ReportGeneratorInterface */ @@ -97,7 +97,7 @@ class MultiYearReportGenerator implements ReportGeneratorInterface /** * Sets the categories used in the report. * - * @param Collection $categories + * @param Collection $categories * * @return ReportGeneratorInterface */ @@ -109,7 +109,7 @@ class MultiYearReportGenerator implements ReportGeneratorInterface /** * Sets the end date used in the report. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -123,7 +123,7 @@ class MultiYearReportGenerator implements ReportGeneratorInterface /** * Unused setter for expenses. * - * @param Collection $expense + * @param Collection $expense * * @return ReportGeneratorInterface */ @@ -135,7 +135,7 @@ class MultiYearReportGenerator implements ReportGeneratorInterface /** * Set the start date of the report. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -149,7 +149,7 @@ class MultiYearReportGenerator implements ReportGeneratorInterface /** * Set the tags for the report. * - * @param Collection $tags + * @param Collection $tags * * @return ReportGeneratorInterface */ diff --git a/app/Generator/Report/Standard/YearReportGenerator.php b/app/Generator/Report/Standard/YearReportGenerator.php index 9a6a22b59e..1d64e3b889 100644 --- a/app/Generator/Report/Standard/YearReportGenerator.php +++ b/app/Generator/Report/Standard/YearReportGenerator.php @@ -73,7 +73,7 @@ class YearReportGenerator implements ReportGeneratorInterface /** * Set the accounts. * - * @param Collection $accounts + * @param Collection $accounts * * @return ReportGeneratorInterface */ @@ -87,7 +87,7 @@ class YearReportGenerator implements ReportGeneratorInterface /** * Unused budget setter. * - * @param Collection $budgets + * @param Collection $budgets * * @return ReportGeneratorInterface */ @@ -99,7 +99,7 @@ class YearReportGenerator implements ReportGeneratorInterface /** * Unused categories setter. * - * @param Collection $categories + * @param Collection $categories * * @return ReportGeneratorInterface */ @@ -111,7 +111,7 @@ class YearReportGenerator implements ReportGeneratorInterface /** * Set the end date. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -125,7 +125,7 @@ class YearReportGenerator implements ReportGeneratorInterface /** * Set the expenses used. * - * @param Collection $expense + * @param Collection $expense * * @return ReportGeneratorInterface */ @@ -137,7 +137,7 @@ class YearReportGenerator implements ReportGeneratorInterface /** * Set the start date. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -151,7 +151,7 @@ class YearReportGenerator implements ReportGeneratorInterface /** * Unused tags setter. * - * @param Collection $tags + * @param Collection $tags * * @return ReportGeneratorInterface */ diff --git a/app/Generator/Report/Tag/MonthReportGenerator.php b/app/Generator/Report/Tag/MonthReportGenerator.php index 201343e83e..1ed38a8702 100644 --- a/app/Generator/Report/Tag/MonthReportGenerator.php +++ b/app/Generator/Report/Tag/MonthReportGenerator.php @@ -81,7 +81,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set the accounts. * - * @param Collection $accounts + * @param Collection $accounts * * @return ReportGeneratorInterface */ @@ -95,7 +95,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Unused budget setter. * - * @param Collection $budgets + * @param Collection $budgets * * @return ReportGeneratorInterface */ @@ -107,7 +107,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Unused category setter. * - * @param Collection $categories + * @param Collection $categories * * @return ReportGeneratorInterface */ @@ -119,7 +119,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set the end date of the report. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -133,7 +133,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set the expenses in this report. * - * @param Collection $expense + * @param Collection $expense * * @return ReportGeneratorInterface */ @@ -145,7 +145,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set the start date. * - * @param Carbon $date + * @param Carbon $date * * @return ReportGeneratorInterface */ @@ -159,7 +159,7 @@ class MonthReportGenerator implements ReportGeneratorInterface /** * Set the tags used in this report. * - * @param Collection $tags + * @param Collection $tags * * @return ReportGeneratorInterface */ diff --git a/app/Generator/Webhook/MessageGeneratorInterface.php b/app/Generator/Webhook/MessageGeneratorInterface.php index 48c8979b09..6623f4ed8e 100644 --- a/app/Generator/Webhook/MessageGeneratorInterface.php +++ b/app/Generator/Webhook/MessageGeneratorInterface.php @@ -42,22 +42,22 @@ interface MessageGeneratorInterface public function getVersion(): int; /** - * @param Collection $objects + * @param Collection $objects */ public function setObjects(Collection $objects): void; /** - * @param int $trigger + * @param int $trigger */ public function setTrigger(int $trigger): void; /** - * @param User $user + * @param User $user */ public function setUser(User $user): void; /** - * @param Collection $webhooks + * @param Collection $webhooks * @return void */ public function setWebhooks(Collection $webhooks): void; diff --git a/app/Generator/Webhook/StandardMessageGenerator.php b/app/Generator/Webhook/StandardMessageGenerator.php index 66ed57089b..b032c906a6 100644 --- a/app/Generator/Webhook/StandardMessageGenerator.php +++ b/app/Generator/Webhook/StandardMessageGenerator.php @@ -81,67 +81,43 @@ class StandardMessageGenerator implements MessageGeneratorInterface } /** - * @inheritDoc - */ - public function getVersion(): int - { - return $this->version; - } - - /** - * @param Collection $objects - */ - public function setObjects(Collection $objects): void - { - $this->objects = $objects; - } - - /** - * @param int $trigger - */ - public function setTrigger(int $trigger): void - { - $this->trigger = $trigger; - } - - /** - * @param User $user - */ - public function setUser(User $user): void - { - $this->user = $user; - } - - /** - * @inheritDoc - */ - public function setWebhooks(Collection $webhooks): void - { - $this->webhooks = $webhooks; - } - - /** - * @param TransactionGroup $transactionGroup - * * @return Collection */ - private function collectAccounts(TransactionGroup $transactionGroup): Collection + private function getWebhooks(): Collection { - $accounts = new Collection(); - /** @var TransactionJournal $journal */ - foreach ($transactionGroup->transactionJournals as $journal) { - /** @var Transaction $transaction */ - foreach ($journal->transactions as $transaction) { - $accounts->push($transaction->account); - } - } - - return $accounts->unique(); + return $this->user->webhooks()->where('active', true)->where('trigger', $this->trigger)->get(['webhooks.*']); } /** - * @param Webhook $webhook - * @param Model $model + * + */ + private function run(): void + { + Log::debug('Now in StandardMessageGenerator::run'); + /** @var Webhook $webhook */ + foreach ($this->webhooks as $webhook) { + $this->runWebhook($webhook); + } + Log::debug('Done with StandardMessageGenerator::run'); + } + + /** + * @param Webhook $webhook + * @throws FireflyException + * @throws JsonException + */ + private function runWebhook(Webhook $webhook): void + { + Log::debug(sprintf('Now in runWebhook(#%d)', $webhook->id)); + /** @var Model $object */ + foreach ($this->objects as $object) { + $this->generateMessage($webhook, $object); + } + } + + /** + * @param Webhook $webhook + * @param Model $model * @throws FireflyException * @throws JsonException */ @@ -212,43 +188,35 @@ class StandardMessageGenerator implements MessageGeneratorInterface } /** + * @inheritDoc + */ + public function getVersion(): int + { + return $this->version; + } + + /** + * @param TransactionGroup $transactionGroup + * * @return Collection */ - private function getWebhooks(): Collection + private function collectAccounts(TransactionGroup $transactionGroup): Collection { - return $this->user->webhooks()->where('active', true)->where('trigger', $this->trigger)->get(['webhooks.*']); - } - - /** - * - */ - private function run(): void - { - Log::debug('Now in StandardMessageGenerator::run'); - /** @var Webhook $webhook */ - foreach ($this->webhooks as $webhook) { - $this->runWebhook($webhook); + $accounts = new Collection(); + /** @var TransactionJournal $journal */ + foreach ($transactionGroup->transactionJournals as $journal) { + /** @var Transaction $transaction */ + foreach ($journal->transactions as $transaction) { + $accounts->push($transaction->account); + } } - Log::debug('Done with StandardMessageGenerator::run'); + + return $accounts->unique(); } /** - * @param Webhook $webhook - * @throws FireflyException - * @throws JsonException - */ - private function runWebhook(Webhook $webhook): void - { - Log::debug(sprintf('Now in runWebhook(#%d)', $webhook->id)); - /** @var Model $object */ - foreach ($this->objects as $object) { - $this->generateMessage($webhook, $object); - } - } - - /** - * @param Webhook $webhook - * @param array $message + * @param Webhook $webhook + * @param array $message * * @return void */ @@ -263,4 +231,36 @@ class StandardMessageGenerator implements MessageGeneratorInterface $webhookMessage->save(); Log::debug(sprintf('Stored new webhook message #%d', $webhookMessage->id)); } + + /** + * @param Collection $objects + */ + public function setObjects(Collection $objects): void + { + $this->objects = $objects; + } + + /** + * @param int $trigger + */ + public function setTrigger(int $trigger): void + { + $this->trigger = $trigger; + } + + /** + * @param User $user + */ + public function setUser(User $user): void + { + $this->user = $user; + } + + /** + * @inheritDoc + */ + public function setWebhooks(Collection $webhooks): void + { + $this->webhooks = $webhooks; + } } diff --git a/app/Handlers/Events/APIEventHandler.php b/app/Handlers/Events/APIEventHandler.php index 3c6d9b44b9..6545a6842d 100644 --- a/app/Handlers/Events/APIEventHandler.php +++ b/app/Handlers/Events/APIEventHandler.php @@ -39,7 +39,7 @@ class APIEventHandler /** * Respond to the creation of an access token. * - * @param AccessTokenCreated $event + * @param AccessTokenCreated $event * * @throws FireflyException */ diff --git a/app/Handlers/Events/AdminEventHandler.php b/app/Handlers/Events/AdminEventHandler.php index 35b8d9499e..f22ce94229 100644 --- a/app/Handlers/Events/AdminEventHandler.php +++ b/app/Handlers/Events/AdminEventHandler.php @@ -41,7 +41,7 @@ use Illuminate\Support\Facades\Notification; class AdminEventHandler { /** - * @param InvitationCreated $event + * @param InvitationCreated $event * @return void */ public function sendInvitationNotification(InvitationCreated $event): void @@ -78,7 +78,7 @@ class AdminEventHandler /** * Send new version message to admin. * - * @param NewVersionAvailable $event + * @param NewVersionAvailable $event * @return void */ public function sendNewVersion(NewVersionAvailable $event): void @@ -115,7 +115,7 @@ class AdminEventHandler /** * Sends a test message to an administrator. * - * @param AdminRequestedTestMessage $event + * @param AdminRequestedTestMessage $event * * @return void */ diff --git a/app/Handlers/Events/AutomationHandler.php b/app/Handlers/Events/AutomationHandler.php index 149dabbd85..2e0d6aab44 100644 --- a/app/Handlers/Events/AutomationHandler.php +++ b/app/Handlers/Events/AutomationHandler.php @@ -41,7 +41,7 @@ class AutomationHandler /** * Respond to the creation of X journals. * - * @param RequestedReportOnJournals $event + * @param RequestedReportOnJournals $event * @throws FireflyException */ public function reportJournals(RequestedReportOnJournals $event): void diff --git a/app/Handlers/Events/BillEventHandler.php b/app/Handlers/Events/BillEventHandler.php index 5ef5ff6541..2ba63fcdd8 100644 --- a/app/Handlers/Events/BillEventHandler.php +++ b/app/Handlers/Events/BillEventHandler.php @@ -37,7 +37,7 @@ use Illuminate\Support\Facades\Notification; class BillEventHandler { /** - * @param WarnUserAboutBill $event + * @param WarnUserAboutBill $event * @return void */ public function warnAboutBill(WarnUserAboutBill $event): void diff --git a/app/Handlers/Events/DestroyedGroupEventHandler.php b/app/Handlers/Events/DestroyedGroupEventHandler.php index fbcf786fce..a7948333ff 100644 --- a/app/Handlers/Events/DestroyedGroupEventHandler.php +++ b/app/Handlers/Events/DestroyedGroupEventHandler.php @@ -36,7 +36,7 @@ use Illuminate\Support\Facades\Log; class DestroyedGroupEventHandler { /** - * @param DestroyedTransactionGroup $destroyedGroupEvent + * @param DestroyedTransactionGroup $destroyedGroupEvent */ public function triggerWebhooks(DestroyedTransactionGroup $destroyedGroupEvent): void { diff --git a/app/Handlers/Events/Model/BudgetLimitHandler.php b/app/Handlers/Events/Model/BudgetLimitHandler.php index 674aacb134..c47ffedecf 100644 --- a/app/Handlers/Events/Model/BudgetLimitHandler.php +++ b/app/Handlers/Events/Model/BudgetLimitHandler.php @@ -43,7 +43,7 @@ use Spatie\Period\Precision; class BudgetLimitHandler { /** - * @param Created $event + * @param Created $event * @return void */ public function created(Created $event): void @@ -53,117 +53,7 @@ class BudgetLimitHandler } /** - * @param Deleted $event - * @return void - */ - public function deleted(Deleted $event): void - { - Log::debug(sprintf('BudgetLimitHandler::deleted(#%s)', $event->budgetLimit->id)); - $budgetLimit = $event->budgetLimit; - $budgetLimit->id = null; - $this->updateAvailableBudget($event->budgetLimit); - } - - /** - * @param Updated $event - * @return void - */ - public function updated(Updated $event): void - { - Log::debug(sprintf('BudgetLimitHandler::updated(#%s)', $event->budgetLimit->id)); - $this->updateAvailableBudget($event->budgetLimit); - } - - /** - * @param AvailableBudget $availableBudget - * @return void - */ - private function calculateAmount(AvailableBudget $availableBudget): void - { - $repository = app(BudgetLimitRepositoryInterface::class); - $repository->setUser($availableBudget->user); - $newAmount = '0'; - $abPeriod = Period::make($availableBudget->start_date, $availableBudget->end_date, Precision::DAY()); - Log::debug( - sprintf( - 'Now at AB #%d, ("%s" to "%s")', - $availableBudget->id, - $availableBudget->start_date->format('Y-m-d'), - $availableBudget->end_date->format('Y-m-d') - ) - ); - // have to recalc everything just in case. - $set = $repository->getAllBudgetLimitsByCurrency($availableBudget->transactionCurrency, $availableBudget->start_date, $availableBudget->end_date); - Log::debug(sprintf('Found %d interesting budget limit(s).', $set->count())); - /** @var BudgetLimit $budgetLimit */ - foreach ($set as $budgetLimit) { - Log::debug( - sprintf( - 'Found interesting budget limit #%d ("%s" to "%s")', - $budgetLimit->id, - $budgetLimit->start_date->format('Y-m-d'), - $budgetLimit->end_date->format('Y-m-d') - ) - ); - // overlap in days: - $limitPeriod = Period::make( - $budgetLimit->start_date, - $budgetLimit->end_date, - precision: Precision::DAY(), - boundaries: Boundaries::EXCLUDE_NONE() - ); - // if both equal eachother, amount from this BL must be added to the AB - if ($limitPeriod->equals($abPeriod)) { - $newAmount = bcadd($newAmount, $budgetLimit->amount); - } - // if budget limit period inside AB period, can be added in full. - if (!$limitPeriod->equals($abPeriod) && $abPeriod->contains($limitPeriod)) { - $newAmount = bcadd($newAmount, $budgetLimit->amount); - } - if (!$limitPeriod->equals($abPeriod) && $abPeriod->overlapsWith($limitPeriod)) { - $overlap = $abPeriod->overlap($limitPeriod); - if (null !== $overlap) { - $length = $overlap->length(); - $daily = bcmul($this->getDailyAmount($budgetLimit), (string)$length); - $newAmount = bcadd($newAmount, $daily); - } - } - } - if (0 === bccomp('0', $newAmount)) { - Log::debug('New amount is zero, deleting AB.'); - $availableBudget->delete(); - return; - } - Log::debug(sprintf('Concluded new amount for this AB must be %s', $newAmount)); - $availableBudget->amount = $newAmount; - $availableBudget->save(); - } - - /** - * @param BudgetLimit $budgetLimit - * @return string - */ - private function getDailyAmount(BudgetLimit $budgetLimit): string - { - if (0 === (int)$budgetLimit->id) { - return '0'; - } - $limitPeriod = Period::make( - $budgetLimit->start_date, - $budgetLimit->end_date, - precision: Precision::DAY(), - boundaries: Boundaries::EXCLUDE_NONE() - ); - $days = $limitPeriod->length(); - $amount = bcdiv((string)$budgetLimit->amount, (string)$days, 12); - Log::debug( - sprintf('Total amount for budget limit #%d is %s. Nr. of days is %d. Amount per day is %s', $budgetLimit->id, $budgetLimit->amount, $days, $amount) - ); - return $amount; - } - - /** - * @param BudgetLimit $budgetLimit + * @param BudgetLimit $budgetLimit * @return void */ private function updateAvailableBudget(BudgetLimit $budgetLimit): void @@ -175,7 +65,7 @@ class BudgetLimitHandler // all have to be created or updated. try { $viewRange = app('preferences')->get('viewRange', '1M')->data; - } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) { + } catch (ContainerExceptionInterface | NotFoundExceptionInterface $e) { $viewRange = '1M'; } $start = app('navigation')->startOfPeriod($budgetLimit->start_date, $viewRange); @@ -248,4 +138,114 @@ class BudgetLimitHandler } } + /** + * @param AvailableBudget $availableBudget + * @return void + */ + private function calculateAmount(AvailableBudget $availableBudget): void + { + $repository = app(BudgetLimitRepositoryInterface::class); + $repository->setUser($availableBudget->user); + $newAmount = '0'; + $abPeriod = Period::make($availableBudget->start_date, $availableBudget->end_date, Precision::DAY()); + Log::debug( + sprintf( + 'Now at AB #%d, ("%s" to "%s")', + $availableBudget->id, + $availableBudget->start_date->format('Y-m-d'), + $availableBudget->end_date->format('Y-m-d') + ) + ); + // have to recalc everything just in case. + $set = $repository->getAllBudgetLimitsByCurrency($availableBudget->transactionCurrency, $availableBudget->start_date, $availableBudget->end_date); + Log::debug(sprintf('Found %d interesting budget limit(s).', $set->count())); + /** @var BudgetLimit $budgetLimit */ + foreach ($set as $budgetLimit) { + Log::debug( + sprintf( + 'Found interesting budget limit #%d ("%s" to "%s")', + $budgetLimit->id, + $budgetLimit->start_date->format('Y-m-d'), + $budgetLimit->end_date->format('Y-m-d') + ) + ); + // overlap in days: + $limitPeriod = Period::make( + $budgetLimit->start_date, + $budgetLimit->end_date, + precision : Precision::DAY(), + boundaries: Boundaries::EXCLUDE_NONE() + ); + // if both equal eachother, amount from this BL must be added to the AB + if ($limitPeriod->equals($abPeriod)) { + $newAmount = bcadd($newAmount, $budgetLimit->amount); + } + // if budget limit period inside AB period, can be added in full. + if (!$limitPeriod->equals($abPeriod) && $abPeriod->contains($limitPeriod)) { + $newAmount = bcadd($newAmount, $budgetLimit->amount); + } + if (!$limitPeriod->equals($abPeriod) && $abPeriod->overlapsWith($limitPeriod)) { + $overlap = $abPeriod->overlap($limitPeriod); + if (null !== $overlap) { + $length = $overlap->length(); + $daily = bcmul($this->getDailyAmount($budgetLimit), (string)$length); + $newAmount = bcadd($newAmount, $daily); + } + } + } + if (0 === bccomp('0', $newAmount)) { + Log::debug('New amount is zero, deleting AB.'); + $availableBudget->delete(); + return; + } + Log::debug(sprintf('Concluded new amount for this AB must be %s', $newAmount)); + $availableBudget->amount = $newAmount; + $availableBudget->save(); + } + + /** + * @param BudgetLimit $budgetLimit + * @return string + */ + private function getDailyAmount(BudgetLimit $budgetLimit): string + { + if (0 === (int)$budgetLimit->id) { + return '0'; + } + $limitPeriod = Period::make( + $budgetLimit->start_date, + $budgetLimit->end_date, + precision : Precision::DAY(), + boundaries: Boundaries::EXCLUDE_NONE() + ); + $days = $limitPeriod->length(); + $amount = bcdiv((string)$budgetLimit->amount, (string)$days, 12); + Log::debug( + sprintf('Total amount for budget limit #%d is %s. Nr. of days is %d. Amount per day is %s', $budgetLimit->id, $budgetLimit->amount, $days, $amount) + ); + return $amount; + } + + /** + * @param Deleted $event + * @return void + */ + public function deleted(Deleted $event): void + { + Log::debug(sprintf('BudgetLimitHandler::deleted(#%s)', $event->budgetLimit->id)); + $budgetLimit = $event->budgetLimit; + $budgetLimit->id = null; + $this->updateAvailableBudget($event->budgetLimit); + } + + /** + * @param Updated $event + * @return void + */ + public function updated(Updated $event): void + { + Log::debug(sprintf('BudgetLimitHandler::updated(#%s)', $event->budgetLimit->id)); + $this->updateAvailableBudget($event->budgetLimit); + } + } diff --git a/app/Handlers/Events/PiggyBankEventHandler.php b/app/Handlers/Events/PiggyBankEventHandler.php index 85ce2e6719..3f2cab01cd 100644 --- a/app/Handlers/Events/PiggyBankEventHandler.php +++ b/app/Handlers/Events/PiggyBankEventHandler.php @@ -34,7 +34,7 @@ use Illuminate\Support\Facades\Log; class PiggyBankEventHandler { /** - * @param ChangedPiggyBankAmount $event + * @param ChangedPiggyBankAmount $event * @return void */ public function changePiggyAmount(ChangedPiggyBankAmount $event): void diff --git a/app/Handlers/Events/StoredAccountEventHandler.php b/app/Handlers/Events/StoredAccountEventHandler.php index e28febaa47..a4a48f4cbf 100644 --- a/app/Handlers/Events/StoredAccountEventHandler.php +++ b/app/Handlers/Events/StoredAccountEventHandler.php @@ -33,7 +33,7 @@ use FireflyIII\Services\Internal\Support\CreditRecalculateService; class StoredAccountEventHandler { /** - * @param StoredAccount $event + * @param StoredAccount $event */ public function recalculateCredit(StoredAccount $event): void { diff --git a/app/Handlers/Events/StoredGroupEventHandler.php b/app/Handlers/Events/StoredGroupEventHandler.php index 44de4c78da..853f299fb2 100644 --- a/app/Handlers/Events/StoredGroupEventHandler.php +++ b/app/Handlers/Events/StoredGroupEventHandler.php @@ -42,7 +42,7 @@ class StoredGroupEventHandler /** * This method grabs all the users rules and processes them. * - * @param StoredTransactionGroup $storedGroupEvent + * @param StoredTransactionGroup $storedGroupEvent */ public function processRules(StoredTransactionGroup $storedGroupEvent): void { @@ -79,7 +79,7 @@ class StoredGroupEventHandler } /** - * @param StoredTransactionGroup $event + * @param StoredTransactionGroup $event */ public function recalculateCredit(StoredTransactionGroup $event): void { @@ -93,7 +93,7 @@ class StoredGroupEventHandler /** * This method processes all webhooks that respond to the "stored transaction group" trigger (100) * - * @param StoredTransactionGroup $storedGroupEvent + * @param StoredTransactionGroup $storedGroupEvent */ public function triggerWebhooks(StoredTransactionGroup $storedGroupEvent): void { diff --git a/app/Handlers/Events/UpdatedAccountEventHandler.php b/app/Handlers/Events/UpdatedAccountEventHandler.php index 0de35afd9b..6874fcbba4 100644 --- a/app/Handlers/Events/UpdatedAccountEventHandler.php +++ b/app/Handlers/Events/UpdatedAccountEventHandler.php @@ -33,7 +33,7 @@ use FireflyIII\Services\Internal\Support\CreditRecalculateService; class UpdatedAccountEventHandler { /** - * @param UpdatedAccount $event + * @param UpdatedAccount $event */ public function recalculateCredit(UpdatedAccount $event): void { diff --git a/app/Handlers/Events/UpdatedGroupEventHandler.php b/app/Handlers/Events/UpdatedGroupEventHandler.php index 99e0046079..991edabd6d 100644 --- a/app/Handlers/Events/UpdatedGroupEventHandler.php +++ b/app/Handlers/Events/UpdatedGroupEventHandler.php @@ -45,7 +45,7 @@ class UpdatedGroupEventHandler /** * This method will check all the rules when a journal is updated. * - * @param UpdatedTransactionGroup $updatedGroupEvent + * @param UpdatedTransactionGroup $updatedGroupEvent */ public function processRules(UpdatedTransactionGroup $updatedGroupEvent): void { @@ -79,7 +79,7 @@ class UpdatedGroupEventHandler } /** - * @param UpdatedTransactionGroup $event + * @param UpdatedTransactionGroup $event */ public function recalculateCredit(UpdatedTransactionGroup $event): void { @@ -91,7 +91,7 @@ class UpdatedGroupEventHandler } /** - * @param UpdatedTransactionGroup $updatedGroupEvent + * @param UpdatedTransactionGroup $updatedGroupEvent */ public function triggerWebhooks(UpdatedTransactionGroup $updatedGroupEvent): void { @@ -116,7 +116,7 @@ class UpdatedGroupEventHandler /** * This method will make sure all source / destination accounts are the same. * - * @param UpdatedTransactionGroup $updatedGroupEvent + * @param UpdatedTransactionGroup $updatedGroupEvent */ public function unifyAccounts(UpdatedTransactionGroup $updatedGroupEvent): void { diff --git a/app/Handlers/Events/UserEventHandler.php b/app/Handlers/Events/UserEventHandler.php index 83af75e4dd..a351789b10 100644 --- a/app/Handlers/Events/UserEventHandler.php +++ b/app/Handlers/Events/UserEventHandler.php @@ -63,7 +63,7 @@ class UserEventHandler /** * This method will bestow upon a user the "owner" role if he is the first user in the system. * - * @param RegisteredUser $event + * @param RegisteredUser $event */ public function attachUserRole(RegisteredUser $event): void { @@ -80,7 +80,7 @@ class UserEventHandler /** * Fires to see if a user is admin. * - * @param Login $event + * @param Login $event */ public function checkSingleUserIsAdmin(Login $event): void { @@ -108,7 +108,7 @@ class UserEventHandler } /** - * @param RegisteredUser $event + * @param RegisteredUser $event */ public function createExchangeRates(RegisteredUser $event): void { @@ -117,7 +117,7 @@ class UserEventHandler } /** - * @param RegisteredUser $event + * @param RegisteredUser $event * * @throws FireflyException */ @@ -162,7 +162,7 @@ class UserEventHandler /** * Set the demo user back to English. * - * @param Login $event + * @param Login $event * * @throws FireflyException */ @@ -182,7 +182,7 @@ class UserEventHandler } /** - * @param DetectedNewIPAddress $event + * @param DetectedNewIPAddress $event * * @throws FireflyException */ @@ -224,7 +224,7 @@ class UserEventHandler } /** - * @param RegisteredUser $event + * @param RegisteredUser $event */ public function sendAdminRegistrationNotification(RegisteredUser $event): void { @@ -259,7 +259,7 @@ class UserEventHandler * Send email to confirm email change. Will not be made into a notification, because * this requires some custom fields from the user and not just the "user" object. * - * @param UserChangedEmail $event + * @param UserChangedEmail $event * * @throws FireflyException */ @@ -283,7 +283,7 @@ class UserEventHandler * Send email to be able to undo email change. Will not be made into a notification, because * this requires some custom fields from the user and not just the "user" object. * - * @param UserChangedEmail $event + * @param UserChangedEmail $event * * @throws FireflyException */ @@ -305,7 +305,8 @@ class UserEventHandler /** * Send a new password to the user. - * @param RequestedNewPassword $event + * + * @param RequestedNewPassword $event */ public function sendNewPassword(RequestedNewPassword $event): void { @@ -327,7 +328,7 @@ class UserEventHandler } /** - * @param InvitationCreated $event + * @param InvitationCreated $event * @return void * @throws FireflyException */ @@ -348,7 +349,7 @@ class UserEventHandler * This method will send the user a registration mail, welcoming him or her to Firefly III. * This message is only sent when the configuration of Firefly III says so. * - * @param RegisteredUser $event + * @param RegisteredUser $event * */ public function sendRegistrationMail(RegisteredUser $event): void @@ -374,7 +375,7 @@ class UserEventHandler } /** - * @param ActuallyLoggedIn $event + * @param ActuallyLoggedIn $event * @throws FireflyException */ public function storeUserIPAddress(ActuallyLoggedIn $event): void diff --git a/app/Handlers/Events/VersionCheckEventHandler.php b/app/Handlers/Events/VersionCheckEventHandler.php index 923c1a1930..1e380d3f31 100644 --- a/app/Handlers/Events/VersionCheckEventHandler.php +++ b/app/Handlers/Events/VersionCheckEventHandler.php @@ -42,7 +42,7 @@ class VersionCheckEventHandler /** * Checks with GitHub to see if there is a new version. * - * @param RequestedVersionCheckStatus $event + * @param RequestedVersionCheckStatus $event * * @throws FireflyException * @throws ContainerExceptionInterface @@ -91,7 +91,7 @@ class VersionCheckEventHandler } /** - * @param RequestedVersionCheckStatus $event + * @param RequestedVersionCheckStatus $event * * @throws FireflyException * @throws ContainerExceptionInterface diff --git a/app/Helpers/Attachments/AttachmentHelper.php b/app/Helpers/Attachments/AttachmentHelper.php index 49bce5c6d6..8c9c038992 100644 --- a/app/Helpers/Attachments/AttachmentHelper.php +++ b/app/Helpers/Attachments/AttachmentHelper.php @@ -70,7 +70,7 @@ class AttachmentHelper implements AttachmentHelperInterface * Returns the content of an attachment. * * - * @param Attachment $attachment + * @param Attachment $attachment * * @return string */ @@ -90,7 +90,7 @@ class AttachmentHelper implements AttachmentHelperInterface /** * Returns the file path relative to upload disk for an attachment, * - * @param Attachment $attachment + * @param Attachment $attachment * * @return string */ @@ -132,8 +132,8 @@ class AttachmentHelper implements AttachmentHelperInterface /** * Uploads a file as a string. * - * @param Attachment $attachment - * @param string $content + * @param Attachment $attachment + * @param string $content * * @return bool */ @@ -181,8 +181,8 @@ class AttachmentHelper implements AttachmentHelperInterface /** * Save attachments that get uploaded with models, through the app. * - * @param object $model - * @param array|null $files + * @param object $model + * @param array|null $files * * @return bool * @throws FireflyException @@ -211,44 +211,11 @@ class AttachmentHelper implements AttachmentHelperInterface return true; } - /** - * Check if a model already has this file attached. - * - * @param UploadedFile $file - * @param Model $model - * - * @return bool - */ - protected function hasFile(UploadedFile $file, Model $model): bool - { - $md5 = md5_file($file->getRealPath()); - $name = $file->getClientOriginalName(); - $class = get_class($model); - $count = 0; - // ignore lines about polymorphic calls. - if ($model instanceof PiggyBank) { - $count = $model->account->user->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count(); - } - if (!($model instanceof PiggyBank)) { - $count = $model->user->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count( - ); // @phpstan-ignore-line - } - $result = false; - if ($count > 0) { - $msg = (string)trans('validation.file_already_attached', ['name' => $name]); - $this->errors->add('attachments', $msg); - Log::error($msg); - $result = true; - } - - return $result; - } - /** * Process the upload of a file. * - * @param UploadedFile $file - * @param Model $model + * @param UploadedFile $file + * @param Model $model * * @return Attachment|null * @throws FireflyException @@ -301,62 +268,11 @@ class AttachmentHelper implements AttachmentHelperInterface return $attachment; } - /** - * Verify if the mime of a file is valid. - * - * @param UploadedFile $file - * - * @return bool - */ - protected function validMime(UploadedFile $file): bool - { - Log::debug('Now in validMime()'); - $mime = e($file->getMimeType()); - $name = e($file->getClientOriginalName()); - Log::debug(sprintf('Name is %s, and mime is %s', $name, $mime)); - Log::debug('Valid mimes are', $this->allowedMimes); - $result = true; - - if (!in_array($mime, $this->allowedMimes, true)) { - $msg = (string)trans('validation.file_invalid_mime', ['name' => $name, 'mime' => $mime]); - $this->errors->add('attachments', $msg); - Log::error($msg); - - $result = false; - } - - return $result; - } - - /** - * Verify if the size of a file is valid. - * - * - * @param UploadedFile $file - * - * @return bool - */ - protected function validSize(UploadedFile $file): bool - { - $size = $file->getSize(); - $name = e($file->getClientOriginalName()); - $result = true; - if ($size > $this->maxUploadSize) { - $msg = (string)trans('validation.file_too_large', ['name' => $name]); - $this->errors->add('attachments', $msg); - Log::error($msg); - - $result = false; - } - - return $result; - } - /** * Verify if the file was uploaded correctly. * - * @param UploadedFile $file - * @param Model $model + * @param UploadedFile $file + * @param Model $model * * @return bool */ @@ -384,4 +300,87 @@ class AttachmentHelper implements AttachmentHelperInterface return $result; } + + /** + * Verify if the mime of a file is valid. + * + * @param UploadedFile $file + * + * @return bool + */ + protected function validMime(UploadedFile $file): bool + { + Log::debug('Now in validMime()'); + $mime = e($file->getMimeType()); + $name = e($file->getClientOriginalName()); + Log::debug(sprintf('Name is %s, and mime is %s', $name, $mime)); + Log::debug('Valid mimes are', $this->allowedMimes); + $result = true; + + if (!in_array($mime, $this->allowedMimes, true)) { + $msg = (string)trans('validation.file_invalid_mime', ['name' => $name, 'mime' => $mime]); + $this->errors->add('attachments', $msg); + Log::error($msg); + + $result = false; + } + + return $result; + } + + /** + * Verify if the size of a file is valid. + * + * + * @param UploadedFile $file + * + * @return bool + */ + protected function validSize(UploadedFile $file): bool + { + $size = $file->getSize(); + $name = e($file->getClientOriginalName()); + $result = true; + if ($size > $this->maxUploadSize) { + $msg = (string)trans('validation.file_too_large', ['name' => $name]); + $this->errors->add('attachments', $msg); + Log::error($msg); + + $result = false; + } + + return $result; + } + + /** + * Check if a model already has this file attached. + * + * @param UploadedFile $file + * @param Model $model + * + * @return bool + */ + protected function hasFile(UploadedFile $file, Model $model): bool + { + $md5 = md5_file($file->getRealPath()); + $name = $file->getClientOriginalName(); + $class = get_class($model); + $count = 0; + // ignore lines about polymorphic calls. + if ($model instanceof PiggyBank) { + $count = $model->account->user->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count(); + } + if (!($model instanceof PiggyBank)) { + $count = $model->user->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count(); // @phpstan-ignore-line + } + $result = false; + if ($count > 0) { + $msg = (string)trans('validation.file_already_attached', ['name' => $name]); + $this->errors->add('attachments', $msg); + Log::error($msg); + $result = true; + } + + return $result; + } } diff --git a/app/Helpers/Attachments/AttachmentHelperInterface.php b/app/Helpers/Attachments/AttachmentHelperInterface.php index 1b6173fc8a..766193e86b 100644 --- a/app/Helpers/Attachments/AttachmentHelperInterface.php +++ b/app/Helpers/Attachments/AttachmentHelperInterface.php @@ -35,7 +35,7 @@ interface AttachmentHelperInterface /** * Get content of an attachment. * - * @param Attachment $attachment + * @param Attachment $attachment * * @return string */ @@ -44,7 +44,7 @@ interface AttachmentHelperInterface /** * Get the location of an attachment. * - * @param Attachment $attachment + * @param Attachment $attachment * * @return string */ @@ -74,8 +74,8 @@ interface AttachmentHelperInterface /** * Uploads a file as a string. * - * @param Attachment $attachment - * @param string $content + * @param Attachment $attachment + * @param string $content * * @return bool */ @@ -84,8 +84,8 @@ interface AttachmentHelperInterface /** * Save attachments that got uploaded. * - * @param object $model - * @param null|array $files + * @param object $model + * @param null|array $files * * @return bool */ diff --git a/app/Helpers/Collector/Extensions/AccountCollection.php b/app/Helpers/Collector/Extensions/AccountCollection.php index 43145d073b..afb2466ea4 100644 --- a/app/Helpers/Collector/Extensions/AccountCollection.php +++ b/app/Helpers/Collector/Extensions/AccountCollection.php @@ -36,7 +36,7 @@ trait AccountCollection /** * These accounts must not be included. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -56,7 +56,7 @@ trait AccountCollection /** * These accounts must not be destination accounts. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -75,7 +75,7 @@ trait AccountCollection /** * These accounts must not be source accounts. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -94,7 +94,7 @@ trait AccountCollection /** * Define which accounts can be part of the source and destination transactions. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -117,7 +117,7 @@ trait AccountCollection /** * Both source AND destination must be in this list of accounts. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -140,7 +140,7 @@ trait AccountCollection /** * Define which accounts can be part of the source and destination transactions. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -159,7 +159,7 @@ trait AccountCollection /** * Define which accounts can NOT be part of the source and destination transactions. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -182,7 +182,7 @@ trait AccountCollection /** * Define which accounts can be part of the source and destination transactions. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -201,7 +201,7 @@ trait AccountCollection /** * Either account can be set, but NOT both. This effectively excludes internal transfers. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ diff --git a/app/Helpers/Collector/Extensions/AmountCollection.php b/app/Helpers/Collector/Extensions/AmountCollection.php index bf4d9af521..7e71d6e422 100644 --- a/app/Helpers/Collector/Extensions/AmountCollection.php +++ b/app/Helpers/Collector/Extensions/AmountCollection.php @@ -35,7 +35,7 @@ trait AmountCollection /** * Get transactions with a specific amount. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ @@ -67,7 +67,7 @@ trait AmountCollection /** * Get transactions where the amount is less than. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ @@ -85,7 +85,7 @@ trait AmountCollection /** * Get transactions where the amount is more than. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ @@ -103,7 +103,7 @@ trait AmountCollection /** * Get transactions with a specific foreign amount. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ @@ -122,7 +122,7 @@ trait AmountCollection /** * Get transactions with a specific foreign amount. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ @@ -141,7 +141,7 @@ trait AmountCollection /** * Get transactions where the amount is less than. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ @@ -160,7 +160,7 @@ trait AmountCollection /** * Get transactions where the amount is more than. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ diff --git a/app/Helpers/Collector/Extensions/AttachmentCollection.php b/app/Helpers/Collector/Extensions/AttachmentCollection.php index b755cb0f91..7c5d75fd83 100644 --- a/app/Helpers/Collector/Extensions/AttachmentCollection.php +++ b/app/Helpers/Collector/Extensions/AttachmentCollection.php @@ -37,7 +37,7 @@ use Illuminate\Support\Facades\Log; trait AttachmentCollection { /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameContains(string $name): GroupCollectorInterface @@ -115,7 +115,7 @@ trait AttachmentCollection } /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameDoesNotContain(string $name): GroupCollectorInterface @@ -144,7 +144,7 @@ trait AttachmentCollection } /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameDoesNotEnd(string $name): GroupCollectorInterface @@ -173,7 +173,7 @@ trait AttachmentCollection } /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameDoesNotStart(string $name): GroupCollectorInterface @@ -202,7 +202,7 @@ trait AttachmentCollection } /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameEnds(string $name): GroupCollectorInterface @@ -231,7 +231,7 @@ trait AttachmentCollection } /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameIs(string $name): GroupCollectorInterface @@ -257,7 +257,7 @@ trait AttachmentCollection } /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameIsNot(string $name): GroupCollectorInterface @@ -283,7 +283,7 @@ trait AttachmentCollection } /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameStarts(string $name): GroupCollectorInterface @@ -312,7 +312,7 @@ trait AttachmentCollection } /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesAre(string $value): GroupCollectorInterface @@ -338,7 +338,7 @@ trait AttachmentCollection } /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesAreNot(string $value): GroupCollectorInterface @@ -364,7 +364,7 @@ trait AttachmentCollection } /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesContains(string $value): GroupCollectorInterface @@ -390,7 +390,7 @@ trait AttachmentCollection } /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesDoNotContain(string $value): GroupCollectorInterface @@ -416,7 +416,7 @@ trait AttachmentCollection } /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesDoNotEnd(string $value): GroupCollectorInterface @@ -442,7 +442,7 @@ trait AttachmentCollection } /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesDoNotStart(string $value): GroupCollectorInterface @@ -468,7 +468,7 @@ trait AttachmentCollection } /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesEnds(string $value): GroupCollectorInterface @@ -494,7 +494,7 @@ trait AttachmentCollection } /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesStarts(string $value): GroupCollectorInterface diff --git a/app/Helpers/Collector/Extensions/MetaCollection.php b/app/Helpers/Collector/Extensions/MetaCollection.php index 9ccf3d34bc..22fc700c2a 100644 --- a/app/Helpers/Collector/Extensions/MetaCollection.php +++ b/app/Helpers/Collector/Extensions/MetaCollection.php @@ -53,10 +53,29 @@ trait MetaCollection return $this; } + /** + * Will include bill name + ID, if any. + * + * @return GroupCollectorInterface + */ + public function withBillInformation(): GroupCollectorInterface + { + if (false === $this->hasBillInformation) { + // join bill table + $this->query->leftJoin('bills', 'bills.id', '=', 'transaction_journals.bill_id'); + // add fields + $this->fields[] = 'bills.id as bill_id'; + $this->fields[] = 'bills.name as bill_name'; + $this->hasBillInformation = true; + } + + return $this; + } + /** * Exclude a specific budget. * - * @param Budget $budget + * @param Budget $budget * * @return GroupCollectorInterface */ @@ -72,6 +91,27 @@ trait MetaCollection return $this; } + /** + * Will include budget ID + name, if any. + * + * @return GroupCollectorInterface + */ + public function withBudgetInformation(): GroupCollectorInterface + { + if (false === $this->hasBudgetInformation) { + // join link table + $this->query->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'); + // join cat table + $this->query->leftJoin('budgets', 'budget_transaction_journal.budget_id', '=', 'budgets.id'); + // add fields + $this->fields[] = 'budgets.id as budget_id'; + $this->fields[] = 'budgets.name as budget_name'; + $this->hasBudgetInformation = true; + } + + return $this; + } + /** * @inheritDoc */ @@ -104,10 +144,31 @@ trait MetaCollection return $this; } + /** + * Will include category ID + name, if any. + * + * @return GroupCollectorInterface + */ + public function withCategoryInformation(): GroupCollectorInterface + { + if (false === $this->hasCatInformation) { + // join link table + $this->query->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'); + // join cat table + $this->query->leftJoin('categories', 'category_transaction_journal.category_id', '=', 'categories.id'); + // add fields + $this->fields[] = 'categories.id as category_id'; + $this->fields[] = 'categories.name as category_name'; + $this->hasCatInformation = true; + } + + return $this; + } + /** * Exclude a specific category. * - * @param Category $category + * @param Category $category * * @return GroupCollectorInterface */ @@ -135,6 +196,19 @@ trait MetaCollection return $this; } + /** + * Join table to get tag information. + */ + protected function joinMetaDataTables(): void + { + if (false === $this->hasJoinedMetaTables) { + $this->hasJoinedMetaTables = true; + $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); + $this->fields[] = 'journal_meta.name as meta_name'; + $this->fields[] = 'journal_meta.data as meta_data'; + } + } + /** * @inheritDoc */ @@ -245,7 +319,7 @@ trait MetaCollection } /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function externalUrlContains(string $url): GroupCollectorInterface @@ -260,7 +334,7 @@ trait MetaCollection } /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function externalUrlDoesNotContain(string $url): GroupCollectorInterface @@ -275,7 +349,7 @@ trait MetaCollection } /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function externalUrlDoesNotEnd(string $url): GroupCollectorInterface @@ -290,7 +364,7 @@ trait MetaCollection } /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function externalUrlDoesNotStart(string $url): GroupCollectorInterface @@ -307,7 +381,7 @@ trait MetaCollection } /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function externalUrlEnds(string $url): GroupCollectorInterface @@ -322,7 +396,7 @@ trait MetaCollection } /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function externalUrlStarts(string $url): GroupCollectorInterface @@ -351,6 +425,37 @@ trait MetaCollection return $this; } + /** + * @return GroupCollectorInterface + */ + public function withTagInformation(): GroupCollectorInterface + { + $this->fields[] = 'tags.id as tag_id'; + $this->fields[] = 'tags.tag as tag_name'; + $this->fields[] = 'tags.date as tag_date'; + $this->fields[] = 'tags.description as tag_description'; + $this->fields[] = 'tags.latitude as tag_latitude'; + $this->fields[] = 'tags.longitude as tag_longitude'; + $this->fields[] = 'tags.zoomLevel as tag_zoom_level'; + + $this->joinTagTables(); + + return $this; + } + + /** + * Join table to get tag information. + */ + protected function joinTagTables(): void + { + if (false === $this->hasJoinedTagTables) { + // join some extra tables: + $this->hasJoinedTagTables = true; + $this->query->leftJoin('tag_transaction_journal', 'tag_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'); + $this->query->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id'); + } + } + /** * @inheritDoc */ @@ -424,7 +529,7 @@ trait MetaCollection } /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ @@ -437,7 +542,30 @@ trait MetaCollection } /** - * @param string $value + * @inheritDoc + */ + public function withNotes(): GroupCollectorInterface + { + if (false === $this->hasNotesInformation) { + // join bill table + $this->query->leftJoin( + 'notes', + static function (JoinClause $join) { + $join->on('notes.noteable_id', '=', 'transaction_journals.id'); + $join->where('notes.noteable_type', '=', 'FireflyIII\Models\TransactionJournal'); + $join->whereNull('notes.deleted_at'); + } + ); + // add fields + $this->fields[] = 'notes.text as notes'; + $this->hasNotesInformation = true; + } + + return $this; + } + + /** + * @param string $value * * @return GroupCollectorInterface */ @@ -453,7 +581,7 @@ trait MetaCollection } /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ @@ -469,7 +597,7 @@ trait MetaCollection } /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ @@ -485,7 +613,7 @@ trait MetaCollection } /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ @@ -498,7 +626,7 @@ trait MetaCollection } /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ @@ -511,7 +639,7 @@ trait MetaCollection } /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ @@ -527,7 +655,7 @@ trait MetaCollection } /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ @@ -542,7 +670,7 @@ trait MetaCollection /** * Limit the search to a specific bill. * - * @param Bill $bill + * @param Bill $bill * * @return GroupCollectorInterface */ @@ -557,7 +685,7 @@ trait MetaCollection /** * Limit the search to a specific set of bills. * - * @param Collection $bills + * @param Collection $bills * * @return GroupCollectorInterface */ @@ -572,7 +700,7 @@ trait MetaCollection /** * Limit the search to a specific budget. * - * @param Budget $budget + * @param Budget $budget * * @return GroupCollectorInterface */ @@ -587,7 +715,7 @@ trait MetaCollection /** * Limit the search to a specific set of budgets. * - * @param Collection $budgets + * @param Collection $budgets * * @return GroupCollectorInterface */ @@ -604,7 +732,7 @@ trait MetaCollection /** * Limit the search to a specific bunch of categories. * - * @param Collection $categories + * @param Collection $categories * * @return GroupCollectorInterface */ @@ -621,7 +749,7 @@ trait MetaCollection /** * Limit the search to a specific category. * - * @param Category $category + * @param Category $category * * @return GroupCollectorInterface */ @@ -698,7 +826,7 @@ trait MetaCollection /** * Limit results to a specific tag. * - * @param Tag $tag + * @param Tag $tag * * @return GroupCollectorInterface */ @@ -713,7 +841,7 @@ trait MetaCollection /** * Limit results to a specific set of tags. * - * @param Collection $tags + * @param Collection $tags * * @return GroupCollectorInterface */ @@ -728,7 +856,7 @@ trait MetaCollection /** * Without tags * - * @param Collection $tags + * @param Collection $tags * * @return GroupCollectorInterface */ @@ -778,25 +906,6 @@ trait MetaCollection return $this; } - /** - * Will include bill name + ID, if any. - * - * @return GroupCollectorInterface - */ - public function withBillInformation(): GroupCollectorInterface - { - if (false === $this->hasBillInformation) { - // join bill table - $this->query->leftJoin('bills', 'bills.id', '=', 'transaction_journals.bill_id'); - // add fields - $this->fields[] = 'bills.id as bill_id'; - $this->fields[] = 'bills.name as bill_name'; - $this->hasBillInformation = true; - } - - return $this; - } - /** * Limit results to a transactions without a budget.. * @@ -810,27 +919,6 @@ trait MetaCollection return $this; } - /** - * Will include budget ID + name, if any. - * - * @return GroupCollectorInterface - */ - public function withBudgetInformation(): GroupCollectorInterface - { - if (false === $this->hasBudgetInformation) { - // join link table - $this->query->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'); - // join cat table - $this->query->leftJoin('budgets', 'budget_transaction_journal.budget_id', '=', 'budgets.id'); - // add fields - $this->fields[] = 'budgets.id as budget_id'; - $this->fields[] = 'budgets.name as budget_name'; - $this->hasBudgetInformation = true; - } - - return $this; - } - /** * Limit results to a transactions without a category. * @@ -844,27 +932,6 @@ trait MetaCollection return $this; } - /** - * Will include category ID + name, if any. - * - * @return GroupCollectorInterface - */ - public function withCategoryInformation(): GroupCollectorInterface - { - if (false === $this->hasCatInformation) { - // join link table - $this->query->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'); - // join cat table - $this->query->leftJoin('categories', 'category_transaction_journal.category_id', '=', 'categories.id'); - // add fields - $this->fields[] = 'categories.id as category_id'; - $this->fields[] = 'categories.name as category_name'; - $this->hasCatInformation = true; - } - - return $this; - } - /** * @inheritDoc */ @@ -889,47 +956,6 @@ trait MetaCollection return $this; } - /** - * @inheritDoc - */ - public function withNotes(): GroupCollectorInterface - { - if (false === $this->hasNotesInformation) { - // join bill table - $this->query->leftJoin( - 'notes', - static function (JoinClause $join) { - $join->on('notes.noteable_id', '=', 'transaction_journals.id'); - $join->where('notes.noteable_type', '=', 'FireflyIII\Models\TransactionJournal'); - $join->whereNull('notes.deleted_at'); - } - ); - // add fields - $this->fields[] = 'notes.text as notes'; - $this->hasNotesInformation = true; - } - - return $this; - } - - /** - * @return GroupCollectorInterface - */ - public function withTagInformation(): GroupCollectorInterface - { - $this->fields[] = 'tags.id as tag_id'; - $this->fields[] = 'tags.tag as tag_name'; - $this->fields[] = 'tags.date as tag_date'; - $this->fields[] = 'tags.description as tag_description'; - $this->fields[] = 'tags.latitude as tag_latitude'; - $this->fields[] = 'tags.longitude as tag_longitude'; - $this->fields[] = 'tags.zoomLevel as tag_zoom_level'; - - $this->joinTagTables(); - - return $this; - } - /** * Limit results to a transactions without a bill. * @@ -1036,30 +1062,4 @@ trait MetaCollection return $this; } - - /** - * Join table to get tag information. - */ - protected function joinMetaDataTables(): void - { - if (false === $this->hasJoinedMetaTables) { - $this->hasJoinedMetaTables = true; - $this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id'); - $this->fields[] = 'journal_meta.name as meta_name'; - $this->fields[] = 'journal_meta.data as meta_data'; - } - } - - /** - * Join table to get tag information. - */ - protected function joinTagTables(): void - { - if (false === $this->hasJoinedTagTables) { - // join some extra tables: - $this->hasJoinedTagTables = true; - $this->query->leftJoin('tag_transaction_journal', 'tag_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'); - $this->query->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id'); - } - } } diff --git a/app/Helpers/Collector/Extensions/TimeCollection.php b/app/Helpers/Collector/Extensions/TimeCollection.php index 7d2d598ee0..7cb735ea6f 100644 --- a/app/Helpers/Collector/Extensions/TimeCollection.php +++ b/app/Helpers/Collector/Extensions/TimeCollection.php @@ -33,7 +33,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface; trait TimeCollection { /** - * @param string $day + * @param string $day * @return GroupCollectorInterface */ public function dayAfter(string $day): GroupCollectorInterface @@ -43,7 +43,7 @@ trait TimeCollection } /** - * @param string $day + * @param string $day * @return GroupCollectorInterface */ public function dayBefore(string $day): GroupCollectorInterface @@ -53,7 +53,7 @@ trait TimeCollection } /** - * @param string $day + * @param string $day * @return GroupCollectorInterface */ public function dayIs(string $day): GroupCollectorInterface @@ -63,7 +63,7 @@ trait TimeCollection } /** - * @param string $day + * @param string $day * @return GroupCollectorInterface */ public function dayIsNot(string $day): GroupCollectorInterface @@ -73,9 +73,9 @@ trait TimeCollection } /** - * @param Carbon $start - * @param Carbon $end - * @param string $field + * @param Carbon $start + * @param Carbon $end + * @param string $field * @return GroupCollectorInterface */ public function excludeMetaDateRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface @@ -103,9 +103,21 @@ trait TimeCollection } /** - * @param Carbon $start - * @param Carbon $end - * @param string $field + * @inheritDoc + */ + public function withMetaDate(string $field): GroupCollectorInterface + { + $this->joinMetaDataTables(); + $this->query->where('journal_meta.name', '=', $field); + $this->query->whereNotNull('journal_meta.data'); + + return $this; + } + + /** + * @param Carbon $start + * @param Carbon $end + * @param string $field * @return GroupCollectorInterface */ public function excludeObjectRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface @@ -120,8 +132,8 @@ trait TimeCollection } /** - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * @return GroupCollectorInterface */ public function excludeRange(Carbon $start, Carbon $end): GroupCollectorInterface @@ -139,8 +151,8 @@ trait TimeCollection } /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function metaDayAfter(string $day, string $field): GroupCollectorInterface @@ -162,8 +174,8 @@ trait TimeCollection } /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function metaDayBefore(string $day, string $field): GroupCollectorInterface @@ -185,8 +197,8 @@ trait TimeCollection } /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function metaDayIs(string $day, string $field): GroupCollectorInterface @@ -207,8 +219,8 @@ trait TimeCollection } /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function metaDayIsNot(string $day, string $field): GroupCollectorInterface @@ -229,8 +241,8 @@ trait TimeCollection } /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function metaMonthAfter(string $month, string $field): GroupCollectorInterface @@ -252,8 +264,8 @@ trait TimeCollection } /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function metaMonthBefore(string $month, string $field): GroupCollectorInterface @@ -275,8 +287,8 @@ trait TimeCollection } /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function metaMonthIs(string $month, string $field): GroupCollectorInterface @@ -297,8 +309,8 @@ trait TimeCollection } /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function metaMonthIsNot(string $month, string $field): GroupCollectorInterface @@ -319,8 +331,8 @@ trait TimeCollection } /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function metaYearAfter(string $year, string $field): GroupCollectorInterface @@ -342,8 +354,8 @@ trait TimeCollection } /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function metaYearBefore(string $year, string $field): GroupCollectorInterface @@ -365,8 +377,8 @@ trait TimeCollection } /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function metaYearIs(string $year, string $field): GroupCollectorInterface @@ -388,8 +400,8 @@ trait TimeCollection } /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function metaYearIsNot(string $year, string $field): GroupCollectorInterface @@ -410,7 +422,7 @@ trait TimeCollection } /** - * @param string $month + * @param string $month * @return GroupCollectorInterface */ public function monthAfter(string $month): GroupCollectorInterface @@ -420,7 +432,7 @@ trait TimeCollection } /** - * @param string $month + * @param string $month * @return GroupCollectorInterface */ public function monthBefore(string $month): GroupCollectorInterface @@ -430,7 +442,7 @@ trait TimeCollection } /** - * @param string $month + * @param string $month * @return GroupCollectorInterface */ public function monthIs(string $month): GroupCollectorInterface @@ -440,7 +452,7 @@ trait TimeCollection } /** - * @param string $month + * @param string $month * @return GroupCollectorInterface */ public function monthIsNot(string $month): GroupCollectorInterface @@ -450,8 +462,8 @@ trait TimeCollection } /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function objectDayAfter(string $day, string $field): GroupCollectorInterface @@ -461,8 +473,8 @@ trait TimeCollection } /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function objectDayBefore(string $day, string $field): GroupCollectorInterface @@ -472,8 +484,8 @@ trait TimeCollection } /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function objectDayIs(string $day, string $field): GroupCollectorInterface @@ -483,8 +495,8 @@ trait TimeCollection } /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function objectDayIsNot(string $day, string $field): GroupCollectorInterface @@ -494,8 +506,8 @@ trait TimeCollection } /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function objectMonthAfter(string $month, string $field): GroupCollectorInterface @@ -505,8 +517,8 @@ trait TimeCollection } /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function objectMonthBefore(string $month, string $field): GroupCollectorInterface @@ -516,8 +528,8 @@ trait TimeCollection } /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function objectMonthIs(string $month, string $field): GroupCollectorInterface @@ -527,8 +539,8 @@ trait TimeCollection } /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function objectMonthIsNot(string $month, string $field): GroupCollectorInterface @@ -538,8 +550,8 @@ trait TimeCollection } /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function objectYearAfter(string $year, string $field): GroupCollectorInterface @@ -549,8 +561,8 @@ trait TimeCollection } /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function objectYearBefore(string $year, string $field): GroupCollectorInterface @@ -560,8 +572,8 @@ trait TimeCollection } /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function objectYearIs(string $year, string $field): GroupCollectorInterface @@ -571,8 +583,8 @@ trait TimeCollection } /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function objectYearIsNot(string $year, string $field): GroupCollectorInterface @@ -584,7 +596,7 @@ trait TimeCollection /** * Collect transactions after a specific date. * - * @param Carbon $date + * @param Carbon $date * * @return GroupCollectorInterface */ @@ -599,7 +611,7 @@ trait TimeCollection /** * Collect transactions before a specific date. * - * @param Carbon $date + * @param Carbon $date * * @return GroupCollectorInterface */ @@ -614,7 +626,7 @@ trait TimeCollection /** * Collect transactions created on a specific date. * - * @param Carbon $date + * @param Carbon $date * * @return GroupCollectorInterface */ @@ -629,8 +641,8 @@ trait TimeCollection } /** - * @param Carbon $date - * @param string $field + * @param Carbon $date + * @param string $field * @return GroupCollectorInterface */ public function setMetaAfter(Carbon $date, string $field): GroupCollectorInterface @@ -653,8 +665,8 @@ trait TimeCollection } /** - * @param Carbon $date - * @param string $field + * @param Carbon $date + * @param string $field * @return GroupCollectorInterface */ public function setMetaBefore(Carbon $date, string $field): GroupCollectorInterface @@ -676,9 +688,9 @@ trait TimeCollection } /** - * @param Carbon $start - * @param Carbon $end - * @param string $field + * @param Carbon $start + * @param Carbon $end + * @param string $field * @return GroupCollectorInterface */ public function setMetaDateRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface @@ -706,8 +718,8 @@ trait TimeCollection } /** - * @param Carbon $date - * @param string $field + * @param Carbon $date + * @param string $field * @return GroupCollectorInterface */ public function setObjectAfter(Carbon $date, string $field): GroupCollectorInterface @@ -719,8 +731,8 @@ trait TimeCollection } /** - * @param Carbon $date - * @param string $field + * @param Carbon $date + * @param string $field * @return GroupCollectorInterface */ public function setObjectBefore(Carbon $date, string $field): GroupCollectorInterface @@ -731,9 +743,9 @@ trait TimeCollection } /** - * @param Carbon $start - * @param Carbon $end - * @param string $field + * @param Carbon $start + * @param Carbon $end + * @param string $field * @return GroupCollectorInterface */ public function setObjectRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface @@ -749,8 +761,8 @@ trait TimeCollection /** * Set the start and end time of the results to return. * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return GroupCollectorInterface */ @@ -772,7 +784,7 @@ trait TimeCollection /** * Collect transactions updated on a specific date. * - * @param Carbon $date + * @param Carbon $date * * @return GroupCollectorInterface */ @@ -787,19 +799,7 @@ trait TimeCollection } /** - * @inheritDoc - */ - public function withMetaDate(string $field): GroupCollectorInterface - { - $this->joinMetaDataTables(); - $this->query->where('journal_meta.name', '=', $field); - $this->query->whereNotNull('journal_meta.data'); - - return $this; - } - - /** - * @param string $year + * @param string $year * @return GroupCollectorInterface */ public function yearAfter(string $year): GroupCollectorInterface @@ -809,7 +809,7 @@ trait TimeCollection } /** - * @param string $year + * @param string $year * @return GroupCollectorInterface */ public function yearBefore(string $year): GroupCollectorInterface @@ -819,7 +819,7 @@ trait TimeCollection } /** - * @param string $year + * @param string $year * @return GroupCollectorInterface */ public function yearIs(string $year): GroupCollectorInterface @@ -829,7 +829,7 @@ trait TimeCollection } /** - * @param string $year + * @param string $year * @return GroupCollectorInterface */ public function yearIsNot(string $year): GroupCollectorInterface diff --git a/app/Helpers/Collector/GroupCollector.php b/app/Helpers/Collector/GroupCollector.php index 7de73cb64d..1e81ec92ae 100644 --- a/app/Helpers/Collector/GroupCollector.php +++ b/app/Helpers/Collector/GroupCollector.php @@ -316,7 +316,7 @@ class GroupCollector implements GroupCollectorInterface /** * Limit results to NOT a specific currency, either foreign or normal one. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return GroupCollectorInterface */ @@ -353,7 +353,7 @@ class GroupCollector implements GroupCollectorInterface /** * Limit the result to NOT a set of specific transaction groups. * - * @param array $groupIds + * @param array $groupIds * * @return GroupCollectorInterface */ @@ -367,7 +367,7 @@ class GroupCollector implements GroupCollectorInterface /** * Limit the result to NOT a set of specific journals. * - * @param array $journalIds + * @param array $journalIds * * @return GroupCollectorInterface */ @@ -387,7 +387,7 @@ class GroupCollector implements GroupCollectorInterface /** * Search for words in descriptions. * - * @param array $array + * @param array $array * * @return GroupCollectorInterface */ @@ -505,313 +505,7 @@ class GroupCollector implements GroupCollectorInterface } /** - * Same as getGroups but everything is in a paginator. - * - * @return LengthAwarePaginator - */ - public function getPaginatedGroups(): LengthAwarePaginator - { - $set = $this->getGroups(); - if (0 === $this->limit) { - $this->setLimit(50); - } - - return new LengthAwarePaginator($set, $this->total, $this->limit, $this->page); - } - - /** - * @inheritDoc - */ - public function isNotReconciled(): GroupCollectorInterface - { - $this->query->where('source.reconciled', 0)->where('destination.reconciled', 0); - return $this; - } - - /** - * @inheritDoc - */ - public function isReconciled(): GroupCollectorInterface - { - $this->query->where('source.reconciled', 1)->where('destination.reconciled', 1); - return $this; - } - - /** - * Limit results to a specific currency, either foreign or normal one. - * - * @param TransactionCurrency $currency - * - * @return GroupCollectorInterface - */ - public function setCurrency(TransactionCurrency $currency): GroupCollectorInterface - { - $this->query->where( - static function (EloquentBuilder $q) use ($currency) { - $q->where('source.transaction_currency_id', $currency->id); - $q->orWhere('source.foreign_currency_id', $currency->id); - } - ); - - return $this; - } - - /** - * @inheritDoc - */ - public function setForeignCurrency(TransactionCurrency $currency): GroupCollectorInterface - { - $this->query->where('source.foreign_currency_id', $currency->id); - - return $this; - } - - /** - * Limit the result to a set of specific transaction groups. - * - * @param array $groupIds - * - * @return GroupCollectorInterface - */ - public function setIds(array $groupIds): GroupCollectorInterface - { - $this->query->whereIn('transaction_groups.id', $groupIds); - - return $this; - } - - /** - * Limit the result to a set of specific journals. - * - * @param array $journalIds - * - * @return GroupCollectorInterface - */ - public function setJournalIds(array $journalIds): GroupCollectorInterface - { - if (0 !== count($journalIds)) { - // make all integers. - $integerIDs = array_map('intval', $journalIds); - - - $this->query->whereIn('transaction_journals.id', $integerIDs); - } - - return $this; - } - - /** - * Limit the number of returned entries. - * - * @param int $limit - * - * @return GroupCollectorInterface - */ - public function setLimit(int $limit): GroupCollectorInterface - { - $this->limit = $limit; - app('log')->debug(sprintf('GroupCollector: The limit is now %d', $limit)); - - return $this; - } - - /** - * Set the page to get. - * - * @param int $page - * - * @return GroupCollectorInterface - */ - public function setPage(int $page): GroupCollectorInterface - { - $page = 0 === $page ? 1 : $page; - $this->page = $page; - app('log')->debug(sprintf('GroupCollector: page is now %d', $page)); - - return $this; - } - - /** - * Search for words in descriptions. - * - * @param array $array - * - * @return GroupCollectorInterface - */ - public function setSearchWords(array $array): GroupCollectorInterface - { - if (0 === count($array)) { - return $this; - } - $this->query->where( - static function (EloquentBuilder $q) use ($array) { - $q->where( - static function (EloquentBuilder $q1) use ($array) { - foreach ($array as $word) { - $keyword = sprintf('%%%s%%', $word); - $q1->where('transaction_journals.description', 'LIKE', $keyword); - } - } - ); - $q->orWhere( - static function (EloquentBuilder $q2) use ($array) { - foreach ($array as $word) { - $keyword = sprintf('%%%s%%', $word); - $q2->where('transaction_groups.title', 'LIKE', $keyword); - } - } - ); - } - ); - - return $this; - } - - /** - * Limit the search to one specific transaction group. - * - * @param TransactionGroup $transactionGroup - * - * @return GroupCollectorInterface - */ - public function setTransactionGroup(TransactionGroup $transactionGroup): GroupCollectorInterface - { - $this->query->where('transaction_groups.id', $transactionGroup->id); - - return $this; - } - - /** - * Limit the included transaction types. - * - * @param array $types - * - * @return GroupCollectorInterface - */ - public function setTypes(array $types): GroupCollectorInterface - { - $this->query->whereIn('transaction_types.type', $types); - - return $this; - } - - /** - * Set the user object and start the query. - * - * @param User $user - * - * @return GroupCollectorInterface - */ - public function setUser(User $user): GroupCollectorInterface - { - if (null === $this->user) { - $this->user = $user; - $this->startQuery(); - } - - return $this; - } - - /** - * Automatically include all stuff required to make API calls work. - * - * @return GroupCollectorInterface - */ - public function withAPIInformation(): GroupCollectorInterface - { - // include source + destination account name and type. - $this->withAccountInformation() - // include category ID + name (if any) - ->withCategoryInformation() - // include budget ID + name (if any) - ->withBudgetInformation() - // include bill ID + name (if any) - ->withBillInformation(); - - return $this; - } - - /** - * Convert a selected set of fields to arrays. - * - * @param array $array - * - * @return array - */ - private function convertToInteger(array $array): array - { - foreach ($this->integerFields as $field) { - $array[$field] = array_key_exists($field, $array) ? (int)$array[$field] : null; - } - - return $array; - } - - /** - * @param array $array - * @return array - */ - private function convertToStrings(array $array): array - { - foreach ($this->stringFields as $field) { - $array[$field] = array_key_exists($field, $array) && null !== $array[$field] ? (string)$array[$field] : null; - } - - return $array; - } - - /** - * @param array $existingJournal - * @param TransactionJournal $newJournal - * - * @return array - */ - private function mergeAttachments(array $existingJournal, TransactionJournal $newJournal): array - { - $newArray = $newJournal->toArray(); - if (array_key_exists('attachment_id', $newArray)) { - $attachmentId = (int)$newJournal['attachment_id']; - - $existingJournal['attachments'][$attachmentId] = [ - 'id' => $attachmentId, - ]; - } - - return $existingJournal; - } - - /** - * @param array $existingJournal - * @param TransactionJournal $newJournal - * - * @return array - */ - private function mergeTags(array $existingJournal, TransactionJournal $newJournal): array - { - $newArray = $newJournal->toArray(); - if (array_key_exists('tag_id', $newArray)) { // assume the other fields are present as well. - $tagId = (int)$newJournal['tag_id']; - - $tagDate = null; - try { - $tagDate = Carbon::parse($newArray['tag_date']); - } catch (InvalidFormatException $e) { - Log::debug(sprintf('Could not parse date: %s', $e->getMessage())); - } - - $existingJournal['tags'][$tagId] = [ - 'id' => (int)$newArray['tag_id'], - 'name' => $newArray['tag_name'], - 'date' => $tagDate, - 'description' => $newArray['tag_description'], - ]; - } - - return $existingJournal; - } - - /** - * @param Collection $collection + * @param Collection $collection * * @return Collection * @throws FireflyException @@ -864,7 +558,7 @@ class GroupCollector implements GroupCollectorInterface } /** - * @param TransactionJournal $augumentedJournal + * @param TransactionJournal $augumentedJournal * * @return array * @throws FireflyException @@ -952,14 +646,93 @@ class GroupCollector implements GroupCollectorInterface } /** - * @param array $groups + * Convert a selected set of fields to arrays. + * + * @param array $array + * + * @return array + */ + private function convertToInteger(array $array): array + { + foreach ($this->integerFields as $field) { + $array[$field] = array_key_exists($field, $array) ? (int)$array[$field] : null; + } + + return $array; + } + + /** + * @param array $array + * @return array + */ + private function convertToStrings(array $array): array + { + foreach ($this->stringFields as $field) { + $array[$field] = array_key_exists($field, $array) && null !== $array[$field] ? (string)$array[$field] : null; + } + + return $array; + } + + /** + * @param array $existingJournal + * @param TransactionJournal $newJournal + * + * @return array + */ + private function mergeTags(array $existingJournal, TransactionJournal $newJournal): array + { + $newArray = $newJournal->toArray(); + if (array_key_exists('tag_id', $newArray)) { // assume the other fields are present as well. + $tagId = (int)$newJournal['tag_id']; + + $tagDate = null; + try { + $tagDate = Carbon::parse($newArray['tag_date']); + } catch (InvalidFormatException $e) { + Log::debug(sprintf('Could not parse date: %s', $e->getMessage())); + } + + $existingJournal['tags'][$tagId] = [ + 'id' => (int)$newArray['tag_id'], + 'name' => $newArray['tag_name'], + 'date' => $tagDate, + 'description' => $newArray['tag_description'], + ]; + } + + return $existingJournal; + } + + /** + * @param array $existingJournal + * @param TransactionJournal $newJournal + * + * @return array + */ + private function mergeAttachments(array $existingJournal, TransactionJournal $newJournal): array + { + $newArray = $newJournal->toArray(); + if (array_key_exists('attachment_id', $newArray)) { + $attachmentId = (int)$newJournal['attachment_id']; + + $existingJournal['attachments'][$attachmentId] = [ + 'id' => $attachmentId, + ]; + } + + return $existingJournal; + } + + /** + * @param array $groups * * @return array */ private function parseSums(array $groups): array { /** - * @var int $groudId + * @var int $groudId * @var array $group */ foreach ($groups as $groudId => $group) { @@ -997,7 +770,7 @@ class GroupCollector implements GroupCollectorInterface } /** - * @param Collection $collection + * @param Collection $collection * @return Collection */ private function postFilterCollection(Collection $collection): Collection @@ -1012,7 +785,7 @@ class GroupCollector implements GroupCollectorInterface // and save it (or not) in the new collection. // that new collection is the next current collection /** - * @var int $ii + * @var int $ii * @var array $item */ foreach ($currentCollection as $ii => $item) { @@ -1028,6 +801,214 @@ class GroupCollector implements GroupCollectorInterface return $currentCollection; } + /** + * Same as getGroups but everything is in a paginator. + * + * @return LengthAwarePaginator + */ + public function getPaginatedGroups(): LengthAwarePaginator + { + $set = $this->getGroups(); + if (0 === $this->limit) { + $this->setLimit(50); + } + + return new LengthAwarePaginator($set, $this->total, $this->limit, $this->page); + } + + /** + * Limit the number of returned entries. + * + * @param int $limit + * + * @return GroupCollectorInterface + */ + public function setLimit(int $limit): GroupCollectorInterface + { + $this->limit = $limit; + app('log')->debug(sprintf('GroupCollector: The limit is now %d', $limit)); + + return $this; + } + + /** + * @inheritDoc + */ + public function isNotReconciled(): GroupCollectorInterface + { + $this->query->where('source.reconciled', 0)->where('destination.reconciled', 0); + return $this; + } + + /** + * @inheritDoc + */ + public function isReconciled(): GroupCollectorInterface + { + $this->query->where('source.reconciled', 1)->where('destination.reconciled', 1); + return $this; + } + + /** + * Limit results to a specific currency, either foreign or normal one. + * + * @param TransactionCurrency $currency + * + * @return GroupCollectorInterface + */ + public function setCurrency(TransactionCurrency $currency): GroupCollectorInterface + { + $this->query->where( + static function (EloquentBuilder $q) use ($currency) { + $q->where('source.transaction_currency_id', $currency->id); + $q->orWhere('source.foreign_currency_id', $currency->id); + } + ); + + return $this; + } + + /** + * @inheritDoc + */ + public function setForeignCurrency(TransactionCurrency $currency): GroupCollectorInterface + { + $this->query->where('source.foreign_currency_id', $currency->id); + + return $this; + } + + /** + * Limit the result to a set of specific transaction groups. + * + * @param array $groupIds + * + * @return GroupCollectorInterface + */ + public function setIds(array $groupIds): GroupCollectorInterface + { + $this->query->whereIn('transaction_groups.id', $groupIds); + + return $this; + } + + /** + * Limit the result to a set of specific journals. + * + * @param array $journalIds + * + * @return GroupCollectorInterface + */ + public function setJournalIds(array $journalIds): GroupCollectorInterface + { + if (0 !== count($journalIds)) { + // make all integers. + $integerIDs = array_map('intval', $journalIds); + + + $this->query->whereIn('transaction_journals.id', $integerIDs); + } + + return $this; + } + + /** + * Set the page to get. + * + * @param int $page + * + * @return GroupCollectorInterface + */ + public function setPage(int $page): GroupCollectorInterface + { + $page = 0 === $page ? 1 : $page; + $this->page = $page; + app('log')->debug(sprintf('GroupCollector: page is now %d', $page)); + + return $this; + } + + /** + * Search for words in descriptions. + * + * @param array $array + * + * @return GroupCollectorInterface + */ + public function setSearchWords(array $array): GroupCollectorInterface + { + if (0 === count($array)) { + return $this; + } + $this->query->where( + static function (EloquentBuilder $q) use ($array) { + $q->where( + static function (EloquentBuilder $q1) use ($array) { + foreach ($array as $word) { + $keyword = sprintf('%%%s%%', $word); + $q1->where('transaction_journals.description', 'LIKE', $keyword); + } + } + ); + $q->orWhere( + static function (EloquentBuilder $q2) use ($array) { + foreach ($array as $word) { + $keyword = sprintf('%%%s%%', $word); + $q2->where('transaction_groups.title', 'LIKE', $keyword); + } + } + ); + } + ); + + return $this; + } + + /** + * Limit the search to one specific transaction group. + * + * @param TransactionGroup $transactionGroup + * + * @return GroupCollectorInterface + */ + public function setTransactionGroup(TransactionGroup $transactionGroup): GroupCollectorInterface + { + $this->query->where('transaction_groups.id', $transactionGroup->id); + + return $this; + } + + /** + * Limit the included transaction types. + * + * @param array $types + * + * @return GroupCollectorInterface + */ + public function setTypes(array $types): GroupCollectorInterface + { + $this->query->whereIn('transaction_types.type', $types); + + return $this; + } + + /** + * Set the user object and start the query. + * + * @param User $user + * + * @return GroupCollectorInterface + */ + public function setUser(User $user): GroupCollectorInterface + { + if (null === $this->user) { + $this->user = $user; + $this->startQuery(); + } + + return $this; + } + /** * Build the query. */ @@ -1070,4 +1051,23 @@ class GroupCollector implements GroupCollectorInterface ->orderBy('transaction_journals.description', 'DESC') ->orderBy('source.amount', 'DESC'); } + + /** + * Automatically include all stuff required to make API calls work. + * + * @return GroupCollectorInterface + */ + public function withAPIInformation(): GroupCollectorInterface + { + // include source + destination account name and type. + $this->withAccountInformation() + // include category ID + name (if any) + ->withCategoryInformation() + // include budget ID + name (if any) + ->withBudgetInformation() + // include bill ID + name (if any) + ->withBillInformation(); + + return $this; + } } diff --git a/app/Helpers/Collector/GroupCollectorInterface.php b/app/Helpers/Collector/GroupCollectorInterface.php index e8409de225..cafaa7e0c7 100644 --- a/app/Helpers/Collector/GroupCollectorInterface.php +++ b/app/Helpers/Collector/GroupCollectorInterface.php @@ -42,14 +42,14 @@ interface GroupCollectorInterface /** * Get transactions with a specific amount. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ public function amountIs(string $amount): GroupCollectorInterface; /** - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ @@ -58,7 +58,7 @@ interface GroupCollectorInterface /** * Get transactions where the amount is less than. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ @@ -67,128 +67,128 @@ interface GroupCollectorInterface /** * Get transactions where the foreign amount is more than. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ public function amountMore(string $amount): GroupCollectorInterface; /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameContains(string $name): GroupCollectorInterface; /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameDoesNotContain(string $name): GroupCollectorInterface; /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameDoesNotEnd(string $name): GroupCollectorInterface; /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameDoesNotStart(string $name): GroupCollectorInterface; /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameEnds(string $name): GroupCollectorInterface; /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameIs(string $name): GroupCollectorInterface; /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameIsNot(string $name): GroupCollectorInterface; /** - * @param string $name + * @param string $name * @return GroupCollectorInterface */ public function attachmentNameStarts(string $name): GroupCollectorInterface; /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesAre(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesAreNot(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesContains(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesDoNotContain(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesDoNotEnd(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesDoNotStart(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesEnds(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function attachmentNotesStarts(string $value): GroupCollectorInterface; /** - * @param string $day + * @param string $day * @return GroupCollectorInterface */ public function dayAfter(string $day): GroupCollectorInterface; /** - * @param string $day + * @param string $day * @return GroupCollectorInterface */ public function dayBefore(string $day): GroupCollectorInterface; /** - * @param string $day + * @param string $day * @return GroupCollectorInterface */ public function dayIs(string $day): GroupCollectorInterface; /** - * @param string $day + * @param string $day * @return GroupCollectorInterface */ public function dayIsNot(string $day): GroupCollectorInterface; @@ -196,7 +196,7 @@ interface GroupCollectorInterface /** * End of the description must not match: * - * @param array $array + * @param array $array * * @return GroupCollectorInterface */ @@ -205,7 +205,7 @@ interface GroupCollectorInterface /** * Beginning of the description must not start with: * - * @param array $array + * @param array $array * * @return GroupCollectorInterface */ @@ -214,7 +214,7 @@ interface GroupCollectorInterface /** * End of the description must match: * - * @param array $array + * @param array $array * * @return GroupCollectorInterface */ @@ -223,7 +223,7 @@ interface GroupCollectorInterface /** * Description must be: * - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ @@ -232,7 +232,7 @@ interface GroupCollectorInterface /** * Description must not be: * - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ @@ -241,7 +241,7 @@ interface GroupCollectorInterface /** * Beginning of the description must match: * - * @param array $array + * @param array $array * * @return GroupCollectorInterface */ @@ -250,7 +250,7 @@ interface GroupCollectorInterface /** * These accounts must not be accounts. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -259,7 +259,7 @@ interface GroupCollectorInterface /** * Exclude a specific set of bills * - * @param Collection $bills + * @param Collection $bills * * @return GroupCollectorInterface */ @@ -268,7 +268,7 @@ interface GroupCollectorInterface /** * Exclude a budget * - * @param Budget $budget + * @param Budget $budget * * @return GroupCollectorInterface */ @@ -277,7 +277,7 @@ interface GroupCollectorInterface /** * Exclude a budget. * - * @param Collection $budgets + * @param Collection $budgets * * @return GroupCollectorInterface */ @@ -286,7 +286,7 @@ interface GroupCollectorInterface /** * Exclude a set of categories. * - * @param Collection $categories + * @param Collection $categories * @return GroupCollectorInterface */ public function excludeCategories(Collection $categories): GroupCollectorInterface; @@ -294,7 +294,7 @@ interface GroupCollectorInterface /** * Exclude a specific category * - * @param Category $category + * @param Category $category * * @return GroupCollectorInterface */ @@ -303,7 +303,7 @@ interface GroupCollectorInterface /** * Limit results to NOT a specific currency, either foreign or normal one. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return GroupCollectorInterface */ @@ -312,7 +312,7 @@ interface GroupCollectorInterface /** * Exclude destination accounts. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -321,14 +321,14 @@ interface GroupCollectorInterface /** * Look for specific external ID's. * - * @param string $externalId + * @param string $externalId * * @return GroupCollectorInterface */ public function excludeExternalId(string $externalId): GroupCollectorInterface; /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function excludeExternalUrl(string $url): GroupCollectorInterface; @@ -336,7 +336,7 @@ interface GroupCollectorInterface /** * Limit results to exclude a specific foreign currency. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return GroupCollectorInterface */ @@ -345,7 +345,7 @@ interface GroupCollectorInterface /** * Limit the result to NOT a set of specific transaction groups. * - * @param array $groupIds + * @param array $groupIds * * @return GroupCollectorInterface */ @@ -354,7 +354,7 @@ interface GroupCollectorInterface /** * Look for specific external ID's. * - * @param string $externalId + * @param string $externalId * * @return GroupCollectorInterface */ @@ -363,37 +363,37 @@ interface GroupCollectorInterface /** * Limit the result to NOT a set of specific transaction journals. * - * @param array $journalIds + * @param array $journalIds * * @return GroupCollectorInterface */ public function excludeJournalIds(array $journalIds): GroupCollectorInterface; /** - * @param Carbon $start - * @param Carbon $end - * @param string $field + * @param Carbon $start + * @param Carbon $end + * @param string $field * @return GroupCollectorInterface */ public function excludeMetaDateRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface; /** - * @param Carbon $start - * @param Carbon $end - * @param string $field + * @param Carbon $start + * @param Carbon $end + * @param string $field * @return GroupCollectorInterface */ public function excludeObjectRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface; /** - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * @return GroupCollectorInterface */ public function excludeRange(Carbon $start, Carbon $end): GroupCollectorInterface; /** - * @param string $recurringId + * @param string $recurringId * * @return GroupCollectorInterface */ @@ -402,7 +402,7 @@ interface GroupCollectorInterface /** * Exclude words in descriptions. * - * @param array $array + * @param array $array * * @return GroupCollectorInterface */ @@ -411,7 +411,7 @@ interface GroupCollectorInterface /** * These accounts must not be source accounts. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -420,7 +420,7 @@ interface GroupCollectorInterface /** * Limit the included transaction types. * - * @param array $types + * @param array $types * * @return GroupCollectorInterface */ @@ -432,73 +432,73 @@ interface GroupCollectorInterface public function exists(): GroupCollectorInterface; /** - * @param string $externalId + * @param string $externalId * @return GroupCollectorInterface */ public function externalIdContains(string $externalId): GroupCollectorInterface; /** - * @param string $externalId + * @param string $externalId * @return GroupCollectorInterface */ public function externalIdDoesNotContain(string $externalId): GroupCollectorInterface; /** - * @param string $externalId + * @param string $externalId * @return GroupCollectorInterface */ public function externalIdDoesNotEnd(string $externalId): GroupCollectorInterface; /** - * @param string $externalId + * @param string $externalId * @return GroupCollectorInterface */ public function externalIdDoesNotStart(string $externalId): GroupCollectorInterface; /** - * @param string $externalId + * @param string $externalId * @return GroupCollectorInterface */ public function externalIdEnds(string $externalId): GroupCollectorInterface; /** - * @param string $externalId + * @param string $externalId * @return GroupCollectorInterface */ public function externalIdStarts(string $externalId): GroupCollectorInterface; /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function externalUrlContains(string $url): GroupCollectorInterface; /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function externalUrlDoesNotContain(string $url): GroupCollectorInterface; /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function externalUrlDoesNotEnd(string $url): GroupCollectorInterface; /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function externalUrlDoesNotStart(string $url): GroupCollectorInterface; /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function externalUrlEnds(string $url): GroupCollectorInterface; /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function externalUrlStarts(string $url): GroupCollectorInterface; @@ -513,7 +513,7 @@ interface GroupCollectorInterface /** * Get transactions with a specific foreign amount. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ @@ -522,7 +522,7 @@ interface GroupCollectorInterface /** * Get transactions with a specific foreign amount. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ @@ -531,7 +531,7 @@ interface GroupCollectorInterface /** * Get transactions where the amount is less than. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ @@ -540,7 +540,7 @@ interface GroupCollectorInterface /** * Get transactions where the foreign amount is more than. * - * @param string $amount + * @param string $amount * * @return GroupCollectorInterface */ @@ -587,37 +587,37 @@ interface GroupCollectorInterface public function hasNoAttachments(): GroupCollectorInterface; /** - * @param string $externalId + * @param string $externalId * @return GroupCollectorInterface */ public function internalReferenceContains(string $externalId): GroupCollectorInterface; /** - * @param string $externalId + * @param string $externalId * @return GroupCollectorInterface */ public function internalReferenceDoesNotContain(string $externalId): GroupCollectorInterface; /** - * @param string $externalId + * @param string $externalId * @return GroupCollectorInterface */ public function internalReferenceDoesNotEnd(string $externalId): GroupCollectorInterface; /** - * @param string $externalId + * @param string $externalId * @return GroupCollectorInterface */ public function internalReferenceDoesNotStart(string $externalId): GroupCollectorInterface; /** - * @param string $externalId + * @param string $externalId * @return GroupCollectorInterface */ public function internalReferenceEnds(string $externalId): GroupCollectorInterface; /** - * @param string $externalId + * @param string $externalId * @return GroupCollectorInterface */ public function internalReferenceStarts(string $externalId): GroupCollectorInterface; @@ -637,248 +637,248 @@ interface GroupCollectorInterface public function isReconciled(): GroupCollectorInterface; /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function metaDayAfter(string $day, string $field): GroupCollectorInterface; /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function metaDayBefore(string $day, string $field): GroupCollectorInterface; /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function metaDayIs(string $day, string $field): GroupCollectorInterface; /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function metaDayIsNot(string $day, string $field): GroupCollectorInterface; /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function metaMonthAfter(string $month, string $field): GroupCollectorInterface; /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function metaMonthBefore(string $month, string $field): GroupCollectorInterface; /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function metaMonthIs(string $month, string $field): GroupCollectorInterface; /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function metaMonthIsNot(string $month, string $field): GroupCollectorInterface; /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function metaYearAfter(string $year, string $field): GroupCollectorInterface; /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function metaYearBefore(string $year, string $field): GroupCollectorInterface; /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function metaYearIs(string $year, string $field): GroupCollectorInterface; /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function metaYearIsNot(string $year, string $field): GroupCollectorInterface; /** - * @param string $month + * @param string $month * @return GroupCollectorInterface */ public function monthAfter(string $month): GroupCollectorInterface; /** - * @param string $month + * @param string $month * @return GroupCollectorInterface */ public function monthBefore(string $month): GroupCollectorInterface; /** - * @param string $month + * @param string $month * @return GroupCollectorInterface */ public function monthIs(string $month): GroupCollectorInterface; /** - * @param string $month + * @param string $month * @return GroupCollectorInterface */ public function monthIsNot(string $month): GroupCollectorInterface; /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ public function notesContain(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ public function notesDoNotContain(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ public function notesDontEndWith(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * @return GroupCollectorInterface */ public function notesDontStartWith(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ public function notesEndWith(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ public function notesExactly(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ public function notesExactlyNot(string $value): GroupCollectorInterface; /** - * @param string $value + * @param string $value * * @return GroupCollectorInterface */ public function notesStartWith(string $value): GroupCollectorInterface; /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function objectDayAfter(string $day, string $field): GroupCollectorInterface; /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function objectDayBefore(string $day, string $field): GroupCollectorInterface; /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function objectDayIs(string $day, string $field): GroupCollectorInterface; /** - * @param string $day - * @param string $field + * @param string $day + * @param string $field * @return GroupCollectorInterface */ public function objectDayIsNot(string $day, string $field): GroupCollectorInterface; /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function objectMonthAfter(string $month, string $field): GroupCollectorInterface; /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function objectMonthBefore(string $month, string $field): GroupCollectorInterface; /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function objectMonthIs(string $month, string $field): GroupCollectorInterface; /** - * @param string $month - * @param string $field + * @param string $month + * @param string $field * @return GroupCollectorInterface */ public function objectMonthIsNot(string $month, string $field): GroupCollectorInterface; /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function objectYearAfter(string $year, string $field): GroupCollectorInterface; /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function objectYearBefore(string $year, string $field): GroupCollectorInterface; /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function objectYearIs(string $year, string $field): GroupCollectorInterface; /** - * @param string $year - * @param string $field + * @param string $year + * @param string $field * @return GroupCollectorInterface */ public function objectYearIsNot(string $year, string $field): GroupCollectorInterface; @@ -886,7 +886,7 @@ interface GroupCollectorInterface /** * Define which accounts can be part of the source and destination transactions. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -895,7 +895,7 @@ interface GroupCollectorInterface /** * Collect transactions after a specific date. * - * @param Carbon $date + * @param Carbon $date * * @return GroupCollectorInterface */ @@ -904,7 +904,7 @@ interface GroupCollectorInterface /** * Collect transactions before a specific date. * - * @param Carbon $date + * @param Carbon $date * * @return GroupCollectorInterface */ @@ -913,7 +913,7 @@ interface GroupCollectorInterface /** * Limit the search to a specific bill. * - * @param Bill $bill + * @param Bill $bill * * @return GroupCollectorInterface */ @@ -922,7 +922,7 @@ interface GroupCollectorInterface /** * Limit the search to a specific set of bills. * - * @param Collection $bills + * @param Collection $bills * * @return GroupCollectorInterface */ @@ -931,7 +931,7 @@ interface GroupCollectorInterface /** * Both source AND destination must be in this list of accounts. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -940,7 +940,7 @@ interface GroupCollectorInterface /** * Limit the search to a specific budget. * - * @param Budget $budget + * @param Budget $budget * * @return GroupCollectorInterface */ @@ -949,7 +949,7 @@ interface GroupCollectorInterface /** * Limit the search to a specific set of budgets. * - * @param Collection $budgets + * @param Collection $budgets * * @return GroupCollectorInterface */ @@ -958,7 +958,7 @@ interface GroupCollectorInterface /** * Limit the search to a specific bunch of categories. * - * @param Collection $categories + * @param Collection $categories * * @return GroupCollectorInterface */ @@ -967,7 +967,7 @@ interface GroupCollectorInterface /** * Limit the search to a specific category. * - * @param Category $category + * @param Category $category * * @return GroupCollectorInterface */ @@ -976,7 +976,7 @@ interface GroupCollectorInterface /** * Collect transactions created on a specific date. * - * @param Carbon $date + * @param Carbon $date * * @return GroupCollectorInterface */ @@ -985,7 +985,7 @@ interface GroupCollectorInterface /** * Limit results to a specific currency, either foreign or normal one. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return GroupCollectorInterface */ @@ -994,7 +994,7 @@ interface GroupCollectorInterface /** * Set destination accounts. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -1003,14 +1003,14 @@ interface GroupCollectorInterface /** * Look for specific external ID's. * - * @param string $externalId + * @param string $externalId * * @return GroupCollectorInterface */ public function setExternalId(string $externalId): GroupCollectorInterface; /** - * @param string $url + * @param string $url * @return GroupCollectorInterface */ public function setExternalUrl(string $url): GroupCollectorInterface; @@ -1018,7 +1018,7 @@ interface GroupCollectorInterface /** * Limit results to a specific foreign currency. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return GroupCollectorInterface */ @@ -1027,7 +1027,7 @@ interface GroupCollectorInterface /** * Limit the result to a set of specific transaction groups. * - * @param array $groupIds + * @param array $groupIds * * @return GroupCollectorInterface */ @@ -1036,7 +1036,7 @@ interface GroupCollectorInterface /** * Look for specific external ID's. * - * @param string $externalId + * @param string $externalId * * @return GroupCollectorInterface */ @@ -1045,7 +1045,7 @@ interface GroupCollectorInterface /** * Limit the result to a set of specific transaction journals. * - * @param array $journalIds + * @param array $journalIds * * @return GroupCollectorInterface */ @@ -1054,7 +1054,7 @@ interface GroupCollectorInterface /** * Limit the number of returned entries. * - * @param int $limit + * @param int $limit * * @return GroupCollectorInterface */ @@ -1063,8 +1063,8 @@ interface GroupCollectorInterface /** * Collect transactions after a specific date. * - * @param Carbon $date - * @param string $field + * @param Carbon $date + * @param string $field * @return GroupCollectorInterface */ public function setMetaAfter(Carbon $date, string $field): GroupCollectorInterface; @@ -1072,8 +1072,8 @@ interface GroupCollectorInterface /** * Collect transactions before a specific date. * - * @param Carbon $date - * @param string $field + * @param Carbon $date + * @param string $field * @return GroupCollectorInterface */ public function setMetaBefore(Carbon $date, string $field): GroupCollectorInterface; @@ -1081,9 +1081,9 @@ interface GroupCollectorInterface /** * Set the start and end time of the results to return, based on meta data. * - * @param Carbon $start - * @param Carbon $end - * @param string $field + * @param Carbon $start + * @param Carbon $end + * @param string $field * * @return GroupCollectorInterface */ @@ -1092,30 +1092,30 @@ interface GroupCollectorInterface /** * Define which accounts can NOT be part of the source and destination transactions. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ public function setNotAccounts(Collection $accounts): GroupCollectorInterface; /** - * @param Carbon $date - * @param string $field + * @param Carbon $date + * @param string $field * @return GroupCollectorInterface */ public function setObjectAfter(Carbon $date, string $field): GroupCollectorInterface; /** - * @param Carbon $date - * @param string $field + * @param Carbon $date + * @param string $field * @return GroupCollectorInterface */ public function setObjectBefore(Carbon $date, string $field): GroupCollectorInterface; /** - * @param Carbon $start - * @param Carbon $end - * @param string $field + * @param Carbon $start + * @param Carbon $end + * @param string $field * @return GroupCollectorInterface */ public function setObjectRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface; @@ -1123,7 +1123,7 @@ interface GroupCollectorInterface /** * Set the page to get. * - * @param int $page + * @param int $page * * @return GroupCollectorInterface */ @@ -1132,8 +1132,8 @@ interface GroupCollectorInterface /** * Set the start and end time of the results to return. * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return GroupCollectorInterface */ @@ -1142,7 +1142,7 @@ interface GroupCollectorInterface /** * Look for specific recurring ID's. * - * @param string $recurringId + * @param string $recurringId * * @return GroupCollectorInterface */ @@ -1151,14 +1151,14 @@ interface GroupCollectorInterface /** * Search for words in descriptions. * - * @param array $array + * @param array $array * * @return GroupCollectorInterface */ public function setSearchWords(array $array): GroupCollectorInterface; /** - * @param string $sepaCT + * @param string $sepaCT * @return GroupCollectorInterface */ public function setSepaCT(string $sepaCT): GroupCollectorInterface; @@ -1166,7 +1166,7 @@ interface GroupCollectorInterface /** * Set source accounts. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -1175,7 +1175,7 @@ interface GroupCollectorInterface /** * Limit results to a specific tag. * - * @param Tag $tag + * @param Tag $tag * * @return GroupCollectorInterface */ @@ -1184,7 +1184,7 @@ interface GroupCollectorInterface /** * Limit results to a specific set of tags. * - * @param Collection $tags + * @param Collection $tags * * @return GroupCollectorInterface */ @@ -1193,7 +1193,7 @@ interface GroupCollectorInterface /** * Limit the search to one specific transaction group. * - * @param TransactionGroup $transactionGroup + * @param TransactionGroup $transactionGroup * * @return GroupCollectorInterface */ @@ -1202,7 +1202,7 @@ interface GroupCollectorInterface /** * Limit the included transaction types. * - * @param array $types + * @param array $types * * @return GroupCollectorInterface */ @@ -1211,7 +1211,7 @@ interface GroupCollectorInterface /** * Collect transactions updated on a specific date. * - * @param Carbon $date + * @param Carbon $date * * @return GroupCollectorInterface */ @@ -1220,7 +1220,7 @@ interface GroupCollectorInterface /** * Set the user object and start the query. * - * @param User $user + * @param User $user * * @return GroupCollectorInterface */ @@ -1229,7 +1229,7 @@ interface GroupCollectorInterface /** * Only when does not have these tags * - * @param Collection $tags + * @param Collection $tags * * @return GroupCollectorInterface */ @@ -1238,7 +1238,7 @@ interface GroupCollectorInterface /** * Either account can be set, but NOT both. This effectively excludes internal transfers. * - * @param Collection $accounts + * @param Collection $accounts * * @return GroupCollectorInterface */ @@ -1331,7 +1331,7 @@ interface GroupCollectorInterface /** * Transaction must have meta date field X. * - * @param string $field + * @param string $field * @return GroupCollectorInterface */ public function withMetaDate(string $field): GroupCollectorInterface; @@ -1396,25 +1396,25 @@ interface GroupCollectorInterface public function withoutTags(): GroupCollectorInterface; /** - * @param string $year + * @param string $year * @return GroupCollectorInterface */ public function yearAfter(string $year): GroupCollectorInterface; /** - * @param string $year + * @param string $year * @return GroupCollectorInterface */ public function yearBefore(string $year): GroupCollectorInterface; /** - * @param string $year + * @param string $year * @return GroupCollectorInterface */ public function yearIs(string $year): GroupCollectorInterface; /** - * @param string $year + * @param string $year * @return GroupCollectorInterface */ public function yearIsNot(string $year): GroupCollectorInterface; diff --git a/app/Helpers/Fiscal/FiscalHelper.php b/app/Helpers/Fiscal/FiscalHelper.php index f2dcf4d0f1..3d88481c41 100644 --- a/app/Helpers/Fiscal/FiscalHelper.php +++ b/app/Helpers/Fiscal/FiscalHelper.php @@ -45,7 +45,7 @@ class FiscalHelper implements FiscalHelperInterface } /** - * @param Carbon $date + * @param Carbon $date * * @return Carbon date object * @throws FireflyException @@ -70,7 +70,7 @@ class FiscalHelper implements FiscalHelperInterface } /** - * @param Carbon $date + * @param Carbon $date * * @return Carbon date object * @throws ContainerExceptionInterface diff --git a/app/Helpers/Fiscal/FiscalHelperInterface.php b/app/Helpers/Fiscal/FiscalHelperInterface.php index 559f2fe672..957c6c36dd 100644 --- a/app/Helpers/Fiscal/FiscalHelperInterface.php +++ b/app/Helpers/Fiscal/FiscalHelperInterface.php @@ -34,7 +34,7 @@ interface FiscalHelperInterface * This method produces a clone of the Carbon date object passed, checks preferences * and calculates the last day of the fiscal year. * - * @param Carbon $date + * @param Carbon $date * * @return Carbon date object */ @@ -44,7 +44,7 @@ interface FiscalHelperInterface * This method produces a clone of the Carbon date object passed, checks preferences * and calculates the first day of the fiscal year. * - * @param Carbon $date + * @param Carbon $date * * @return Carbon date object */ diff --git a/app/Helpers/Report/NetWorth.php b/app/Helpers/Report/NetWorth.php index 4379213c56..149e62f882 100644 --- a/app/Helpers/Report/NetWorth.php +++ b/app/Helpers/Report/NetWorth.php @@ -57,8 +57,8 @@ class NetWorth implements NetWorthInterface * This repeats for each currency the user has transactions in. * Result of this method is cached. * - * @param Collection $accounts - * @param Carbon $date + * @param Collection $accounts + * @param Carbon $date * * @return array * @throws JsonException @@ -129,9 +129,9 @@ class NetWorth implements NetWorthInterface } /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void + public function setUser(User | Authenticatable | null $user): void { if (null === $user) { return; diff --git a/app/Helpers/Report/NetWorthInterface.php b/app/Helpers/Report/NetWorthInterface.php index e1d3e0c447..e1c9cc3ce8 100644 --- a/app/Helpers/Report/NetWorthInterface.php +++ b/app/Helpers/Report/NetWorthInterface.php @@ -47,24 +47,24 @@ interface NetWorthInterface * This repeats for each currency the user has transactions in. * Result of this method is cached. * - * @param Collection $accounts - * @param Carbon $date + * @param Collection $accounts + * @param Carbon $date * @return array * @deprecated */ public function getNetWorthByCurrency(Collection $accounts, Carbon $date): array; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** * TODO move to repository * * Same as above but cleaner function with less dependencies. * - * @param Carbon $date + * @param Carbon $date * * @return array */ diff --git a/app/Helpers/Report/PopupReport.php b/app/Helpers/Report/PopupReport.php index 430d7b1740..94b56ac7fd 100644 --- a/app/Helpers/Report/PopupReport.php +++ b/app/Helpers/Report/PopupReport.php @@ -43,9 +43,9 @@ class PopupReport implements PopupReportInterface /** * Collect the transactions for one account and one budget. * - * @param Budget $budget - * @param Account $account - * @param array $attributes + * @param Budget $budget + * @param Account $account + * @param array $attributes * * @return array */ @@ -65,8 +65,8 @@ class PopupReport implements PopupReportInterface /** * Collect the transactions for one account and no budget. * - * @param Account $account - * @param array $attributes + * @param Account $account + * @param array $attributes * * @return array */ @@ -100,8 +100,8 @@ class PopupReport implements PopupReportInterface /** * Collect the transactions for a budget. * - * @param Budget $budget - * @param array $attributes + * @param Budget $budget + * @param array $attributes * * @return array */ @@ -140,8 +140,8 @@ class PopupReport implements PopupReportInterface /** * Collect journals by a category. * - * @param Category|null $category - * @param array $attributes + * @param Category|null $category + * @param array $attributes * * @return array */ @@ -183,8 +183,8 @@ class PopupReport implements PopupReportInterface /** * Group transactions by expense. * - * @param Account $account - * @param array $attributes + * @param Account $account + * @param array $attributes * * @return array */ @@ -229,8 +229,8 @@ class PopupReport implements PopupReportInterface /** * Collect transactions by income. * - * @param Account $account - * @param array $attributes + * @param Account $account + * @param array $attributes * * @return array */ diff --git a/app/Helpers/Report/PopupReportInterface.php b/app/Helpers/Report/PopupReportInterface.php index 2b5c4b821a..311dfa8501 100644 --- a/app/Helpers/Report/PopupReportInterface.php +++ b/app/Helpers/Report/PopupReportInterface.php @@ -35,9 +35,9 @@ interface PopupReportInterface /** * Get balances for budget. * - * @param Budget $budget - * @param Account $account - * @param array $attributes + * @param Budget $budget + * @param Account $account + * @param array $attributes * * @return array */ @@ -46,8 +46,8 @@ interface PopupReportInterface /** * Get balances for transactions without a budget. * - * @param Account $account - * @param array $attributes + * @param Account $account + * @param array $attributes * * @return array */ @@ -56,8 +56,8 @@ interface PopupReportInterface /** * Group by budget. * - * @param Budget $budget - * @param array $attributes + * @param Budget $budget + * @param array $attributes * * @return array */ @@ -66,8 +66,8 @@ interface PopupReportInterface /** * Group by category. * - * @param Category|null $category - * @param array $attributes + * @param Category|null $category + * @param array $attributes * * @return array */ @@ -76,8 +76,8 @@ interface PopupReportInterface /** * Do something with expense. Sorry, I am not very inspirational here. * - * @param Account $account - * @param array $attributes + * @param Account $account + * @param array $attributes * * @return array */ @@ -86,8 +86,8 @@ interface PopupReportInterface /** * Do something with income. Sorry, I am not very inspirational here. * - * @param Account $account - * @param array $attributes + * @param Account $account + * @param array $attributes * * @return array */ diff --git a/app/Helpers/Report/ReportHelper.php b/app/Helpers/Report/ReportHelper.php index 0d3107f121..92a9841d74 100644 --- a/app/Helpers/Report/ReportHelper.php +++ b/app/Helpers/Report/ReportHelper.php @@ -44,7 +44,7 @@ class ReportHelper implements ReportHelperInterface /** * ReportHelper constructor. * - * @param BudgetRepositoryInterface $budgetRepository + * @param BudgetRepositoryInterface $budgetRepository */ public function __construct(BudgetRepositoryInterface $budgetRepository) { @@ -57,9 +57,9 @@ class ReportHelper implements ReportHelperInterface * * Excludes bills which have not had a payment on the mentioned accounts. * - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts * * @return array */ @@ -113,7 +113,7 @@ class ReportHelper implements ReportHelperInterface /** * Generate a list of months for the report. * - * @param Carbon $date + * @param Carbon $date * * @return array */ diff --git a/app/Helpers/Report/ReportHelperInterface.php b/app/Helpers/Report/ReportHelperInterface.php index f5eb876bf3..6dfceaac77 100644 --- a/app/Helpers/Report/ReportHelperInterface.php +++ b/app/Helpers/Report/ReportHelperInterface.php @@ -37,9 +37,9 @@ interface ReportHelperInterface * * Excludes bills which have not had a payment on the mentioned accounts. * - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts * * @return array */ @@ -48,7 +48,7 @@ interface ReportHelperInterface /** * Generate a list of months. * - * @param Carbon $date + * @param Carbon $date * * @return array */ diff --git a/app/Helpers/Webhook/SignatureGeneratorInterface.php b/app/Helpers/Webhook/SignatureGeneratorInterface.php index 806a2d4942..ebbc8a5278 100644 --- a/app/Helpers/Webhook/SignatureGeneratorInterface.php +++ b/app/Helpers/Webhook/SignatureGeneratorInterface.php @@ -31,7 +31,7 @@ use FireflyIII\Models\WebhookMessage; interface SignatureGeneratorInterface { /** - * @param WebhookMessage $message + * @param WebhookMessage $message * * @return string */ diff --git a/app/Http/Controllers/Account/CreateController.php b/app/Http/Controllers/Account/CreateController.php index 02a8792e29..ff88e40f5b 100644 --- a/app/Http/Controllers/Account/CreateController.php +++ b/app/Http/Controllers/Account/CreateController.php @@ -76,8 +76,8 @@ class CreateController extends Controller /** * Create a new account. * - * @param Request $request - * @param string $objectType + * @param Request $request + * @param string $objectType * * @return Factory|View */ @@ -134,7 +134,7 @@ class CreateController extends Controller /** * Store the new account. * - * @param AccountFormRequest $request + * @param AccountFormRequest $request * * @return RedirectResponse|Redirector * @throws FireflyException diff --git a/app/Http/Controllers/Account/DeleteController.php b/app/Http/Controllers/Account/DeleteController.php index ea72eba0c8..a830ec9eb5 100644 --- a/app/Http/Controllers/Account/DeleteController.php +++ b/app/Http/Controllers/Account/DeleteController.php @@ -65,7 +65,7 @@ class DeleteController extends Controller /** * Delete account screen. * - * @param Account $account + * @param Account $account * * @return Factory|RedirectResponse|Redirector|View */ @@ -90,8 +90,8 @@ class DeleteController extends Controller /** * Delete the account. * - * @param Request $request - * @param Account $account + * @param Request $request + * @param Account $account * * @return RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/Account/EditController.php b/app/Http/Controllers/Account/EditController.php index bf98f2b733..292c00ec8c 100644 --- a/app/Http/Controllers/Account/EditController.php +++ b/app/Http/Controllers/Account/EditController.php @@ -70,9 +70,9 @@ class EditController extends Controller /** * Edit account overview. * - * @param Request $request - * @param Account $account - * @param AccountRepositoryInterface $repository + * @param Request $request + * @param Account $account + * @param AccountRepositoryInterface $repository * * @return Factory|RedirectResponse|Redirector|View */ @@ -178,8 +178,8 @@ class EditController extends Controller /** * Update the account. * - * @param AccountFormRequest $request - * @param Account $account + * @param AccountFormRequest $request + * @param Account $account * * @return $this|RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/Account/IndexController.php b/app/Http/Controllers/Account/IndexController.php index 9d7cbe5320..3a6915cb8a 100644 --- a/app/Http/Controllers/Account/IndexController.php +++ b/app/Http/Controllers/Account/IndexController.php @@ -71,8 +71,8 @@ class IndexController extends Controller } /** - * @param Request $request - * @param string $objectType + * @param Request $request + * @param string $objectType * * @return Factory|View * @throws FireflyException @@ -127,8 +127,8 @@ class IndexController extends Controller /** * Show list of accounts. * - * @param Request $request - * @param string $objectType + * @param Request $request + * @param string $objectType * * @return Factory|View * @throws FireflyException diff --git a/app/Http/Controllers/Account/ReconcileController.php b/app/Http/Controllers/Account/ReconcileController.php index c2980ac665..7dfbdf1596 100644 --- a/app/Http/Controllers/Account/ReconcileController.php +++ b/app/Http/Controllers/Account/ReconcileController.php @@ -77,9 +77,9 @@ class ReconcileController extends Controller /** * Reconciliation overview. * - * @param Account $account - * @param Carbon|null $start - * @param Carbon|null $end + * @param Account $account + * @param Carbon|null $start + * @param Carbon|null $end * * @return Factory|RedirectResponse|Redirector|View * @throws FireflyException @@ -154,10 +154,10 @@ class ReconcileController extends Controller /** * Submit a new reconciliation. * - * @param ReconciliationStoreRequest $request - * @param Account $account - * @param Carbon $start - * @param Carbon $end + * @param ReconciliationStoreRequest $request + * @param Account $account + * @param Carbon $start + * @param Carbon $end * * @return RedirectResponse|Redirector * @throws DuplicateTransactionException @@ -202,10 +202,10 @@ class ReconcileController extends Controller /** * Creates a reconciliation group. * - * @param Account $account - * @param Carbon $start - * @param Carbon $end - * @param string $difference + * @param Account $account + * @param Carbon $start + * @param Carbon $end + * @param string $difference * * @return RedirectResponse|Redirector|string * @throws DuplicateTransactionException diff --git a/app/Http/Controllers/Account/ShowController.php b/app/Http/Controllers/Account/ShowController.php index f51028f9e7..7a1b28cb8f 100644 --- a/app/Http/Controllers/Account/ShowController.php +++ b/app/Http/Controllers/Account/ShowController.php @@ -77,10 +77,10 @@ class ShowController extends Controller /** * Show an account. * - * @param Request $request - * @param Account $account - * @param Carbon|null $start - * @param Carbon|null $end + * @param Request $request + * @param Account $account + * @param Carbon|null $start + * @param Carbon|null $end * * @return RedirectResponse|Redirector|Factory|View * @throws FireflyException @@ -162,8 +162,8 @@ class ShowController extends Controller /** * Show an account. * - * @param Request $request - * @param Account $account + * @param Request $request + * @param Account $account * * @return RedirectResponse|Redirector|Factory|View * @throws FireflyException @@ -183,7 +183,7 @@ class ShowController extends Controller $end = today(config('app.timezone')); $today = today(config('app.timezone')); $start = $this->repository->oldestJournalDate($account) ?? today(config('app.timezone'))->startOfMonth(); - $subTitleIcon = config('firefly.subIconsByIdentifier.'.$account->accountType->type); + $subTitleIcon = config('firefly.subIconsByIdentifier.' . $account->accountType->type); $page = (int)$request->get('page'); $pageSize = (int)app('preferences')->get('listPageSize', 50)->data; $currency = $this->repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency(); diff --git a/app/Http/Controllers/Admin/ConfigurationController.php b/app/Http/Controllers/Admin/ConfigurationController.php index 35b8287f09..c1cad3b239 100644 --- a/app/Http/Controllers/Admin/ConfigurationController.php +++ b/app/Http/Controllers/Admin/ConfigurationController.php @@ -89,7 +89,7 @@ class ConfigurationController extends Controller /** * Store new configuration values. * - * @param ConfigurationRequest $request + * @param ConfigurationRequest $request * * @return RedirectResponse */ diff --git a/app/Http/Controllers/Admin/HomeController.php b/app/Http/Controllers/Admin/HomeController.php index 751dc3b4ab..73fea12c8e 100644 --- a/app/Http/Controllers/Admin/HomeController.php +++ b/app/Http/Controllers/Admin/HomeController.php @@ -107,7 +107,7 @@ class HomeController extends Controller /** * Send a test message to the admin. * - * @param Request $request + * @param Request $request * * @return RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/Admin/LinkController.php b/app/Http/Controllers/Admin/LinkController.php index a1f52b1b47..38b60a53d8 100644 --- a/app/Http/Controllers/Admin/LinkController.php +++ b/app/Http/Controllers/Admin/LinkController.php @@ -86,8 +86,8 @@ class LinkController extends Controller /** * Delete a link form. * - * @param Request $request - * @param LinkType $linkType + * @param Request $request + * @param LinkType $linkType * * @return Factory|RedirectResponse|Redirector|View */ @@ -122,8 +122,8 @@ class LinkController extends Controller /** * Actually destroy the link. * - * @param Request $request - * @param LinkType $linkType + * @param Request $request + * @param LinkType $linkType * * @return RedirectResponse|Redirector */ @@ -143,8 +143,8 @@ class LinkController extends Controller /** * Edit a link form. * - * @param Request $request - * @param LinkType $linkType + * @param Request $request + * @param LinkType $linkType * * @return Factory|RedirectResponse|Redirector|View */ @@ -193,7 +193,7 @@ class LinkController extends Controller /** * Show a single link. * - * @param LinkType $linkType + * @param LinkType $linkType * * @return Factory|View */ @@ -211,7 +211,7 @@ class LinkController extends Controller /** * Store the new link. * - * @param LinkTypeFormRequest $request + * @param LinkTypeFormRequest $request * * @return $this|RedirectResponse|Redirector */ @@ -242,8 +242,8 @@ class LinkController extends Controller /** * Update an existing link. * - * @param LinkTypeFormRequest $request - * @param LinkType $linkType + * @param LinkTypeFormRequest $request + * @param LinkType $linkType * * @return $this|RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/Admin/UpdateController.php b/app/Http/Controllers/Admin/UpdateController.php index 2a24c22b59..6222135aad 100644 --- a/app/Http/Controllers/Admin/UpdateController.php +++ b/app/Http/Controllers/Admin/UpdateController.php @@ -91,7 +91,7 @@ class UpdateController extends Controller /** * Post new settings. * - * @param Request $request + * @param Request $request * * @return RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 03db618d89..06faaca447 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -70,7 +70,7 @@ class UserController extends Controller } /** - * @param User $user + * @param User $user * * @return Application|Factory|RedirectResponse|Redirector|View */ @@ -88,7 +88,7 @@ class UserController extends Controller } /** - * @param InvitedUser $invitedUser + * @param InvitedUser $invitedUser * @return RedirectResponse */ public function deleteInvite(InvitedUser $invitedUser): JsonResponse @@ -108,7 +108,7 @@ class UserController extends Controller /** * Destroy a user. * - * @param User $user + * @param User $user * * @return RedirectResponse|Redirector */ @@ -128,7 +128,7 @@ class UserController extends Controller /** * Edit user form. * - * @param User $user + * @param User $user * * @return Factory|View */ @@ -191,7 +191,7 @@ class UserController extends Controller } /** - * @param InviteUserFormRequest $request + * @param InviteUserFormRequest $request * @return RedirectResponse */ public function invite(InviteUserFormRequest $request): RedirectResponse @@ -209,7 +209,7 @@ class UserController extends Controller /** * Show single user. * - * @param User $user + * @param User $user * * @return Factory|View */ @@ -237,8 +237,8 @@ class UserController extends Controller /** * Update single user. * - * @param UserFormRequest $request - * @param User $user + * @param UserFormRequest $request + * @param User $user * * @return $this|RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/AttachmentController.php b/app/Http/Controllers/AttachmentController.php index 33d78335e8..6f45458f30 100644 --- a/app/Http/Controllers/AttachmentController.php +++ b/app/Http/Controllers/AttachmentController.php @@ -68,7 +68,7 @@ class AttachmentController extends Controller /** * Form to delete an attachment. * - * @param Attachment $attachment + * @param Attachment $attachment * * @return Factory|View */ @@ -85,8 +85,8 @@ class AttachmentController extends Controller /** * Destroy attachment. * - * @param Request $request - * @param Attachment $attachment + * @param Request $request + * @param Attachment $attachment * * @return RedirectResponse|Redirector */ @@ -105,7 +105,7 @@ class AttachmentController extends Controller /** * Download attachment to PC. * - * @param Attachment $attachment + * @param Attachment $attachment * * @return LaravelResponse * @@ -122,7 +122,7 @@ class AttachmentController extends Controller $response ->header('Content-Description', 'File Transfer') ->header('Content-Type', 'application/octet-stream') - ->header('Content-Disposition', 'attachment; filename='.$quoted) + ->header('Content-Disposition', 'attachment; filename=' . $quoted) ->header('Content-Transfer-Encoding', 'binary') ->header('Connection', 'Keep-Alive') ->header('Expires', '0') @@ -138,8 +138,8 @@ class AttachmentController extends Controller /** * Edit an attachment. * - * @param Request $request - * @param Attachment $attachment + * @param Request $request + * @param Attachment $attachment * * @return Factory|View */ @@ -183,8 +183,8 @@ class AttachmentController extends Controller /** * Update attachment. * - * @param AttachmentFormRequest $request - * @param Attachment $attachment + * @param AttachmentFormRequest $request + * @param Attachment $attachment * * @return RedirectResponse */ @@ -210,8 +210,8 @@ class AttachmentController extends Controller /** * View attachment in browser. * - * @param Request $request - * @param Attachment $attachment + * @param Request $request + * @param Attachment $attachment * * @return LaravelResponse * @throws FireflyException @@ -241,7 +241,7 @@ class AttachmentController extends Controller [ 'Content-Security-Policy' => implode('; ', $csp), 'Content-Type' => $attachment->mime, - 'Content-Disposition' => 'inline; filename="'.$attachment->filename.'"', + 'Content-Disposition' => 'inline; filename="' . $attachment->filename . '"', ] ); } diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php index 4fe1637e73..2dd3028ef2 100644 --- a/app/Http/Controllers/Auth/ForgotPasswordController.php +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -61,8 +61,8 @@ class ForgotPasswordController extends Controller /** * Send a reset link to the given user. * - * @param Request $request - * @param UserRepositoryInterface $repository + * @param Request $request + * @param UserRepositoryInterface $repository * * @return Factory|RedirectResponse|View */ diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index f49ba24642..dbaf4cfbd6 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -128,10 +128,41 @@ class LoginController extends Controller $this->sendFailedLoginResponse($request); } + /** + * Get the login username to be used by the controller. + * + * @return string + */ + public function username() + { + return $this->username; + } + + /** + * Get the failed login response instance. + * + * @param Request $request + * + * @return void + * + * @throws ValidationException + */ + protected function sendFailedLoginResponse(Request $request) + { + $exception = ValidationException::withMessages( + [ + $this->username() => [trans('auth.failed')], + ] + ); + $exception->redirectTo = route('login'); + + throw $exception; + } + /** * Log the user out of the application. * - * @param Request $request + * @param Request $request * * @return RedirectResponse|Redirector|Response */ @@ -168,7 +199,7 @@ class LoginController extends Controller /** * Show the application's login form. * - * @param Request $request + * @param Request $request * * @return Factory|Application|View|Redirector|RedirectResponse * @throws FireflyException @@ -213,35 +244,4 @@ class LoginController extends Controller return view('auth.login', compact('allowRegistration', 'email', 'remember', 'allowReset', 'title', 'usernameField')); } - - /** - * Get the login username to be used by the controller. - * - * @return string - */ - public function username() - { - return $this->username; - } - - /** - * Get the failed login response instance. - * - * @param Request $request - * - * @return void - * - * @throws ValidationException - */ - protected function sendFailedLoginResponse(Request $request) - { - $exception = ValidationException::withMessages( - [ - $this->username() => [trans('auth.failed')], - ] - ); - $exception->redirectTo = route('login'); - - throw $exception; - } } diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index d4e6acf323..331ecc66bc 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -78,7 +78,7 @@ class RegisterController extends Controller /** * Handle a registration request for the application. * - * @param Request $request + * @param Request $request * * @return Application|Redirector|RedirectResponse * @throws FireflyException @@ -114,6 +114,30 @@ class RegisterController extends Controller return redirect($this->redirectPath()); } + /** + * @return bool + * @throws FireflyException + */ + protected function allowedToRegister(): bool + { + // is allowed to register? + $allowRegistration = true; + try { + $singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data; + } catch (ContainerExceptionInterface | NotFoundExceptionInterface $e) { + $singleUserMode = true; + } + $userCount = User::count(); + $guard = config('auth.defaults.guard'); + if (true === $singleUserMode && $userCount > 0 && 'web' === $guard) { + $allowRegistration = false; + } + if ('web' !== $guard) { + $allowRegistration = false; + } + return $allowRegistration; + } + /** * Show the application registration form if the invitation code is valid. * @@ -151,7 +175,7 @@ class RegisterController extends Controller /** * Show the application registration form. * - * @param Request $request + * @param Request $request * * @return Factory|View * @throws ContainerExceptionInterface @@ -174,28 +198,4 @@ class RegisterController extends Controller return view('auth.register', compact('isDemoSite', 'email', 'pageTitle')); } - - /** - * @return bool - * @throws FireflyException - */ - protected function allowedToRegister(): bool - { - // is allowed to register? - $allowRegistration = true; - try { - $singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data; - } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) { - $singleUserMode = true; - } - $userCount = User::count(); - $guard = config('auth.defaults.guard'); - if (true === $singleUserMode && $userCount > 0 && 'web' === $guard) { - $allowRegistration = false; - } - if ('web' !== $guard) { - $allowRegistration = false; - } - return $allowRegistration; - } } diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php index 1b84607bb4..5d477d1f7e 100644 --- a/app/Http/Controllers/Auth/ResetPasswordController.php +++ b/app/Http/Controllers/Auth/ResetPasswordController.php @@ -73,7 +73,7 @@ class ResetPasswordController extends Controller /** * Reset the given user's password. * - * @param Request $request + * @param Request $request * * @return Factory|JsonResponse|RedirectResponse|View * @throws ValidationException @@ -117,8 +117,8 @@ class ResetPasswordController extends Controller * * If no token is present, display the link request form. * - * @param Request $request - * @param null $token + * @param Request $request + * @param null $token * * @return Factory|View * @throws FireflyException diff --git a/app/Http/Controllers/Auth/TwoFactorController.php b/app/Http/Controllers/Auth/TwoFactorController.php index b55cca871d..7bd4eabc5b 100644 --- a/app/Http/Controllers/Auth/TwoFactorController.php +++ b/app/Http/Controllers/Auth/TwoFactorController.php @@ -54,7 +54,7 @@ class TwoFactorController extends Controller } /** - * @param Request $request + * @param Request $request * * @return RedirectResponse|Redirector */ @@ -99,20 +99,26 @@ class TwoFactorController extends Controller } /** - * @param string $mfaCode + * Each MFA history has a timestamp and a code, saving the MFA entries for 5 minutes. So if the + * submitted MFA code has been submitted in the last 5 minutes, it won't work despite being valid. + * + * @param string $mfaCode + * @param array $mfaHistory + * + * @return bool */ - private function addToMFAHistory(string $mfaCode): void + private function inMFAHistory(string $mfaCode, array $mfaHistory): bool { - /** @var array $mfaHistory */ - $mfaHistory = Preferences::get('mfa_history', [])->data; - $entry = [ - 'time' => time(), - 'code' => $mfaCode, - ]; - $mfaHistory[] = $entry; + $now = time(); + foreach ($mfaHistory as $entry) { + $time = $entry['time']; + $code = $entry['code']; + if ($code === $mfaCode && $now - $time <= 300) { + return true; + } + } - Preferences::set('mfa_history', $mfaHistory); - $this->filterMFAHistory(); + return false; } /** @@ -138,32 +144,26 @@ class TwoFactorController extends Controller } /** - * Each MFA history has a timestamp and a code, saving the MFA entries for 5 minutes. So if the - * submitted MFA code has been submitted in the last 5 minutes, it won't work despite being valid. - * - * @param string $mfaCode - * @param array $mfaHistory - * - * @return bool + * @param string $mfaCode */ - private function inMFAHistory(string $mfaCode, array $mfaHistory): bool + private function addToMFAHistory(string $mfaCode): void { - $now = time(); - foreach ($mfaHistory as $entry) { - $time = $entry['time']; - $code = $entry['code']; - if ($code === $mfaCode && $now - $time <= 300) { - return true; - } - } + /** @var array $mfaHistory */ + $mfaHistory = Preferences::get('mfa_history', [])->data; + $entry = [ + 'time' => time(), + 'code' => $mfaCode, + ]; + $mfaHistory[] = $entry; - return false; + Preferences::set('mfa_history', $mfaHistory); + $this->filterMFAHistory(); } /** * Checks if code is in users backup codes. * - * @param string $mfaCode + * @param string $mfaCode * * @return bool */ @@ -180,7 +180,7 @@ class TwoFactorController extends Controller /** * Remove the used code from the list of backup codes. * - * @param string $mfaCode + * @param string $mfaCode */ private function removeFromBackupCodes(string $mfaCode): void { diff --git a/app/Http/Controllers/Bill/CreateController.php b/app/Http/Controllers/Bill/CreateController.php index 6504dce7ac..8dfdde0f48 100644 --- a/app/Http/Controllers/Bill/CreateController.php +++ b/app/Http/Controllers/Bill/CreateController.php @@ -67,7 +67,7 @@ class CreateController extends Controller /** * Create a new bill. * - * @param Request $request + * @param Request $request * * @return Factory|View */ @@ -77,7 +77,7 @@ class CreateController extends Controller /** @var array $billPeriods */ $billPeriods = config('firefly.bill_periods'); foreach ($billPeriods as $current) { - $periods[$current] = (string)trans('firefly.repeat_freq_'.$current); + $periods[$current] = (string)trans('firefly.repeat_freq_' . $current); } $subTitle = (string)trans('firefly.create_new_bill'); $defaultCurrency = app('amount')->getDefaultCurrency(); @@ -94,7 +94,7 @@ class CreateController extends Controller /** * Store a new bill. * - * @param BillStoreRequest $request + * @param BillStoreRequest $request * * @return RedirectResponse * diff --git a/app/Http/Controllers/Bill/DeleteController.php b/app/Http/Controllers/Bill/DeleteController.php index 97e1bb433f..3499e40176 100644 --- a/app/Http/Controllers/Bill/DeleteController.php +++ b/app/Http/Controllers/Bill/DeleteController.php @@ -65,7 +65,7 @@ class DeleteController extends Controller /** * Delete a bill. * - * @param Bill $bill + * @param Bill $bill * * @return Factory|View */ @@ -81,8 +81,8 @@ class DeleteController extends Controller /** * Destroy a bill. * - * @param Request $request - * @param Bill $bill + * @param Request $request + * @param Bill $bill * * @return RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/Bill/EditController.php b/app/Http/Controllers/Bill/EditController.php index c909db419a..f3f9e935cb 100644 --- a/app/Http/Controllers/Bill/EditController.php +++ b/app/Http/Controllers/Bill/EditController.php @@ -66,8 +66,8 @@ class EditController extends Controller /** * Edit a bill. * - * @param Request $request - * @param Bill $bill + * @param Request $request + * @param Bill $bill * * @return Factory|View */ @@ -78,7 +78,7 @@ class EditController extends Controller $billPeriods = config('firefly.bill_periods'); foreach ($billPeriods as $current) { - $periods[$current] = (string)trans('firefly.'.$current); + $periods[$current] = (string)trans('firefly.' . $current); } $subTitle = (string)trans('firefly.edit_bill', ['name' => $bill->name]); @@ -115,8 +115,8 @@ class EditController extends Controller /** * Update a bill. * - * @param BillUpdateRequest $request - * @param Bill $bill + * @param BillUpdateRequest $request + * @param Bill $bill * * @return RedirectResponse */ diff --git a/app/Http/Controllers/Bill/IndexController.php b/app/Http/Controllers/Bill/IndexController.php index 41702e41b6..6ee7bad3b8 100644 --- a/app/Http/Controllers/Bill/IndexController.php +++ b/app/Http/Controllers/Bill/IndexController.php @@ -135,77 +135,7 @@ class IndexController extends Controller } /** - * Set the order of a bill. - * - * @param Request $request - * @param Bill $bill - * - * @return JsonResponse - */ - public function setOrder(Request $request, Bill $bill): JsonResponse - { - $objectGroupTitle = (string)$request->get('objectGroupTitle'); - $newOrder = (int)$request->get('order'); - $this->repository->setOrder($bill, $newOrder); - if ('' !== $objectGroupTitle) { - $this->repository->setObjectGroup($bill, $objectGroupTitle); - } - if ('' === $objectGroupTitle) { - $this->repository->removeObjectGroup($bill); - } - - return response()->json(['data' => 'OK']); - } - - /** - * @param array $bill - * @param string $range - * - * @return string - */ - private function amountPerPeriod(array $bill, string $range): string - { - $avg = bcdiv(bcadd((string)$bill['amount_min'], (string)$bill['amount_max']), '2'); - - Log::debug(sprintf('Amount per period for bill #%d "%s"', $bill['id'], $bill['name'])); - Log::debug(sprintf('Average is %s', $avg)); - // calculate amount per year: - $multiplies = [ - 'yearly' => '1', - 'half-year' => '2', - 'quarterly' => '4', - 'monthly' => '12', - 'weekly' => '52.17', - 'daily' => '365.24', - ]; - $yearAmount = bcmul($avg, bcdiv($multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1))); - Log::debug(sprintf('Amount per year is %s (%s * %s / %s)', $yearAmount, $avg, $multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1))); - - // per period: - $division = [ - '1Y' => '1', - '6M' => '2', - '3M' => '4', - '1M' => '12', - '1W' => '52.16', - '1D' => '365.24', - 'YTD' => '1', - 'QTD' => '4', - 'MTD' => '12', - 'last7' => '52.16', - 'last30' => '12', - 'last90' => '4', - 'last365' => '1', - ]; - $perPeriod = bcdiv($yearAmount, $division[$range]); - - Log::debug(sprintf('Amount per %s is %s (%s / %s)', $range, $perPeriod, $yearAmount, $division[$range])); - - return $perPeriod; - } - - /** - * @param array $bills + * @param array $bills * * @return array * @throws FireflyException @@ -251,7 +181,54 @@ class IndexController extends Controller } /** - * @param array $sums + * @param array $bill + * @param string $range + * + * @return string + */ + private function amountPerPeriod(array $bill, string $range): string + { + $avg = bcdiv(bcadd((string)$bill['amount_min'], (string)$bill['amount_max']), '2'); + + Log::debug(sprintf('Amount per period for bill #%d "%s"', $bill['id'], $bill['name'])); + Log::debug(sprintf('Average is %s', $avg)); + // calculate amount per year: + $multiplies = [ + 'yearly' => '1', + 'half-year' => '2', + 'quarterly' => '4', + 'monthly' => '12', + 'weekly' => '52.17', + 'daily' => '365.24', + ]; + $yearAmount = bcmul($avg, bcdiv($multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1))); + Log::debug(sprintf('Amount per year is %s (%s * %s / %s)', $yearAmount, $avg, $multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1))); + + // per period: + $division = [ + '1Y' => '1', + '6M' => '2', + '3M' => '4', + '1M' => '12', + '1W' => '52.16', + '1D' => '365.24', + 'YTD' => '1', + 'QTD' => '4', + 'MTD' => '12', + 'last7' => '52.16', + 'last30' => '12', + 'last90' => '4', + 'last365' => '1', + ]; + $perPeriod = bcdiv($yearAmount, $division[$range]); + + Log::debug(sprintf('Amount per %s is %s (%s / %s)', $range, $perPeriod, $yearAmount, $division[$range])); + + return $perPeriod; + } + + /** + * @param array $sums * * @return array */ @@ -266,7 +243,7 @@ class IndexController extends Controller */ foreach ($sums as $array) { /** - * @var int $currencyId + * @var int $currencyId * @var array $entry */ foreach ($array as $currencyId => $entry) { @@ -287,4 +264,27 @@ class IndexController extends Controller return $totals; } + + /** + * Set the order of a bill. + * + * @param Request $request + * @param Bill $bill + * + * @return JsonResponse + */ + public function setOrder(Request $request, Bill $bill): JsonResponse + { + $objectGroupTitle = (string)$request->get('objectGroupTitle'); + $newOrder = (int)$request->get('order'); + $this->repository->setOrder($bill, $newOrder); + if ('' !== $objectGroupTitle) { + $this->repository->setObjectGroup($bill, $objectGroupTitle); + } + if ('' === $objectGroupTitle) { + $this->repository->removeObjectGroup($bill); + } + + return response()->json(['data' => 'OK']); + } } diff --git a/app/Http/Controllers/Bill/ShowController.php b/app/Http/Controllers/Bill/ShowController.php index 87180560a6..3813448d31 100644 --- a/app/Http/Controllers/Bill/ShowController.php +++ b/app/Http/Controllers/Bill/ShowController.php @@ -77,8 +77,8 @@ class ShowController extends Controller /** * Rescan bills for transactions. * - * @param Request $request - * @param Bill $bill + * @param Request $request + * @param Bill $bill * * @return RedirectResponse|Redirector */ @@ -121,8 +121,8 @@ class ShowController extends Controller /** * Show a bill. * - * @param Request $request - * @param Bill $bill + * @param Request $request + * @param Bill $bill * * @return Factory|View * @throws ContainerExceptionInterface diff --git a/app/Http/Controllers/Budget/BudgetLimitController.php b/app/Http/Controllers/Budget/BudgetLimitController.php index a966d80526..b62e1192e5 100644 --- a/app/Http/Controllers/Budget/BudgetLimitController.php +++ b/app/Http/Controllers/Budget/BudgetLimitController.php @@ -77,9 +77,9 @@ class BudgetLimitController extends Controller } /** - * @param Budget $budget - * @param Carbon $start - * @param Carbon $end + * @param Budget $budget + * @param Carbon $start + * @param Carbon $end * * @return Factory|View */ @@ -107,8 +107,8 @@ class BudgetLimitController extends Controller } /** - * @param Request $request - * @param BudgetLimit $budgetLimit + * @param Request $request + * @param BudgetLimit $budgetLimit * * @return RedirectResponse|Redirector */ @@ -122,12 +122,13 @@ class BudgetLimitController extends Controller /** * TODO why redirect AND json response? - * @param Request $request + * + * @param Request $request * * @return RedirectResponse|JsonResponse * @throws FireflyException */ - public function store(Request $request): RedirectResponse|JsonResponse + public function store(Request $request): RedirectResponse | JsonResponse { Log::debug('Going to store new budget-limit.', $request->all()); // first search for existing one and update it if necessary. @@ -202,8 +203,8 @@ class BudgetLimitController extends Controller } /** - * @param Request $request - * @param BudgetLimit $budgetLimit + * @param Request $request + * @param BudgetLimit $budgetLimit * * @return JsonResponse */ diff --git a/app/Http/Controllers/Budget/CreateController.php b/app/Http/Controllers/Budget/CreateController.php index 8de40a769d..da18c84c23 100644 --- a/app/Http/Controllers/Budget/CreateController.php +++ b/app/Http/Controllers/Budget/CreateController.php @@ -65,7 +65,7 @@ class CreateController extends Controller /** * Form to create a budget. * - * @param Request $request + * @param Request $request * * @return Factory|View */ @@ -110,7 +110,7 @@ class CreateController extends Controller /** * Stores a budget. * - * @param BudgetFormStoreRequest $request + * @param BudgetFormStoreRequest $request * * @return RedirectResponse * @throws FireflyException diff --git a/app/Http/Controllers/Budget/DeleteController.php b/app/Http/Controllers/Budget/DeleteController.php index a0672a531f..bb8158395c 100644 --- a/app/Http/Controllers/Budget/DeleteController.php +++ b/app/Http/Controllers/Budget/DeleteController.php @@ -64,7 +64,7 @@ class DeleteController extends Controller /** * Deletes a budget. * - * @param Budget $budget + * @param Budget $budget * * @return Factory|View */ @@ -81,8 +81,8 @@ class DeleteController extends Controller /** * Destroys a budget. * - * @param Request $request - * @param Budget $budget + * @param Request $request + * @param Budget $budget * * @return RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/Budget/EditController.php b/app/Http/Controllers/Budget/EditController.php index e35b1e30fc..76a2bedbcd 100644 --- a/app/Http/Controllers/Budget/EditController.php +++ b/app/Http/Controllers/Budget/EditController.php @@ -67,8 +67,8 @@ class EditController extends Controller /** * Budget edit form. * - * @param Request $request - * @param Budget $budget + * @param Request $request + * @param Budget $budget * * @return Factory|View */ @@ -118,8 +118,8 @@ class EditController extends Controller /** * Budget update routine. * - * @param BudgetFormUpdateRequest $request - * @param Budget $budget + * @param BudgetFormUpdateRequest $request + * @param Budget $budget * * @return RedirectResponse */ diff --git a/app/Http/Controllers/Budget/IndexController.php b/app/Http/Controllers/Budget/IndexController.php index 05e6dcaff6..8d541550b7 100644 --- a/app/Http/Controllers/Budget/IndexController.php +++ b/app/Http/Controllers/Budget/IndexController.php @@ -88,10 +88,10 @@ class IndexController extends Controller /** * Show all budgets. * - * @param Request $request + * @param Request $request * - * @param Carbon|null $start - * @param Carbon|null $end + * @param Carbon|null $start + * @param Carbon|null $end * * @return Factory|View * @throws FireflyException @@ -174,31 +174,8 @@ class IndexController extends Controller } /** - * @param Request $request - * @param BudgetRepositoryInterface $repository - * - * @return JsonResponse - */ - public function reorder(Request $request, BudgetRepositoryInterface $repository): JsonResponse - { - $budgetIds = $request->get('budgetIds'); - - foreach ($budgetIds as $index => $budgetId) { - $budgetId = (int)$budgetId; - $budget = $repository->find($budgetId); - if (null !== $budget) { - Log::debug(sprintf('Set budget #%d ("%s") to position %d', $budget->id, $budget->name, $index + 1)); - $repository->setBudgetOrder($budget, $index + 1); - } - } - app('preferences')->mark(); - - return response()->json(['OK']); - } - - /** - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -229,10 +206,10 @@ class IndexController extends Controller } /** - * @param Carbon $start - * @param Carbon $end - * @param Collection $currencies - * @param TransactionCurrency $defaultCurrency + * @param Carbon $start + * @param Carbon $end + * @param Collection $currencies + * @param TransactionCurrency $defaultCurrency * * @return array */ @@ -287,7 +264,7 @@ class IndexController extends Controller } /** - * @param array $budgets + * @param array $budgets * * @return array */ @@ -340,7 +317,7 @@ class IndexController extends Controller } // final calculation for 'left': /** - * @var int $currencyId + * @var int $currencyId * @var array $info */ foreach ($sums['budgeted'] as $currencyId => $info) { @@ -351,4 +328,27 @@ class IndexController extends Controller return $sums; } + + /** + * @param Request $request + * @param BudgetRepositoryInterface $repository + * + * @return JsonResponse + */ + public function reorder(Request $request, BudgetRepositoryInterface $repository): JsonResponse + { + $budgetIds = $request->get('budgetIds'); + + foreach ($budgetIds as $index => $budgetId) { + $budgetId = (int)$budgetId; + $budget = $repository->find($budgetId); + if (null !== $budget) { + Log::debug(sprintf('Set budget #%d ("%s") to position %d', $budget->id, $budget->name, $index + 1)); + $repository->setBudgetOrder($budget, $index + 1); + } + } + app('preferences')->mark(); + + return response()->json(['OK']); + } } diff --git a/app/Http/Controllers/Budget/ShowController.php b/app/Http/Controllers/Budget/ShowController.php index d399bc6ff8..1d9e53e90b 100644 --- a/app/Http/Controllers/Budget/ShowController.php +++ b/app/Http/Controllers/Budget/ShowController.php @@ -76,9 +76,9 @@ class ShowController extends Controller /** * Show transactions without a budget. * - * @param Request $request - * @param Carbon|null $start - * @param Carbon|null $end + * @param Request $request + * @param Carbon|null $start + * @param Carbon|null $end * * @return Factory|View * @throws FireflyException @@ -116,7 +116,7 @@ class ShowController extends Controller /** * Shows ALL transactions without a budget. * - * @param Request $request + * @param Request $request * * @return Factory|View * @throws ContainerExceptionInterface @@ -144,8 +144,8 @@ class ShowController extends Controller /** * Show a single budget. * - * @param Request $request - * @param Budget $budget + * @param Request $request + * @param Budget $budget * * @return Factory|View * @throws ContainerExceptionInterface @@ -179,9 +179,9 @@ class ShowController extends Controller /** * Show a single budget by a budget limit. * - * @param Request $request - * @param Budget $budget - * @param BudgetLimit $budgetLimit + * @param Request $request + * @param Budget $budget + * @param BudgetLimit $budgetLimit * * @return Factory|View * @throws FireflyException diff --git a/app/Http/Controllers/Category/CreateController.php b/app/Http/Controllers/Category/CreateController.php index ed7f656260..77e2b7ea83 100644 --- a/app/Http/Controllers/Category/CreateController.php +++ b/app/Http/Controllers/Category/CreateController.php @@ -66,7 +66,7 @@ class CreateController extends Controller /** * Create category. * - * @param Request $request + * @param Request $request * * @return Factory|View */ @@ -84,7 +84,7 @@ class CreateController extends Controller /** * Store new category. * - * @param CategoryFormRequest $request + * @param CategoryFormRequest $request * * @return $this|RedirectResponse|Redirector * @throws FireflyException diff --git a/app/Http/Controllers/Category/DeleteController.php b/app/Http/Controllers/Category/DeleteController.php index b661b26046..78b87dc95e 100644 --- a/app/Http/Controllers/Category/DeleteController.php +++ b/app/Http/Controllers/Category/DeleteController.php @@ -63,7 +63,7 @@ class DeleteController extends Controller /** * Delete a category. * - * @param Category $category + * @param Category $category * * @return Factory|View */ @@ -80,8 +80,8 @@ class DeleteController extends Controller /** * Destroy a category. * - * @param Request $request - * @param Category $category + * @param Request $request + * @param Category $category * * @return RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/Category/EditController.php b/app/Http/Controllers/Category/EditController.php index 412a4cebfe..ba3c591c9d 100644 --- a/app/Http/Controllers/Category/EditController.php +++ b/app/Http/Controllers/Category/EditController.php @@ -66,8 +66,8 @@ class EditController extends Controller /** * Edit a category. * - * @param Request $request - * @param Category $category + * @param Request $request + * @param Category $category * * @return Factory|View */ @@ -91,8 +91,8 @@ class EditController extends Controller /** * Update category. * - * @param CategoryFormRequest $request - * @param Category $category + * @param CategoryFormRequest $request + * @param Category $category * * @return RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/Category/IndexController.php b/app/Http/Controllers/Category/IndexController.php index 6a3d54d35b..5dc6e902ac 100644 --- a/app/Http/Controllers/Category/IndexController.php +++ b/app/Http/Controllers/Category/IndexController.php @@ -65,7 +65,7 @@ class IndexController extends Controller /** * Show all categories. * - * @param Request $request + * @param Request $request * * @return Factory|View * @throws ContainerExceptionInterface diff --git a/app/Http/Controllers/Category/NoCategoryController.php b/app/Http/Controllers/Category/NoCategoryController.php index 5cdf5ad222..7406a23a85 100644 --- a/app/Http/Controllers/Category/NoCategoryController.php +++ b/app/Http/Controllers/Category/NoCategoryController.php @@ -73,9 +73,9 @@ class NoCategoryController extends Controller /** * Show transactions without a category. * - * @param Request $request - * @param Carbon|null $start - * @param Carbon|null $end + * @param Request $request + * @param Carbon|null $start + * @param Carbon|null $end * * @return Factory|View * @throws FireflyException @@ -116,7 +116,7 @@ class NoCategoryController extends Controller /** * Show all transactions without a category. * - * @param Request $request + * @param Request $request * * @return Factory|View * @throws FireflyException diff --git a/app/Http/Controllers/Category/ShowController.php b/app/Http/Controllers/Category/ShowController.php index 990663174a..e534a4d984 100644 --- a/app/Http/Controllers/Category/ShowController.php +++ b/app/Http/Controllers/Category/ShowController.php @@ -73,10 +73,10 @@ class ShowController extends Controller /** * Show a single category. * - * @param Request $request - * @param Category $category - * @param Carbon|null $start - * @param Carbon|null $end + * @param Request $request + * @param Category $category + * @param Carbon|null $start + * @param Carbon|null $end * * @return Factory|View * @throws FireflyException @@ -120,8 +120,8 @@ class ShowController extends Controller /** * Show all transactions within a category. * - * @param Request $request - * @param Category $category + * @param Request $request + * @param Category $category * * @return Factory|View * @throws ContainerExceptionInterface diff --git a/app/Http/Controllers/Chart/AccountController.php b/app/Http/Controllers/Chart/AccountController.php index 1b1cf09140..03fd897dfc 100644 --- a/app/Http/Controllers/Chart/AccountController.php +++ b/app/Http/Controllers/Chart/AccountController.php @@ -145,7 +145,7 @@ class AccountController extends Controller // loop all found currencies and build the data array for the chart. /** - * @var int $currencyId + * @var int $currencyId * @var TransactionCurrency $currency */ foreach ($currencies as $currencyId => $currency) { @@ -173,12 +173,28 @@ class AccountController extends Controller return response()->json($data); } + /** + * Expenses per budget for all time, as shown on account overview. + * + * @param AccountRepositoryInterface $repository + * @param Account $account + * + * @return JsonResponse + */ + public function expenseBudgetAll(AccountRepositoryInterface $repository, Account $account): JsonResponse + { + $start = $repository->oldestJournalDate($account) ?? today(config('app.timezone'))->startOfMonth(); + $end = today(config('app.timezone')); + + return $this->expenseBudget($account, $start, $end); + } + /** * Expenses per budget, as shown on account overview. * - * @param Account $account - * @param Carbon $start - * @param Carbon $end + * @param Account $account + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -232,27 +248,27 @@ class AccountController extends Controller } /** - * Expenses per budget for all time, as shown on account overview. + * Expenses grouped by category for account. * - * @param AccountRepositoryInterface $repository - * @param Account $account + * @param AccountRepositoryInterface $repository + * @param Account $account * * @return JsonResponse */ - public function expenseBudgetAll(AccountRepositoryInterface $repository, Account $account): JsonResponse + public function expenseCategoryAll(AccountRepositoryInterface $repository, Account $account): JsonResponse { $start = $repository->oldestJournalDate($account) ?? today(config('app.timezone'))->startOfMonth(); $end = today(config('app.timezone')); - return $this->expenseBudget($account, $start, $end); + return $this->expenseCategory($account, $start, $end); } /** * Expenses per category for one single account. * - * @param Account $account - * @param Carbon $start - * @param Carbon $end + * @param Account $account + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -303,26 +319,10 @@ class AccountController extends Controller return response()->json($data); } - /** - * Expenses grouped by category for account. - * - * @param AccountRepositoryInterface $repository - * @param Account $account - * - * @return JsonResponse - */ - public function expenseCategoryAll(AccountRepositoryInterface $repository, Account $account): JsonResponse - { - $start = $repository->oldestJournalDate($account) ?? today(config('app.timezone'))->startOfMonth(); - $end = today(config('app.timezone')); - - return $this->expenseCategory($account, $start, $end); - } - /** * Shows the balances for all the user's frontpage accounts. * - * @param AccountRepositoryInterface $repository + * @param AccountRepositoryInterface $repository * * @return JsonResponse * @throws FireflyException @@ -347,12 +347,28 @@ class AccountController extends Controller return response()->json($this->accountBalanceChart($accounts, $start, $end)); } + /** + * Shows the income grouped by category for an account, in all time. + * + * @param AccountRepositoryInterface $repository + * @param Account $account + * + * @return JsonResponse + */ + public function incomeCategoryAll(AccountRepositoryInterface $repository, Account $account): JsonResponse + { + $start = $repository->oldestJournalDate($account) ?? today(config('app.timezone'))->startOfMonth(); + $end = today(config('app.timezone')); + + return $this->incomeCategory($account, $start, $end); + } + /** * Shows all income per account for each category. * - * @param Account $account - * @param Carbon $start - * @param Carbon $end + * @param Account $account + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -403,29 +419,13 @@ class AccountController extends Controller return response()->json($data); } - /** - * Shows the income grouped by category for an account, in all time. - * - * @param AccountRepositoryInterface $repository - * @param Account $account - * - * @return JsonResponse - */ - public function incomeCategoryAll(AccountRepositoryInterface $repository, Account $account): JsonResponse - { - $start = $repository->oldestJournalDate($account) ?? today(config('app.timezone'))->startOfMonth(); - $end = today(config('app.timezone')); - - return $this->incomeCategory($account, $start, $end); - } - /** * Shows overview of account during a single period. * - * @param Account $account - * @param Carbon $start + * @param Account $account + * @param Carbon $start * - * @param Carbon $end + * @param Carbon $end * * @return JsonResponse * @throws FireflyException @@ -460,15 +460,63 @@ class AccountController extends Controller return response()->json($data); } + /** + * @param Carbon $start + * @param Carbon $end + * @param Account $account + * @param TransactionCurrency $currency + * + * @return array + * @throws FireflyException + * @throws JsonException + */ + private function periodByCurrency(Carbon $start, Carbon $end, Account $account, TransactionCurrency $currency): array + { + $locale = app('steam')->getLocale(); + $step = $this->calculateStep($start, $end); + $result = [ + 'label' => sprintf('%s (%s)', $account->name, $currency->symbol), + 'currency_symbol' => $currency->symbol, + 'currency_code' => $currency->code, + ]; + $entries = []; + $current = clone $start; + if ('1D' === $step) { + // per day the entire period, balance for every day. + $format = (string)trans('config.month_and_day_js', [], $locale); + $range = app('steam')->balanceInRange($account, $start, $end, $currency); + $previous = array_values($range)[0]; + while ($end >= $current) { + $theDate = $current->format('Y-m-d'); + $balance = $range[$theDate] ?? $previous; + $label = $current->isoFormat($format); + $entries[$label] = (float)$balance; + $previous = $balance; + $current->addDay(); + } + } + if ('1W' === $step || '1M' === $step || '1Y' === $step) { + while ($end >= $current) { + $balance = (float)app('steam')->balance($account, $current, $currency); + $label = app('navigation')->periodShow($current, $step); + $entries[$label] = $balance; + $current = app('navigation')->addPeriod($current, $step, 0); + } + } + $result['entries'] = $entries; + + return $result; + } + /** * Shows the balances for a given set of dates and accounts. * * TODO this chart is not multi currency aware. * - * @param Collection $accounts + * @param Collection $accounts * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * @return JsonResponse * @throws FireflyException * @throws JsonException @@ -544,7 +592,7 @@ class AccountController extends Controller // loop all found currencies and build the data array for the chart. /** - * @var int $currencyId + * @var int $currencyId * @var TransactionCurrency $currency */ foreach ($currencies as $currencyId => $currency) { @@ -571,52 +619,4 @@ class AccountController extends Controller return response()->json($data); } - - /** - * @param Carbon $start - * @param Carbon $end - * @param Account $account - * @param TransactionCurrency $currency - * - * @return array - * @throws FireflyException - * @throws JsonException - */ - private function periodByCurrency(Carbon $start, Carbon $end, Account $account, TransactionCurrency $currency): array - { - $locale = app('steam')->getLocale(); - $step = $this->calculateStep($start, $end); - $result = [ - 'label' => sprintf('%s (%s)', $account->name, $currency->symbol), - 'currency_symbol' => $currency->symbol, - 'currency_code' => $currency->code, - ]; - $entries = []; - $current = clone $start; - if ('1D' === $step) { - // per day the entire period, balance for every day. - $format = (string)trans('config.month_and_day_js', [], $locale); - $range = app('steam')->balanceInRange($account, $start, $end, $currency); - $previous = array_values($range)[0]; - while ($end >= $current) { - $theDate = $current->format('Y-m-d'); - $balance = $range[$theDate] ?? $previous; - $label = $current->isoFormat($format); - $entries[$label] = (float)$balance; - $previous = $balance; - $current->addDay(); - } - } - if ('1W' === $step || '1M' === $step || '1Y' === $step) { - while ($end >= $current) { - $balance = (float)app('steam')->balance($account, $current, $currency); - $label = app('navigation')->periodShow($current, $step); - $entries[$label] = $balance; - $current = app('navigation')->addPeriod($current, $step, 0); - } - } - $result['entries'] = $entries; - - return $result; - } } diff --git a/app/Http/Controllers/Chart/BillController.php b/app/Http/Controllers/Chart/BillController.php index edd98df59c..6397554f0d 100644 --- a/app/Http/Controllers/Chart/BillController.php +++ b/app/Http/Controllers/Chart/BillController.php @@ -53,7 +53,7 @@ class BillController extends Controller /** * Shows all bills and whether or not they've been paid this month (pie chart). * - * @param BillRepositoryInterface $repository + * @param BillRepositoryInterface $repository * * @return JsonResponse */ @@ -107,7 +107,7 @@ class BillController extends Controller /** * Shows overview for a single bill. * - * @param Bill $bill + * @param Bill $bill * * @return JsonResponse * @throws FireflyException diff --git a/app/Http/Controllers/Chart/BudgetController.php b/app/Http/Controllers/Chart/BudgetController.php index 0a407a9cbc..cc77852515 100644 --- a/app/Http/Controllers/Chart/BudgetController.php +++ b/app/Http/Controllers/Chart/BudgetController.php @@ -83,7 +83,7 @@ class BudgetController extends Controller /** * Shows overview of a single budget. * - * @param Budget $budget + * @param Budget $budget * * @return JsonResponse */ @@ -148,8 +148,8 @@ class BudgetController extends Controller /** * Shows the amount left in a specific budget limit. * - * @param Budget $budget - * @param BudgetLimit $budgetLimit + * @param Budget $budget + * @param BudgetLimit $budgetLimit * * @return JsonResponse * @@ -200,8 +200,8 @@ class BudgetController extends Controller /** * Shows how much is spent per asset account. * - * @param Budget $budget - * @param BudgetLimit|null $budgetLimit + * @param Budget $budget + * @param BudgetLimit|null $budgetLimit * * @return JsonResponse */ @@ -268,8 +268,8 @@ class BudgetController extends Controller /** * Shows how much is spent per category. * - * @param Budget $budget - * @param BudgetLimit|null $budgetLimit + * @param Budget $budget + * @param BudgetLimit|null $budgetLimit * * @return JsonResponse */ @@ -332,8 +332,8 @@ class BudgetController extends Controller * Shows how much is spent per expense account. * * - * @param Budget $budget - * @param BudgetLimit|null $budgetLimit + * @param Budget $budget + * @param BudgetLimit|null $budgetLimit * * @return JsonResponse */ @@ -429,11 +429,11 @@ class BudgetController extends Controller /** * Shows a budget overview chart (spent and budgeted). * - * @param Budget $budget - * @param TransactionCurrency $currency - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Budget $budget + * @param TransactionCurrency $currency + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -505,10 +505,10 @@ class BudgetController extends Controller /** * Shows a chart for transactions without a budget. * - * @param TransactionCurrency $currency - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param TransactionCurrency $currency + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ diff --git a/app/Http/Controllers/Chart/BudgetReportController.php b/app/Http/Controllers/Chart/BudgetReportController.php index 8cd516cc0c..dcc9758c86 100644 --- a/app/Http/Controllers/Chart/BudgetReportController.php +++ b/app/Http/Controllers/Chart/BudgetReportController.php @@ -71,10 +71,10 @@ class BudgetReportController extends Controller /** * Chart that groups the expenses by budget. * - * @param Collection $accounts - * @param Collection $budgets - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $budgets + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -107,10 +107,10 @@ class BudgetReportController extends Controller /** * Chart that groups the expenses by budget. * - * @param Collection $accounts - * @param Collection $budgets - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $budgets + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -144,10 +144,10 @@ class BudgetReportController extends Controller /** * Chart that groups expenses by the account. * - * @param Collection $accounts - * @param Collection $budgets - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $budgets + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -181,10 +181,10 @@ class BudgetReportController extends Controller /** * Main overview of a budget in the budget report. * - * @param Collection $accounts - * @param Budget $budget - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Budget $budget + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -226,13 +226,36 @@ class BudgetReportController extends Controller return response()->json($data); } + /** + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + private function makeEntries(Carbon $start, Carbon $end): array + { + $return = []; + $format = app('navigation')->preferredCarbonLocalizedFormat($start, $end); + $preferredRange = app('navigation')->preferredRangeFormat($start, $end); + $currentStart = clone $start; + while ($currentStart <= $end) { + $currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange); + $key = $currentStart->isoFormat($format); + $return[$key] = '0'; + $currentStart = clone $currentEnd; + $currentStart->addDay()->startOfDay(); + } + + return $return; + } + /** * Chart that groups expenses by the account. * - * @param Collection $accounts - * @param Collection $budgets - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $budgets + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -262,27 +285,4 @@ class BudgetReportController extends Controller return response()->json($data); } - - /** - * @param Carbon $start - * @param Carbon $end - * - * @return array - */ - private function makeEntries(Carbon $start, Carbon $end): array - { - $return = []; - $format = app('navigation')->preferredCarbonLocalizedFormat($start, $end); - $preferredRange = app('navigation')->preferredRangeFormat($start, $end); - $currentStart = clone $start; - while ($currentStart <= $end) { - $currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange); - $key = $currentStart->isoFormat($format); - $return[$key] = '0'; - $currentStart = clone $currentEnd; - $currentStart->addDay()->startOfDay(); - } - - return $return; - } } diff --git a/app/Http/Controllers/Chart/CategoryController.php b/app/Http/Controllers/Chart/CategoryController.php index 54de47bb70..f600454d4d 100644 --- a/app/Http/Controllers/Chart/CategoryController.php +++ b/app/Http/Controllers/Chart/CategoryController.php @@ -70,7 +70,7 @@ class CategoryController extends Controller * Show an overview for a category for all time, per month/week/year. * TODO test method, for category refactor. * - * @param Category $category + * @param Category $category * * @return JsonResponse * @throws FireflyException @@ -102,6 +102,14 @@ class CategoryController extends Controller return response()->json($data); } + /** + * @return Carbon + */ + private function getDate(): Carbon + { + return today(config('app.timezone')); + } + /** * Shows the category chart on the front page. * TODO test method for category refactor. @@ -133,10 +141,10 @@ class CategoryController extends Controller * Chart report. * TODO test method for category refactor. * - * @param Category $category - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Category $category + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -158,88 +166,13 @@ class CategoryController extends Controller return response()->json($data); } - /** - * Chart for period for transactions without a category. - * TODO test me. - * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end - * - * @return JsonResponse - */ - public function reportPeriodNoCategory(Collection $accounts, Carbon $start, Carbon $end): JsonResponse - { - $cache = new CacheProperties(); - $cache->addProperty($start); - $cache->addProperty($end); - $cache->addProperty('chart.category.period.no-cat'); - $cache->addProperty($accounts->pluck('id')->toArray()); - if ($cache->has()) { - return response()->json($cache->get()); - } - $data = $this->reportPeriodChart($accounts, $start, $end, null); - - $cache->store($data); - - return response()->json($data); - } - - /** - * Chart for a specific period. - * TODO test me, for category refactor. - * - * @param Category $category - * @param Carbon $date - * - * @return JsonResponse - * @throws FireflyException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - public function specificPeriod(Category $category, Carbon $date): JsonResponse - { - $range = app('navigation')->getViewRange(false); - $start = app('navigation')->startOfPeriod($date, $range); - $end = session()->get('end'); - if ($end < $start) { - [$end, $start] = [$start, $end]; - } - - $cache = new CacheProperties(); - $cache->addProperty($start); - $cache->addProperty($end); - $cache->addProperty($category->id); - $cache->addProperty('chart.category.period-chart'); - if ($cache->has()) { - return response()->json($cache->get()); - } - - /** @var WholePeriodChartGenerator $chartGenerator */ - $chartGenerator = app(WholePeriodChartGenerator::class); - $chartData = $chartGenerator->generate($category, $start, $end); - $data = $this->generator->multiSet($chartData); - - $cache->store($data); - - return response()->json($data); - } - - /** - * @return Carbon - */ - private function getDate(): Carbon - { - return today(config('app.timezone')); - } - /** * Generate report chart for either with or without category. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end - * @param Category|null $category + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * @param Category|null $category * * @return array */ @@ -318,4 +251,71 @@ class CategoryController extends Controller return $this->generator->multiSet($chartData); } + + /** + * Chart for period for transactions without a category. + * TODO test me. + * + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * + * @return JsonResponse + */ + public function reportPeriodNoCategory(Collection $accounts, Carbon $start, Carbon $end): JsonResponse + { + $cache = new CacheProperties(); + $cache->addProperty($start); + $cache->addProperty($end); + $cache->addProperty('chart.category.period.no-cat'); + $cache->addProperty($accounts->pluck('id')->toArray()); + if ($cache->has()) { + return response()->json($cache->get()); + } + $data = $this->reportPeriodChart($accounts, $start, $end, null); + + $cache->store($data); + + return response()->json($data); + } + + /** + * Chart for a specific period. + * TODO test me, for category refactor. + * + * @param Category $category + * @param Carbon $date + * + * @return JsonResponse + * @throws FireflyException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function specificPeriod(Category $category, Carbon $date): JsonResponse + { + $range = app('navigation')->getViewRange(false); + $start = app('navigation')->startOfPeriod($date, $range); + $end = session()->get('end'); + if ($end < $start) { + [$end, $start] = [$start, $end]; + } + + $cache = new CacheProperties(); + $cache->addProperty($start); + $cache->addProperty($end); + $cache->addProperty($category->id); + $cache->addProperty('chart.category.period-chart'); + if ($cache->has()) { + return response()->json($cache->get()); + } + + /** @var WholePeriodChartGenerator $chartGenerator */ + $chartGenerator = app(WholePeriodChartGenerator::class); + $chartData = $chartGenerator->generate($category, $start, $end); + $data = $this->generator->multiSet($chartData); + + $cache->store($data); + + return response()->json($data); + } } diff --git a/app/Http/Controllers/Chart/CategoryReportController.php b/app/Http/Controllers/Chart/CategoryReportController.php index 1e6da6b0db..9d23654432 100644 --- a/app/Http/Controllers/Chart/CategoryReportController.php +++ b/app/Http/Controllers/Chart/CategoryReportController.php @@ -67,10 +67,10 @@ class CategoryReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -103,10 +103,10 @@ class CategoryReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -138,10 +138,10 @@ class CategoryReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -173,10 +173,10 @@ class CategoryReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -209,10 +209,10 @@ class CategoryReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -245,10 +245,10 @@ class CategoryReportController extends Controller } /** - * @param Collection $accounts - * @param Category $category - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Category $category + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse * @@ -320,10 +320,35 @@ class CategoryReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * TODO duplicate function + * + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + private function makeEntries(Carbon $start, Carbon $end): array + { + $return = []; + $format = app('navigation')->preferredCarbonLocalizedFormat($start, $end); + $preferredRange = app('navigation')->preferredRangeFormat($start, $end); + $currentStart = clone $start; + while ($currentStart <= $end) { + $currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange); + $key = $currentStart->isoFormat($format); + $return[$key] = '0'; + $currentStart = clone $currentEnd; + $currentStart->addDay()->startOfDay(); + } + + return $return; + } + + /** + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -356,10 +381,10 @@ class CategoryReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -390,29 +415,4 @@ class CategoryReportController extends Controller return response()->json($data); } - - /** - * TODO duplicate function - * - * @param Carbon $start - * @param Carbon $end - * - * @return array - */ - private function makeEntries(Carbon $start, Carbon $end): array - { - $return = []; - $format = app('navigation')->preferredCarbonLocalizedFormat($start, $end); - $preferredRange = app('navigation')->preferredRangeFormat($start, $end); - $currentStart = clone $start; - while ($currentStart <= $end) { - $currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange); - $key = $currentStart->isoFormat($format); - $return[$key] = '0'; - $currentStart = clone $currentEnd; - $currentStart->addDay()->startOfDay(); - } - - return $return; - } } diff --git a/app/Http/Controllers/Chart/DoubleReportController.php b/app/Http/Controllers/Chart/DoubleReportController.php index 99130b929c..1cda544991 100644 --- a/app/Http/Controllers/Chart/DoubleReportController.php +++ b/app/Http/Controllers/Chart/DoubleReportController.php @@ -66,10 +66,10 @@ class DoubleReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $others - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $others + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -101,10 +101,10 @@ class DoubleReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $others - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $others + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -136,10 +136,10 @@ class DoubleReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $others - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $others + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -171,10 +171,10 @@ class DoubleReportController extends Controller } /** - * @param Collection $accounts - * @param Account $account - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Account $account + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse * @@ -248,10 +248,60 @@ class DoubleReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $others - * @param Carbon $start - * @param Carbon $end + * TODO duplicate function + * + * @param Collection $accounts + * @param int $id + * @param string $name + * @param null|string $iban + * + * @return string + */ + private function getCounterpartName(Collection $accounts, int $id, string $name, ?string $iban): string + { + /** @var Account $account */ + foreach ($accounts as $account) { + if ($account->name === $name && $account->id !== $id) { + return $account->name; + } + if (null !== $account->iban && $account->iban === $iban && $account->id !== $id) { + return $account->iban; + } + } + + return $name; + } + + /** + * TODO duplicate function + * + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + private function makeEntries(Carbon $start, Carbon $end): array + { + $return = []; + $format = app('navigation')->preferredCarbonLocalizedFormat($start, $end); + $preferredRange = app('navigation')->preferredRangeFormat($start, $end); + $currentStart = clone $start; + while ($currentStart <= $end) { + $currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange); + $key = $currentStart->isoFormat($format); + $return[$key] = '0'; + $currentStart = clone $currentEnd; + $currentStart->addDay()->startOfDay(); + } + + return $return; + } + + /** + * @param Collection $accounts + * @param Collection $others + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -308,10 +358,10 @@ class DoubleReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $others - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $others + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -366,54 +416,4 @@ class DoubleReportController extends Controller return response()->json($data); } - - /** - * TODO duplicate function - * - * @param Collection $accounts - * @param int $id - * @param string $name - * @param null|string $iban - * - * @return string - */ - private function getCounterpartName(Collection $accounts, int $id, string $name, ?string $iban): string - { - /** @var Account $account */ - foreach ($accounts as $account) { - if ($account->name === $name && $account->id !== $id) { - return $account->name; - } - if (null !== $account->iban && $account->iban === $iban && $account->id !== $id) { - return $account->iban; - } - } - - return $name; - } - - /** - * TODO duplicate function - * - * @param Carbon $start - * @param Carbon $end - * - * @return array - */ - private function makeEntries(Carbon $start, Carbon $end): array - { - $return = []; - $format = app('navigation')->preferredCarbonLocalizedFormat($start, $end); - $preferredRange = app('navigation')->preferredRangeFormat($start, $end); - $currentStart = clone $start; - while ($currentStart <= $end) { - $currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange); - $key = $currentStart->isoFormat($format); - $return[$key] = '0'; - $currentStart = clone $currentEnd; - $currentStart->addDay()->startOfDay(); - } - - return $return; - } } diff --git a/app/Http/Controllers/Chart/ExpenseReportController.php b/app/Http/Controllers/Chart/ExpenseReportController.php index eb31f4aed9..6757e856c4 100644 --- a/app/Http/Controllers/Chart/ExpenseReportController.php +++ b/app/Http/Controllers/Chart/ExpenseReportController.php @@ -73,10 +73,10 @@ class ExpenseReportController extends Controller * * TODO this chart is not multi currency aware. * - * @param Collection $accounts - * @param Collection $expense - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $expense + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse * @throws JsonException @@ -106,34 +106,34 @@ class ExpenseReportController extends Controller // prep chart data: /** - * @var string $name + * @var string $name * @var Collection $combination */ foreach ($combined as $name => $combination) { // first is always expense account: /** @var Account $exp */ - $exp = $combination->first(); - $chartData[$exp->id.'-in'] = [ + $exp = $combination->first(); + $chartData[$exp->id . '-in'] = [ 'label' => sprintf('%s (%s)', $name, (string)trans('firefly.income')), 'type' => 'bar', 'yAxisID' => 'y-axis-0', 'entries' => [], ]; - $chartData[$exp->id.'-out'] = [ + $chartData[$exp->id . '-out'] = [ 'label' => sprintf('%s (%s)', $name, (string)trans('firefly.expenses')), 'type' => 'bar', 'yAxisID' => 'y-axis-0', 'entries' => [], ]; // total in, total out: - $chartData[$exp->id.'-total-in'] = [ + $chartData[$exp->id . '-total-in'] = [ 'label' => sprintf('%s (%s)', $name, (string)trans('firefly.sum_of_income')), 'type' => 'line', 'fill' => false, 'yAxisID' => 'y-axis-1', 'entries' => [], ]; - $chartData[$exp->id.'-total-out'] = [ + $chartData[$exp->id . '-total-out'] = [ 'label' => sprintf('%s (%s)', $name, (string)trans('firefly.sum_of_expenses')), 'type' => 'line', 'fill' => false, @@ -158,10 +158,10 @@ class ExpenseReportController extends Controller // first is always expense account: /** @var Account $exp */ $exp = $combination->first(); - $labelIn = $exp->id.'-in'; - $labelOut = $exp->id.'-out'; - $labelSumIn = $exp->id.'-total-in'; - $labelSumOut = $exp->id.'-total-out'; + $labelIn = $exp->id . '-in'; + $labelOut = $exp->id . '-out'; + $labelSumIn = $exp->id . '-total-in'; + $labelSumOut = $exp->id . '-total-out'; $currentIncome = bcmul($income[$name] ?? '0', '-1'); $currentExpense = $expenses[$name] ?? '0'; diff --git a/app/Http/Controllers/Chart/PiggyBankController.php b/app/Http/Controllers/Chart/PiggyBankController.php index 47880cf858..7057f84947 100644 --- a/app/Http/Controllers/Chart/PiggyBankController.php +++ b/app/Http/Controllers/Chart/PiggyBankController.php @@ -61,8 +61,8 @@ class PiggyBankController extends Controller * * TODO this chart is not multi currency aware. * - * @param PiggyBankRepositoryInterface $repository - * @param PiggyBank $piggyBank + * @param PiggyBankRepositoryInterface $repository + * @param PiggyBank $piggyBank * * @return JsonResponse * @throws FireflyException diff --git a/app/Http/Controllers/Chart/ReportController.php b/app/Http/Controllers/Chart/ReportController.php index 685bb3fd5e..9565ef75e5 100644 --- a/app/Http/Controllers/Chart/ReportController.php +++ b/app/Http/Controllers/Chart/ReportController.php @@ -67,9 +67,9 @@ class ReportController extends Controller * This chart, by default, is shown on the multi-year and year report pages, * which means that giving it a 2 week "period" should be enough granularity. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse * @throws FireflyException @@ -120,7 +120,7 @@ class ReportController extends Controller $label = $current->isoFormat((string)trans('config.month_and_day_js', [], $locale)); if (!array_key_exists($currencyId, $chartData)) { $chartData[$currencyId] = [ - 'label' => 'Net worth in '.$netWorthItem['currency']->name, + 'label' => 'Net worth in ' . $netWorthItem['currency']->name, 'type' => 'line', 'currency_symbol' => $netWorthItem['currency']->symbol, 'currency_code' => $netWorthItem['currency']->code, @@ -141,9 +141,9 @@ class ReportController extends Controller /** * Shows income and expense, debit/credit: operations. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse * @throws JsonException diff --git a/app/Http/Controllers/Chart/TagReportController.php b/app/Http/Controllers/Chart/TagReportController.php index d462590876..2f3b7db2dd 100644 --- a/app/Http/Controllers/Chart/TagReportController.php +++ b/app/Http/Controllers/Chart/TagReportController.php @@ -68,10 +68,10 @@ class TagReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -104,10 +104,10 @@ class TagReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -140,10 +140,10 @@ class TagReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -176,10 +176,10 @@ class TagReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -212,10 +212,10 @@ class TagReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -250,10 +250,10 @@ class TagReportController extends Controller /** * Generate main tag overview chart. * - * @param Collection $accounts - * @param Tag $tag - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Tag $tag + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse * @@ -325,10 +325,35 @@ class TagReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * TODO duplicate function + * + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + private function makeEntries(Carbon $start, Carbon $end): array + { + $return = []; + $format = app('navigation')->preferredCarbonLocalizedFormat($start, $end); + $preferredRange = app('navigation')->preferredRangeFormat($start, $end); + $currentStart = clone $start; + while ($currentStart <= $end) { + $currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange); + $key = $currentStart->isoFormat($format); + $return[$key] = '0'; + $currentStart = clone $currentEnd; + $currentStart->addDay()->startOfDay(); + } + + return $return; + } + + /** + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -361,10 +386,10 @@ class TagReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -397,10 +422,10 @@ class TagReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -431,10 +456,10 @@ class TagReportController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -463,29 +488,4 @@ class TagReportController extends Controller return response()->json($data); } - - /** - * TODO duplicate function - * - * @param Carbon $start - * @param Carbon $end - * - * @return array - */ - private function makeEntries(Carbon $start, Carbon $end): array - { - $return = []; - $format = app('navigation')->preferredCarbonLocalizedFormat($start, $end); - $preferredRange = app('navigation')->preferredRangeFormat($start, $end); - $currentStart = clone $start; - while ($currentStart <= $end) { - $currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange); - $key = $currentStart->isoFormat($format); - $return[$key] = '0'; - $currentStart = clone $currentEnd; - $currentStart->addDay()->startOfDay(); - } - - return $return; - } } diff --git a/app/Http/Controllers/Chart/TransactionController.php b/app/Http/Controllers/Chart/TransactionController.php index f0a6112527..ccb349fe75 100644 --- a/app/Http/Controllers/Chart/TransactionController.php +++ b/app/Http/Controllers/Chart/TransactionController.php @@ -50,8 +50,8 @@ class TransactionController extends Controller } /** - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -92,9 +92,9 @@ class TransactionController extends Controller } /** - * @param string $objectType - * @param Carbon $start - * @param Carbon $end + * @param string $objectType + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -145,9 +145,9 @@ class TransactionController extends Controller } /** - * @param string $objectType - * @param Carbon $start - * @param Carbon $end + * @param string $objectType + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ @@ -198,9 +198,9 @@ class TransactionController extends Controller } /** - * @param string $objectType - * @param Carbon $start - * @param Carbon $end + * @param string $objectType + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ diff --git a/app/Http/Controllers/CurrencyController.php b/app/Http/Controllers/CurrencyController.php index 00364402fb..f4e6349dd0 100644 --- a/app/Http/Controllers/CurrencyController.php +++ b/app/Http/Controllers/CurrencyController.php @@ -72,7 +72,7 @@ class CurrencyController extends Controller /** * Create a currency. * - * @param Request $request + * @param Request $request * * @return Factory|RedirectResponse|Redirector|View */ @@ -103,7 +103,7 @@ class CurrencyController extends Controller /** * Make currency the default currency. * - * @param Request $request + * @param Request $request * * @return RedirectResponse|Redirector * @throws FireflyException @@ -132,8 +132,8 @@ class CurrencyController extends Controller /** * Deletes a currency. * - * @param Request $request - * @param TransactionCurrency $currency + * @param Request $request + * @param TransactionCurrency $currency * * @return Factory|RedirectResponse|Redirector|View */ @@ -168,8 +168,8 @@ class CurrencyController extends Controller /** * Destroys a currency. * - * @param Request $request - * @param TransactionCurrency $currency + * @param Request $request + * @param TransactionCurrency $currency * * @return RedirectResponse|Redirector */ @@ -207,7 +207,7 @@ class CurrencyController extends Controller } /** - * @param Request $request + * @param Request $request * @return JsonResponse * @throws FireflyException */ @@ -260,8 +260,8 @@ class CurrencyController extends Controller /** * Edit a currency. * - * @param Request $request - * @param TransactionCurrency $currency + * @param Request $request + * @param TransactionCurrency $currency * * @return Factory|RedirectResponse|Redirector|View */ @@ -299,7 +299,7 @@ class CurrencyController extends Controller } /** - * @param Request $request + * @param Request $request * @return JsonResponse */ public function enableCurrency(Request $request): JsonResponse @@ -323,7 +323,7 @@ class CurrencyController extends Controller /** * Show overview of currencies. * - * @param Request $request + * @param Request $request * * @return Factory|View * @throws ContainerExceptionInterface @@ -354,7 +354,7 @@ class CurrencyController extends Controller /** * Store new currency. * - * @param CurrencyFormRequest $request + * @param CurrencyFormRequest $request * * @return $this|RedirectResponse|Redirector */ @@ -364,7 +364,7 @@ class CurrencyController extends Controller $user = auth()->user(); $data = $request->getCurrencyData(); if (!$this->userRepository->hasRole($user, 'owner')) { - Log::error('User '.auth()->user()->id.' is not admin, but tried to store a currency.'); + Log::error('User ' . auth()->user()->id . ' is not admin, but tried to store a currency.'); Log::channel('audit')->info('Tried to create (POST) currency without admin rights.', $data); return redirect($this->getPreviousUrl('currencies.create.url')); @@ -397,8 +397,8 @@ class CurrencyController extends Controller /** * Updates a currency. * - * @param CurrencyFormRequest $request - * @param TransactionCurrency $currency + * @param CurrencyFormRequest $request + * @param TransactionCurrency $currency * * @return RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/DebugController.php b/app/Http/Controllers/DebugController.php index d52b983021..634adb525a 100644 --- a/app/Http/Controllers/DebugController.php +++ b/app/Http/Controllers/DebugController.php @@ -78,7 +78,7 @@ class DebugController extends Controller /** * Clear log and session. * - * @param Request $request + * @param Request $request * * @return RedirectResponse|Redirector * @throws FireflyException @@ -109,7 +109,7 @@ class DebugController extends Controller /** * Show debug info. * - * @param Request $request + * @param Request $request * * @return Factory|View * @throws FireflyException @@ -212,7 +212,7 @@ class DebugController extends Controller } if ('' !== $logContent) { // last few lines - $logContent = 'Truncated from this point <----|'.substr($logContent, -8192); + $logContent = 'Truncated from this point <----|' . substr($logContent, -8192); } return view( @@ -261,7 +261,7 @@ class DebugController extends Controller /** * Flash all types of messages. * - * @param Request $request + * @param Request $request * * @return RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/Export/IndexController.php b/app/Http/Controllers/Export/IndexController.php index 05872cb77e..ad0cb4b99a 100644 --- a/app/Http/Controllers/Export/IndexController.php +++ b/app/Http/Controllers/Export/IndexController.php @@ -92,7 +92,7 @@ class IndexController extends Controller $response ->header('Content-Description', 'File Transfer') ->header('Content-Type', 'text/x-csv') - ->header('Content-Disposition', 'attachment; filename='.$quoted) + ->header('Content-Disposition', 'attachment; filename=' . $quoted) //->header('Content-Transfer-Encoding', 'binary') ->header('Connection', 'Keep-Alive') ->header('Expires', '0') diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 268efe234e..34af46d70f 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -60,7 +60,7 @@ class HomeController extends Controller /** * Change index date range. * - * @param Request $request + * @param Request $request * * @return JsonResponse * @throws Exception @@ -111,7 +111,7 @@ class HomeController extends Controller /** * Show index. * - * @param AccountRepositoryInterface $repository + * @param AccountRepositoryInterface $repository * * @return mixed * @throws FireflyException diff --git a/app/Http/Controllers/JavascriptController.php b/app/Http/Controllers/JavascriptController.php index 2a38ceb849..bdb002df78 100644 --- a/app/Http/Controllers/JavascriptController.php +++ b/app/Http/Controllers/JavascriptController.php @@ -47,8 +47,8 @@ class JavascriptController extends Controller /** * Show info about accounts. * - * @param AccountRepositoryInterface $repository - * @param CurrencyRepositoryInterface $currencyRepository + * @param AccountRepositoryInterface $repository + * @param CurrencyRepositoryInterface $currencyRepository * * @return Response * @throws ContainerExceptionInterface @@ -81,7 +81,7 @@ class JavascriptController extends Controller /** * Get info about currencies. * - * @param CurrencyRepositoryInterface $repository + * @param CurrencyRepositoryInterface $repository * * @return Response */ @@ -104,9 +104,9 @@ class JavascriptController extends Controller /** * Show some common variables to be used in scripts. * - * @param Request $request - * @param AccountRepositoryInterface $repository - * @param CurrencyRepositoryInterface $currencyRepository + * @param Request $request + * @param AccountRepositoryInterface $repository + * @param CurrencyRepositoryInterface $currencyRepository * * @return Response * @throws FireflyException @@ -149,7 +149,7 @@ class JavascriptController extends Controller /** * Bit of a hack but OK. * - * @param Request $request + * @param Request $request * * @return Response */ diff --git a/app/Http/Controllers/Json/BoxController.php b/app/Http/Controllers/Json/BoxController.php index 1b905307fc..1bd0a3788e 100644 --- a/app/Http/Controllers/Json/BoxController.php +++ b/app/Http/Controllers/Json/BoxController.php @@ -127,7 +127,7 @@ class BoxController extends Controller /** * Current total balance. * - * @param CurrencyRepositoryInterface $repository + * @param CurrencyRepositoryInterface $repository * * @return JsonResponse */ diff --git a/app/Http/Controllers/Json/BudgetController.php b/app/Http/Controllers/Json/BudgetController.php index 6715d9b2e7..bbad8baef0 100644 --- a/app/Http/Controllers/Json/BudgetController.php +++ b/app/Http/Controllers/Json/BudgetController.php @@ -68,9 +68,9 @@ class BudgetController extends Controller } /** - * @param TransactionCurrency $currency - * @param Carbon $start - * @param Carbon $end + * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end * * @return JsonResponse */ diff --git a/app/Http/Controllers/Json/FrontpageController.php b/app/Http/Controllers/Json/FrontpageController.php index db0e2f10c0..e0c94ca7e4 100644 --- a/app/Http/Controllers/Json/FrontpageController.php +++ b/app/Http/Controllers/Json/FrontpageController.php @@ -39,7 +39,7 @@ class FrontpageController extends Controller /** * Piggy bank pie chart. * - * @param PiggyBankRepositoryInterface $repository + * @param PiggyBankRepositoryInterface $repository * * @return JsonResponse * @throws FireflyException diff --git a/app/Http/Controllers/Json/IntroController.php b/app/Http/Controllers/Json/IntroController.php index 8f0b7b2c24..7b98747d9c 100644 --- a/app/Http/Controllers/Json/IntroController.php +++ b/app/Http/Controllers/Json/IntroController.php @@ -39,8 +39,8 @@ class IntroController extends Controller /** * Returns the introduction wizard for a page. * - * @param string $route - * @param string|null $specificPage + * @param string $route + * @param string|null $specificPage * * @return JsonResponse */ @@ -74,7 +74,7 @@ class IntroController extends Controller /** * Returns true if there is a general outro step. * - * @param string $route + * @param string $route * * @return bool */ @@ -99,8 +99,8 @@ class IntroController extends Controller /** * Enable the boxes for a specific page again. * - * @param string $route - * @param string|null $specialPage + * @param string $route + * @param string|null $specialPage * * @return JsonResponse * @throws FireflyException @@ -109,9 +109,9 @@ class IntroController extends Controller { $specialPage = $specialPage ?? ''; $route = str_replace('.', '_', $route); - $key = 'shown_demo_'.$route; + $key = 'shown_demo_' . $route; if ('' !== $specialPage) { - $key .= '_'.$specialPage; + $key .= '_' . $specialPage; } Log::debug(sprintf('Going to mark the following route as NOT done: %s with special "%s" (%s)', $route, $specialPage, $key)); app('preferences')->set($key, false); @@ -123,8 +123,8 @@ class IntroController extends Controller /** * Set that you saw them. * - * @param string $route - * @param string|null $specialPage + * @param string $route + * @param string|null $specialPage * * @return JsonResponse * @throws FireflyException @@ -132,9 +132,9 @@ class IntroController extends Controller public function postFinished(string $route, string $specialPage = null): JsonResponse { $specialPage = $specialPage ?? ''; - $key = 'shown_demo_'.$route; + $key = 'shown_demo_' . $route; if ('' !== $specialPage) { - $key .= '_'.$specialPage; + $key .= '_' . $specialPage; } Log::debug(sprintf('Going to mark the following route as done: %s with special "%s" (%s)', $route, $specialPage, $key)); app('preferences')->set($key, true); diff --git a/app/Http/Controllers/Json/ReconcileController.php b/app/Http/Controllers/Json/ReconcileController.php index b0778d25ea..19d2e3373a 100644 --- a/app/Http/Controllers/Json/ReconcileController.php +++ b/app/Http/Controllers/Json/ReconcileController.php @@ -70,10 +70,10 @@ class ReconcileController extends Controller /** * Overview of reconciliation. * - * @param Request $request - * @param Account|null $account - * @param Carbon|null $start - * @param Carbon|null $end + * @param Request $request + * @param Account|null $account + * @param Carbon|null $start + * @param Carbon|null $end * * @return JsonResponse * @throws FireflyException @@ -169,12 +169,52 @@ class ReconcileController extends Controller return response()->json($return); } + /** + * @param Account $account + * @param TransactionCurrency $currency + * @param array $journal + * @param string $amount + * + * @return string + */ + private function processJournal(Account $account, TransactionCurrency $currency, array $journal, string $amount): string + { + $toAdd = '0'; + Log::debug(sprintf('User submitted %s #%d: "%s"', $journal['transaction_type_type'], $journal['transaction_journal_id'], $journal['description'])); + + // not much magic below we need to cover using tests. + + if ($account->id === $journal['source_account_id']) { + if ($currency->id === $journal['currency_id']) { + $toAdd = $journal['amount']; + } + if (null !== $journal['foreign_currency_id'] && $journal['foreign_currency_id'] === $currency->id) { + $toAdd = $journal['foreign_amount']; + } + } + if ($account->id === $journal['destination_account_id']) { + if ($currency->id === $journal['currency_id']) { + $toAdd = bcmul($journal['amount'], '-1'); + } + if (null !== $journal['foreign_currency_id'] && $journal['foreign_currency_id'] === $currency->id) { + $toAdd = bcmul($journal['foreign_amount'], '-1'); + } + } + + + Log::debug(sprintf('Going to add %s to %s', $toAdd, $amount)); + $amount = bcadd($amount, $toAdd); + Log::debug(sprintf('Result is %s', $amount)); + + return $amount; + } + /** * Returns a list of transactions in a modal. * - * @param Account $account - * @param Carbon|null $start - * @param Carbon|null $end + * @param Account $account + * @param Carbon|null $start + * @param Carbon|null $end * * @return JsonResponse * @throws FireflyException @@ -225,51 +265,11 @@ class ReconcileController extends Controller return response()->json(['html' => $html, 'startBalance' => $startBalance, 'endBalance' => $endBalance]); } - /** - * @param Account $account - * @param TransactionCurrency $currency - * @param array $journal - * @param string $amount - * - * @return string - */ - private function processJournal(Account $account, TransactionCurrency $currency, array $journal, string $amount): string - { - $toAdd = '0'; - Log::debug(sprintf('User submitted %s #%d: "%s"', $journal['transaction_type_type'], $journal['transaction_journal_id'], $journal['description'])); - - // not much magic below we need to cover using tests. - - if ($account->id === $journal['source_account_id']) { - if ($currency->id === $journal['currency_id']) { - $toAdd = $journal['amount']; - } - if (null !== $journal['foreign_currency_id'] && $journal['foreign_currency_id'] === $currency->id) { - $toAdd = $journal['foreign_amount']; - } - } - if ($account->id === $journal['destination_account_id']) { - if ($currency->id === $journal['currency_id']) { - $toAdd = bcmul($journal['amount'], '-1'); - } - if (null !== $journal['foreign_currency_id'] && $journal['foreign_currency_id'] === $currency->id) { - $toAdd = bcmul($journal['foreign_amount'], '-1'); - } - } - - - Log::debug(sprintf('Going to add %s to %s', $toAdd, $amount)); - $amount = bcadd($amount, $toAdd); - Log::debug(sprintf('Result is %s', $amount)); - - return $amount; - } - /** * "fix" amounts to make it easier on the reconciliation overview: * - * @param Account $account - * @param array $array + * @param Account $account + * @param array $array * * @return array */ diff --git a/app/Http/Controllers/Json/RecurrenceController.php b/app/Http/Controllers/Json/RecurrenceController.php index 44d742a373..25de916d5a 100644 --- a/app/Http/Controllers/Json/RecurrenceController.php +++ b/app/Http/Controllers/Json/RecurrenceController.php @@ -63,7 +63,7 @@ class RecurrenceController extends Controller /** * Shows all events for a repetition. Used in calendar. * - * @param Request $request + * @param Request $request * * @return JsonResponse * @@ -123,7 +123,7 @@ class RecurrenceController extends Controller foreach ($occurrences as $current) { if ($current->gte($start)) { $event = [ - 'id' => $repetitionType.$firstDate->format('Ymd'), + 'id' => $repetitionType . $firstDate->format('Ymd'), 'title' => 'X', 'allDay' => true, 'start' => $current->format('Y-m-d'), @@ -141,7 +141,7 @@ class RecurrenceController extends Controller /** * Suggests repetition moments. * - * @param Request $request + * @param Request $request * * @return JsonResponse * @throws FireflyException diff --git a/app/Http/Controllers/Json/RuleController.php b/app/Http/Controllers/Json/RuleController.php index 3360fca391..d84b18d3c2 100644 --- a/app/Http/Controllers/Json/RuleController.php +++ b/app/Http/Controllers/Json/RuleController.php @@ -38,7 +38,7 @@ class RuleController extends Controller /** * Render HTML form for rule action. * - * @param Request $request + * @param Request $request * * @return JsonResponse * @throws FireflyException @@ -49,7 +49,7 @@ class RuleController extends Controller $keys = array_keys(config('firefly.rule-actions')); $actions = []; foreach ($keys as $key) { - $actions[$key] = (string)trans('firefly.rule_action_'.$key.'_choice'); + $actions[$key] = (string)trans('firefly.rule_action_' . $key . '_choice'); } try { $view = view('rules.partials.action', compact('actions', 'count'))->render(); @@ -65,7 +65,7 @@ class RuleController extends Controller /** * Render HTML for rule trigger. * - * @param Request $request + * @param Request $request * * @return JsonResponse * @throws FireflyException diff --git a/app/Http/Controllers/NewUserController.php b/app/Http/Controllers/NewUserController.php index cfae0db8c8..5ba5d4fd12 100644 --- a/app/Http/Controllers/NewUserController.php +++ b/app/Http/Controllers/NewUserController.php @@ -85,8 +85,8 @@ class NewUserController extends Controller /** * Store his new settings. * - * @param NewUserFormRequest $request - * @param CurrencyRepositoryInterface $currencyRepository + * @param NewUserFormRequest $request + * @param CurrencyRepositoryInterface $currencyRepository * * @return RedirectResponse|Redirector * @throws FireflyException diff --git a/app/Http/Controllers/ObjectGroup/DeleteController.php b/app/Http/Controllers/ObjectGroup/DeleteController.php index bcce7db010..c0a3b41ecd 100644 --- a/app/Http/Controllers/ObjectGroup/DeleteController.php +++ b/app/Http/Controllers/ObjectGroup/DeleteController.php @@ -62,7 +62,7 @@ class DeleteController extends Controller /** * Delete a piggy bank. * - * @param ObjectGroup $objectGroup + * @param ObjectGroup $objectGroup * * @return Factory|View */ @@ -80,7 +80,7 @@ class DeleteController extends Controller /** * Destroy the piggy bank. * - * @param ObjectGroup $objectGroup + * @param ObjectGroup $objectGroup * * @return RedirectResponse */ diff --git a/app/Http/Controllers/ObjectGroup/EditController.php b/app/Http/Controllers/ObjectGroup/EditController.php index cc1a20ec68..507804d773 100644 --- a/app/Http/Controllers/ObjectGroup/EditController.php +++ b/app/Http/Controllers/ObjectGroup/EditController.php @@ -65,7 +65,7 @@ class EditController extends Controller /** * Edit an object group. * - * @param ObjectGroup $objectGroup + * @param ObjectGroup $objectGroup * * @return Factory|View */ @@ -85,8 +85,8 @@ class EditController extends Controller /** * Update a piggy bank. * - * @param ObjectGroupFormRequest $request - * @param ObjectGroup $objectGroup + * @param ObjectGroupFormRequest $request + * @param ObjectGroup $objectGroup * * @return Application|RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/ObjectGroup/IndexController.php b/app/Http/Controllers/ObjectGroup/IndexController.php index 27071864a8..7f48d4240c 100644 --- a/app/Http/Controllers/ObjectGroup/IndexController.php +++ b/app/Http/Controllers/ObjectGroup/IndexController.php @@ -75,8 +75,8 @@ class IndexController extends Controller } /** - * @param Request $request - * @param ObjectGroup $objectGroup + * @param Request $request + * @param ObjectGroup $objectGroup * * @return JsonResponse */ diff --git a/app/Http/Controllers/PiggyBank/AmountController.php b/app/Http/Controllers/PiggyBank/AmountController.php index d76491a68e..ec59780b2e 100644 --- a/app/Http/Controllers/PiggyBank/AmountController.php +++ b/app/Http/Controllers/PiggyBank/AmountController.php @@ -68,7 +68,7 @@ class AmountController extends Controller /** * Add money to piggy bank. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return Factory|View */ @@ -89,7 +89,7 @@ class AmountController extends Controller /** * Add money to piggy bank (for mobile devices). * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return Factory|View */ @@ -113,8 +113,8 @@ class AmountController extends Controller /** * Add money to piggy bank. * - * @param Request $request - * @param PiggyBank $piggyBank + * @param Request $request + * @param PiggyBank $piggyBank * * @return RedirectResponse */ @@ -140,7 +140,7 @@ class AmountController extends Controller return redirect(route('piggy-banks.index')); } - Log::error('Cannot add '.$amount.' because canAddAmount returned false.'); + Log::error('Cannot add ' . $amount . ' because canAddAmount returned false.'); session()->flash( 'error', (string)trans( @@ -155,8 +155,8 @@ class AmountController extends Controller /** * Remove money from piggy bank. * - * @param Request $request - * @param PiggyBank $piggyBank + * @param Request $request + * @param PiggyBank $piggyBank * * @return RedirectResponse */ @@ -197,7 +197,7 @@ class AmountController extends Controller /** * Remove money from piggy bank form. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return Factory|View */ @@ -212,7 +212,7 @@ class AmountController extends Controller /** * Remove money from piggy bank (for mobile devices). * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return Factory|View */ diff --git a/app/Http/Controllers/PiggyBank/CreateController.php b/app/Http/Controllers/PiggyBank/CreateController.php index 2253f0b18c..66c3a8d518 100644 --- a/app/Http/Controllers/PiggyBank/CreateController.php +++ b/app/Http/Controllers/PiggyBank/CreateController.php @@ -86,7 +86,7 @@ class CreateController extends Controller /** * Store a new piggy bank. * - * @param PiggyBankStoreRequest $request + * @param PiggyBankStoreRequest $request * * @return RedirectResponse|Redirector * @throws FireflyException diff --git a/app/Http/Controllers/PiggyBank/DeleteController.php b/app/Http/Controllers/PiggyBank/DeleteController.php index 2515a1cc35..45d17de6a1 100644 --- a/app/Http/Controllers/PiggyBank/DeleteController.php +++ b/app/Http/Controllers/PiggyBank/DeleteController.php @@ -62,7 +62,7 @@ class DeleteController extends Controller /** * Delete a piggy bank. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return Factory|View */ @@ -79,7 +79,7 @@ class DeleteController extends Controller /** * Destroy the piggy bank. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return RedirectResponse */ diff --git a/app/Http/Controllers/PiggyBank/EditController.php b/app/Http/Controllers/PiggyBank/EditController.php index 48c925e050..45b1db77fa 100644 --- a/app/Http/Controllers/PiggyBank/EditController.php +++ b/app/Http/Controllers/PiggyBank/EditController.php @@ -70,7 +70,7 @@ class EditController extends Controller /** * Edit a piggy bank. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return Factory|View */ @@ -113,8 +113,8 @@ class EditController extends Controller /** * Update a piggy bank. * - * @param PiggyBankUpdateRequest $request - * @param PiggyBank $piggyBank + * @param PiggyBankUpdateRequest $request + * @param PiggyBank $piggyBank * * @return RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/PiggyBank/IndexController.php b/app/Http/Controllers/PiggyBank/IndexController.php index 9383eebd87..fb0412e1cd 100644 --- a/app/Http/Controllers/PiggyBank/IndexController.php +++ b/app/Http/Controllers/PiggyBank/IndexController.php @@ -74,7 +74,7 @@ class IndexController extends Controller * * TODO very complicated function. * - * @param Request $request + * @param Request $request * * @return Factory|View * @throws FireflyException @@ -145,30 +145,7 @@ class IndexController extends Controller } /** - * Set the order of a piggy bank. - * - * @param Request $request - * @param PiggyBank $piggyBank - * - * @return JsonResponse - */ - public function setOrder(Request $request, PiggyBank $piggyBank): JsonResponse - { - $objectGroupTitle = (string)$request->get('objectGroupTitle'); - $newOrder = (int)$request->get('order'); - $this->piggyRepos->setOrder($piggyBank, $newOrder); - if ('' !== $objectGroupTitle) { - $this->piggyRepos->setObjectGroup($piggyBank, $objectGroupTitle); - } - if ('' === $objectGroupTitle) { - $this->piggyRepos->removeObjectGroup($piggyBank); - } - - return response()->json(['data' => 'OK']); - } - - /** - * @param array $piggyBanks + * @param array $piggyBanks * * @return array */ @@ -206,4 +183,27 @@ class IndexController extends Controller return $piggyBanks; } + + /** + * Set the order of a piggy bank. + * + * @param Request $request + * @param PiggyBank $piggyBank + * + * @return JsonResponse + */ + public function setOrder(Request $request, PiggyBank $piggyBank): JsonResponse + { + $objectGroupTitle = (string)$request->get('objectGroupTitle'); + $newOrder = (int)$request->get('order'); + $this->piggyRepos->setOrder($piggyBank, $newOrder); + if ('' !== $objectGroupTitle) { + $this->piggyRepos->setObjectGroup($piggyBank, $objectGroupTitle); + } + if ('' === $objectGroupTitle) { + $this->piggyRepos->removeObjectGroup($piggyBank); + } + + return response()->json(['data' => 'OK']); + } } diff --git a/app/Http/Controllers/PiggyBank/ShowController.php b/app/Http/Controllers/PiggyBank/ShowController.php index a81404e93b..d9ff1f9e36 100644 --- a/app/Http/Controllers/PiggyBank/ShowController.php +++ b/app/Http/Controllers/PiggyBank/ShowController.php @@ -66,7 +66,7 @@ class ShowController extends Controller /** * Show a single piggy bank. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return Factory|View * @throws FireflyException diff --git a/app/Http/Controllers/Popup/ReportController.php b/app/Http/Controllers/Popup/ReportController.php index 59225acbd9..e24946453b 100644 --- a/app/Http/Controllers/Popup/ReportController.php +++ b/app/Http/Controllers/Popup/ReportController.php @@ -40,7 +40,7 @@ class ReportController extends Controller /** * Generate popup view. * - * @param Request $request + * @param Request $request * * @return JsonResponse * @throws FireflyException diff --git a/app/Http/Controllers/PreferencesController.php b/app/Http/Controllers/PreferencesController.php index 067e040eaa..cf92b1603d 100644 --- a/app/Http/Controllers/PreferencesController.php +++ b/app/Http/Controllers/PreferencesController.php @@ -65,7 +65,7 @@ class PreferencesController extends Controller /** * Show overview of preferences. * - * @param AccountRepositoryInterface $repository + * @param AccountRepositoryInterface $repository * * @return Factory|View * @throws FireflyException @@ -106,7 +106,7 @@ class PreferencesController extends Controller $slackUrl = app('preferences')->get('slack_webhook_url', '')->data; $customFiscalYear = app('preferences')->get('customFiscalYear', 0)->data; $fiscalYearStartStr = app('preferences')->get('fiscalYearStart', '01-01')->data; - $fiscalYearStart = date('Y').'-'.$fiscalYearStartStr; + $fiscalYearStart = date('Y') . '-' . $fiscalYearStartStr; $tjOptionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data; $availableDarkModes = config('firefly.available_dark_modes'); @@ -159,7 +159,7 @@ class PreferencesController extends Controller /** * Store new preferences. * - * @param Request $request + * @param Request $request * * @return RedirectResponse|Redirector * @throws FireflyException diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index eaff77be1a..59b624fac6 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -95,55 +95,10 @@ class ProfileController extends Controller $this->middleware(IsDemoUser::class)->except(['index']); } - /** - * Change your email address. - * - * @param Request $request - * - * @return Factory|RedirectResponse|View - */ - public function changeEmail(Request $request): Factory|RedirectResponse|View - { - if (!$this->internalAuth) { - $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); - - return redirect(route('profile.index')); - } - - $title = auth()->user()->email; - $email = auth()->user()->email; - $subTitle = (string)trans('firefly.change_your_email'); - $subTitleIcon = 'fa-envelope'; - - return view('profile.change-email', compact('title', 'subTitle', 'subTitleIcon', 'email')); - } - - /** - * Change your password. - * - * @param Request $request - * - * @return Factory|RedirectResponse|Redirector|View - */ - public function changePassword(Request $request) - { - if (!$this->internalAuth) { - $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); - - return redirect(route('profile.index')); - } - - $title = auth()->user()->email; - $subTitle = (string)trans('firefly.change_your_password'); - $subTitleIcon = 'fa-key'; - - return view('profile.change-password', compact('title', 'subTitle', 'subTitleIcon')); - } - /** * View that generates a 2FA code for the user. * - * @param Request $request + * @param Request $request * * @return Factory|View|RedirectResponse * @throws IncompatibleWithGoogleAuthenticatorException @@ -152,7 +107,7 @@ class ProfileController extends Controller * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function code(Request $request): Factory|View|RedirectResponse + public function code(Request $request): Factory | View | RedirectResponse { if (!$this->internalAuth) { $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); @@ -201,14 +156,14 @@ class ProfileController extends Controller /** * Screen to confirm email change. * - * @param UserRepositoryInterface $repository - * @param string $token + * @param UserRepositoryInterface $repository + * @param string $token * * @return RedirectResponse|Redirector * * @throws FireflyException */ - public function confirmEmailChange(UserRepositoryInterface $repository, string $token): RedirectResponse|Redirector + public function confirmEmailChange(UserRepositoryInterface $repository, string $token): RedirectResponse | Redirector { if (!$this->internalAuth) { throw new FireflyException(trans('firefly.external_user_mgt_disabled')); @@ -238,11 +193,11 @@ class ProfileController extends Controller /** * Delete your account view. * - * @param Request $request + * @param Request $request * * @return View|RedirectResponse */ - public function deleteAccount(Request $request): View|RedirectResponse + public function deleteAccount(Request $request): View | RedirectResponse { if (!$this->internalAuth) { $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); @@ -260,7 +215,7 @@ class ProfileController extends Controller * Delete 2FA routine. * */ - public function deleteCode(Request $request): RedirectResponse|Redirector + public function deleteCode(Request $request): RedirectResponse | Redirector { if (!$this->internalAuth) { $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); @@ -288,7 +243,7 @@ class ProfileController extends Controller * Enable 2FA screen. * */ - public function enable2FA(Request $request): RedirectResponse|Redirector + public function enable2FA(Request $request): RedirectResponse | Redirector { if (!$this->internalAuth) { $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); @@ -320,7 +275,7 @@ class ProfileController extends Controller * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function index(): Factory|View + public function index(): Factory | View { /** @var User $user */ $user = auth()->user(); @@ -335,7 +290,7 @@ class ProfileController extends Controller if (0 === $count) { /** @var ClientRepository $repository */ $repository = app(ClientRepository::class); - $repository->createPersonalAccessClient(null, config('app.name').' Personal Access Client', 'http://localhost'); + $repository->createPersonalAccessClient(null, config('app.name') . ' Personal Access Client', 'http://localhost'); } $accessToken = app('preferences')->get('access_token'); @@ -353,7 +308,7 @@ class ProfileController extends Controller /** * @return Factory|View|RedirectResponse */ - public function logoutOtherSessions(): Factory|View|RedirectResponse + public function logoutOtherSessions(): Factory | View | RedirectResponse { if (!$this->internalAuth) { session()->flash('info', (string)trans('firefly.external_auth_disabled')); @@ -365,12 +320,12 @@ class ProfileController extends Controller } /** - * @param Request $request + * @param Request $request * * @return Factory|View|RedirectResponse * @throws FireflyException */ - public function newBackupCodes(Request $request): Factory|View|RedirectResponse + public function newBackupCodes(Request $request): Factory | View | RedirectResponse { if (!$this->internalAuth) { $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); @@ -396,12 +351,12 @@ class ProfileController extends Controller /** * Submit the change email form. * - * @param EmailFormRequest $request - * @param UserRepositoryInterface $repository + * @param EmailFormRequest $request + * @param UserRepositoryInterface $repository * * @return Factory|RedirectResponse|Redirector */ - public function postChangeEmail(EmailFormRequest $request, UserRepositoryInterface $repository): Factory|RedirectResponse|Redirector + public function postChangeEmail(EmailFormRequest $request, UserRepositoryInterface $repository): Factory | RedirectResponse | Redirector { if (!$this->internalAuth) { $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); @@ -442,11 +397,34 @@ class ProfileController extends Controller return redirect(route('index')); } + /** + * Change your email address. + * + * @param Request $request + * + * @return Factory|RedirectResponse|View + */ + public function changeEmail(Request $request): Factory | RedirectResponse | View + { + if (!$this->internalAuth) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); + + return redirect(route('profile.index')); + } + + $title = auth()->user()->email; + $email = auth()->user()->email; + $subTitle = (string)trans('firefly.change_your_email'); + $subTitleIcon = 'fa-envelope'; + + return view('profile.change-email', compact('title', 'subTitle', 'subTitleIcon', 'email')); + } + /** * Submit change password form. * - * @param ProfileFormRequest $request - * @param UserRepositoryInterface $repository + * @param ProfileFormRequest $request + * @param UserRepositoryInterface $repository * * @return RedirectResponse|Redirector */ @@ -477,10 +455,32 @@ class ProfileController extends Controller return redirect(route('profile.index')); } + /** + * Change your password. + * + * @param Request $request + * + * @return Factory|RedirectResponse|Redirector|View + */ + public function changePassword(Request $request) + { + if (!$this->internalAuth) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); + + return redirect(route('profile.index')); + } + + $title = auth()->user()->email; + $subTitle = (string)trans('firefly.change_your_password'); + $subTitleIcon = 'fa-key'; + + return view('profile.change-password', compact('title', 'subTitle', 'subTitleIcon')); + } + /** * Submit 2FA for the first time. * - * @param TokenFormRequest $request + * @param TokenFormRequest $request * * @return RedirectResponse|Redirector * @throws FireflyException @@ -527,11 +527,56 @@ class ProfileController extends Controller return redirect(route('profile.index')); } + /** + * TODO duplicate code. + * + * @param string $mfaCode + * + * @throws FireflyException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + private function addToMFAHistory(string $mfaCode): void + { + /** @var array $mfaHistory */ + $mfaHistory = app('preferences')->get('mfa_history', [])->data; + $entry = [ + 'time' => time(), + 'code' => $mfaCode, + ]; + $mfaHistory[] = $entry; + + app('preferences')->set('mfa_history', $mfaHistory); + $this->filterMFAHistory(); + } + + /** + * Remove old entries from the preferences array. + */ + private function filterMFAHistory(): void + { + /** @var array $mfaHistory */ + $mfaHistory = app('preferences')->get('mfa_history', [])->data; + $newHistory = []; + $now = time(); + foreach ($mfaHistory as $entry) { + $time = $entry['time']; + $code = $entry['code']; + if ($now - $time <= 300) { + $newHistory[] = [ + 'time' => $time, + 'code' => $code, + ]; + } + } + app('preferences')->set('mfa_history', $newHistory); + } + /** * Submit delete account. * - * @param UserRepositoryInterface $repository - * @param DeleteAccountFormRequest $request + * @param UserRepositoryInterface $repository + * @param DeleteAccountFormRequest $request * * @return RedirectResponse|Redirector */ @@ -560,7 +605,7 @@ class ProfileController extends Controller } /** - * @param Request $request + * @param Request $request * * @return Application|RedirectResponse|Redirector * @throws AuthenticationException @@ -590,7 +635,7 @@ class ProfileController extends Controller /** * Regenerate access token. * - * @param Request $request + * @param Request $request * * @return RedirectResponse|Redirector * @throws Exception @@ -615,9 +660,9 @@ class ProfileController extends Controller /** * Undo change of user email address. * - * @param UserRepositoryInterface $repository - * @param string $token - * @param string $hash + * @param UserRepositoryInterface $repository + * @param string $token + * @param string $hash * * @return RedirectResponse|Redirector * @@ -666,49 +711,4 @@ class ProfileController extends Controller return redirect(route('login')); } - - /** - * TODO duplicate code. - * - * @param string $mfaCode - * - * @throws FireflyException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - private function addToMFAHistory(string $mfaCode): void - { - /** @var array $mfaHistory */ - $mfaHistory = app('preferences')->get('mfa_history', [])->data; - $entry = [ - 'time' => time(), - 'code' => $mfaCode, - ]; - $mfaHistory[] = $entry; - - app('preferences')->set('mfa_history', $mfaHistory); - $this->filterMFAHistory(); - } - - /** - * Remove old entries from the preferences array. - */ - private function filterMFAHistory(): void - { - /** @var array $mfaHistory */ - $mfaHistory = app('preferences')->get('mfa_history', [])->data; - $newHistory = []; - $now = time(); - foreach ($mfaHistory as $entry) { - $time = $entry['time']; - $code = $entry['code']; - if ($now - $time <= 300) { - $newHistory[] = [ - 'time' => $time, - 'code' => $code, - ]; - } - } - app('preferences')->set('mfa_history', $newHistory); - } } diff --git a/app/Http/Controllers/Recurring/CreateController.php b/app/Http/Controllers/Recurring/CreateController.php index aebb15bfd7..ac51114be3 100644 --- a/app/Http/Controllers/Recurring/CreateController.php +++ b/app/Http/Controllers/Recurring/CreateController.php @@ -79,7 +79,7 @@ class CreateController extends Controller /** * Create a new recurring transaction. * - * @param Request $request + * @param Request $request * * @return Factory|View */ @@ -124,8 +124,8 @@ class CreateController extends Controller } /** - * @param Request $request - * @param TransactionJournal $journal + * @param Request $request + * @param TransactionJournal $journal * * @return Factory|\Illuminate\Contracts\View\View */ @@ -221,7 +221,7 @@ class CreateController extends Controller /** * Store a recurring transaction. * - * @param RecurrenceFormRequest $request + * @param RecurrenceFormRequest $request * * @return RedirectResponse|Redirector * @throws FireflyException diff --git a/app/Http/Controllers/Recurring/DeleteController.php b/app/Http/Controllers/Recurring/DeleteController.php index 0e3eb64aa5..829ae2b9fe 100644 --- a/app/Http/Controllers/Recurring/DeleteController.php +++ b/app/Http/Controllers/Recurring/DeleteController.php @@ -65,7 +65,7 @@ class DeleteController extends Controller /** * Delete a recurring transaction form. * - * @param Recurrence $recurrence + * @param Recurrence $recurrence * * @return Factory|View */ @@ -83,16 +83,16 @@ class DeleteController extends Controller /** * Destroy the recurring transaction. * - * @param RecurringRepositoryInterface $repository - * @param Request $request - * @param Recurrence $recurrence + * @param RecurringRepositoryInterface $repository + * @param Request $request + * @param Recurrence $recurrence * * @return RedirectResponse|Redirector */ public function destroy(RecurringRepositoryInterface $repository, Request $request, Recurrence $recurrence) { $repository->destroy($recurrence); - $request->session()->flash('success', (string)trans('firefly.'.'recurrence_deleted', ['title' => $recurrence->title])); + $request->session()->flash('success', (string)trans('firefly.' . 'recurrence_deleted', ['title' => $recurrence->title])); app('preferences')->mark(); return redirect($this->getPreviousUrl('recurrences.delete.url')); diff --git a/app/Http/Controllers/Recurring/EditController.php b/app/Http/Controllers/Recurring/EditController.php index 484189c99c..f61ae3ac60 100644 --- a/app/Http/Controllers/Recurring/EditController.php +++ b/app/Http/Controllers/Recurring/EditController.php @@ -80,8 +80,8 @@ class EditController extends Controller /** * Edit a recurring transaction. * - * @param Request $request - * @param Recurrence $recurrence + * @param Request $request + * @param Recurrence $recurrence * * @return Factory|View * @throws FireflyException @@ -107,7 +107,7 @@ class EditController extends Controller $repetition = $recurrence->recurrenceRepetitions()->first(); $currentRepType = $repetition->repetition_type; if ('' !== $repetition->repetition_moment) { - $currentRepType .= ','.$repetition->repetition_moment; + $currentRepType .= ',' . $repetition->repetition_moment; } // put previous url in session if not redirect from store (not "return_to_edit"). @@ -167,8 +167,8 @@ class EditController extends Controller /** * Update the recurring transaction. * - * @param RecurrenceFormRequest $request - * @param Recurrence $recurrence + * @param RecurrenceFormRequest $request + * @param Recurrence $recurrence * * @return RedirectResponse|Redirector * @throws FireflyException diff --git a/app/Http/Controllers/Recurring/IndexController.php b/app/Http/Controllers/Recurring/IndexController.php index 2cd093e608..c7af4775b4 100644 --- a/app/Http/Controllers/Recurring/IndexController.php +++ b/app/Http/Controllers/Recurring/IndexController.php @@ -74,7 +74,7 @@ class IndexController extends Controller * TODO the notes of a recurrence are pretty pointless at this moment. * Show all recurring transactions. * - * @param Request $request + * @param Request $request * * @return Factory|View * @throws FireflyException diff --git a/app/Http/Controllers/Recurring/TriggerController.php b/app/Http/Controllers/Recurring/TriggerController.php index 1f1e1bdf68..6cc4b6dfa8 100644 --- a/app/Http/Controllers/Recurring/TriggerController.php +++ b/app/Http/Controllers/Recurring/TriggerController.php @@ -39,8 +39,8 @@ use Illuminate\Support\Facades\Log; class TriggerController extends Controller { /** - * @param Recurrence $recurrence - * @param TriggerRecurrenceRequest $request + * @param Recurrence $recurrence + * @param TriggerRecurrenceRequest $request * @return RedirectResponse */ public function trigger(Recurrence $recurrence, TriggerRecurrenceRequest $request): RedirectResponse diff --git a/app/Http/Controllers/Report/AccountController.php b/app/Http/Controllers/Report/AccountController.php index 1d7a8a5263..eac746a1d8 100644 --- a/app/Http/Controllers/Report/AccountController.php +++ b/app/Http/Controllers/Report/AccountController.php @@ -40,9 +40,9 @@ class AccountController extends Controller /** * Show partial overview for account balances. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException diff --git a/app/Http/Controllers/Report/BalanceController.php b/app/Http/Controllers/Report/BalanceController.php index 7909be8e9a..7eeaffc454 100644 --- a/app/Http/Controllers/Report/BalanceController.php +++ b/app/Http/Controllers/Report/BalanceController.php @@ -62,9 +62,9 @@ class BalanceController extends Controller /** * Show overview of budget balances. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException diff --git a/app/Http/Controllers/Report/BillController.php b/app/Http/Controllers/Report/BillController.php index f8b87d3b8c..fab0deb615 100644 --- a/app/Http/Controllers/Report/BillController.php +++ b/app/Http/Controllers/Report/BillController.php @@ -38,9 +38,9 @@ use Throwable; class BillController extends Controller { /** - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return mixed|string * @throws FireflyException diff --git a/app/Http/Controllers/Report/BudgetController.php b/app/Http/Controllers/Report/BudgetController.php index 60560315fe..9c82a31a44 100644 --- a/app/Http/Controllers/Report/BudgetController.php +++ b/app/Http/Controllers/Report/BudgetController.php @@ -68,10 +68,10 @@ class BudgetController extends Controller /** * Partial used in the budget report. * - * @param Collection $accounts - * @param Collection $budgets - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $budgets + * @param Carbon $start + * @param Carbon $end * * @return Factory|View * @throws FireflyException @@ -95,10 +95,10 @@ class BudgetController extends Controller } /** - * @param Collection $accounts - * @param Collection $budgets - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $budgets + * @param Carbon $start + * @param Carbon $end * * @return Factory|View */ @@ -151,10 +151,10 @@ class BudgetController extends Controller } /** - * @param Collection $accounts - * @param Collection $budgets - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $budgets + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -204,10 +204,10 @@ class BudgetController extends Controller } /** - * @param Collection $accounts - * @param Collection $budgets - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $budgets + * @param Carbon $start + * @param Carbon $end * * @return Factory|View */ @@ -274,9 +274,9 @@ class BudgetController extends Controller /** * Show partial overview of budgets. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -301,9 +301,9 @@ class BudgetController extends Controller /** * Show budget overview for a period. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return mixed|string * @throws FireflyException @@ -364,10 +364,10 @@ class BudgetController extends Controller } /** - * @param Collection $accounts - * @param Collection $budgets - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $budgets + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException diff --git a/app/Http/Controllers/Report/CategoryController.php b/app/Http/Controllers/Report/CategoryController.php index 729ba83d3e..acab659218 100644 --- a/app/Http/Controllers/Report/CategoryController.php +++ b/app/Http/Controllers/Report/CategoryController.php @@ -68,10 +68,10 @@ class CategoryController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return Factory|View */ @@ -167,10 +167,10 @@ class CategoryController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return Factory|View */ @@ -271,10 +271,10 @@ class CategoryController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -324,10 +324,10 @@ class CategoryController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -377,10 +377,10 @@ class CategoryController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return Factory|View */ @@ -487,9 +487,9 @@ class CategoryController extends Controller /** * Show overview of expenses in category. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return mixed|string * @throws FireflyException @@ -567,10 +567,10 @@ class CategoryController extends Controller /** * Show overview of income in category. * - * @param Collection $accounts + * @param Collection $accounts * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -646,9 +646,9 @@ class CategoryController extends Controller /** * Show overview of category transactions on the default report. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -687,10 +687,10 @@ class CategoryController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -738,10 +738,10 @@ class CategoryController extends Controller } /** - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException diff --git a/app/Http/Controllers/Report/DoubleController.php b/app/Http/Controllers/Report/DoubleController.php index 1dfda88e75..b2b68938d5 100644 --- a/app/Http/Controllers/Report/DoubleController.php +++ b/app/Http/Controllers/Report/DoubleController.php @@ -71,10 +71,10 @@ class DoubleController extends Controller } /** - * @param Collection $accounts - * @param Collection $doubles - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $doubles + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -124,10 +124,10 @@ class DoubleController extends Controller } /** - * @param Collection $accounts - * @param Collection $doubles - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $doubles + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -177,10 +177,10 @@ class DoubleController extends Controller } /** - * @param Collection $accounts - * @param Collection $double - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $double + * @param Carbon $start + * @param Carbon $end * * @return Factory|View */ @@ -296,10 +296,35 @@ class DoubleController extends Controller } /** - * @param Collection $accounts - * @param Collection $double - * @param Carbon $start - * @param Carbon $end + * TODO this method is duplicated. + * + * @param Collection $accounts + * @param int $id + * @param string $name + * @param string|null $iban + * + * @return string + */ + private function getCounterpartName(Collection $accounts, int $id, string $name, ?string $iban): string + { + /** @var Account $account */ + foreach ($accounts as $account) { + if ($account->name === $name && $account->id !== $id) { + return $account->name; + } + if (null !== $account->iban && $account->iban === $iban && $account->id !== $id) { + return $account->iban; + } + } + + return $name; + } + + /** + * @param Collection $accounts + * @param Collection $double + * @param Carbon $start + * @param Carbon $end * * @return Factory|View */ @@ -396,10 +421,10 @@ class DoubleController extends Controller } /** - * @param Collection $accounts - * @param Collection $doubles - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $doubles + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -447,10 +472,10 @@ class DoubleController extends Controller } /** - * @param Collection $accounts - * @param Collection $doubles - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $doubles + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -496,29 +521,4 @@ class DoubleController extends Controller return $result; } - - /** - * TODO this method is duplicated. - * - * @param Collection $accounts - * @param int $id - * @param string $name - * @param string|null $iban - * - * @return string - */ - private function getCounterpartName(Collection $accounts, int $id, string $name, ?string $iban): string - { - /** @var Account $account */ - foreach ($accounts as $account) { - if ($account->name === $name && $account->id !== $id) { - return $account->name; - } - if (null !== $account->iban && $account->iban === $iban && $account->id !== $id) { - return $account->iban; - } - } - - return $name; - } } diff --git a/app/Http/Controllers/Report/OperationsController.php b/app/Http/Controllers/Report/OperationsController.php index 7d833b2d09..7f534dba26 100644 --- a/app/Http/Controllers/Report/OperationsController.php +++ b/app/Http/Controllers/Report/OperationsController.php @@ -62,9 +62,9 @@ class OperationsController extends Controller /** * View of income and expense. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return mixed|string * @throws FireflyException @@ -98,9 +98,9 @@ class OperationsController extends Controller /** * View of income. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -134,9 +134,9 @@ class OperationsController extends Controller /** * Overview of income and expense. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return mixed|string * @throws FireflyException diff --git a/app/Http/Controllers/Report/TagController.php b/app/Http/Controllers/Report/TagController.php index 5929d992d5..8b43ead1db 100644 --- a/app/Http/Controllers/Report/TagController.php +++ b/app/Http/Controllers/Report/TagController.php @@ -61,10 +61,10 @@ class TagController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return Factory|View */ @@ -160,10 +160,10 @@ class TagController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return Factory|View */ @@ -264,10 +264,10 @@ class TagController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -317,10 +317,10 @@ class TagController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -370,10 +370,10 @@ class TagController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return Factory|View */ @@ -478,10 +478,10 @@ class TagController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -529,10 +529,10 @@ class TagController extends Controller } /** - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index c266fd6b66..c900af4634 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -80,9 +80,9 @@ class ReportController extends Controller /** * Show audit report. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return Factory|View|string * @@ -115,10 +115,10 @@ class ReportController extends Controller /** * Show budget report. * - * @param Collection $accounts - * @param Collection $budgets - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $budgets + * @param Carbon $start + * @param Carbon $end * * @return Factory|View|string * @@ -152,10 +152,10 @@ class ReportController extends Controller /** * Show category report. * - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return Factory|View|string * @@ -189,9 +189,9 @@ class ReportController extends Controller /** * Show default report. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return Factory|View|string * @@ -225,10 +225,10 @@ class ReportController extends Controller /** * Show account report. * - * @param Collection $accounts - * @param Collection $expense - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $expense + * @param Carbon $start + * @param Carbon $end * * @return string * @throws FireflyException @@ -262,7 +262,7 @@ class ReportController extends Controller /** * Show index. * - * @param AccountRepositoryInterface $repository + * @param AccountRepositoryInterface $repository * * @return Factory|View * @throws ContainerExceptionInterface @@ -305,7 +305,7 @@ class ReportController extends Controller /** * Show options for reports. * - * @param string $reportType + * @param string $reportType * * @return JsonResponse * @throws FireflyException @@ -326,7 +326,7 @@ class ReportController extends Controller /** * Process the submit of report. * - * @param ReportFormRequest $request + * @param ReportFormRequest $request * * @return RedirectResponse|Redirector * @@ -395,10 +395,10 @@ class ReportController extends Controller /** * Get a tag report. * - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return Factory|View|string * @throws FireflyException diff --git a/app/Http/Controllers/Rule/CreateController.php b/app/Http/Controllers/Rule/CreateController.php index cd17de1fbc..836373616e 100644 --- a/app/Http/Controllers/Rule/CreateController.php +++ b/app/Http/Controllers/Rule/CreateController.php @@ -74,8 +74,8 @@ class CreateController extends Controller /** * Create a new rule. It will be stored under the given $ruleGroup. * - * @param Request $request - * @param RuleGroup|null $ruleGroup + * @param Request $request + * @param RuleGroup|null $ruleGroup * * @return Factory|View * @throws FireflyException @@ -137,8 +137,8 @@ class CreateController extends Controller /** * Create a new rule. It will be stored under the given $ruleGroup. * - * @param Request $request - * @param Bill $bill + * @param Request $request + * @param Bill $bill * * @return Factory|View * @throws FireflyException @@ -189,8 +189,8 @@ class CreateController extends Controller } /** - * @param Request $request - * @param TransactionJournal $journal + * @param Request $request + * @param TransactionJournal $journal * * @return Factory|\Illuminate\Contracts\View\View * @throws FireflyException @@ -240,7 +240,7 @@ class CreateController extends Controller } /** - * @param Request $request + * @param Request $request * @return JsonResponse */ public function duplicate(Request $request): JsonResponse @@ -257,7 +257,7 @@ class CreateController extends Controller /** * Store the new rule. * - * @param RuleFormRequest $request + * @param RuleFormRequest $request * * @return RedirectResponse|Redirector * diff --git a/app/Http/Controllers/Rule/DeleteController.php b/app/Http/Controllers/Rule/DeleteController.php index c38652d5f2..5f208b1735 100644 --- a/app/Http/Controllers/Rule/DeleteController.php +++ b/app/Http/Controllers/Rule/DeleteController.php @@ -62,7 +62,7 @@ class DeleteController extends Controller /** * Delete a given rule. * - * @param Rule $rule + * @param Rule $rule * * @return Factory|View */ @@ -79,7 +79,7 @@ class DeleteController extends Controller /** * Actually destroy the given rule. * - * @param Rule $rule + * @param Rule $rule * * @return RedirectResponse */ diff --git a/app/Http/Controllers/Rule/EditController.php b/app/Http/Controllers/Rule/EditController.php index 22261682e8..de93bb2839 100644 --- a/app/Http/Controllers/Rule/EditController.php +++ b/app/Http/Controllers/Rule/EditController.php @@ -74,8 +74,8 @@ class EditController extends Controller /** * Edit a rule. * - * @param Request $request - * @param Rule $rule + * @param Request $request + * @param Rule $rule * * @return Factory|View * @throws FireflyException @@ -140,33 +140,7 @@ class EditController extends Controller } /** - * Update the rule. - * - * @param RuleFormRequest $request - * @param Rule $rule - * - * @return RedirectResponse|Redirector - */ - public function update(RuleFormRequest $request, Rule $rule) - { - $data = $request->getRuleData(); - - $this->ruleRepos->update($rule, $data); - - session()->flash('success', (string)trans('firefly.updated_rule', ['title' => $rule->title])); - app('preferences')->mark(); - $redirect = redirect($this->getPreviousUrl('rules.edit.url')); - if (1 === (int)$request->get('return_to_edit')) { - session()->put('rules.edit.fromUpdate', true); - - $redirect = redirect(route('rules.edit', [$rule->id]))->withInput(['return_to_edit' => 1]); - } - - return $redirect; - } - - /** - * @param array $submittedOperators + * @param array $submittedOperators * * @return array * @throws FireflyException @@ -208,4 +182,30 @@ class EditController extends Controller return $renderedEntries; } + + /** + * Update the rule. + * + * @param RuleFormRequest $request + * @param Rule $rule + * + * @return RedirectResponse|Redirector + */ + public function update(RuleFormRequest $request, Rule $rule) + { + $data = $request->getRuleData(); + + $this->ruleRepos->update($rule, $data); + + session()->flash('success', (string)trans('firefly.updated_rule', ['title' => $rule->title])); + app('preferences')->mark(); + $redirect = redirect($this->getPreviousUrl('rules.edit.url')); + if (1 === (int)$request->get('return_to_edit')) { + session()->put('rules.edit.fromUpdate', true); + + $redirect = redirect(route('rules.edit', [$rule->id]))->withInput(['return_to_edit' => 1]); + } + + return $redirect; + } } diff --git a/app/Http/Controllers/Rule/IndexController.php b/app/Http/Controllers/Rule/IndexController.php index eec5193b90..f4dec56a96 100644 --- a/app/Http/Controllers/Rule/IndexController.php +++ b/app/Http/Controllers/Rule/IndexController.php @@ -80,9 +80,9 @@ class IndexController extends Controller } /** - * @param Request $request - * @param Rule $rule - * @param RuleGroup $ruleGroup + * @param Request $request + * @param Rule $rule + * @param RuleGroup $ruleGroup * * @return JsonResponse */ @@ -95,7 +95,7 @@ class IndexController extends Controller } /** - * @param Rule $rule + * @param Rule $rule * * @return RedirectResponse */ diff --git a/app/Http/Controllers/Rule/SelectController.php b/app/Http/Controllers/Rule/SelectController.php index cec6291ebb..89a3317702 100644 --- a/app/Http/Controllers/Rule/SelectController.php +++ b/app/Http/Controllers/Rule/SelectController.php @@ -70,8 +70,8 @@ class SelectController extends Controller /** * Execute the given rule on a set of existing transactions. * - * @param SelectTransactionsRequest $request - * @param Rule $rule + * @param SelectTransactionsRequest $request + * @param Rule $rule * * @return RedirectResponse */ @@ -106,7 +106,7 @@ class SelectController extends Controller /** * View to select transactions by a rule. * - * @param Rule $rule + * @param Rule $rule * * @return Factory|View */ @@ -129,7 +129,7 @@ class SelectController extends Controller * This method allows the user to test a certain set of rule triggers. The rule triggers are passed along * using the URL parameters (GET), and are usually put there using a Javascript thing. * - * @param TestRuleFormRequest $request + * @param TestRuleFormRequest $request * * @return JsonResponse * @throws FireflyException @@ -196,7 +196,7 @@ class SelectController extends Controller * This method allows the user to test a certain set of rule triggers. The rule triggers are grabbed from * the rule itself. * - * @param Rule $rule + * @param Rule $rule * * @return JsonResponse * @throws FireflyException diff --git a/app/Http/Controllers/RuleGroup/CreateController.php b/app/Http/Controllers/RuleGroup/CreateController.php index 9bcb38f7d0..c6d667d66c 100644 --- a/app/Http/Controllers/RuleGroup/CreateController.php +++ b/app/Http/Controllers/RuleGroup/CreateController.php @@ -82,7 +82,7 @@ class CreateController extends Controller /** * Store the rule group. * - * @param RuleGroupFormRequest $request + * @param RuleGroupFormRequest $request * * @return RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/RuleGroup/DeleteController.php b/app/Http/Controllers/RuleGroup/DeleteController.php index fd3d6de3dc..c488a609c7 100644 --- a/app/Http/Controllers/RuleGroup/DeleteController.php +++ b/app/Http/Controllers/RuleGroup/DeleteController.php @@ -64,7 +64,7 @@ class DeleteController extends Controller /** * Delete a rule group. * - * @param RuleGroup $ruleGroup + * @param RuleGroup $ruleGroup * * @return Factory|View */ @@ -81,8 +81,8 @@ class DeleteController extends Controller /** * Actually destroy the rule group. * - * @param Request $request - * @param RuleGroup $ruleGroup + * @param Request $request + * @param RuleGroup $ruleGroup * * @return RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/RuleGroup/EditController.php b/app/Http/Controllers/RuleGroup/EditController.php index 20c7d5873a..828fd3d0c2 100644 --- a/app/Http/Controllers/RuleGroup/EditController.php +++ b/app/Http/Controllers/RuleGroup/EditController.php @@ -65,8 +65,8 @@ class EditController extends Controller /** * Edit a rule group. * - * @param Request $request - * @param RuleGroup $ruleGroup + * @param Request $request + * @param RuleGroup $ruleGroup * * @return Factory|View */ @@ -91,7 +91,7 @@ class EditController extends Controller /** * Move a rule group in either direction. * - * @param Request $request + * @param Request $request * * @return JsonResponse */ @@ -123,8 +123,8 @@ class EditController extends Controller /** * Update the rule group. * - * @param RuleGroupFormRequest $request - * @param RuleGroup $ruleGroup + * @param RuleGroupFormRequest $request + * @param RuleGroup $ruleGroup * * @return $this|RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/RuleGroup/ExecutionController.php b/app/Http/Controllers/RuleGroup/ExecutionController.php index 336179f203..be6285e55f 100644 --- a/app/Http/Controllers/RuleGroup/ExecutionController.php +++ b/app/Http/Controllers/RuleGroup/ExecutionController.php @@ -66,8 +66,8 @@ class ExecutionController extends Controller /** * Execute the given rulegroup on a set of existing transactions. * - * @param SelectTransactionsRequest $request - * @param RuleGroup $ruleGroup + * @param SelectTransactionsRequest $request + * @param RuleGroup $ruleGroup * * @return RedirectResponse * @throws Exception @@ -103,7 +103,7 @@ class ExecutionController extends Controller /** * Select transactions to apply the group on. * - * @param RuleGroup $ruleGroup + * @param RuleGroup $ruleGroup * * @return Factory|View */ diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index f945d3fbb0..1ef3bfd253 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -58,8 +58,8 @@ class SearchController extends Controller /** * Do the search. * - * @param Request $request - * @param SearchInterface $searcher + * @param Request $request + * @param SearchInterface $searcher * * @return Factory|View */ @@ -99,8 +99,8 @@ class SearchController extends Controller /** * JSON request that does the work. * - * @param Request $request - * @param SearchInterface $searcher + * @param Request $request + * @param SearchInterface $searcher * * @return JsonResponse * @throws FireflyException @@ -121,7 +121,7 @@ class SearchController extends Controller $hasPages = $groups->hasPages(); $searchTime = round($searcher->searchTime(), 3); // in seconds $parameters = ['search' => $fullQuery]; - $url = route('search.index').'?'.http_build_query($parameters); + $url = route('search.index') . '?' . http_build_query($parameters); $groups->setPath($url); try { diff --git a/app/Http/Controllers/System/InstallController.php b/app/Http/Controllers/System/InstallController.php index f10d9ff6cd..e233a9b459 100644 --- a/app/Http/Controllers/System/InstallController.php +++ b/app/Http/Controllers/System/InstallController.php @@ -92,31 +92,7 @@ class InstallController extends Controller } /** - * Create specific RSA keys. - */ - public function keys(): void - { - // switch on PHP version. - $keys = []; - // switch on class existence. - Log::info('Will run PHP8 code.'); - $keys = RSA::createKey(4096); - - [$publicKey, $privateKey] = [ - Passport::keyPath('oauth-public.key'), - Passport::keyPath('oauth-private.key'), - ]; - - if (file_exists($publicKey) || file_exists($privateKey)) { - return; - } - - file_put_contents($publicKey, $keys['publickey']); - file_put_contents($privateKey, $keys['privatekey']); - } - - /** - * @param Request $request + * @param Request $request * * @return JsonResponse */ @@ -160,8 +136,8 @@ class InstallController extends Controller } /** - * @param string $command - * @param array $args + * @param string $command + * @param array $args * @return bool * @throws FireflyException */ @@ -185,4 +161,28 @@ class InstallController extends Controller return true; } + + /** + * Create specific RSA keys. + */ + public function keys(): void + { + // switch on PHP version. + $keys = []; + // switch on class existence. + Log::info('Will run PHP8 code.'); + $keys = RSA::createKey(4096); + + [$publicKey, $privateKey] = [ + Passport::keyPath('oauth-public.key'), + Passport::keyPath('oauth-private.key'), + ]; + + if (file_exists($publicKey) || file_exists($privateKey)) { + return; + } + + file_put_contents($publicKey, $keys['publickey']); + file_put_contents($privateKey, $keys['privatekey']); + } } diff --git a/app/Http/Controllers/TagController.php b/app/Http/Controllers/TagController.php index a73e7819b7..1fd2592349 100644 --- a/app/Http/Controllers/TagController.php +++ b/app/Http/Controllers/TagController.php @@ -103,7 +103,7 @@ class TagController extends Controller /** * Delete a tag. * - * @param Tag $tag + * @param Tag $tag * * @return Factory|View */ @@ -117,28 +117,10 @@ class TagController extends Controller return view('tags.delete', compact('tag', 'subTitle')); } - /** - * Destroy a tag. - * - * @param Tag $tag - * - * @return RedirectResponse - */ - public function destroy(Tag $tag): RedirectResponse - { - $tagName = $tag->tag; - $this->repository->destroy($tag); - - session()->flash('success', (string)trans('firefly.deleted_tag', ['tag' => $tagName])); - app('preferences')->mark(); - - return redirect($this->getPreviousUrl('tags.delete.url')); - } - /** * Edit a tag. * - * @param Tag $tag + * @param Tag $tag * * @return Factory|View */ @@ -173,7 +155,7 @@ class TagController extends Controller /** * Edit a tag. * - * @param TagRepositoryInterface $repository + * @param TagRepositoryInterface $repository * * @return Factory|View */ @@ -223,13 +205,31 @@ class TagController extends Controller return redirect(route('tags.index')); } + /** + * Destroy a tag. + * + * @param Tag $tag + * + * @return RedirectResponse + */ + public function destroy(Tag $tag): RedirectResponse + { + $tagName = $tag->tag; + $this->repository->destroy($tag); + + session()->flash('success', (string)trans('firefly.deleted_tag', ['tag' => $tagName])); + app('preferences')->mark(); + + return redirect($this->getPreviousUrl('tags.delete.url')); + } + /** * Show a single tag. * - * @param Request $request - * @param Tag $tag - * @param Carbon|null $start - * @param Carbon|null $end + * @param Request $request + * @param Tag $tag + * @param Carbon|null $start + * @param Carbon|null $end * * @return Factory|View * @throws FireflyException @@ -276,8 +276,8 @@ class TagController extends Controller /** * Show a single tag over all time. * - * @param Request $request - * @param Tag $tag + * @param Request $request + * @param Tag $tag * * @return Factory|View * @throws ContainerExceptionInterface @@ -310,7 +310,7 @@ class TagController extends Controller /** * Store a tag. * - * @param TagFormRequest $request + * @param TagFormRequest $request * * @return RedirectResponse */ @@ -351,8 +351,8 @@ class TagController extends Controller /** * Update a tag. * - * @param TagFormRequest $request - * @param Tag $tag + * @param TagFormRequest $request + * @param Tag $tag * * @return RedirectResponse */ diff --git a/app/Http/Controllers/Transaction/BulkController.php b/app/Http/Controllers/Transaction/BulkController.php index 8e95a26a03..28f4831ea4 100644 --- a/app/Http/Controllers/Transaction/BulkController.php +++ b/app/Http/Controllers/Transaction/BulkController.php @@ -70,7 +70,7 @@ class BulkController extends Controller * * TODO user wont be able to tell if the journal is part of a split. * - * @param array $journals + * @param array $journals * * @return Factory|View */ @@ -93,7 +93,7 @@ class BulkController extends Controller /** * Update all journals. * - * @param BulkEditJournalRequest $request + * @param BulkEditJournalRequest $request * * @return Application|RedirectResponse|Redirector */ @@ -135,9 +135,9 @@ class BulkController extends Controller } /** - * @param TransactionJournal $journal - * @param bool $ignoreUpdate - * @param int $budgetId + * @param TransactionJournal $journal + * @param bool $ignoreUpdate + * @param int $budgetId * * @return bool */ @@ -153,27 +153,9 @@ class BulkController extends Controller } /** - * @param TransactionJournal $journal - * @param bool $ignoreUpdate - * @param string $category - * - * @return bool - */ - private function updateJournalCategory(TransactionJournal $journal, bool $ignoreUpdate, string $category): bool - { - if (true === $ignoreUpdate) { - return false; - } - Log::debug(sprintf('Set budget to %s', $category)); - $this->repository->updateCategory($journal, $category); - - return true; - } - - /** - * @param TransactionJournal $journal - * @param string $action - * @param array $tags + * @param TransactionJournal $journal + * @param string $action + * @param array $tags * * @return bool */ @@ -191,4 +173,22 @@ class BulkController extends Controller return true; } + + /** + * @param TransactionJournal $journal + * @param bool $ignoreUpdate + * @param string $category + * + * @return bool + */ + private function updateJournalCategory(TransactionJournal $journal, bool $ignoreUpdate, string $category): bool + { + if (true === $ignoreUpdate) { + return false; + } + Log::debug(sprintf('Set budget to %s', $category)); + $this->repository->updateCategory($journal, $category); + + return true; + } } diff --git a/app/Http/Controllers/Transaction/ConvertController.php b/app/Http/Controllers/Transaction/ConvertController.php index 334daf9e8d..ac5b9e6cab 100644 --- a/app/Http/Controllers/Transaction/ConvertController.php +++ b/app/Http/Controllers/Transaction/ConvertController.php @@ -82,8 +82,8 @@ class ConvertController extends Controller /** * Show overview of a to be converted transaction. * - * @param TransactionType $destinationType - * @param TransactionGroup $group + * @param TransactionType $destinationType + * @param TransactionGroup $group * * @return RedirectResponse|Redirector|Factory|View * @throws Exception @@ -104,7 +104,7 @@ class ConvertController extends Controller $groupTitle = $group->title ?? $first->description; $groupArray = $transformer->transformObject($group); - $subTitle = (string)trans('firefly.convert_to_'.$destinationType->type, ['description' => $groupTitle]); + $subTitle = (string)trans('firefly.convert_to_' . $destinationType->type, ['description' => $groupTitle]); $subTitleIcon = 'fa-exchange'; // get a list of asset accounts and liabilities and stuff, in various combinations: @@ -120,7 +120,7 @@ class ConvertController extends Controller if ($sourceType->type === $destinationType->type) { // cannot convert to its own type. Log::debug('This is already a transaction of the expected type..'); - session()->flash('info', (string)trans('firefly.convert_is_already_type_'.$destinationType->type)); + session()->flash('info', (string)trans('firefly.convert_is_already_type_' . $destinationType->type)); return redirect(route('transactions.show', [$group->id])); } @@ -144,12 +144,139 @@ class ConvertController extends Controller ); } + /** + * @return array + */ + private function getValidDepositSources(): array + { + // make repositories + $liabilityTypes = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN]; + $accountList = $this->accountRepository + ->getActiveAccountsByType([AccountType::REVENUE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]); + $grouped = []; + // group accounts: + /** @var Account $account */ + foreach ($accountList as $account) { + $role = (string)$this->accountRepository->getMetaValue($account, 'account_role'); + $name = $account->name; + if ('' === $role) { + $role = 'no_account_type'; + } + + // maybe it's a liability thing: + if (in_array($account->accountType->type, $liabilityTypes, true)) { + $role = 'l_' . $account->accountType->type; + } + if (AccountType::CASH === $account->accountType->type) { + $role = 'cash_account'; + $name = sprintf('(%s)', trans('firefly.cash')); + } + if (AccountType::REVENUE === $account->accountType->type) { + $role = 'revenue_account'; + } + + $key = (string)trans('firefly.opt_group_' . $role); + $grouped[$key][$account->id] = $name; + } + + return $grouped; + } + + /** + * @return array + */ + private function getValidWithdrawalDests(): array + { + // make repositories + $liabilityTypes = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN]; + $accountList = $this->accountRepository->getActiveAccountsByType( + [AccountType::EXPENSE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE] + ); + $grouped = []; + // group accounts: + /** @var Account $account */ + foreach ($accountList as $account) { + $role = (string)$this->accountRepository->getMetaValue($account, 'account_role'); + $name = $account->name; + if ('' === $role) { + $role = 'no_account_type'; + } + + // maybe it's a liability thing: + if (in_array($account->accountType->type, $liabilityTypes, true)) { + $role = 'l_' . $account->accountType->type; + } + if (AccountType::CASH === $account->accountType->type) { + $role = 'cash_account'; + $name = sprintf('(%s)', trans('firefly.cash')); + } + if (AccountType::EXPENSE === $account->accountType->type) { + $role = 'expense_account'; + } + + $key = (string)trans('firefly.opt_group_' . $role); + $grouped[$key][$account->id] = $name; + } + + return $grouped; + } + + /** + * @return array + * @throws Exception + */ + private function getLiabilities(): array + { + // make repositories + $accountList = $this->accountRepository->getActiveAccountsByType([AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]); + $defaultCurrency = app('amount')->getDefaultCurrency(); + $grouped = []; + // group accounts: + /** @var Account $account */ + foreach ($accountList as $account) { + $balance = app('steam')->balance($account, today()); + $currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency; + $role = 'l_' . $account->accountType->type; + $key = (string)trans('firefly.opt_group_' . $role); + $grouped[$key][$account->id] = $account->name . ' (' . app('amount')->formatAnything($currency, $balance, false) . ')'; + } + + return $grouped; + } + + /** + * @return array + * @throws Exception + */ + private function getAssetAccounts(): array + { + // make repositories + $accountList = $this->accountRepository->getActiveAccountsByType([AccountType::ASSET]); + $defaultCurrency = app('amount')->getDefaultCurrency(); + $grouped = []; + // group accounts: + /** @var Account $account */ + foreach ($accountList as $account) { + $balance = app('steam')->balance($account, today()); + $currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency; + $role = (string)$this->accountRepository->getMetaValue($account, 'account_role'); + if ('' === $role) { + $role = 'no_account_type'; + } + + $key = (string)trans('firefly.opt_group_' . $role); + $grouped[$key][$account->id] = $account->name . ' (' . app('amount')->formatAnything($currency, $balance, false) . ')'; + } + + return $grouped; + } + /** * Do the conversion. * - * @param Request $request - * @param TransactionType $destinationType - * @param TransactionGroup $group + * @param Request $request + * @param TransactionType $destinationType + * @param TransactionGroup $group * * @return RedirectResponse|Redirector * @@ -175,16 +302,16 @@ class ConvertController extends Controller // correct transfers: $group->refresh(); - session()->flash('success', (string)trans('firefly.converted_to_'.$destinationType->type)); + session()->flash('success', (string)trans('firefly.converted_to_' . $destinationType->type)); event(new UpdatedTransactionGroup($group, true, true)); return redirect(route('transactions.show', [$group->id])); } /** - * @param TransactionJournal $journal - * @param TransactionType $transactionType - * @param array $data + * @param TransactionJournal $journal + * @param TransactionType $transactionType + * @param array $data * * @return TransactionJournal * @throws FireflyException @@ -234,131 +361,4 @@ class ConvertController extends Controller return $journal; } - - /** - * @return array - * @throws Exception - */ - private function getAssetAccounts(): array - { - // make repositories - $accountList = $this->accountRepository->getActiveAccountsByType([AccountType::ASSET]); - $defaultCurrency = app('amount')->getDefaultCurrency(); - $grouped = []; - // group accounts: - /** @var Account $account */ - foreach ($accountList as $account) { - $balance = app('steam')->balance($account, today()); - $currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency; - $role = (string)$this->accountRepository->getMetaValue($account, 'account_role'); - if ('' === $role) { - $role = 'no_account_type'; - } - - $key = (string)trans('firefly.opt_group_'.$role); - $grouped[$key][$account->id] = $account->name.' ('.app('amount')->formatAnything($currency, $balance, false).')'; - } - - return $grouped; - } - - /** - * @return array - * @throws Exception - */ - private function getLiabilities(): array - { - // make repositories - $accountList = $this->accountRepository->getActiveAccountsByType([AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]); - $defaultCurrency = app('amount')->getDefaultCurrency(); - $grouped = []; - // group accounts: - /** @var Account $account */ - foreach ($accountList as $account) { - $balance = app('steam')->balance($account, today()); - $currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency; - $role = 'l_'.$account->accountType->type; - $key = (string)trans('firefly.opt_group_'.$role); - $grouped[$key][$account->id] = $account->name.' ('.app('amount')->formatAnything($currency, $balance, false).')'; - } - - return $grouped; - } - - /** - * @return array - */ - private function getValidDepositSources(): array - { - // make repositories - $liabilityTypes = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN]; - $accountList = $this->accountRepository - ->getActiveAccountsByType([AccountType::REVENUE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]); - $grouped = []; - // group accounts: - /** @var Account $account */ - foreach ($accountList as $account) { - $role = (string)$this->accountRepository->getMetaValue($account, 'account_role'); - $name = $account->name; - if ('' === $role) { - $role = 'no_account_type'; - } - - // maybe it's a liability thing: - if (in_array($account->accountType->type, $liabilityTypes, true)) { - $role = 'l_'.$account->accountType->type; - } - if (AccountType::CASH === $account->accountType->type) { - $role = 'cash_account'; - $name = sprintf('(%s)', trans('firefly.cash')); - } - if (AccountType::REVENUE === $account->accountType->type) { - $role = 'revenue_account'; - } - - $key = (string)trans('firefly.opt_group_'.$role); - $grouped[$key][$account->id] = $name; - } - - return $grouped; - } - - /** - * @return array - */ - private function getValidWithdrawalDests(): array - { - // make repositories - $liabilityTypes = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN]; - $accountList = $this->accountRepository->getActiveAccountsByType( - [AccountType::EXPENSE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE] - ); - $grouped = []; - // group accounts: - /** @var Account $account */ - foreach ($accountList as $account) { - $role = (string)$this->accountRepository->getMetaValue($account, 'account_role'); - $name = $account->name; - if ('' === $role) { - $role = 'no_account_type'; - } - - // maybe it's a liability thing: - if (in_array($account->accountType->type, $liabilityTypes, true)) { - $role = 'l_'.$account->accountType->type; - } - if (AccountType::CASH === $account->accountType->type) { - $role = 'cash_account'; - $name = sprintf('(%s)', trans('firefly.cash')); - } - if (AccountType::EXPENSE === $account->accountType->type) { - $role = 'expense_account'; - } - - $key = (string)trans('firefly.opt_group_'.$role); - $grouped[$key][$account->id] = $name; - } - - return $grouped; - } } diff --git a/app/Http/Controllers/Transaction/CreateController.php b/app/Http/Controllers/Transaction/CreateController.php index 6f433bc529..aa0b5ea285 100644 --- a/app/Http/Controllers/Transaction/CreateController.php +++ b/app/Http/Controllers/Transaction/CreateController.php @@ -65,7 +65,7 @@ class CreateController extends Controller } /** - * @param Request $request + * @param Request $request * * @return JsonResponse */ @@ -99,7 +99,7 @@ class CreateController extends Controller /** * Create a new transaction group. * - * @param string|null $objectType + * @param string|null $objectType * * @return Factory|View * @throws FireflyException diff --git a/app/Http/Controllers/Transaction/DeleteController.php b/app/Http/Controllers/Transaction/DeleteController.php index 421f4b7ac5..8e2acc65bb 100644 --- a/app/Http/Controllers/Transaction/DeleteController.php +++ b/app/Http/Controllers/Transaction/DeleteController.php @@ -69,7 +69,7 @@ class DeleteController extends Controller /** * Shows the form that allows a user to delete a transaction journal. * - * @param TransactionGroup $group + * @param TransactionGroup $group * * @return Factory|View|Redirector|RedirectResponse */ @@ -86,7 +86,7 @@ class DeleteController extends Controller throw new NotFoundHttpException(); } $objectType = strtolower($journal->transaction_type_type ?? $journal->transactionType->type); - $subTitle = (string)trans('firefly.delete_'.$objectType, ['description' => $group->title ?? $journal->description]); + $subTitle = (string)trans('firefly.delete_' . $objectType, ['description' => $group->title ?? $journal->description]); $previous = app('steam')->getSafePreviousUrl(); // put previous url in session Log::debug('Will try to remember previous URL'); @@ -98,7 +98,7 @@ class DeleteController extends Controller /** * Actually destroys the journal. * - * @param TransactionGroup $group + * @param TransactionGroup $group * * @return RedirectResponse */ @@ -114,7 +114,7 @@ class DeleteController extends Controller throw new NotFoundHttpException(); } $objectType = strtolower($journal->transaction_type_type ?? $journal->transactionType->type); - session()->flash('success', (string)trans('firefly.deleted_'.strtolower($objectType), ['description' => $group->title ?? $journal->description])); + session()->flash('success', (string)trans('firefly.deleted_' . strtolower($objectType), ['description' => $group->title ?? $journal->description])); // grab asset account(s) from group: $accounts = []; diff --git a/app/Http/Controllers/Transaction/EditController.php b/app/Http/Controllers/Transaction/EditController.php index c7123a510b..0a23eb77ce 100644 --- a/app/Http/Controllers/Transaction/EditController.php +++ b/app/Http/Controllers/Transaction/EditController.php @@ -57,7 +57,7 @@ class EditController extends Controller } /** - * @param TransactionGroup $transactionGroup + * @param TransactionGroup $transactionGroup * * @return Factory|View|RedirectResponse|Redirector */ diff --git a/app/Http/Controllers/Transaction/IndexController.php b/app/Http/Controllers/Transaction/IndexController.php index 37516a313d..74636f6fb2 100644 --- a/app/Http/Controllers/Transaction/IndexController.php +++ b/app/Http/Controllers/Transaction/IndexController.php @@ -69,10 +69,10 @@ class IndexController extends Controller /** * Index for a range of transactions. * - * @param Request $request - * @param string $objectType - * @param Carbon|null $start - * @param Carbon|null $end + * @param Request $request + * @param string $objectType + * @param Carbon|null $start + * @param Carbon|null $end * * @return Factory|View * @throws FireflyException @@ -85,8 +85,8 @@ class IndexController extends Controller $objectType = 'transfer'; } - $subTitleIcon = config('firefly.transactionIconsByType.'.$objectType); - $types = config('firefly.transactionTypesByType.'.$objectType); + $subTitleIcon = config('firefly.transactionIconsByType.' . $objectType); + $types = config('firefly.transactionTypesByType.' . $objectType); $page = (int)$request->get('page'); $pageSize = (int)app('preferences')->get('listPageSize', 50)->data; if (null === $start) { @@ -130,8 +130,8 @@ class IndexController extends Controller /** * Index for ALL transactions. * - * @param Request $request - * @param string $objectType + * @param Request $request + * @param string $objectType * * @return Factory|View * @throws ContainerExceptionInterface @@ -139,8 +139,8 @@ class IndexController extends Controller */ public function indexAll(Request $request, string $objectType) { - $subTitleIcon = config('firefly.transactionIconsByType.'.$objectType); - $types = config('firefly.transactionTypesByType.'.$objectType); + $subTitleIcon = config('firefly.transactionIconsByType.' . $objectType); + $types = config('firefly.transactionTypesByType.' . $objectType); $page = (int)$request->get('page'); $pageSize = (int)app('preferences')->get('listPageSize', 50)->data; $path = route('transactions.index.all', [$objectType]); @@ -148,7 +148,7 @@ class IndexController extends Controller $start = null === $first ? new Carbon() : $first->date; $last = $this->repository->getLast(); $end = $last ? $last->date : today(config('app.timezone')); - $subTitle = (string)trans('firefly.all_'.$objectType); + $subTitle = (string)trans('firefly.all_' . $objectType); /** @var GroupCollectorInterface $collector */ $collector = app(GroupCollectorInterface::class); diff --git a/app/Http/Controllers/Transaction/LinkController.php b/app/Http/Controllers/Transaction/LinkController.php index 89017870c0..9ee8c28214 100644 --- a/app/Http/Controllers/Transaction/LinkController.php +++ b/app/Http/Controllers/Transaction/LinkController.php @@ -69,7 +69,7 @@ class LinkController extends Controller /** * Delete a link. * - * @param TransactionJournalLink $link + * @param TransactionJournalLink $link * * @return Factory|View */ @@ -85,7 +85,7 @@ class LinkController extends Controller /** * Actually destroy it. * - * @param TransactionJournalLink $link + * @param TransactionJournalLink $link * * @return RedirectResponse|Redirector */ @@ -100,7 +100,7 @@ class LinkController extends Controller } /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return Factory|View */ @@ -114,8 +114,8 @@ class LinkController extends Controller /** * Store a new link. * - * @param JournalLinkRequest $request - * @param TransactionJournal $journal + * @param JournalLinkRequest $request + * @param TransactionJournal $journal * * @return RedirectResponse|Redirector */ @@ -154,7 +154,7 @@ class LinkController extends Controller /** * Switch link from A <> B to B <> A. * - * @param Request $request + * @param Request $request * @return RedirectResponse|Redirector */ public function switchLink(Request $request) diff --git a/app/Http/Controllers/Transaction/MassController.php b/app/Http/Controllers/Transaction/MassController.php index 9b7d0c9dd1..c1837268a2 100644 --- a/app/Http/Controllers/Transaction/MassController.php +++ b/app/Http/Controllers/Transaction/MassController.php @@ -74,7 +74,7 @@ class MassController extends Controller /** * Mass delete transactions. * - * @param array $journals + * @param array $journals * * @return IlluminateView */ @@ -91,7 +91,7 @@ class MassController extends Controller /** * Do the mass delete. * - * @param MassDeleteJournalRequest $request + * @param MassDeleteJournalRequest $request * * @return Application|Redirector|RedirectResponse * @@ -127,7 +127,7 @@ class MassController extends Controller /** * Mass edit of journals. * - * @param array $journals + * @param array $journals * * @return IlluminateView */ @@ -165,7 +165,7 @@ class MassController extends Controller /** * Mass update of journals. * - * @param MassEditJournalRequest $request + * @param MassEditJournalRequest $request * * @return RedirectResponse|Redirector * @throws FireflyException @@ -197,75 +197,8 @@ class MassController extends Controller } /** - * @param MassEditJournalRequest $request - * @param int $journalId - * @param string $key - * - * @return Carbon|null - */ - private function getDateFromRequest(MassEditJournalRequest $request, int $journalId, string $key): ?Carbon - { - $value = $request->get($key); - if (!is_array($value)) { - return null; - } - if (!array_key_exists($journalId, $value)) { - return null; - } - try { - $carbon = Carbon::parse($value[$journalId]); - } catch (InvalidArgumentException $e) { - $e->getMessage(); - - return null; - } - - return $carbon; - } - - /** - * @param MassEditJournalRequest $request - * @param int $journalId - * @param string $string - * - * @return int|null - */ - private function getIntFromRequest(MassEditJournalRequest $request, int $journalId, string $string): ?int - { - $value = $request->get($string); - if (!is_array($value)) { - return null; - } - if (!array_key_exists($journalId, $value)) { - return null; - } - - return (int)$value[$journalId]; - } - - /** - * @param MassEditJournalRequest $request - * @param int $journalId - * @param string $string - * - * @return string|null - */ - private function getStringFromRequest(MassEditJournalRequest $request, int $journalId, string $string): ?string - { - $value = $request->get($string); - if (!is_array($value)) { - return null; - } - if (!array_key_exists($journalId, $value)) { - return null; - } - - return (string)$value[$journalId]; - } - - /** - * @param int $journalId - * @param MassEditJournalRequest $request + * @param int $journalId + * @param MassEditJournalRequest $request * * @throws FireflyException */ @@ -299,4 +232,71 @@ class MassController extends Controller // trigger rules event(new UpdatedTransactionGroup($journal->transactionGroup, true, true)); } + + /** + * @param MassEditJournalRequest $request + * @param int $journalId + * @param string $key + * + * @return Carbon|null + */ + private function getDateFromRequest(MassEditJournalRequest $request, int $journalId, string $key): ?Carbon + { + $value = $request->get($key); + if (!is_array($value)) { + return null; + } + if (!array_key_exists($journalId, $value)) { + return null; + } + try { + $carbon = Carbon::parse($value[$journalId]); + } catch (InvalidArgumentException $e) { + $e->getMessage(); + + return null; + } + + return $carbon; + } + + /** + * @param MassEditJournalRequest $request + * @param int $journalId + * @param string $string + * + * @return string|null + */ + private function getStringFromRequest(MassEditJournalRequest $request, int $journalId, string $string): ?string + { + $value = $request->get($string); + if (!is_array($value)) { + return null; + } + if (!array_key_exists($journalId, $value)) { + return null; + } + + return (string)$value[$journalId]; + } + + /** + * @param MassEditJournalRequest $request + * @param int $journalId + * @param string $string + * + * @return int|null + */ + private function getIntFromRequest(MassEditJournalRequest $request, int $journalId, string $string): ?int + { + $value = $request->get($string); + if (!is_array($value)) { + return null; + } + if (!array_key_exists($journalId, $value)) { + return null; + } + + return (int)$value[$journalId]; + } } diff --git a/app/Http/Controllers/Webhooks/DeleteController.php b/app/Http/Controllers/Webhooks/DeleteController.php index ff5569aaff..7d0cd15ae7 100644 --- a/app/Http/Controllers/Webhooks/DeleteController.php +++ b/app/Http/Controllers/Webhooks/DeleteController.php @@ -59,7 +59,7 @@ class DeleteController extends Controller /** * Delete account screen. * - * @param Webhook $webhook + * @param Webhook $webhook * * @return Factory|Application|View */ diff --git a/app/Http/Controllers/Webhooks/EditController.php b/app/Http/Controllers/Webhooks/EditController.php index 454abf2daf..01a028334c 100644 --- a/app/Http/Controllers/Webhooks/EditController.php +++ b/app/Http/Controllers/Webhooks/EditController.php @@ -58,7 +58,7 @@ class EditController extends Controller /** * Delete account screen. * - * @param Webhook $webhook + * @param Webhook $webhook * * @return Factory|Application|View */ diff --git a/app/Http/Controllers/Webhooks/IndexController.php b/app/Http/Controllers/Webhooks/IndexController.php index c7a8070b3d..fb5067aa21 100644 --- a/app/Http/Controllers/Webhooks/IndexController.php +++ b/app/Http/Controllers/Webhooks/IndexController.php @@ -55,7 +55,7 @@ class IndexController extends Controller /** * Show debug info. * - * @param Request $request + * @param Request $request * * @return Factory|View */ diff --git a/app/Http/Controllers/Webhooks/ShowController.php b/app/Http/Controllers/Webhooks/ShowController.php index db25066ce4..233523f96f 100644 --- a/app/Http/Controllers/Webhooks/ShowController.php +++ b/app/Http/Controllers/Webhooks/ShowController.php @@ -58,7 +58,7 @@ class ShowController extends Controller /** * Delete account screen. * - * @param Webhook $webhook + * @param Webhook $webhook * * @return Factory|Application|View */ diff --git a/app/Http/Middleware/AcceptHeaders.php b/app/Http/Middleware/AcceptHeaders.php index 41cec7e828..974d0512fe 100644 --- a/app/Http/Middleware/AcceptHeaders.php +++ b/app/Http/Middleware/AcceptHeaders.php @@ -37,8 +37,8 @@ class AcceptHeaders /** * Handle the incoming requests. * - * @param Request $request - * @param callable $next + * @param Request $request + * @param callable $next * @return Response * @throws BadHttpHeaderException */ @@ -76,8 +76,8 @@ class AcceptHeaders } /** - * @param string $content - * @param array $accepted + * @param string $content + * @param array $accepted * @return bool */ private function acceptsHeader(string $content, array $accepted): bool diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index 68794f1421..05377cb11b 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -47,7 +47,7 @@ class Authenticate /** * Create a new middleware instance. * - * @param Auth $auth + * @param Auth $auth * * @return void */ @@ -59,9 +59,9 @@ class Authenticate /** * Handle an incoming request. * - * @param Request $request - * @param Closure $next - * @param string[] ...$guards + * @param Request $request + * @param Closure $next + * @param string[] ...$guards * * @return mixed * @@ -78,8 +78,8 @@ class Authenticate /** * Determine if the user is logged in to any of the given guards. * - * @param mixed $request - * @param array $guards + * @param mixed $request + * @param array $guards * * @return mixed * @throws FireflyException @@ -119,8 +119,8 @@ class Authenticate } /** - * @param User|null $user - * @param array $guards + * @param User|null $user + * @param array $guards * @return void * @throws AuthenticationException */ diff --git a/app/Http/Middleware/Binder.php b/app/Http/Middleware/Binder.php index 7f8287486c..8c8c6e4bd5 100644 --- a/app/Http/Middleware/Binder.php +++ b/app/Http/Middleware/Binder.php @@ -50,7 +50,7 @@ class Binder /** * Binder constructor. * - * @param Auth $auth + * @param Auth $auth */ public function __construct(Auth $auth) { @@ -61,8 +61,8 @@ class Binder /** * Handle an incoming request. * - * @param Request $request - * @param Closure $next + * @param Request $request + * @param Closure $next * * @return mixed * @@ -82,9 +82,9 @@ class Binder /** * Do the binding. * - * @param string $key - * @param string $value - * @param Route $route + * @param string $key + * @param string $value + * @param Route $route * * @return mixed */ diff --git a/app/Http/Middleware/InstallationId.php b/app/Http/Middleware/InstallationId.php index 10314bd8f6..7a741e9ea6 100644 --- a/app/Http/Middleware/InstallationId.php +++ b/app/Http/Middleware/InstallationId.php @@ -38,8 +38,8 @@ class InstallationId /** * Handle an incoming request. * - * @param Request $request - * @param Closure $next + * @param Request $request + * @param Closure $next * * @return mixed * diff --git a/app/Http/Middleware/Installer.php b/app/Http/Middleware/Installer.php index 6f79d16137..feb97cad43 100644 --- a/app/Http/Middleware/Installer.php +++ b/app/Http/Middleware/Installer.php @@ -42,8 +42,8 @@ class Installer /** * Handle an incoming request. * - * @param Request $request - * @param Closure $next + * @param Request $request + * @param Closure $next * * @return mixed * @@ -78,30 +78,6 @@ class Installer return $next($request); } - /** - * Is access denied error. - * - * @param string $message - * - * @return bool - */ - protected function isAccessDenied(string $message): bool - { - return false !== stripos($message, 'Access denied'); - } - - /** - * Is no tables exist error. - * - * @param string $message - * - * @return bool - */ - protected function noTablesExist(string $message): bool - { - return false !== stripos($message, 'Base table or view not found'); - } - /** * Check if the tables are created and accounted for. * @@ -138,6 +114,30 @@ class Installer return false; } + /** + * Is access denied error. + * + * @param string $message + * + * @return bool + */ + protected function isAccessDenied(string $message): bool + { + return false !== stripos($message, 'Access denied'); + } + + /** + * Is no tables exist error. + * + * @param string $message + * + * @return bool + */ + protected function noTablesExist(string $message): bool + { + return false !== stripos($message, 'Base table or view not found'); + } + /** * Check if the "db_version" variable is correct. * diff --git a/app/Http/Middleware/InterestingMessage.php b/app/Http/Middleware/InterestingMessage.php index 3a2b277ee1..b609de52ab 100644 --- a/app/Http/Middleware/InterestingMessage.php +++ b/app/Http/Middleware/InterestingMessage.php @@ -40,8 +40,8 @@ class InterestingMessage /** * Flashes the user an interesting message if the URL parameters warrant it. * - * @param Request $request - * @param Closure $next + * @param Request $request + * @param Closure $next * * @return mixed * @@ -73,35 +73,16 @@ class InterestingMessage } /** - * @param Request $request - * * @return bool */ - private function accountMessage(Request $request): bool + private function testing(): bool { - // get parameters from request. - $accountId = $request->get('account_id'); - $message = $request->get('message'); - - return null !== $accountId && null !== $message; + // ignore middleware in test environment. + return 'testing' === config('app.env') || !auth()->check(); } /** - * @param Request $request - * - * @return bool - */ - private function billMessage(Request $request): bool - { - // get parameters from request. - $billId = $request->get('bill_id'); - $message = $request->get('message'); - - return null !== $billId && null !== $message; - } - - /** - * @param Request $request + * @param Request $request * * @return bool */ @@ -115,56 +96,7 @@ class InterestingMessage } /** - * @param Request $request - */ - private function handleAccountMessage(Request $request): void - { - // get parameters from request. - $accountId = $request->get('account_id'); - $message = $request->get('message'); - - /** @var Account $account */ - $account = auth()->user()->accounts()->withTrashed()->find($accountId); - - if (null === $account) { - return; - } - if ('deleted' === $message) { - session()->flash('success', (string)trans('firefly.account_deleted', ['name' => $account->name])); - } - if ('created' === $message) { - session()->flash('success', (string)trans('firefly.stored_new_account', ['name' => $account->name])); - } - if ('updated' === $message) { - session()->flash('success', (string)trans('firefly.updated_account', ['name' => $account->name])); - } - } - - /** - * @param Request $request - */ - private function handleBillMessage(Request $request): void - { - // get parameters from request. - $billId = $request->get('bill_id'); - $message = $request->get('message'); - - /** @var Bill $bill */ - $bill = auth()->user()->bills()->withTrashed()->find($billId); - - if (null === $bill) { - return; - } - if ('deleted' === $message) { - session()->flash('success', (string)trans('firefly.deleted_bill', ['name' => $bill->name])); - } - if ('created' === $message) { - session()->flash('success', (string)trans('firefly.stored_new_bill', ['name' => $bill->name])); - } - } - - /** - * @param Request $request + * @param Request $request */ private function handleGroupMessage(Request $request): void { @@ -205,7 +137,98 @@ class InterestingMessage } /** - * @param Request $request + * @param Request $request + * + * @return bool + */ + private function accountMessage(Request $request): bool + { + // get parameters from request. + $accountId = $request->get('account_id'); + $message = $request->get('message'); + + return null !== $accountId && null !== $message; + } + + /** + * @param Request $request + */ + private function handleAccountMessage(Request $request): void + { + // get parameters from request. + $accountId = $request->get('account_id'); + $message = $request->get('message'); + + /** @var Account $account */ + $account = auth()->user()->accounts()->withTrashed()->find($accountId); + + if (null === $account) { + return; + } + if ('deleted' === $message) { + session()->flash('success', (string)trans('firefly.account_deleted', ['name' => $account->name])); + } + if ('created' === $message) { + session()->flash('success', (string)trans('firefly.stored_new_account', ['name' => $account->name])); + } + if ('updated' === $message) { + session()->flash('success', (string)trans('firefly.updated_account', ['name' => $account->name])); + } + } + + /** + * @param Request $request + * + * @return bool + */ + private function billMessage(Request $request): bool + { + // get parameters from request. + $billId = $request->get('bill_id'); + $message = $request->get('message'); + + return null !== $billId && null !== $message; + } + + /** + * @param Request $request + */ + private function handleBillMessage(Request $request): void + { + // get parameters from request. + $billId = $request->get('bill_id'); + $message = $request->get('message'); + + /** @var Bill $bill */ + $bill = auth()->user()->bills()->withTrashed()->find($billId); + + if (null === $bill) { + return; + } + if ('deleted' === $message) { + session()->flash('success', (string)trans('firefly.deleted_bill', ['name' => $bill->name])); + } + if ('created' === $message) { + session()->flash('success', (string)trans('firefly.stored_new_bill', ['name' => $bill->name])); + } + } + + /** + * @param Request $request + * + * @return bool + */ + private function webhookMessage(Request $request): bool + { + // get parameters from request. + $billId = $request->get('webhook_id'); + $message = $request->get('message'); + + return null !== $billId && null !== $message; + } + + /** + * @param Request $request */ private function handleWebhookMessage(Request $request): void { @@ -229,27 +252,4 @@ class InterestingMessage session()->flash('success', (string)trans('firefly.stored_new_webhook', ['title' => $webhook->title])); } } - - /** - * @return bool - */ - private function testing(): bool - { - // ignore middleware in test environment. - return 'testing' === config('app.env') || !auth()->check(); - } - - /** - * @param Request $request - * - * @return bool - */ - private function webhookMessage(Request $request): bool - { - // get parameters from request. - $billId = $request->get('webhook_id'); - $message = $request->get('message'); - - return null !== $billId && null !== $message; - } } diff --git a/app/Http/Middleware/IsAdmin.php b/app/Http/Middleware/IsAdmin.php index 32d8b04c98..0bde6c57d4 100644 --- a/app/Http/Middleware/IsAdmin.php +++ b/app/Http/Middleware/IsAdmin.php @@ -37,9 +37,9 @@ class IsAdmin /** * Handle an incoming request. Must be admin. * - * @param Request $request - * @param Closure $next - * @param string|null $guard + * @param Request $request + * @param Closure $next + * @param string|null $guard * * @return mixed */ diff --git a/app/Http/Middleware/IsDemoUser.php b/app/Http/Middleware/IsDemoUser.php index 9d1211aff0..e174c8d95e 100644 --- a/app/Http/Middleware/IsDemoUser.php +++ b/app/Http/Middleware/IsDemoUser.php @@ -37,8 +37,8 @@ class IsDemoUser /** * Handle an incoming request. * - * @param Request $request - * @param Closure $next + * @param Request $request + * @param Closure $next * * @return mixed */ diff --git a/app/Http/Middleware/Range.php b/app/Http/Middleware/Range.php index bc96161593..997dcd218a 100644 --- a/app/Http/Middleware/Range.php +++ b/app/Http/Middleware/Range.php @@ -41,8 +41,8 @@ class Range /** * Handle an incoming request. * - * @param Request $request - * @param Closure $next + * @param Request $request + * @param Closure $next * * @return mixed */ @@ -63,20 +63,30 @@ class Range } /** - * Configure the list length. + * Set the range for the current view. */ - private function configureList(): void + private function setRange(): void { - $pref = app('preferences')->get('list-length', config('firefly.list_length', 10))->data; - app('view')->share('listLength', $pref); + // ignore preference. set the range to be the current month: + if (!app('session')->has('start') && !app('session')->has('end')) { + $viewRange = app('preferences')->get('viewRange', '1M')->data; + $today = today(config('app.timezone')); + $start = app('navigation')->updateStartDate($viewRange, $today); + $end = app('navigation')->updateEndDate($viewRange, $start); - // share security message: - if ( - app('fireflyconfig')->has('upgrade_security_message') - && app('fireflyconfig')->has('upgrade_security_level') - ) { - app('view')->share('upgrade_security_message', app('fireflyconfig')->get('upgrade_security_message')->data); - app('view')->share('upgrade_security_level', app('fireflyconfig')->get('upgrade_security_level')->data); + app('session')->put('start', $start); + app('session')->put('end', $end); + } + if (!app('session')->has('first')) { + /** @var JournalRepositoryInterface $repository */ + $repository = app(JournalRepositoryInterface::class); + $journal = $repository->firstNull(); + $first = today(config('app.timezone'))->startOfYear(); + + if (null !== $journal) { + $first = $journal->date ?? $first; + } + app('session')->put('first', $first); } } @@ -117,30 +127,20 @@ class Range } /** - * Set the range for the current view. + * Configure the list length. */ - private function setRange(): void + private function configureList(): void { - // ignore preference. set the range to be the current month: - if (!app('session')->has('start') && !app('session')->has('end')) { - $viewRange = app('preferences')->get('viewRange', '1M')->data; - $today = today(config('app.timezone')); - $start = app('navigation')->updateStartDate($viewRange, $today); - $end = app('navigation')->updateEndDate($viewRange, $start); + $pref = app('preferences')->get('list-length', config('firefly.list_length', 10))->data; + app('view')->share('listLength', $pref); - app('session')->put('start', $start); - app('session')->put('end', $end); - } - if (!app('session')->has('first')) { - /** @var JournalRepositoryInterface $repository */ - $repository = app(JournalRepositoryInterface::class); - $journal = $repository->firstNull(); - $first = today(config('app.timezone'))->startOfYear(); - - if (null !== $journal) { - $first = $journal->date ?? $first; - } - app('session')->put('first', $first); + // share security message: + if ( + app('fireflyconfig')->has('upgrade_security_message') + && app('fireflyconfig')->has('upgrade_security_level') + ) { + app('view')->share('upgrade_security_message', app('fireflyconfig')->get('upgrade_security_message')->data); + app('view')->share('upgrade_security_level', app('fireflyconfig')->get('upgrade_security_level')->data); } } } diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index 68216e5758..b5bc8281ef 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -37,9 +37,9 @@ class RedirectIfAuthenticated /** * Handle an incoming request. * - * @param Request $request - * @param Closure $next - * @param string|null $guard + * @param Request $request + * @param Closure $next + * @param string|null $guard * * @return mixed */ diff --git a/app/Http/Middleware/SecureHeaders.php b/app/Http/Middleware/SecureHeaders.php index 443bf866c4..b2c5040815 100644 --- a/app/Http/Middleware/SecureHeaders.php +++ b/app/Http/Middleware/SecureHeaders.php @@ -36,8 +36,8 @@ class SecureHeaders /** * Handle an incoming request. * - * @param Request $request - * @param Closure $next + * @param Request $request + * @param Closure $next * * @return mixed * @throws Exception diff --git a/app/Http/Middleware/StartFireflySession.php b/app/Http/Middleware/StartFireflySession.php index 162f7d3f20..753965a3d4 100644 --- a/app/Http/Middleware/StartFireflySession.php +++ b/app/Http/Middleware/StartFireflySession.php @@ -37,8 +37,8 @@ class StartFireflySession extends StartSession /** * Store the current URL for the request if necessary. * - * @param Request $request - * @param Session $session + * @param Request $request + * @param Session $session */ protected function storeCurrentUrl(Request $request, $session): void { diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php index b622b72050..51094a3040 100644 --- a/app/Http/Middleware/TrustProxies.php +++ b/app/Http/Middleware/TrustProxies.php @@ -34,12 +34,12 @@ use Symfony\Component\HttpFoundation\Request; 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; + 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; /** * TrustProxies constructor. diff --git a/app/Http/Requests/AccountFormRequest.php b/app/Http/Requests/AccountFormRequest.php index 2c5ea2818c..c669846070 100644 --- a/app/Http/Requests/AccountFormRequest.php +++ b/app/Http/Requests/AccountFormRequest.php @@ -118,12 +118,12 @@ class AccountFormRequest extends FormRequest 'virtual_balance' => 'numeric|nullable|max:1000000000', 'currency_id' => 'exists:transaction_currencies,id', 'account_number' => 'between:1,255|uniqueAccountNumberForUser|nullable', - 'account_role' => 'in:'.$accountRoles, + 'account_role' => 'in:' . $accountRoles, 'active' => 'boolean', - 'cc_type' => 'in:'.$ccPaymentTypes, + 'cc_type' => 'in:' . $ccPaymentTypes, 'amount_currency_id_opening_balance' => 'exists:transaction_currencies,id', 'amount_currency_id_virtual_balance' => 'exists:transaction_currencies,id', - 'what' => 'in:'.$types, + 'what' => 'in:' . $types, 'interest_period' => 'in:daily,monthly,yearly', ]; $rules = Location::requestRules($rules); @@ -133,7 +133,7 @@ class AccountFormRequest extends FormRequest if (null !== $account) { // add rules: $rules['id'] = 'belongsToUser:accounts'; - $rules['name'] = 'required|max:1024|min:1|uniqueAccountForUser:'.$account->id; + $rules['name'] = 'required|max:1024|min:1|uniqueAccountForUser:' . $account->id; $rules['iban'] = ['iban', 'nullable', new UniqueIban($account, $account->accountType->type)]; } @@ -143,7 +143,7 @@ class AccountFormRequest extends FormRequest /** * Configure the validator instance with special rules for after the basic validation rules. * - * @param Validator $validator + * @param Validator $validator * * @return void */ diff --git a/app/Http/Requests/BudgetFormStoreRequest.php b/app/Http/Requests/BudgetFormStoreRequest.php index 3e1817b93c..3165ee7e78 100644 --- a/app/Http/Requests/BudgetFormStoreRequest.php +++ b/app/Http/Requests/BudgetFormStoreRequest.php @@ -75,7 +75,7 @@ class BudgetFormStoreRequest extends FormRequest /** * Configure the validator instance with special rules for after the basic validation rules. * - * @param Validator $validator + * @param Validator $validator * * @return void */ diff --git a/app/Http/Requests/BudgetFormUpdateRequest.php b/app/Http/Requests/BudgetFormUpdateRequest.php index 3b89ef8759..ab61f774f5 100644 --- a/app/Http/Requests/BudgetFormUpdateRequest.php +++ b/app/Http/Requests/BudgetFormUpdateRequest.php @@ -69,7 +69,7 @@ class BudgetFormUpdateRequest extends FormRequest $budget = $this->route()->parameter('budget'); if (null !== $budget) { - $nameRule = 'required|between:1,100|uniqueObjectForUser:budgets,name,'.$budget->id; + $nameRule = 'required|between:1,100|uniqueObjectForUser:budgets,name,' . $budget->id; } return [ @@ -85,7 +85,7 @@ class BudgetFormUpdateRequest extends FormRequest /** * Configure the validator instance with special rules for after the basic validation rules. * - * @param Validator $validator + * @param Validator $validator * * @return void */ diff --git a/app/Http/Requests/CategoryFormRequest.php b/app/Http/Requests/CategoryFormRequest.php index 476140da26..0e3c309d36 100644 --- a/app/Http/Requests/CategoryFormRequest.php +++ b/app/Http/Requests/CategoryFormRequest.php @@ -61,7 +61,7 @@ class CategoryFormRequest extends FormRequest $category = $this->route()->parameter('category'); if (null !== $category) { - $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name,'.$category->id; + $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name,' . $category->id; } // fixed diff --git a/app/Http/Requests/RecurrenceFormRequest.php b/app/Http/Requests/RecurrenceFormRequest.php index 9b99ef9d34..dce42861b4 100644 --- a/app/Http/Requests/RecurrenceFormRequest.php +++ b/app/Http/Requests/RecurrenceFormRequest.php @@ -133,7 +133,7 @@ class RecurrenceFormRequest extends FormRequest $factory = app(CategoryFactory::class); $factory->setUser(auth()->user()); /** - * @var int $index + * @var int $index * @var array $transaction */ foreach ($return['transactions'] as $index => $transaction) { @@ -149,6 +149,40 @@ class RecurrenceFormRequest extends FormRequest return $return; } + /** + * Parses repetition data. + * + * @return array + */ + private function parseRepetitionData(): array + { + $value = $this->convertString('repetition_type'); + $return = [ + 'type' => '', + 'moment' => '', + ]; + + if ('daily' === $value) { + $return['type'] = $value; + } + //monthly,17 + //ndom,3,7 + if (in_array(substr($value, 0, 6), ['yearly', 'weekly'], true)) { + $return['type'] = substr($value, 0, 6); + $return['moment'] = substr($value, 7); + } + if (str_starts_with($value, 'monthly')) { + $return['type'] = substr($value, 0, 7); + $return['moment'] = substr($value, 8); + } + if (str_starts_with($value, 'ndom')) { + $return['type'] = substr($value, 0, 4); + $return['moment'] = substr($value, 5); + } + + return $return; + } + /** * The rules for this request. * @@ -162,7 +196,7 @@ class RecurrenceFormRequest extends FormRequest $rules = [ // mandatory info for recurrence. 'title' => 'required|between:1,255|uniqueObjectForUser:recurrences,title', - 'first_date' => 'required|date|after:'.$today->format('Y-m-d'), + 'first_date' => 'required|date|after:' . $today->format('Y-m-d'), 'repetition_type' => ['required', new ValidRecurrenceRepetitionValue(), new ValidRecurrenceRepetitionType(), 'between:1,20'], 'skip' => 'required|numeric|integer|gte:0|lte:31', @@ -206,7 +240,7 @@ class RecurrenceFormRequest extends FormRequest // if ends at date X, set another rule. if ('until_date' === $this->convertString('repetition_end')) { - $rules['repeat_until'] = 'required|date|after:'.$tomorrow->format('Y-m-d'); + $rules['repeat_until'] = 'required|date|after:' . $tomorrow->format('Y-m-d'); } // switch on type to expand rules for source and destination accounts: @@ -230,17 +264,34 @@ class RecurrenceFormRequest extends FormRequest $recurrence = $this->route()->parameter('recurrence'); if ($recurrence instanceof Recurrence) { $rules['id'] = 'required|numeric|exists:recurrences,id'; - $rules['title'] = 'required|between:1,255|uniqueObjectForUser:recurrences,title,'.$recurrence->id; + $rules['title'] = 'required|between:1,255|uniqueObjectForUser:recurrences,title,' . $recurrence->id; $rules['first_date'] = 'required|date'; } return $rules; } + /** + * Configure the validator instance with special rules for after the basic validation rules. + * + * @param Validator $validator + * + * @return void + */ + public function withValidator(Validator $validator): void + { + $validator->after( + function (Validator $validator) { + // validate all account info + $this->validateAccountInformation($validator); + } + ); + } + /** * Validates the given account information. Switches on given transaction type. * - * @param Validator $validator + * @param Validator $validator * * @throws FireflyException */ @@ -302,55 +353,4 @@ class RecurrenceFormRequest extends FormRequest $validator->errors()->add('withdrawal_destination_id', $message); } } - - /** - * Configure the validator instance with special rules for after the basic validation rules. - * - * @param Validator $validator - * - * @return void - */ - public function withValidator(Validator $validator): void - { - $validator->after( - function (Validator $validator) { - // validate all account info - $this->validateAccountInformation($validator); - } - ); - } - - /** - * Parses repetition data. - * - * @return array - */ - private function parseRepetitionData(): array - { - $value = $this->convertString('repetition_type'); - $return = [ - 'type' => '', - 'moment' => '', - ]; - - if ('daily' === $value) { - $return['type'] = $value; - } - //monthly,17 - //ndom,3,7 - if (in_array(substr($value, 0, 6), ['yearly', 'weekly'], true)) { - $return['type'] = substr($value, 0, 6); - $return['moment'] = substr($value, 7); - } - if (str_starts_with($value, 'monthly')) { - $return['type'] = substr($value, 0, 7); - $return['moment'] = substr($value, 8); - } - if (str_starts_with($value, 'ndom')) { - $return['type'] = substr($value, 0, 4); - $return['moment'] = substr($value, 5); - } - - return $return; - } } diff --git a/app/Http/Requests/RuleFormRequest.php b/app/Http/Requests/RuleFormRequest.php index 2fbec2fc9f..39e067686b 100644 --- a/app/Http/Requests/RuleFormRequest.php +++ b/app/Http/Requests/RuleFormRequest.php @@ -39,7 +39,53 @@ class RuleFormRequest extends FormRequest use ChecksLogin; /** - * @param array $array + * Get all data for controller. + * + * @return array + * + */ + public function getRuleData(): array + { + return [ + 'title' => $this->convertString('title'), + 'rule_group_id' => $this->convertInteger('rule_group_id'), + 'active' => $this->boolean('active'), + 'trigger' => $this->convertString('trigger'), + 'description' => $this->stringWithNewlines('description'), + 'stop_processing' => $this->boolean('stop_processing'), + 'strict' => $this->boolean('strict'), + 'triggers' => $this->getRuleTriggerData(), + 'actions' => $this->getRuleActionData(), + ]; + } + + /** + * @return array + */ + private function getRuleTriggerData(): array + { + $return = []; + $triggerData = $this->get('triggers'); + if (is_array($triggerData)) { + foreach ($triggerData as $trigger) { + $stopProcessing = $trigger['stop_processing'] ?? '0'; + $prohibited = $trigger['prohibited'] ?? '0'; + $set = [ + 'type' => $trigger['type'] ?? 'invalid', + 'value' => $trigger['value'] ?? '', + 'stop_processing' => 1 === (int)$stopProcessing, + 'prohibited' => 1 === (int)$prohibited, + ]; + $set = self::replaceAmountTrigger($set); + $return[] = $set; + } + } + + return $return; + } + + /** + * @param array $array * @return array */ public static function replaceAmountTrigger(array $array): array @@ -67,24 +113,24 @@ class RuleFormRequest extends FormRequest } /** - * Get all data for controller. - * * @return array - * */ - public function getRuleData(): array + private function getRuleActionData(): array { - return [ - 'title' => $this->convertString('title'), - 'rule_group_id' => $this->convertInteger('rule_group_id'), - 'active' => $this->boolean('active'), - 'trigger' => $this->convertString('trigger'), - 'description' => $this->stringWithNewlines('description'), - 'stop_processing' => $this->boolean('stop_processing'), - 'strict' => $this->boolean('strict'), - 'triggers' => $this->getRuleTriggerData(), - 'actions' => $this->getRuleActionData(), - ]; + $return = []; + $actionData = $this->get('actions'); + if (is_array($actionData)) { + foreach ($actionData as $action) { + $stopProcessing = $action['stop_processing'] ?? '0'; + $return[] = [ + 'type' => $action['type'] ?? 'invalid', + 'value' => $action['value'] ?? '', + 'stop_processing' => 1 === (int)$stopProcessing, + ]; + } + } + + return $return; } /** @@ -110,9 +156,9 @@ class RuleFormRequest extends FormRequest 'stop_processing' => 'boolean', 'rule_group_id' => 'required|belongsToUser:rule_groups', 'trigger' => 'required|in:store-journal,update-journal', - 'triggers.*.type' => 'required|in:'.implode(',', $validTriggers), + 'triggers.*.type' => 'required|in:' . implode(',', $validTriggers), 'triggers.*.value' => sprintf('required_if:triggers.*.type,%s|max:1024|min:1|ruleTriggerValue', $contextTriggers), - 'actions.*.type' => 'required|in:'.implode(',', $validActions), + 'actions.*.type' => 'required|in:' . implode(',', $validActions), 'actions.*.value' => sprintf('required_if:actions.*.type,%s|min:0|max:1024|ruleActionValue', $contextActions), 'strict' => 'in:0,1', ]; @@ -121,55 +167,9 @@ class RuleFormRequest extends FormRequest $rule = $this->route()->parameter('rule'); if (null !== $rule) { - $rules['title'] = 'required|between:1,100|uniqueObjectForUser:rules,title,'.$rule->id; + $rules['title'] = 'required|between:1,100|uniqueObjectForUser:rules,title,' . $rule->id; } return $rules; } - - /** - * @return array - */ - private function getRuleActionData(): array - { - $return = []; - $actionData = $this->get('actions'); - if (is_array($actionData)) { - foreach ($actionData as $action) { - $stopProcessing = $action['stop_processing'] ?? '0'; - $return[] = [ - 'type' => $action['type'] ?? 'invalid', - 'value' => $action['value'] ?? '', - 'stop_processing' => 1 === (int)$stopProcessing, - ]; - } - } - - return $return; - } - - /** - * @return array - */ - private function getRuleTriggerData(): array - { - $return = []; - $triggerData = $this->get('triggers'); - if (is_array($triggerData)) { - foreach ($triggerData as $trigger) { - $stopProcessing = $trigger['stop_processing'] ?? '0'; - $prohibited = $trigger['prohibited'] ?? '0'; - $set = [ - 'type' => $trigger['type'] ?? 'invalid', - 'value' => $trigger['value'] ?? '', - 'stop_processing' => 1 === (int)$stopProcessing, - 'prohibited' => 1 === (int)$prohibited, - ]; - $set = self::replaceAmountTrigger($set); - $return[] = $set; - } - } - - return $return; - } } diff --git a/app/Http/Requests/RuleGroupFormRequest.php b/app/Http/Requests/RuleGroupFormRequest.php index 3b23ecc0f7..91da192e06 100644 --- a/app/Http/Requests/RuleGroupFormRequest.php +++ b/app/Http/Requests/RuleGroupFormRequest.php @@ -69,7 +69,7 @@ class RuleGroupFormRequest extends FormRequest $ruleGroup = $this->route()->parameter('ruleGroup'); if (null !== $ruleGroup) { - $titleRule = 'required|between:1,100|uniqueObjectForUser:rule_groups,title,'.$ruleGroup->id; + $titleRule = 'required|between:1,100|uniqueObjectForUser:rule_groups,title,' . $ruleGroup->id; } return [ diff --git a/app/Http/Requests/SelectTransactionsRequest.php b/app/Http/Requests/SelectTransactionsRequest.php index da47ec0d44..17f5284ca1 100644 --- a/app/Http/Requests/SelectTransactionsRequest.php +++ b/app/Http/Requests/SelectTransactionsRequest.php @@ -50,8 +50,8 @@ class SelectTransactionsRequest extends FormRequest $today = today(config('app.timezone'))->addDay()->format('Y-m-d'); return [ - 'start' => 'required|date|after:'.$first, - 'end' => 'required|date|before:'.$today, + 'start' => 'required|date|after:' . $first, + 'end' => 'required|date|before:' . $today, 'accounts' => 'required', 'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts', ]; diff --git a/app/Http/Requests/TagFormRequest.php b/app/Http/Requests/TagFormRequest.php index 9a4f82fdad..c006faaef7 100644 --- a/app/Http/Requests/TagFormRequest.php +++ b/app/Http/Requests/TagFormRequest.php @@ -69,7 +69,7 @@ class TagFormRequest extends FormRequest $tagRule = 'required|max:1024|min:1|uniqueObjectForUser:tags,tag'; if (null !== $tag) { $idRule = 'belongsToUser:tags'; - $tagRule = 'required|max:1024|min:1|uniqueObjectForUser:tags,tag,'.$tag->id; + $tagRule = 'required|max:1024|min:1|uniqueObjectForUser:tags,tag,' . $tag->id; } $rules = [ diff --git a/app/Http/Requests/TestRuleFormRequest.php b/app/Http/Requests/TestRuleFormRequest.php index 261f64437f..39b7cc62d3 100644 --- a/app/Http/Requests/TestRuleFormRequest.php +++ b/app/Http/Requests/TestRuleFormRequest.php @@ -49,7 +49,7 @@ class TestRuleFormRequest extends FormRequest $validTriggers = $this->getTriggers(); return [ - 'rule-trigger.*' => 'required|max:1024|min:1|in:'.implode(',', $validTriggers), + 'rule-trigger.*' => 'required|max:1024|min:1|in:' . implode(',', $validTriggers), 'rule-trigger-value.*' => 'required|max:1024|min:1|ruleTriggerValue', ]; } diff --git a/app/Jobs/CreateAutoBudgetLimits.php b/app/Jobs/CreateAutoBudgetLimits.php index 23b53454c1..8b6e629d0b 100644 --- a/app/Jobs/CreateAutoBudgetLimits.php +++ b/app/Jobs/CreateAutoBudgetLimits.php @@ -54,7 +54,7 @@ class CreateAutoBudgetLimits implements ShouldQueue * Create a new job instance. * * - * @param Carbon|null $date + * @param Carbon|null $date */ public function __construct(?Carbon $date) { @@ -82,201 +82,7 @@ class CreateAutoBudgetLimits implements ShouldQueue } /** - * @param Carbon $date - */ - public function setDate(Carbon $date): void - { - $newDate = clone $date; - $newDate->startOfDay(); - $this->date = $newDate; - } - - /** - * @param AutoBudget $autoBudget - * @return void - */ - private function createAdjustedLimit(AutoBudget $autoBudget): void - { - Log::debug(sprintf('Will now manage rollover for auto budget #%d', $autoBudget->id)); - // current period: - $start = app('navigation')->startOfPeriod($this->date, $autoBudget->period); - $end = app('navigation')->endOfPeriod($start, $autoBudget->period); - - // which means previous period: - $previousStart = app('navigation')->subtractPeriod($start, $autoBudget->period); - $previousEnd = app('navigation')->endOfPeriod($previousStart, $autoBudget->period); - - Log::debug( - sprintf( - 'Current period is %s-%s, so previous period is %s-%s', - $start->format('Y-m-d'), - $end->format('Y-m-d'), - $previousStart->format('Y-m-d'), - $previousEnd->format('Y-m-d') - ) - ); - - // has budget limit in previous period? - $budgetLimit = $this->findBudgetLimit($autoBudget->budget, $previousStart, $previousEnd); - - if (null === $budgetLimit) { - Log::debug('No budget limit exists in previous period, so create one.'); - // if not, create standard amount, and we're done. - $this->createBudgetLimit($autoBudget, $start, $end); - return; - } - Log::debug('Budget limit exists for previous period.'); - - // if has one, calculate expenses and use that as a base. - $repository = app(OperationsRepositoryInterface::class); - $repository->setUser($autoBudget->budget->user); - $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection([$autoBudget->budget]), $autoBudget->transactionCurrency); - $currencyId = (int)$autoBudget->transaction_currency_id; - $spentAmount = $spent[$currencyId]['sum'] ?? '0'; - Log::debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount)); - - // what you spent in previous period PLUS the amount for the current period, - // if that is more than zero, that's the amount that will be set. - - $budgetAvailable = bcadd(bcadd($budgetLimit->amount, $autoBudget->amount), $spentAmount); - $totalAmount = $autoBudget->amount; - Log::debug(sprintf('Total amount available for current budget period is %s', $budgetAvailable)); - - - if (-1 !== bccomp($budgetAvailable, $totalAmount)) { - Log::info(sprintf('There is no overspending, no need to adjust. Budget limit amount will be %s.', $budgetAvailable)); - // create budget limit: - $this->createBudgetLimit($autoBudget, $start, $end, $budgetAvailable); - } - if (1 !== bccomp($budgetAvailable, $totalAmount) && 1 === bccomp($budgetAvailable, '0')) { - Log::info(sprintf('There was overspending, so the new amount will be %s.', $budgetAvailable)); - // create budget limit: - $this->createBudgetLimit($autoBudget, $start, $end, $budgetAvailable); - } - if (1 !== bccomp($budgetAvailable, $totalAmount) && -1 === bccomp($budgetAvailable, '0')) { - Log::info('There was overspending, but so much even this period cant fix that. Reset it to 1.'); - // create budget limit: - $this->createBudgetLimit($autoBudget, $start, $end, '1'); - } - Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id)); - } - - /** - * @param AutoBudget $autoBudget - * @param Carbon $start - * @param Carbon $end - * @param string|null $amount - */ - private function createBudgetLimit(AutoBudget $autoBudget, Carbon $start, Carbon $end, ?string $amount = null) - { - Log::debug(sprintf('No budget limit exist. Must create one for auto-budget #%d', $autoBudget->id)); - if (null !== $amount) { - Log::debug(sprintf('Amount is overruled and will be set to %s', $amount)); - } - $budgetLimit = new BudgetLimit(); - $budgetLimit->budget()->associate($autoBudget->budget); - $budgetLimit->transactionCurrency()->associate($autoBudget->transactionCurrency); - $budgetLimit->start_date = $start; - $budgetLimit->end_date = $end; - $budgetLimit->amount = $amount ?? $autoBudget->amount; - $budgetLimit->period = $autoBudget->period; - $budgetLimit->generated = true; - $budgetLimit->save(); - - Log::debug(sprintf('Created budget limit #%d.', $budgetLimit->id)); - } - - /** - * @param AutoBudget $autoBudget - * - * @throws FireflyException - */ - private function createRollover(AutoBudget $autoBudget): void - { - Log::debug(sprintf('Will now manage rollover for auto budget #%d', $autoBudget->id)); - // current period: - $start = app('navigation')->startOfPeriod($this->date, $autoBudget->period); - $end = app('navigation')->endOfPeriod($start, $autoBudget->period); - - // which means previous period: - $previousStart = app('navigation')->subtractPeriod($start, $autoBudget->period); - $previousEnd = app('navigation')->endOfPeriod($previousStart, $autoBudget->period); - - Log::debug( - sprintf( - 'Current period is %s-%s, so previous period is %s-%s', - $start->format('Y-m-d'), - $end->format('Y-m-d'), - $previousStart->format('Y-m-d'), - $previousEnd->format('Y-m-d') - ) - ); - - // has budget limit in previous period? - $budgetLimit = $this->findBudgetLimit($autoBudget->budget, $previousStart, $previousEnd); - - if (null === $budgetLimit) { - Log::debug('No budget limit exists in previous period, so create one.'); - // if not, create it and we're done. - $this->createBudgetLimit($autoBudget, $start, $end); - Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id)); - - return; - } - Log::debug('Budget limit exists for previous period.'); - // if has one, calculate expenses and use that as a base. - $repository = app(OperationsRepositoryInterface::class); - $repository->setUser($autoBudget->budget->user); - $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection([$autoBudget->budget]), $autoBudget->transactionCurrency); - $currencyId = (int)$autoBudget->transaction_currency_id; - $spentAmount = $spent[$currencyId]['sum'] ?? '0'; - Log::debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount)); - - // if you spent more in previous budget period, than whatever you had previous budget period, the amount resets - // previous budget limit + spent - $budgetLeft = bcadd($budgetLimit->amount, $spentAmount); - $totalAmount = $autoBudget->amount; - Log::debug(sprintf('Total amount left for previous budget period is %s', $budgetLeft)); - - if (-1 !== bccomp('0', $budgetLeft)) { - Log::info(sprintf('The amount left is negative, so it will be reset to %s.', $totalAmount)); - } - if (1 !== bccomp('0', $budgetLeft)) { - $totalAmount = bcadd($budgetLeft, $totalAmount); - Log::info(sprintf('The amount left is positive, so the new amount will be %s.', $totalAmount)); - } - - // create budget limit: - $this->createBudgetLimit($autoBudget, $start, $end, $totalAmount); - Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id)); - } - - /** - * @param Budget $budget - * @param Carbon $start - * @param Carbon $end - * - * @return BudgetLimit|null - */ - private function findBudgetLimit(Budget $budget, Carbon $start, Carbon $end): ?BudgetLimit - { - Log::debug( - sprintf( - 'Going to find a budget limit for budget #%d ("%s") between %s and %s', - $budget->id, - $budget->name, - $start->format('Y-m-d'), - $end->format('Y-m-d') - ) - ); - - return $budget->budgetlimits() - ->where('start_date', $start->format('Y-m-d')) - ->where('end_date', $end->format('Y-m-d'))->first(); - } - - /** - * @param AutoBudget $autoBudget + * @param AutoBudget $autoBudget * * @throws FireflyException */ @@ -353,7 +159,7 @@ class CreateAutoBudgetLimits implements ShouldQueue } /** - * @param AutoBudget $autoBudget + * @param AutoBudget $autoBudget * * @return bool * @throws FireflyException @@ -391,4 +197,198 @@ class CreateAutoBudgetLimits implements ShouldQueue } throw new FireflyException(sprintf('isMagicDay() can\'t handle period "%s"', $autoBudget->period)); } + + /** + * @param Budget $budget + * @param Carbon $start + * @param Carbon $end + * + * @return BudgetLimit|null + */ + private function findBudgetLimit(Budget $budget, Carbon $start, Carbon $end): ?BudgetLimit + { + Log::debug( + sprintf( + 'Going to find a budget limit for budget #%d ("%s") between %s and %s', + $budget->id, + $budget->name, + $start->format('Y-m-d'), + $end->format('Y-m-d') + ) + ); + + return $budget->budgetlimits() + ->where('start_date', $start->format('Y-m-d')) + ->where('end_date', $end->format('Y-m-d'))->first(); + } + + /** + * @param AutoBudget $autoBudget + * @param Carbon $start + * @param Carbon $end + * @param string|null $amount + */ + private function createBudgetLimit(AutoBudget $autoBudget, Carbon $start, Carbon $end, ?string $amount = null) + { + Log::debug(sprintf('No budget limit exist. Must create one for auto-budget #%d', $autoBudget->id)); + if (null !== $amount) { + Log::debug(sprintf('Amount is overruled and will be set to %s', $amount)); + } + $budgetLimit = new BudgetLimit(); + $budgetLimit->budget()->associate($autoBudget->budget); + $budgetLimit->transactionCurrency()->associate($autoBudget->transactionCurrency); + $budgetLimit->start_date = $start; + $budgetLimit->end_date = $end; + $budgetLimit->amount = $amount ?? $autoBudget->amount; + $budgetLimit->period = $autoBudget->period; + $budgetLimit->generated = true; + $budgetLimit->save(); + + Log::debug(sprintf('Created budget limit #%d.', $budgetLimit->id)); + } + + /** + * @param AutoBudget $autoBudget + * + * @throws FireflyException + */ + private function createRollover(AutoBudget $autoBudget): void + { + Log::debug(sprintf('Will now manage rollover for auto budget #%d', $autoBudget->id)); + // current period: + $start = app('navigation')->startOfPeriod($this->date, $autoBudget->period); + $end = app('navigation')->endOfPeriod($start, $autoBudget->period); + + // which means previous period: + $previousStart = app('navigation')->subtractPeriod($start, $autoBudget->period); + $previousEnd = app('navigation')->endOfPeriod($previousStart, $autoBudget->period); + + Log::debug( + sprintf( + 'Current period is %s-%s, so previous period is %s-%s', + $start->format('Y-m-d'), + $end->format('Y-m-d'), + $previousStart->format('Y-m-d'), + $previousEnd->format('Y-m-d') + ) + ); + + // has budget limit in previous period? + $budgetLimit = $this->findBudgetLimit($autoBudget->budget, $previousStart, $previousEnd); + + if (null === $budgetLimit) { + Log::debug('No budget limit exists in previous period, so create one.'); + // if not, create it and we're done. + $this->createBudgetLimit($autoBudget, $start, $end); + Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id)); + + return; + } + Log::debug('Budget limit exists for previous period.'); + // if has one, calculate expenses and use that as a base. + $repository = app(OperationsRepositoryInterface::class); + $repository->setUser($autoBudget->budget->user); + $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection([$autoBudget->budget]), $autoBudget->transactionCurrency); + $currencyId = (int)$autoBudget->transaction_currency_id; + $spentAmount = $spent[$currencyId]['sum'] ?? '0'; + Log::debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount)); + + // if you spent more in previous budget period, than whatever you had previous budget period, the amount resets + // previous budget limit + spent + $budgetLeft = bcadd($budgetLimit->amount, $spentAmount); + $totalAmount = $autoBudget->amount; + Log::debug(sprintf('Total amount left for previous budget period is %s', $budgetLeft)); + + if (-1 !== bccomp('0', $budgetLeft)) { + Log::info(sprintf('The amount left is negative, so it will be reset to %s.', $totalAmount)); + } + if (1 !== bccomp('0', $budgetLeft)) { + $totalAmount = bcadd($budgetLeft, $totalAmount); + Log::info(sprintf('The amount left is positive, so the new amount will be %s.', $totalAmount)); + } + + // create budget limit: + $this->createBudgetLimit($autoBudget, $start, $end, $totalAmount); + Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id)); + } + + /** + * @param AutoBudget $autoBudget + * @return void + */ + private function createAdjustedLimit(AutoBudget $autoBudget): void + { + Log::debug(sprintf('Will now manage rollover for auto budget #%d', $autoBudget->id)); + // current period: + $start = app('navigation')->startOfPeriod($this->date, $autoBudget->period); + $end = app('navigation')->endOfPeriod($start, $autoBudget->period); + + // which means previous period: + $previousStart = app('navigation')->subtractPeriod($start, $autoBudget->period); + $previousEnd = app('navigation')->endOfPeriod($previousStart, $autoBudget->period); + + Log::debug( + sprintf( + 'Current period is %s-%s, so previous period is %s-%s', + $start->format('Y-m-d'), + $end->format('Y-m-d'), + $previousStart->format('Y-m-d'), + $previousEnd->format('Y-m-d') + ) + ); + + // has budget limit in previous period? + $budgetLimit = $this->findBudgetLimit($autoBudget->budget, $previousStart, $previousEnd); + + if (null === $budgetLimit) { + Log::debug('No budget limit exists in previous period, so create one.'); + // if not, create standard amount, and we're done. + $this->createBudgetLimit($autoBudget, $start, $end); + return; + } + Log::debug('Budget limit exists for previous period.'); + + // if has one, calculate expenses and use that as a base. + $repository = app(OperationsRepositoryInterface::class); + $repository->setUser($autoBudget->budget->user); + $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection([$autoBudget->budget]), $autoBudget->transactionCurrency); + $currencyId = (int)$autoBudget->transaction_currency_id; + $spentAmount = $spent[$currencyId]['sum'] ?? '0'; + Log::debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount)); + + // what you spent in previous period PLUS the amount for the current period, + // if that is more than zero, that's the amount that will be set. + + $budgetAvailable = bcadd(bcadd($budgetLimit->amount, $autoBudget->amount), $spentAmount); + $totalAmount = $autoBudget->amount; + Log::debug(sprintf('Total amount available for current budget period is %s', $budgetAvailable)); + + + if (-1 !== bccomp($budgetAvailable, $totalAmount)) { + Log::info(sprintf('There is no overspending, no need to adjust. Budget limit amount will be %s.', $budgetAvailable)); + // create budget limit: + $this->createBudgetLimit($autoBudget, $start, $end, $budgetAvailable); + } + if (1 !== bccomp($budgetAvailable, $totalAmount) && 1 === bccomp($budgetAvailable, '0')) { + Log::info(sprintf('There was overspending, so the new amount will be %s.', $budgetAvailable)); + // create budget limit: + $this->createBudgetLimit($autoBudget, $start, $end, $budgetAvailable); + } + if (1 !== bccomp($budgetAvailable, $totalAmount) && -1 === bccomp($budgetAvailable, '0')) { + Log::info('There was overspending, but so much even this period cant fix that. Reset it to 1.'); + // create budget limit: + $this->createBudgetLimit($autoBudget, $start, $end, '1'); + } + Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id)); + } + + /** + * @param Carbon $date + */ + public function setDate(Carbon $date): void + { + $newDate = clone $date; + $newDate->startOfDay(); + $this->date = $newDate; + } } diff --git a/app/Jobs/CreateRecurringTransactions.php b/app/Jobs/CreateRecurringTransactions.php index c9881843eb..20c81942f6 100644 --- a/app/Jobs/CreateRecurringTransactions.php +++ b/app/Jobs/CreateRecurringTransactions.php @@ -70,7 +70,7 @@ class CreateRecurringTransactions implements ShouldQueue * Create a new job instance. * * - * @param Carbon|null $date + * @param Carbon|null $date */ public function __construct(?Carbon $date) { @@ -160,45 +160,7 @@ class CreateRecurringTransactions implements ShouldQueue } /** - * @param Carbon $date - */ - public function setDate(Carbon $date): void - { - $newDate = clone $date; - $newDate->startOfDay(); - $this->date = $newDate; - } - - /** - * @param bool $force - */ - public function setForce(bool $force): void - { - $this->force = $force; - } - - /** - * @param Collection $recurrences - */ - public function setRecurrences(Collection $recurrences): void - { - $this->recurrences = $recurrences; - } - - /** - * Return recurring transaction is active. - * - * @param Recurrence $recurrence - * - * @return bool - */ - private function active(Recurrence $recurrence): bool - { - return $recurrence->active; - } - - /** - * @param Collection $recurrences + * @param Collection $recurrences * * @return Collection */ @@ -211,10 +173,115 @@ class CreateRecurringTransactions implements ShouldQueue ); } + /** + * Is the info in the recurrence valid? + * + * @param Recurrence $recurrence + * + * @return bool + * + */ + private function validRecurrence(Recurrence $recurrence): bool + { + Log::debug(sprintf('Now filtering recurrence #%d, owned by user #%d', $recurrence->id, $recurrence->user_id)); + // is not active. + if (!$this->active($recurrence)) { + Log::info(sprintf('Recurrence #%d is not active. Skipped.', $recurrence->id)); + + return false; + } + + // has repeated X times. + $journalCount = $this->repository->getJournalCount($recurrence); + if (0 !== $recurrence->repetitions && $journalCount >= $recurrence->repetitions && false === $this->force) { + Log::info(sprintf('Recurrence #%d has run %d times, so will run no longer.', $recurrence->id, $recurrence->repetitions)); + + return false; + } + + // is no longer running + if ($this->repeatUntilHasPassed($recurrence)) { + Log::info( + sprintf( + 'Recurrence #%d was set to run until %s, and today\'s date is %s. Skipped.', + $recurrence->id, + $recurrence->repeat_until->format('Y-m-d'), + $this->date->format('Y-m-d') + ) + ); + + return false; + } + + // first_date is in the future + if ($this->hasNotStartedYet($recurrence)) { + Log::info( + sprintf( + 'Recurrence #%d is set to run on %s, and today\'s date is %s. Skipped.', + $recurrence->id, + $recurrence->first_date->format('Y-m-d'), + $this->date->format('Y-m-d') + ) + ); + + return false; + } + + // already fired today (with success): + if (false === $this->force && $this->hasFiredToday($recurrence)) { + Log::info(sprintf('Recurrence #%d has already fired today. Skipped.', $recurrence->id)); + + return false; + } + Log::debug('Will be included.'); + + return true; + } + + /** + * Return recurring transaction is active. + * + * @param Recurrence $recurrence + * + * @return bool + */ + private function active(Recurrence $recurrence): bool + { + return $recurrence->active; + } + + /** + * Return true if the $repeat_until date is in the past. + * + * @param Recurrence $recurrence + * + * @return bool + */ + private function repeatUntilHasPassed(Recurrence $recurrence): bool + { + // date has passed + return null !== $recurrence->repeat_until && $recurrence->repeat_until->lt($this->date); + } + + /** + * Has the recurrence started yet? + * + * @param Recurrence $recurrence + * + * @return bool + */ + private function hasNotStartedYet(Recurrence $recurrence): bool + { + $startDate = $this->getStartDate($recurrence); + Log::debug(sprintf('Start date is %s', $startDate->format('Y-m-d'))); + + return $startDate->gt($this->date); + } + /** * Get the start date of a recurrence. * - * @param Recurrence $recurrence + * @param Recurrence $recurrence * * @return Carbon */ @@ -229,67 +296,85 @@ class CreateRecurringTransactions implements ShouldQueue } /** - * Get transaction information from a recurring transaction. + * Has the recurrence fired today. * - * @param Recurrence $recurrence - * @param RecurrenceRepetition $repetition - * @param Carbon $date - * - * @return array + * @param Recurrence $recurrence * + * @return bool */ - private function getTransactionData(Recurrence $recurrence, RecurrenceRepetition $repetition, Carbon $date): array + private function hasFiredToday(Recurrence $recurrence): bool { - // total transactions expected for this recurrence: - $total = $this->repository->totalTransactions($recurrence, $repetition); - $count = $this->repository->getJournalCount($recurrence) + 1; - $transactions = $recurrence->recurrenceTransactions()->get(); - $return = []; - /** @var RecurrenceTransaction $transaction */ - foreach ($transactions as $index => $transaction) { - $single = [ - 'type' => strtolower($recurrence->transactionType->type), - 'date' => $date, - 'user' => $recurrence->user_id, - 'currency_id' => (int)$transaction->transaction_currency_id, - 'currency_code' => null, - 'description' => $transactions->first()->description, - 'amount' => $transaction->amount, - 'budget_id' => $this->repository->getBudget($transaction), - 'budget_name' => null, - 'category_id' => $this->repository->getCategoryId($transaction), - 'category_name' => $this->repository->getCategoryName($transaction), - 'source_id' => $transaction->source_id, - 'source_name' => null, - 'destination_id' => $transaction->destination_id, - 'destination_name' => null, - 'foreign_currency_id' => $transaction->foreign_currency_id, - 'foreign_currency_code' => null, - 'foreign_amount' => $transaction->foreign_amount, - 'reconciled' => false, - 'identifier' => $index, - 'recurrence_id' => (int)$recurrence->id, - 'order' => $index, - 'notes' => (string)trans('firefly.created_from_recurrence', ['id' => $recurrence->id, 'title' => $recurrence->title]), - 'tags' => $this->repository->getTags($transaction), - 'piggy_bank_id' => $this->repository->getPiggyBank($transaction), - 'piggy_bank_name' => null, - 'bill_id' => $this->repository->getBillId($transaction), - 'bill_name' => null, - 'recurrence_total' => $total, - 'recurrence_count' => $count, - 'recurrence_date' => $date, - ]; - $return[] = $single; - } - - return $return; + return null !== $recurrence->latest_date && $recurrence->latest_date->eq($this->date); } /** - * @param Recurrence $recurrence - * @param RecurrenceRepetition $repetition - * @param Carbon $date + * Separate method that will loop all repetitions and do something with it. Will return + * all created transaction journals. + * + * @param Recurrence $recurrence + * + * @return Collection + * @throws DuplicateTransactionException + * @throws FireflyException + */ + private function handleRepetitions(Recurrence $recurrence): Collection + { + $collection = new Collection(); + /** @var RecurrenceRepetition $repetition */ + foreach ($recurrence->recurrenceRepetitions as $repetition) { + Log::debug( + sprintf( + 'Now repeating %s with value "%s", skips every %d time(s)', + $repetition->repetition_type, + $repetition->repetition_moment, + $repetition->repetition_skip + ) + ); + + // start looping from $startDate to today perhaps we have a hit? + // add two days to $this->date, so we always include the weekend. + $includeWeekend = clone $this->date; + $includeWeekend->addDays(2); + $occurrences = $this->repository->getOccurrencesInRange($repetition, $recurrence->first_date, $includeWeekend); + + unset($includeWeekend); + + $result = $this->handleOccurrences($recurrence, $repetition, $occurrences); + $collection = $collection->merge($result); + } + + return $collection; + } + + /** + * Check if the occurences should be executed. + * + * @param Recurrence $recurrence + * @param RecurrenceRepetition $repetition + * @param array $occurrences + * + * @return Collection + * @throws DuplicateTransactionException + * @throws FireflyException + */ + private function handleOccurrences(Recurrence $recurrence, RecurrenceRepetition $repetition, array $occurrences): Collection + { + $collection = new Collection(); + /** @var Carbon $date */ + foreach ($occurrences as $date) { + $result = $this->handleOccurrence($recurrence, $repetition, $date); + if (null !== $result) { + $collection->push($result); + } + } + + return $collection; + } + + /** + * @param Recurrence $recurrence + * @param RecurrenceRepetition $repetition + * @param Carbon $date * * @return TransactionGroup|null * @throws DuplicateTransactionException @@ -360,171 +445,86 @@ class CreateRecurringTransactions implements ShouldQueue } /** - * Check if the occurences should be executed. + * Get transaction information from a recurring transaction. * - * @param Recurrence $recurrence - * @param RecurrenceRepetition $repetition - * @param array $occurrences + * @param Recurrence $recurrence + * @param RecurrenceRepetition $repetition + * @param Carbon $date + * + * @return array * - * @return Collection - * @throws DuplicateTransactionException - * @throws FireflyException */ - private function handleOccurrences(Recurrence $recurrence, RecurrenceRepetition $repetition, array $occurrences): Collection + private function getTransactionData(Recurrence $recurrence, RecurrenceRepetition $repetition, Carbon $date): array { - $collection = new Collection(); - /** @var Carbon $date */ - foreach ($occurrences as $date) { - $result = $this->handleOccurrence($recurrence, $repetition, $date); - if (null !== $result) { - $collection->push($result); - } + // total transactions expected for this recurrence: + $total = $this->repository->totalTransactions($recurrence, $repetition); + $count = $this->repository->getJournalCount($recurrence) + 1; + $transactions = $recurrence->recurrenceTransactions()->get(); + $return = []; + /** @var RecurrenceTransaction $transaction */ + foreach ($transactions as $index => $transaction) { + $single = [ + 'type' => strtolower($recurrence->transactionType->type), + 'date' => $date, + 'user' => $recurrence->user_id, + 'currency_id' => (int)$transaction->transaction_currency_id, + 'currency_code' => null, + 'description' => $transactions->first()->description, + 'amount' => $transaction->amount, + 'budget_id' => $this->repository->getBudget($transaction), + 'budget_name' => null, + 'category_id' => $this->repository->getCategoryId($transaction), + 'category_name' => $this->repository->getCategoryName($transaction), + 'source_id' => $transaction->source_id, + 'source_name' => null, + 'destination_id' => $transaction->destination_id, + 'destination_name' => null, + 'foreign_currency_id' => $transaction->foreign_currency_id, + 'foreign_currency_code' => null, + 'foreign_amount' => $transaction->foreign_amount, + 'reconciled' => false, + 'identifier' => $index, + 'recurrence_id' => (int)$recurrence->id, + 'order' => $index, + 'notes' => (string)trans('firefly.created_from_recurrence', ['id' => $recurrence->id, 'title' => $recurrence->title]), + 'tags' => $this->repository->getTags($transaction), + 'piggy_bank_id' => $this->repository->getPiggyBank($transaction), + 'piggy_bank_name' => null, + 'bill_id' => $this->repository->getBillId($transaction), + 'bill_name' => null, + 'recurrence_total' => $total, + 'recurrence_count' => $count, + 'recurrence_date' => $date, + ]; + $return[] = $single; } - return $collection; + return $return; } /** - * Separate method that will loop all repetitions and do something with it. Will return - * all created transaction journals. - * - * @param Recurrence $recurrence - * - * @return Collection - * @throws DuplicateTransactionException - * @throws FireflyException + * @param Carbon $date */ - private function handleRepetitions(Recurrence $recurrence): Collection + public function setDate(Carbon $date): void { - $collection = new Collection(); - /** @var RecurrenceRepetition $repetition */ - foreach ($recurrence->recurrenceRepetitions as $repetition) { - Log::debug( - sprintf( - 'Now repeating %s with value "%s", skips every %d time(s)', - $repetition->repetition_type, - $repetition->repetition_moment, - $repetition->repetition_skip - ) - ); - - // start looping from $startDate to today perhaps we have a hit? - // add two days to $this->date, so we always include the weekend. - $includeWeekend = clone $this->date; - $includeWeekend->addDays(2); - $occurrences = $this->repository->getOccurrencesInRange($repetition, $recurrence->first_date, $includeWeekend); - - unset($includeWeekend); - - $result = $this->handleOccurrences($recurrence, $repetition, $occurrences); - $collection = $collection->merge($result); - } - - return $collection; + $newDate = clone $date; + $newDate->startOfDay(); + $this->date = $newDate; } /** - * Has the recurrence fired today. - * - * @param Recurrence $recurrence - * - * @return bool + * @param bool $force */ - private function hasFiredToday(Recurrence $recurrence): bool + public function setForce(bool $force): void { - return null !== $recurrence->latest_date && $recurrence->latest_date->eq($this->date); + $this->force = $force; } /** - * Has the recurrence started yet? - * - * @param Recurrence $recurrence - * - * @return bool + * @param Collection $recurrences */ - private function hasNotStartedYet(Recurrence $recurrence): bool + public function setRecurrences(Collection $recurrences): void { - $startDate = $this->getStartDate($recurrence); - Log::debug(sprintf('Start date is %s', $startDate->format('Y-m-d'))); - - return $startDate->gt($this->date); - } - - /** - * Return true if the $repeat_until date is in the past. - * - * @param Recurrence $recurrence - * - * @return bool - */ - private function repeatUntilHasPassed(Recurrence $recurrence): bool - { - // date has passed - return null !== $recurrence->repeat_until && $recurrence->repeat_until->lt($this->date); - } - - /** - * Is the info in the recurrence valid? - * - * @param Recurrence $recurrence - * - * @return bool - * - */ - private function validRecurrence(Recurrence $recurrence): bool - { - Log::debug(sprintf('Now filtering recurrence #%d, owned by user #%d', $recurrence->id, $recurrence->user_id)); - // is not active. - if (!$this->active($recurrence)) { - Log::info(sprintf('Recurrence #%d is not active. Skipped.', $recurrence->id)); - - return false; - } - - // has repeated X times. - $journalCount = $this->repository->getJournalCount($recurrence); - if (0 !== $recurrence->repetitions && $journalCount >= $recurrence->repetitions && false === $this->force) { - Log::info(sprintf('Recurrence #%d has run %d times, so will run no longer.', $recurrence->id, $recurrence->repetitions)); - - return false; - } - - // is no longer running - if ($this->repeatUntilHasPassed($recurrence)) { - Log::info( - sprintf( - 'Recurrence #%d was set to run until %s, and today\'s date is %s. Skipped.', - $recurrence->id, - $recurrence->repeat_until->format('Y-m-d'), - $this->date->format('Y-m-d') - ) - ); - - return false; - } - - // first_date is in the future - if ($this->hasNotStartedYet($recurrence)) { - Log::info( - sprintf( - 'Recurrence #%d is set to run on %s, and today\'s date is %s. Skipped.', - $recurrence->id, - $recurrence->first_date->format('Y-m-d'), - $this->date->format('Y-m-d') - ) - ); - - return false; - } - - // already fired today (with success): - if (false === $this->force && $this->hasFiredToday($recurrence)) { - Log::info(sprintf('Recurrence #%d has already fired today. Skipped.', $recurrence->id)); - - return false; - } - Log::debug('Will be included.'); - - return true; + $this->recurrences = $recurrences; } } diff --git a/app/Jobs/DownloadExchangeRates.php b/app/Jobs/DownloadExchangeRates.php index 7327bfb3d9..8519838eeb 100644 --- a/app/Jobs/DownloadExchangeRates.php +++ b/app/Jobs/DownloadExchangeRates.php @@ -58,7 +58,7 @@ class DownloadExchangeRates implements ShouldQueue * Create a new job instance. * * - * @param Carbon|null $date + * @param Carbon|null $date */ public function __construct(?Carbon $date) { @@ -93,17 +93,7 @@ class DownloadExchangeRates implements ShouldQueue } /** - * @param Carbon $date - */ - public function setDate(Carbon $date): void - { - $newDate = clone $date; - $newDate->startOfDay(); - $this->date = $newDate; - } - - /** - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * @return void * @throws GuzzleException */ @@ -134,8 +124,21 @@ class DownloadExchangeRates implements ShouldQueue $this->saveRates($currency, $date, $json['rates']); } + private function saveRates(TransactionCurrency $currency, Carbon $date, array $rates): void + { + foreach ($rates as $code => $rate) { + $to = $this->getCurrency($code); + if (null === $to) { + Log::debug(sprintf('Currency %s is not in use, do not save rate.', $code)); + continue; + } + Log::debug(sprintf('Currency %s is in use.', $code)); + $this->saveRate($currency, $to, $date, $rate); + } + } + /** - * @param string $code + * @param string $code * @return TransactionCurrency|null */ private function getCurrency(string $code): ?TransactionCurrency @@ -175,16 +178,13 @@ class DownloadExchangeRates implements ShouldQueue } } - private function saveRates(TransactionCurrency $currency, Carbon $date, array $rates): void + /** + * @param Carbon $date + */ + public function setDate(Carbon $date): void { - foreach ($rates as $code => $rate) { - $to = $this->getCurrency($code); - if (null === $to) { - Log::debug(sprintf('Currency %s is not in use, do not save rate.', $code)); - continue; - } - Log::debug(sprintf('Currency %s is in use.', $code)); - $this->saveRate($currency, $to, $date, $rate); - } + $newDate = clone $date; + $newDate->startOfDay(); + $this->date = $newDate; } } diff --git a/app/Jobs/MailError.php b/app/Jobs/MailError.php index ef17690a12..bb4b916b7d 100644 --- a/app/Jobs/MailError.php +++ b/app/Jobs/MailError.php @@ -51,10 +51,10 @@ class MailError extends Job implements ShouldQueue /** * MailError constructor. * - * @param array $userData - * @param string $destination - * @param string $ipAddress - * @param array $exceptionData + * @param array $userData + * @param string $destination + * @param string $ipAddress + * @param array $exceptionData */ public function __construct(array $userData, string $destination, string $ipAddress, array $exceptionData) { @@ -70,6 +70,7 @@ class MailError extends Job implements ShouldQueue /** * Execute the job. + * * @throws FireflyException */ public function handle() @@ -91,7 +92,7 @@ class MailError extends Job implements ShouldQueue } } ); - } catch (Exception|TransportException $e) { // intentional generic exception + } catch (Exception | TransportException $e) { // intentional generic exception $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { Log::warning('[Bcc] Could not email or log the error. Please validate your email settings, use the .env.example file as a guide.'); diff --git a/app/Jobs/SendWebhookMessage.php b/app/Jobs/SendWebhookMessage.php index c557ec61c4..42dfdf5d46 100644 --- a/app/Jobs/SendWebhookMessage.php +++ b/app/Jobs/SendWebhookMessage.php @@ -48,7 +48,7 @@ class SendWebhookMessage implements ShouldQueue /** * Create a new job instance. * - * @param WebhookMessage $message + * @param WebhookMessage $message */ public function __construct(WebhookMessage $message) { diff --git a/app/Jobs/WarnAboutBills.php b/app/Jobs/WarnAboutBills.php index 42eaa04a55..fd0d2434f4 100644 --- a/app/Jobs/WarnAboutBills.php +++ b/app/Jobs/WarnAboutBills.php @@ -51,7 +51,7 @@ class WarnAboutBills implements ShouldQueue * Create a new job instance. * * - * @param Carbon|null $date + * @param Carbon|null $date */ public function __construct(?Carbon $date) { @@ -96,37 +96,7 @@ class WarnAboutBills implements ShouldQueue } /** - * @param Carbon $date - */ - public function setDate(Carbon $date): void - { - $newDate = clone $date; - $newDate->startOfDay(); - $this->date = $newDate; - } - - /** - * @param bool $force - */ - public function setForce(bool $force): void - { - $this->force = $force; - } - - /** - * @param Bill $bill - * @param string $field - * @return int - */ - private function getDiff(Bill $bill, string $field): int - { - $today = clone $this->date; - $carbon = clone $bill->$field; - return $today->diffInDays($carbon, false); - } - - /** - * @param Bill $bill + * @param Bill $bill * @return bool */ private function hasDateFields(Bill $bill): bool @@ -143,8 +113,8 @@ class WarnAboutBills implements ShouldQueue } /** - * @param Bill $bill - * @param string $field + * @param Bill $bill + * @param string $field * @return bool */ private function needsWarning(Bill $bill, string $field): bool @@ -162,8 +132,20 @@ class WarnAboutBills implements ShouldQueue } /** - * @param Bill $bill - * @param string $field + * @param Bill $bill + * @param string $field + * @return int + */ + private function getDiff(Bill $bill, string $field): int + { + $today = clone $this->date; + $carbon = clone $bill->$field; + return $today->diffInDays($carbon, false); + } + + /** + * @param Bill $bill + * @param string $field * @return void */ private function sendWarning(Bill $bill, string $field): void @@ -172,4 +154,22 @@ class WarnAboutBills implements ShouldQueue Log::debug('Will now send warning!'); event(new WarnUserAboutBill($bill, $field, $diff)); } + + /** + * @param Carbon $date + */ + public function setDate(Carbon $date): void + { + $newDate = clone $date; + $newDate->startOfDay(); + $this->date = $newDate; + } + + /** + * @param bool $force + */ + public function setForce(bool $force): void + { + $this->force = $force; + } } diff --git a/app/Mail/BillWarningMail.php b/app/Mail/BillWarningMail.php index 308d86c706..7984a2bff9 100644 --- a/app/Mail/BillWarningMail.php +++ b/app/Mail/BillWarningMail.php @@ -41,9 +41,9 @@ class BillWarningMail extends Mailable /** * ConfirmEmailChangeMail constructor. * - * @param Bill $bill - * @param string $field - * @param int $diff + * @param Bill $bill + * @param string $field + * @param int $diff */ public function __construct(Bill $bill, string $field, int $diff) { diff --git a/app/Mail/ConfirmEmailChangeMail.php b/app/Mail/ConfirmEmailChangeMail.php index cf8bd272c7..452ce6e4e7 100644 --- a/app/Mail/ConfirmEmailChangeMail.php +++ b/app/Mail/ConfirmEmailChangeMail.php @@ -46,9 +46,9 @@ class ConfirmEmailChangeMail extends Mailable /** * ConfirmEmailChangeMail constructor. * - * @param string $newEmail - * @param string $oldEmail - * @param string $url + * @param string $newEmail + * @param string $oldEmail + * @param string $url */ public function __construct(string $newEmail, string $oldEmail, string $url) { diff --git a/app/Mail/InvitationMail.php b/app/Mail/InvitationMail.php index 9f82a8f6f3..6d87b56e64 100644 --- a/app/Mail/InvitationMail.php +++ b/app/Mail/InvitationMail.php @@ -41,9 +41,9 @@ class InvitationMail extends Mailable /** * OAuthTokenCreatedMail constructor. * - * @param string $invitee - * @param string $admin - * @param string $url + * @param string $invitee + * @param string $admin + * @param string $url */ public function __construct(string $invitee, string $admin, string $url) { diff --git a/app/Mail/NewIPAddressWarningMail.php b/app/Mail/NewIPAddressWarningMail.php index 472c6274b5..bddb54d960 100644 --- a/app/Mail/NewIPAddressWarningMail.php +++ b/app/Mail/NewIPAddressWarningMail.php @@ -45,7 +45,7 @@ class NewIPAddressWarningMail extends Mailable /** * OAuthTokenCreatedMail constructor. * - * @param string $ipAddress + * @param string $ipAddress */ public function __construct(string $ipAddress) { diff --git a/app/Mail/OAuthTokenCreatedMail.php b/app/Mail/OAuthTokenCreatedMail.php index 5284c8c767..2c75fa3d36 100644 --- a/app/Mail/OAuthTokenCreatedMail.php +++ b/app/Mail/OAuthTokenCreatedMail.php @@ -43,7 +43,7 @@ class OAuthTokenCreatedMail extends Mailable /** * OAuthTokenCreatedMail constructor. * - * @param Client $client + * @param Client $client */ public function __construct(Client $client) { diff --git a/app/Mail/RegisteredUser.php b/app/Mail/RegisteredUser.php index 54169051e9..d460047eed 100644 --- a/app/Mail/RegisteredUser.php +++ b/app/Mail/RegisteredUser.php @@ -44,7 +44,7 @@ class RegisteredUser extends Mailable /** * Create a new message instance. * - * @param string $address + * @param string $address */ public function __construct(string $address) { diff --git a/app/Mail/ReportNewJournalsMail.php b/app/Mail/ReportNewJournalsMail.php index 28830e07b1..80ae173355 100644 --- a/app/Mail/ReportNewJournalsMail.php +++ b/app/Mail/ReportNewJournalsMail.php @@ -48,7 +48,7 @@ class ReportNewJournalsMail extends Mailable /** * ConfirmEmailChangeMail constructor. * - * @param Collection $groups + * @param Collection $groups */ public function __construct(Collection $groups) { diff --git a/app/Mail/RequestedNewPassword.php b/app/Mail/RequestedNewPassword.php index a9cd775dd0..f91c84ceef 100644 --- a/app/Mail/RequestedNewPassword.php +++ b/app/Mail/RequestedNewPassword.php @@ -43,7 +43,7 @@ class RequestedNewPassword extends Mailable /** * RequestedNewPassword constructor. * - * @param string $url + * @param string $url */ public function __construct(string $url) { diff --git a/app/Mail/UndoEmailChangeMail.php b/app/Mail/UndoEmailChangeMail.php index 1f800a5af9..6f6a202997 100644 --- a/app/Mail/UndoEmailChangeMail.php +++ b/app/Mail/UndoEmailChangeMail.php @@ -44,9 +44,9 @@ class UndoEmailChangeMail extends Mailable /** * UndoEmailChangeMail constructor. * - * @param string $newEmail - * @param string $oldEmail - * @param string $url + * @param string $newEmail + * @param string $oldEmail + * @param string $url */ public function __construct(string $newEmail, string $oldEmail, string $url) { diff --git a/app/Models/Account.php b/app/Models/Account.php index b661a1db33..5ef09f8ef0 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -42,36 +42,36 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Class Account * - * @property int $id + * @property int $id * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property \Illuminate\Support\Carbon|null $deleted_at - * @property int $user_id - * @property int $account_type_id - * @property string $name - * @property string|null $virtual_balance - * @property string|null $iban - * @property bool $active - * @property bool $encrypted - * @property int $order - * @property-read Collection|AccountMeta[] $accountMeta - * @property-read int|null $account_meta_count - * @property AccountType $accountType - * @property-read Collection|Attachment[] $attachments - * @property-read int|null $attachments_count - * @property-read string $account_number - * @property-read string $edit_name - * @property-read Collection|Location[] $locations - * @property-read int|null $locations_count - * @property-read Collection|Note[] $notes - * @property-read int|null $notes_count - * @property-read Collection|ObjectGroup[] $objectGroups - * @property-read int|null $object_groups_count - * @property-read Collection|PiggyBank[] $piggyBanks - * @property-read int|null $piggy_banks_count - * @property-read Collection|Transaction[] $transactions - * @property-read int|null $transactions_count - * @property-read User $user + * @property int $user_id + * @property int $account_type_id + * @property string $name + * @property string|null $virtual_balance + * @property string|null $iban + * @property bool $active + * @property bool $encrypted + * @property int $order + * @property-read Collection|AccountMeta[] $accountMeta + * @property-read int|null $account_meta_count + * @property AccountType $accountType + * @property-read Collection|Attachment[] $attachments + * @property-read int|null $attachments_count + * @property-read string $account_number + * @property-read string $edit_name + * @property-read Collection|Location[] $locations + * @property-read int|null $locations_count + * @property-read Collection|Note[] $notes + * @property-read int|null $notes_count + * @property-read Collection|ObjectGroup[] $objectGroups + * @property-read int|null $object_groups_count + * @property-read Collection|PiggyBank[] $piggyBanks + * @property-read int|null $piggy_banks_count + * @property-read Collection|Transaction[] $transactions + * @property-read int|null $transactions_count + * @property-read User $user * @method static EloquentBuilder|Account accountTypeIn($types) * @method static EloquentBuilder|Account newModelQuery() * @method static EloquentBuilder|Account newQuery() @@ -91,17 +91,17 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static EloquentBuilder|Account whereVirtualBalance($value) * @method static Builder|Account withTrashed() * @method static Builder|Account withoutTrashed() - * @property Carbon $lastActivityDate - * @property string $startBalance - * @property string $endBalance - * @property string $difference - * @property string $interest - * @property string $interestPeriod - * @property string $accountTypeString - * @property Location $location - * @property string $liability_direction - * @property string $current_debt - * @property int|null $user_group_id + * @property Carbon $lastActivityDate + * @property string $startBalance + * @property string $endBalance + * @property string $difference + * @property string $interest + * @property string $interestPeriod + * @property string $accountTypeString + * @property Location $location + * @property string $liability_direction + * @property string $current_debt + * @property int|null $user_group_id * @method static EloquentBuilder|Account whereUserGroupId($value) * @mixin Eloquent */ @@ -133,7 +133,7 @@ class Account extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return Account * @throws NotFoundHttpException @@ -154,11 +154,11 @@ class Account extends Model } /** - * @return HasMany + * @return BelongsTo */ - public function accountMeta(): HasMany + public function user(): BelongsTo { - return $this->hasMany(AccountMeta::class); + return $this->belongsTo(User::class); } /** @@ -192,6 +192,14 @@ class Account extends Model return $metaValue ? $metaValue->data : ''; } + /** + * @return HasMany + */ + public function accountMeta(): HasMany + { + return $this->hasMany(AccountMeta::class); + } + /** * @return string */ @@ -240,8 +248,8 @@ class Account extends Model /** * - * @param EloquentBuilder $query - * @param array $types + * @param EloquentBuilder $query + * @param array $types */ public function scopeAccountTypeIn(EloquentBuilder $query, array $types): void { @@ -254,7 +262,7 @@ class Account extends Model /** * - * @param mixed $value + * @param mixed $value * */ @@ -275,14 +283,6 @@ class Account extends Model return $this->hasMany(Transaction::class); } - /** - * @return BelongsTo - */ - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } - /** * Get the virtual balance * diff --git a/app/Models/AccountMeta.php b/app/Models/AccountMeta.php index 11239faac4..6d7a31aaa2 100644 --- a/app/Models/AccountMeta.php +++ b/app/Models/AccountMeta.php @@ -28,17 +28,16 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Carbon; -use JsonException; /** * Class AccountMeta * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property int $account_id - * @property string $name - * @property mixed $data + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property int $account_id + * @property string $name + * @property mixed $data * @property-read Account $account * @method static Builder|AccountMeta newModelQuery() * @method static Builder|AccountMeta newQuery() @@ -77,7 +76,7 @@ class AccountMeta extends Model } /** - * @param mixed $value + * @param mixed $value * * @return mixed */ @@ -87,7 +86,7 @@ class AccountMeta extends Model } /** - * @param mixed $value + * @param mixed $value * */ diff --git a/app/Models/AccountType.php b/app/Models/AccountType.php index 6f005e2546..b166052150 100644 --- a/app/Models/AccountType.php +++ b/app/Models/AccountType.php @@ -33,12 +33,12 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\AccountType * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property string $type + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property string $type * @property-read Collection|Account[] $accounts - * @property-read int|null $accounts_count + * @property-read int|null $accounts_count * @method static Builder|AccountType newModelQuery() * @method static Builder|AccountType newQuery() * @method static Builder|AccountType query() diff --git a/app/Models/Attachment.php b/app/Models/Attachment.php index 4f8e968885..99d5678ecf 100644 --- a/app/Models/Attachment.php +++ b/app/Models/Attachment.php @@ -38,26 +38,26 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\Attachment * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $user_id - * @property int $attachable_id - * @property string $attachable_type - * @property bool $file_exists - * @property string $md5 - * @property string $filename - * @property string|null $title - * @property string|null $description - * @property string $mime - * @property int $size - * @property bool $uploaded - * @property string $notes_text + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $user_id + * @property int $attachable_id + * @property string $attachable_type + * @property bool $file_exists + * @property string $md5 + * @property string $filename + * @property string|null $title + * @property string|null $description + * @property string $mime + * @property int $size + * @property bool $uploaded + * @property string $notes_text * @property-read Model|Eloquent $attachable - * @property Collection|Note[] $notes - * @property-read int|null $notes_count - * @property-read User $user + * @property Collection|Note[] $notes + * @property-read int|null $notes_count + * @property-read User $user * @method static \Illuminate\Database\Eloquent\Builder|Attachment newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Attachment newQuery() * @method static Builder|Attachment onlyTrashed() @@ -78,7 +78,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static \Illuminate\Database\Eloquent\Builder|Attachment whereUserId($value) * @method static Builder|Attachment withTrashed() * @method static Builder|Attachment withoutTrashed() - * @property int|null $user_group_id + * @property int|null $user_group_id * @method static \Illuminate\Database\Eloquent\Builder|Attachment whereUserGroupId($value) * @mixin Eloquent */ @@ -104,7 +104,7 @@ class Attachment extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return Attachment * @throws NotFoundHttpException @@ -124,6 +124,14 @@ class Attachment extends Model throw new NotFoundHttpException(); } + /** + * @return BelongsTo + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + /** * Get all of the owning attachable models. * @@ -152,12 +160,4 @@ class Attachment extends Model { return $this->morphMany(Note::class, 'noteable'); } - - /** - * @return BelongsTo - */ - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } } diff --git a/app/Models/AuditLogEntry.php b/app/Models/AuditLogEntry.php index adbada0ab5..fac7d1a7ef 100644 --- a/app/Models/AuditLogEntry.php +++ b/app/Models/AuditLogEntry.php @@ -42,17 +42,17 @@ use Illuminate\Support\Carbon; * @method static Builder|AuditLogEntry query() * @method static \Illuminate\Database\Query\Builder|AuditLogEntry withTrashed() * @method static \Illuminate\Database\Query\Builder|AuditLogEntry withoutTrashed() - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $auditable_id - * @property string $auditable_type - * @property int $changer_id - * @property string $changer_type - * @property string $action - * @property array|null $before - * @property array|null $after + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $auditable_id + * @property string $auditable_type + * @property int $changer_id + * @property string $changer_type + * @property string $action + * @property array|null $before + * @property array|null $after * @method static Builder|AuditLogEntry whereAction($value) * @method static Builder|AuditLogEntry whereAfter($value) * @method static Builder|AuditLogEntry whereAuditableId($value) @@ -70,13 +70,14 @@ class AuditLogEntry extends Model { use SoftDeletes; - protected $casts = [ - 'before' => 'array', - 'after' => 'array', - 'created_at' => 'datetime', - 'updated_at' => 'datetime', - 'deleted_at' => 'datetime', - ]; + protected $casts + = [ + 'before' => 'array', + 'after' => 'array', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + 'deleted_at' => 'datetime', + ]; /** */ diff --git a/app/Models/AutoBudget.php b/app/Models/AutoBudget.php index 5714c7c71f..41f446da71 100644 --- a/app/Models/AutoBudget.php +++ b/app/Models/AutoBudget.php @@ -35,16 +35,16 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\AutoBudget * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $budget_id - * @property int $transaction_currency_id - * @property int $auto_budget_type - * @property string $amount - * @property string $period - * @property-read Budget $budget + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $budget_id + * @property int $transaction_currency_id + * @property int $auto_budget_type + * @property string $amount + * @property string $period + * @property-read Budget $budget * @property-read TransactionCurrency $transactionCurrency * @method static \Illuminate\Database\Eloquent\Builder|AutoBudget newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|AutoBudget newQuery() diff --git a/app/Models/AvailableBudget.php b/app/Models/AvailableBudget.php index bc654e74f7..47419033c5 100644 --- a/app/Models/AvailableBudget.php +++ b/app/Models/AvailableBudget.php @@ -36,17 +36,17 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\AvailableBudget * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $user_id - * @property int $transaction_currency_id - * @property string $amount - * @property Carbon $start_date - * @property Carbon $end_date + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $user_id + * @property int $transaction_currency_id + * @property string $amount + * @property Carbon $start_date + * @property Carbon $end_date * @property-read TransactionCurrency $transactionCurrency - * @property-read User $user + * @property-read User $user * @method static \Illuminate\Database\Eloquent\Builder|AvailableBudget newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|AvailableBudget newQuery() * @method static Builder|AvailableBudget onlyTrashed() @@ -62,7 +62,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static \Illuminate\Database\Eloquent\Builder|AvailableBudget whereUserId($value) * @method static Builder|AvailableBudget withTrashed() * @method static Builder|AvailableBudget withoutTrashed() - * @property int|null $user_group_id + * @property int|null $user_group_id * @method static \Illuminate\Database\Eloquent\Builder|AvailableBudget whereUserGroupId($value) * @mixin Eloquent */ @@ -90,7 +90,7 @@ class AvailableBudget extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return AvailableBudget * @throws NotFoundHttpException @@ -113,17 +113,17 @@ class AvailableBudget extends Model /** * @return BelongsTo */ - public function transactionCurrency(): BelongsTo + public function user(): BelongsTo { - return $this->belongsTo(TransactionCurrency::class); + return $this->belongsTo(User::class); } /** * @return BelongsTo */ - public function user(): BelongsTo + public function transactionCurrency(): BelongsTo { - return $this->belongsTo(User::class); + return $this->belongsTo(TransactionCurrency::class); } protected function amount(): Attribute diff --git a/app/Models/Bill.php b/app/Models/Bill.php index a253c1b19d..d7ef58b2bf 100644 --- a/app/Models/Bill.php +++ b/app/Models/Bill.php @@ -39,36 +39,36 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\Bill * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $user_id - * @property int|null $transaction_currency_id - * @property string $name - * @property string $match - * @property string $amount_min - * @property string $amount_max - * @property Carbon $date - * @property Carbon|null $end_date - * @property Carbon|null $extension_date - * @property string $repeat_freq - * @property int $skip - * @property bool $automatch - * @property bool $active - * @property bool $name_encrypted - * @property bool $match_encrypted - * @property int $order - * @property-read Collection|Attachment[] $attachments - * @property-read int|null $attachments_count - * @property-read Collection|Note[] $notes - * @property-read int|null $notes_count - * @property-read Collection|ObjectGroup[] $objectGroups - * @property-read int|null $object_groups_count - * @property-read TransactionCurrency|null $transactionCurrency + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $user_id + * @property int|null $transaction_currency_id + * @property string $name + * @property string $match + * @property string $amount_min + * @property string $amount_max + * @property Carbon $date + * @property Carbon|null $end_date + * @property Carbon|null $extension_date + * @property string $repeat_freq + * @property int $skip + * @property bool $automatch + * @property bool $active + * @property bool $name_encrypted + * @property bool $match_encrypted + * @property int $order + * @property-read Collection|Attachment[] $attachments + * @property-read int|null $attachments_count + * @property-read Collection|Note[] $notes + * @property-read int|null $notes_count + * @property-read Collection|ObjectGroup[] $objectGroups + * @property-read int|null $object_groups_count + * @property-read TransactionCurrency|null $transactionCurrency * @property-read Collection|TransactionJournal[] $transactionJournals - * @property-read int|null $transaction_journals_count - * @property-read User $user + * @property-read int|null $transaction_journals_count + * @property-read User $user * @method static \Illuminate\Database\Eloquent\Builder|Bill newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Bill newQuery() * @method static Builder|Bill onlyTrashed() @@ -95,7 +95,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static \Illuminate\Database\Eloquent\Builder|Bill whereUserId($value) * @method static Builder|Bill withTrashed() * @method static Builder|Bill withoutTrashed() - * @property int|null $user_group_id + * @property int|null $user_group_id * @method static \Illuminate\Database\Eloquent\Builder|Bill whereUserGroupId($value) * @mixin Eloquent */ @@ -146,7 +146,7 @@ class Bill extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return Bill * @throws NotFoundHttpException @@ -166,6 +166,14 @@ class Bill extends Model throw new NotFoundHttpException(); } + /** + * @return BelongsTo + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + /** * @return MorphMany */ @@ -192,7 +200,7 @@ class Bill extends Model /** * - * @param mixed $value + * @param mixed $value */ public function setAmountMaxAttribute($value): void { @@ -200,7 +208,7 @@ class Bill extends Model } /** - * @param mixed $value + * @param mixed $value * */ @@ -225,14 +233,6 @@ class Bill extends Model return $this->hasMany(TransactionJournal::class); } - /** - * @return BelongsTo - */ - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } - /** * Get the max amount * diff --git a/app/Models/Budget.php b/app/Models/Budget.php index dee29d680b..aa0716ff15 100644 --- a/app/Models/Budget.php +++ b/app/Models/Budget.php @@ -39,26 +39,26 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\Budget * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $user_id - * @property string $name - * @property bool $active - * @property bool $encrypted - * @property int $order - * @property-read Collection|Attachment[] $attachments - * @property-read int|null $attachments_count - * @property-read Collection|AutoBudget[] $autoBudgets - * @property-read int|null $auto_budgets_count - * @property-read Collection|BudgetLimit[] $budgetlimits - * @property-read int|null $budgetlimits_count + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $user_id + * @property string $name + * @property bool $active + * @property bool $encrypted + * @property int $order + * @property-read Collection|Attachment[] $attachments + * @property-read int|null $attachments_count + * @property-read Collection|AutoBudget[] $autoBudgets + * @property-read int|null $auto_budgets_count + * @property-read Collection|BudgetLimit[] $budgetlimits + * @property-read int|null $budgetlimits_count * @property-read Collection|TransactionJournal[] $transactionJournals - * @property-read int|null $transaction_journals_count - * @property-read Collection|Transaction[] $transactions - * @property-read int|null $transactions_count - * @property-read User $user + * @property-read int|null $transaction_journals_count + * @property-read Collection|Transaction[] $transactions + * @property-read int|null $transactions_count + * @property-read User $user * @method static \Illuminate\Database\Eloquent\Builder|Budget newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Budget newQuery() * @method static Builder|Budget onlyTrashed() @@ -74,11 +74,11 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static \Illuminate\Database\Eloquent\Builder|Budget whereUserId($value) * @method static Builder|Budget withTrashed() * @method static Builder|Budget withoutTrashed() - * @property string $email - * @property int|null $user_group_id + * @property string $email + * @property int|null $user_group_id * @method static \Illuminate\Database\Eloquent\Builder|Budget whereUserGroupId($value) - * @property-read Collection|Note[] $notes - * @property-read int|null $notes_count + * @property-read Collection|Note[] $notes + * @property-read int|null $notes_count * @mixin Eloquent */ class Budget extends Model @@ -106,7 +106,7 @@ class Budget extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return Budget * @throws NotFoundHttpException @@ -126,6 +126,14 @@ class Budget extends Model throw new NotFoundHttpException(); } + /** + * @return BelongsTo + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + /** * @return MorphMany */ @@ -173,12 +181,4 @@ class Budget extends Model { return $this->belongsToMany(Transaction::class, 'budget_transaction', 'budget_id'); } - - /** - * @return BelongsTo - */ - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } } diff --git a/app/Models/BudgetLimit.php b/app/Models/BudgetLimit.php index f39ddc8b32..59cec2c1f1 100644 --- a/app/Models/BudgetLimit.php +++ b/app/Models/BudgetLimit.php @@ -37,18 +37,18 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\BudgetLimit * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property int $budget_id - * @property int|null $transaction_currency_id - * @property Carbon $start_date - * @property Carbon|null $end_date - * @property string $amount - * @property string $spent - * @property string|null $period - * @property int $generated - * @property-read Budget $budget + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property int $budget_id + * @property int|null $transaction_currency_id + * @property Carbon $start_date + * @property Carbon|null $end_date + * @property string $amount + * @property string $spent + * @property string|null $period + * @property int $generated + * @property-read Budget $budget * @property-read TransactionCurrency|null $transactionCurrency * @method static Builder|BudgetLimit newModelQuery() * @method static Builder|BudgetLimit newQuery() @@ -73,25 +73,26 @@ class BudgetLimit extends Model * @var array */ protected $casts - = [ + = [ 'created_at' => 'datetime', 'updated_at' => 'datetime', 'start_date' => 'date', 'end_date' => 'date', 'auto_budget' => 'boolean', ]; - protected $dispatchesEvents = [ - 'created' => Created::class, - 'updated' => Updated::class, - 'deleted' => Deleted::class, - ]; + protected $dispatchesEvents + = [ + 'created' => Created::class, + 'updated' => Updated::class, + 'deleted' => Deleted::class, + ]; /** @var array Fields that can be filled */ protected $fillable = ['budget_id', 'start_date', 'end_date', 'amount', 'transaction_currency_id']; /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return BudgetLimit * @throws NotFoundHttpException diff --git a/app/Models/Category.php b/app/Models/Category.php index 0cfc680ea8..84ac0c3038 100644 --- a/app/Models/Category.php +++ b/app/Models/Category.php @@ -38,23 +38,23 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\Category * - * @property int $id - * @property \Illuminate\Support\Carbon|null $created_at - * @property \Illuminate\Support\Carbon|null $updated_at - * @property \Illuminate\Support\Carbon|null $deleted_at - * @property int $user_id - * @property string $name - * @property Carbon $lastActivity - * @property bool $encrypted - * @property-read Collection|Attachment[] $attachments - * @property-read int|null $attachments_count - * @property-read Collection|Note[] $notes - * @property-read int|null $notes_count + * @property int $id + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + * @property \Illuminate\Support\Carbon|null $deleted_at + * @property int $user_id + * @property string $name + * @property Carbon $lastActivity + * @property bool $encrypted + * @property-read Collection|Attachment[] $attachments + * @property-read int|null $attachments_count + * @property-read Collection|Note[] $notes + * @property-read int|null $notes_count * @property-read Collection|TransactionJournal[] $transactionJournals - * @property-read int|null $transaction_journals_count - * @property-read Collection|Transaction[] $transactions - * @property-read int|null $transactions_count - * @property-read User $user + * @property-read int|null $transaction_journals_count + * @property-read Collection|Transaction[] $transactions + * @property-read int|null $transactions_count + * @property-read User $user * @method static \Illuminate\Database\Eloquent\Builder|Category newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Category newQuery() * @method static Builder|Category onlyTrashed() @@ -68,7 +68,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static \Illuminate\Database\Eloquent\Builder|Category whereUserId($value) * @method static Builder|Category withTrashed() * @method static Builder|Category withoutTrashed() - * @property int|null $user_group_id + * @property int|null $user_group_id * @method static \Illuminate\Database\Eloquent\Builder|Category whereUserGroupId($value) * @mixin Eloquent */ @@ -96,7 +96,7 @@ class Category extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return Category * @throws NotFoundHttpException @@ -116,6 +116,14 @@ class Category extends Model throw new NotFoundHttpException(); } + /** + * @return BelongsTo + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + /** * @return MorphMany */ @@ -147,12 +155,4 @@ class Category extends Model { return $this->belongsToMany(Transaction::class, 'category_transaction', 'category_id'); } - - /** - * @return BelongsTo - */ - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } } diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php index 984e4b5311..8abf4eb569 100644 --- a/app/Models/Configuration.php +++ b/app/Models/Configuration.php @@ -32,12 +32,12 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\Configuration * - * @property int $id + * @property int $id * @property Carbon|null $created_at * @property Carbon|null $updated_at * @property Carbon|null $deleted_at - * @property string $name - * @property mixed $data + * @property string $name + * @property mixed $data * @method static \Illuminate\Database\Eloquent\Builder|Configuration newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Configuration newQuery() * @method static Builder|Configuration onlyTrashed() @@ -74,7 +74,7 @@ class Configuration extends Model * TODO can be replaced with native laravel code. * * - * @param mixed $value + * @param mixed $value * * @return mixed */ @@ -85,7 +85,7 @@ class Configuration extends Model /** * - * @param mixed $value + * @param mixed $value */ public function setDataAttribute($value): void { diff --git a/app/Models/CurrencyExchangeRate.php b/app/Models/CurrencyExchangeRate.php index 8197d802a1..05c23410b9 100644 --- a/app/Models/CurrencyExchangeRate.php +++ b/app/Models/CurrencyExchangeRate.php @@ -34,19 +34,19 @@ use Illuminate\Support\Carbon; /** * Class CurrencyExchangeRate * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property string|null $deleted_at - * @property int $user_id - * @property int $from_currency_id - * @property int $to_currency_id - * @property Carbon $date - * @property string $rate - * @property string|null $user_rate + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property string|null $deleted_at + * @property int $user_id + * @property int $from_currency_id + * @property int $to_currency_id + * @property Carbon $date + * @property string $rate + * @property string|null $user_rate * @property-read TransactionCurrency $fromCurrency * @property-read TransactionCurrency $toCurrency - * @property-read User $user + * @property-read User $user * @method static Builder|CurrencyExchangeRate newModelQuery() * @method static Builder|CurrencyExchangeRate newQuery() * @method static Builder|CurrencyExchangeRate query() @@ -60,7 +60,7 @@ use Illuminate\Support\Carbon; * @method static Builder|CurrencyExchangeRate whereUpdatedAt($value) * @method static Builder|CurrencyExchangeRate whereUserId($value) * @method static Builder|CurrencyExchangeRate whereUserRate($value) - * @property int|null $user_group_id + * @property int|null $user_group_id * @method static Builder|CurrencyExchangeRate whereUserGroupId($value) * @mixin Eloquent */ diff --git a/app/Models/GroupMembership.php b/app/Models/GroupMembership.php index e872ad78f0..1af5447862 100644 --- a/app/Models/GroupMembership.php +++ b/app/Models/GroupMembership.php @@ -34,16 +34,16 @@ use Illuminate\Support\Carbon; /** * Class GroupMembership * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property string|null $deleted_at - * @property int $user_id - * @property int $user_group_id - * @property int $user_role_id - * @property-read User $user + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property string|null $deleted_at + * @property int $user_id + * @property int $user_group_id + * @property int $user_role_id + * @property-read User $user * @property-read UserGroup $userGroup - * @property-read UserRole $userRole + * @property-read UserRole $userRole * @method static Builder|GroupMembership newModelQuery() * @method static Builder|GroupMembership newQuery() * @method static Builder|GroupMembership query() diff --git a/app/Models/InvitedUser.php b/app/Models/InvitedUser.php index 8bf840361d..e7ea080af2 100644 --- a/app/Models/InvitedUser.php +++ b/app/Models/InvitedUser.php @@ -35,18 +35,18 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Class InvitedUser * - * @property-read User $user + * @property-read User $user * @method static Builder|InvitedUser newModelQuery() * @method static Builder|InvitedUser newQuery() * @method static Builder|InvitedUser query() - * @property int $id + * @property int $id * @property Carbon|null $created_at * @property Carbon|null $updated_at - * @property int $user_id - * @property string $email - * @property string $invite_code - * @property Carbon $expires - * @property bool $redeemed + * @property int $user_id + * @property string $email + * @property string $invite_code + * @property Carbon $expires + * @property bool $redeemed * @method static Builder|InvitedUser whereCreatedAt($value) * @method static Builder|InvitedUser whereEmail($value) * @method static Builder|InvitedUser whereExpires($value) @@ -69,7 +69,7 @@ class InvitedUser extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return WebhookAttempt * @throws NotFoundHttpException diff --git a/app/Models/LinkType.php b/app/Models/LinkType.php index 6a5ae23b17..1703672153 100644 --- a/app/Models/LinkType.php +++ b/app/Models/LinkType.php @@ -35,17 +35,17 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\LinkType * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property string $name - * @property string $outward - * @property string $inward - * @property int $journalCount - * @property bool $editable + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property string $name + * @property string $outward + * @property string $inward + * @property int $journalCount + * @property bool $editable * @property-read Collection|TransactionJournalLink[] $transactionJournalLinks - * @property-read int|null $transaction_journal_links_count + * @property-read int|null $transaction_journal_links_count * @method static \Illuminate\Database\Eloquent\Builder|LinkType newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|LinkType newQuery() * @method static Builder|LinkType onlyTrashed() @@ -85,7 +85,7 @@ class LinkType extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return LinkType * diff --git a/app/Models/Location.php b/app/Models/Location.php index 3c98f51174..4894867837 100644 --- a/app/Models/Location.php +++ b/app/Models/Location.php @@ -35,18 +35,18 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\Location * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $locatable_id - * @property string $locatable_type - * @property float|null $latitude - * @property float|null $longitude - * @property int|null $zoom_level + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $locatable_id + * @property string $locatable_type + * @property float|null $latitude + * @property float|null $longitude + * @property int|null $zoom_level * @property-read Collection|Account[] $accounts - * @property-read int|null $accounts_count - * @property-read Model|Eloquent $locatable + * @property-read int|null $accounts_count + * @property-read Model|Eloquent $locatable * @method static Builder|Location newModelQuery() * @method static Builder|Location newQuery() * @method static Builder|Location query() @@ -83,7 +83,7 @@ class Location extends Model /** * Add rules for locations. * - * @param array $rules + * @param array $rules * * @return array */ diff --git a/app/Models/Note.php b/app/Models/Note.php index 940305a4fa..1a8a2cab11 100644 --- a/app/Models/Note.php +++ b/app/Models/Note.php @@ -33,14 +33,14 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\Note * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $noteable_id - * @property string $noteable_type - * @property string|null $title - * @property string|null $text + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $noteable_id + * @property string $noteable_type + * @property string|null $title + * @property string|null $text * @property-read Model|Eloquent $noteable * @method static \Illuminate\Database\Eloquent\Builder|Note newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Note newQuery() diff --git a/app/Models/ObjectGroup.php b/app/Models/ObjectGroup.php index a1717fe218..ec1aa89410 100644 --- a/app/Models/ObjectGroup.php +++ b/app/Models/ObjectGroup.php @@ -37,20 +37,20 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\ObjectGroup * - * @property int $id - * @property int $user_id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property string $title - * @property int $order - * @property-read Collection|Account[] $accounts - * @property-read int|null $accounts_count - * @property-read Collection|Bill[] $bills - * @property-read int|null $bills_count + * @property int $id + * @property int $user_id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property string $title + * @property int $order + * @property-read Collection|Account[] $accounts + * @property-read int|null $accounts_count + * @property-read Collection|Bill[] $bills + * @property-read int|null $bills_count * @property-read Collection|PiggyBank[] $piggyBanks - * @property-read int|null $piggy_banks_count - * @property-read User $user + * @property-read int|null $piggy_banks_count + * @property-read User $user * @method static Builder|ObjectGroup newModelQuery() * @method static Builder|ObjectGroup newQuery() * @method static Builder|ObjectGroup query() @@ -82,7 +82,7 @@ class ObjectGroup extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return ObjectGroup * @throws NotFoundHttpException @@ -101,6 +101,14 @@ class ObjectGroup extends Model throw new NotFoundHttpException(); } + /** + * @return BelongsTo + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + /** * @return MorphToMany */ @@ -124,12 +132,4 @@ class ObjectGroup extends Model { return $this->morphedByMany(PiggyBank::class, 'object_groupable'); } - - /** - * @return BelongsTo - */ - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } } diff --git a/app/Models/PiggyBank.php b/app/Models/PiggyBank.php index ee60f7d9ba..47c5aa6de0 100644 --- a/app/Models/PiggyBank.php +++ b/app/Models/PiggyBank.php @@ -38,29 +38,29 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\PiggyBank * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $account_id - * @property string $name - * @property string $targetamount - * @property Carbon|null $startdate - * @property Carbon|null $targetdate - * @property int $order - * @property bool $active - * @property bool $encrypted - * @property-read Account $account - * @property-read Collection|Attachment[] $attachments - * @property-read int|null $attachments_count - * @property-read Collection|Note[] $notes - * @property-read int|null $notes_count - * @property-read Collection|ObjectGroup[] $objectGroups - * @property-read int|null $object_groups_count - * @property-read Collection|PiggyBankEvent[] $piggyBankEvents - * @property-read int|null $piggy_bank_events_count + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $account_id + * @property string $name + * @property string $targetamount + * @property Carbon|null $startdate + * @property Carbon|null $targetdate + * @property int $order + * @property bool $active + * @property bool $encrypted + * @property-read Account $account + * @property-read Collection|Attachment[] $attachments + * @property-read int|null $attachments_count + * @property-read Collection|Note[] $notes + * @property-read int|null $notes_count + * @property-read Collection|ObjectGroup[] $objectGroups + * @property-read int|null $object_groups_count + * @property-read Collection|PiggyBankEvent[] $piggyBankEvents + * @property-read int|null $piggy_bank_events_count * @property-read Collection|PiggyBankRepetition[] $piggyBankRepetitions - * @property-read int|null $piggy_bank_repetitions_count + * @property-read int|null $piggy_bank_repetitions_count * @method static \Illuminate\Database\Eloquent\Builder|PiggyBank newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|PiggyBank newQuery() * @method static Builder|PiggyBank onlyTrashed() @@ -109,7 +109,7 @@ class PiggyBank extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return PiggyBank * @throws NotFoundHttpException @@ -178,7 +178,7 @@ class PiggyBank extends Model /** * - * @param mixed $value + * @param mixed $value */ public function setTargetamountAttribute($value): void { diff --git a/app/Models/PiggyBankEvent.php b/app/Models/PiggyBankEvent.php index f3b5b34767..8334aac725 100644 --- a/app/Models/PiggyBankEvent.php +++ b/app/Models/PiggyBankEvent.php @@ -33,14 +33,14 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\PiggyBankEvent * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property int $piggy_bank_id - * @property int|null $transaction_journal_id - * @property Carbon $date - * @property string $amount - * @property PiggyBank $piggyBank + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property int $piggy_bank_id + * @property int|null $transaction_journal_id + * @property Carbon $date + * @property string $amount + * @property PiggyBank $piggyBank * @property-read TransactionJournal|null $transactionJournal * @method static Builder|PiggyBankEvent newModelQuery() * @method static Builder|PiggyBankEvent newQuery() @@ -82,7 +82,7 @@ class PiggyBankEvent extends Model /** * - * @param mixed $value + * @param mixed $value */ public function setAmountAttribute($value): void { diff --git a/app/Models/PiggyBankRepetition.php b/app/Models/PiggyBankRepetition.php index 8837c2dc4b..c00650b38c 100644 --- a/app/Models/PiggyBankRepetition.php +++ b/app/Models/PiggyBankRepetition.php @@ -33,14 +33,14 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; /** * FireflyIII\Models\PiggyBankRepetition * - * @property int $id + * @property int $id * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at - * @property int $piggy_bank_id + * @property int $piggy_bank_id * @property \Illuminate\Support\Carbon|null $startdate * @property \Illuminate\Support\Carbon|null $targetdate - * @property string $currentamount - * @property-read PiggyBank $piggyBank + * @property string $currentamount + * @property-read PiggyBank $piggyBank * @method static EloquentBuilder|PiggyBankRepetition newModelQuery() * @method static EloquentBuilder|PiggyBankRepetition newQuery() * @method static EloquentBuilder|PiggyBankRepetition onDates(Carbon $start, Carbon $target) @@ -82,9 +82,9 @@ class PiggyBankRepetition extends Model /** * - * @param EloquentBuilder $query - * @param Carbon $start - * @param Carbon $target + * @param EloquentBuilder $query + * @param Carbon $start + * @param Carbon $target * * @return EloquentBuilder */ @@ -95,8 +95,8 @@ class PiggyBankRepetition extends Model /** * - * @param EloquentBuilder $query - * @param Carbon $date + * @param EloquentBuilder $query + * @param Carbon $date * * @return EloquentBuilder */ @@ -118,7 +118,7 @@ class PiggyBankRepetition extends Model /** * - * @param mixed $value + * @param mixed $value */ public function setCurrentamountAttribute($value): void { diff --git a/app/Models/Preference.php b/app/Models/Preference.php index 4121b925ef..e83e2e60d1 100644 --- a/app/Models/Preference.php +++ b/app/Models/Preference.php @@ -34,13 +34,13 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\Preference * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property int $user_id - * @property string $name + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property int $user_id + * @property string $name * @property int|string|array|null $data - * @property-read User $user + * @property-read User $user * @method static Builder|Preference newModelQuery() * @method static Builder|Preference newQuery() * @method static Builder|Preference query() @@ -72,7 +72,7 @@ class Preference extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return Preference * @throws NotFoundHttpException diff --git a/app/Models/Recurrence.php b/app/Models/Recurrence.php index db78c9983a..df6f6f21a3 100644 --- a/app/Models/Recurrence.php +++ b/app/Models/Recurrence.php @@ -38,33 +38,33 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\Recurrence * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $user_id - * @property int $transaction_type_id - * @property string $title - * @property string $description - * @property Carbon $first_date - * @property Carbon|null $repeat_until - * @property Carbon|null $latest_date - * @property int $repetitions - * @property bool $apply_rules - * @property bool $active - * @property-read Collection|Attachment[] $attachments - * @property-read int|null $attachments_count - * @property-read Collection|Note[] $notes - * @property-read int|null $notes_count - * @property-read Collection|RecurrenceMeta[] $recurrenceMeta - * @property-read int|null $recurrence_meta_count - * @property-read Collection|RecurrenceRepetition[] $recurrenceRepetitions - * @property-read int|null $recurrence_repetitions_count + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $user_id + * @property int $transaction_type_id + * @property string $title + * @property string $description + * @property Carbon $first_date + * @property Carbon|null $repeat_until + * @property Carbon|null $latest_date + * @property int $repetitions + * @property bool $apply_rules + * @property bool $active + * @property-read Collection|Attachment[] $attachments + * @property-read int|null $attachments_count + * @property-read Collection|Note[] $notes + * @property-read int|null $notes_count + * @property-read Collection|RecurrenceMeta[] $recurrenceMeta + * @property-read int|null $recurrence_meta_count + * @property-read Collection|RecurrenceRepetition[] $recurrenceRepetitions + * @property-read int|null $recurrence_repetitions_count * @property-read Collection|RecurrenceTransaction[] $recurrenceTransactions - * @property-read int|null $recurrence_transactions_count - * @property-read TransactionCurrency $transactionCurrency - * @property-read TransactionType $transactionType - * @property-read User $user + * @property-read int|null $recurrence_transactions_count + * @property-read TransactionCurrency $transactionCurrency + * @property-read TransactionType $transactionType + * @property-read User $user * @method static \Illuminate\Database\Eloquent\Builder|Recurrence newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Recurrence newQuery() * @method static Builder|Recurrence onlyTrashed() @@ -85,7 +85,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static \Illuminate\Database\Eloquent\Builder|Recurrence whereUserId($value) * @method static Builder|Recurrence withTrashed() * @method static Builder|Recurrence withoutTrashed() - * @property int|null $user_group_id + * @property int|null $user_group_id * @method static \Illuminate\Database\Eloquent\Builder|Recurrence whereUserGroupId($value) * @mixin Eloquent */ @@ -122,7 +122,7 @@ class Recurrence extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return Recurrence * @throws NotFoundHttpException @@ -142,6 +142,14 @@ class Recurrence extends Model throw new NotFoundHttpException(); } + /** + * @return BelongsTo + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + /** * @return MorphMany */ @@ -197,12 +205,4 @@ class Recurrence extends Model { return $this->belongsTo(TransactionType::class); } - - /** - * @return BelongsTo - */ - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } } diff --git a/app/Models/RecurrenceMeta.php b/app/Models/RecurrenceMeta.php index 09699d1d8a..d5e764fb61 100644 --- a/app/Models/RecurrenceMeta.php +++ b/app/Models/RecurrenceMeta.php @@ -33,13 +33,13 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\RecurrenceMeta * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $recurrence_id - * @property string $name - * @property mixed $value + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $recurrence_id + * @property string $name + * @property mixed $value * @property-read Recurrence $recurrence * @method static \Illuminate\Database\Eloquent\Builder|RecurrenceMeta newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|RecurrenceMeta newQuery() diff --git a/app/Models/RecurrenceRepetition.php b/app/Models/RecurrenceRepetition.php index 1e3ac12556..8e8970e4a3 100644 --- a/app/Models/RecurrenceRepetition.php +++ b/app/Models/RecurrenceRepetition.php @@ -33,15 +33,15 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\RecurrenceRepetition * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $recurrence_id - * @property string $repetition_type - * @property string $repetition_moment - * @property int $repetition_skip - * @property int $weekend + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $recurrence_id + * @property string $repetition_type + * @property string $repetition_moment + * @property int $repetition_skip + * @property int $weekend * @property-read Recurrence $recurrence * @method static \Illuminate\Database\Eloquent\Builder|RecurrenceRepetition newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|RecurrenceRepetition newQuery() diff --git a/app/Models/RecurrenceTransaction.php b/app/Models/RecurrenceTransaction.php index 9969113ab2..e7911de4a7 100644 --- a/app/Models/RecurrenceTransaction.php +++ b/app/Models/RecurrenceTransaction.php @@ -36,25 +36,25 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\RecurrenceTransaction * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $recurrence_id - * @property int $transaction_currency_id - * @property int|null $foreign_currency_id - * @property int $source_id - * @property int $destination_id - * @property string $amount - * @property string|null $foreign_amount - * @property string $description - * @property-read Account $destinationAccount - * @property-read TransactionCurrency|null $foreignCurrency - * @property-read Recurrence $recurrence + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $recurrence_id + * @property int $transaction_currency_id + * @property int|null $foreign_currency_id + * @property int $source_id + * @property int $destination_id + * @property string $amount + * @property string|null $foreign_amount + * @property string $description + * @property-read Account $destinationAccount + * @property-read TransactionCurrency|null $foreignCurrency + * @property-read Recurrence $recurrence * @property-read Collection|RecurrenceTransactionMeta[] $recurrenceTransactionMeta - * @property-read int|null $recurrence_transaction_meta_count - * @property-read Account $sourceAccount - * @property-read TransactionCurrency $transactionCurrency + * @property-read int|null $recurrence_transaction_meta_count + * @property-read Account $sourceAccount + * @property-read TransactionCurrency $transactionCurrency * @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction newQuery() * @method static Builder|RecurrenceTransaction onlyTrashed() @@ -73,9 +73,9 @@ use Illuminate\Support\Carbon; * @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction whereUpdatedAt($value) * @method static Builder|RecurrenceTransaction withTrashed() * @method static Builder|RecurrenceTransaction withoutTrashed() - * @property int|null $transaction_type_id + * @property int|null $transaction_type_id * @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction whereTransactionTypeId($value) - * @property-read TransactionType|null $transactionType + * @property-read TransactionType|null $transactionType * @mixin Eloquent */ class RecurrenceTransaction extends Model diff --git a/app/Models/RecurrenceTransactionMeta.php b/app/Models/RecurrenceTransactionMeta.php index 31794fa5cf..c290cba2fb 100644 --- a/app/Models/RecurrenceTransactionMeta.php +++ b/app/Models/RecurrenceTransactionMeta.php @@ -33,13 +33,13 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\RecurrenceTransactionMeta * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $rt_id - * @property string $name - * @property mixed $value + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $rt_id + * @property string $name + * @property mixed $value * @property-read RecurrenceTransaction $recurrenceTransaction * @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransactionMeta newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransactionMeta newQuery() diff --git a/app/Models/Role.php b/app/Models/Role.php index 2aecb38ad7..d9cb20b297 100644 --- a/app/Models/Role.php +++ b/app/Models/Role.php @@ -34,14 +34,14 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\Role * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property string $name - * @property string|null $display_name - * @property string|null $description + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property string $name + * @property string|null $display_name + * @property string|null $description * @property-read Collection|User[] $users - * @property-read int|null $users_count + * @property-read int|null $users_count * @method static Builder|Role newModelQuery() * @method static Builder|Role newQuery() * @method static Builder|Role query() diff --git a/app/Models/Rule.php b/app/Models/Rule.php index 350b79d2f2..7660de859a 100644 --- a/app/Models/Rule.php +++ b/app/Models/Rule.php @@ -37,25 +37,25 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\Rule * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $user_id - * @property int $rule_group_id - * @property string $title - * @property string|null $description - * @property int $order - * @property bool $active - * @property bool $stop_processing - * @property bool $strict - * @property-read string $action_value + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $user_id + * @property int $rule_group_id + * @property string $title + * @property string|null $description + * @property int $order + * @property bool $active + * @property bool $stop_processing + * @property bool $strict + * @property-read string $action_value * @property-read Collection|RuleAction[] $ruleActions - * @property-read int|null $rule_actions_count - * @property-read RuleGroup $ruleGroup - * @property Collection|RuleTrigger[] $ruleTriggers - * @property-read int|null $rule_triggers_count - * @property-read User $user + * @property-read int|null $rule_actions_count + * @property-read RuleGroup $ruleGroup + * @property Collection|RuleTrigger[] $ruleTriggers + * @property-read int|null $rule_triggers_count + * @property-read User $user * @method static \Illuminate\Database\Eloquent\Builder|Rule newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Rule newQuery() * @method static Builder|Rule onlyTrashed() @@ -74,7 +74,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static \Illuminate\Database\Eloquent\Builder|Rule whereUserId($value) * @method static Builder|Rule withTrashed() * @method static Builder|Rule withoutTrashed() - * @property int|null $user_group_id + * @property int|null $user_group_id * @method static \Illuminate\Database\Eloquent\Builder|Rule whereUserGroupId($value) * @mixin Eloquent */ @@ -104,7 +104,7 @@ class Rule extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return Rule * @throws NotFoundHttpException @@ -124,6 +124,14 @@ class Rule extends Model throw new NotFoundHttpException(); } + /** + * @return BelongsTo + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + /** * @return HasMany */ @@ -149,7 +157,7 @@ class Rule extends Model } /** - * @param mixed $value + * @param mixed $value * */ @@ -157,12 +165,4 @@ class Rule extends Model { $this->attributes['description'] = e($value); } - - /** - * @return BelongsTo - */ - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } } diff --git a/app/Models/RuleAction.php b/app/Models/RuleAction.php index 29ee17ec90..977aa71354 100644 --- a/app/Models/RuleAction.php +++ b/app/Models/RuleAction.php @@ -32,16 +32,16 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\RuleAction * - * @property int $id + * @property int $id * @property Carbon|null $created_at * @property Carbon|null $updated_at - * @property int $rule_id - * @property string $action_type - * @property string $action_value - * @property int $order - * @property bool $active - * @property bool $stop_processing - * @property-read Rule $rule + * @property int $rule_id + * @property string $action_type + * @property string $action_value + * @property int $order + * @property bool $active + * @property bool $stop_processing + * @property-read Rule $rule * @method static Builder|RuleAction newModelQuery() * @method static Builder|RuleAction newQuery() * @method static Builder|RuleAction query() diff --git a/app/Models/RuleGroup.php b/app/Models/RuleGroup.php index b12d2dd0b4..8d7b42ff04 100644 --- a/app/Models/RuleGroup.php +++ b/app/Models/RuleGroup.php @@ -37,19 +37,19 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\RuleGroup * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $user_id - * @property string $title - * @property string|null $description - * @property int $order - * @property bool $active - * @property bool $stop_processing + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $user_id + * @property string $title + * @property string|null $description + * @property int $order + * @property bool $active + * @property bool $stop_processing * @property Collection|Rule[] $rules - * @property-read int|null $rules_count - * @property-read User $user + * @property-read int|null $rules_count + * @property-read User $user * @method static \Illuminate\Database\Eloquent\Builder|RuleGroup newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|RuleGroup newQuery() * @method static Builder|RuleGroup onlyTrashed() @@ -66,7 +66,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static \Illuminate\Database\Eloquent\Builder|RuleGroup whereUserId($value) * @method static Builder|RuleGroup withTrashed() * @method static Builder|RuleGroup withoutTrashed() - * @property int|null $user_group_id + * @property int|null $user_group_id * @method static \Illuminate\Database\Eloquent\Builder|RuleGroup whereUserGroupId($value) * @mixin Eloquent */ @@ -95,7 +95,7 @@ class RuleGroup extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return RuleGroup * @throws NotFoundHttpException @@ -115,14 +115,6 @@ class RuleGroup extends Model throw new NotFoundHttpException(); } - /** - * @return HasMany - */ - public function rules(): HasMany - { - return $this->hasMany(Rule::class); - } - /** * @return BelongsTo */ @@ -130,4 +122,12 @@ class RuleGroup extends Model { return $this->belongsTo(User::class); } + + /** + * @return HasMany + */ + public function rules(): HasMany + { + return $this->hasMany(Rule::class); + } } diff --git a/app/Models/RuleTrigger.php b/app/Models/RuleTrigger.php index df4a906c0d..20cf189375 100644 --- a/app/Models/RuleTrigger.php +++ b/app/Models/RuleTrigger.php @@ -32,16 +32,16 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\RuleTrigger * - * @property int $id + * @property int $id * @property Carbon|null $created_at * @property Carbon|null $updated_at - * @property int $rule_id - * @property string $trigger_type - * @property string $trigger_value - * @property int $order - * @property bool $active - * @property bool $stop_processing - * @property-read Rule $rule + * @property int $rule_id + * @property string $trigger_type + * @property string $trigger_value + * @property int $order + * @property bool $active + * @property bool $stop_processing + * @property-read Rule $rule * @method static Builder|RuleTrigger newModelQuery() * @method static Builder|RuleTrigger newQuery() * @method static Builder|RuleTrigger query() diff --git a/app/Models/Tag.php b/app/Models/Tag.php index 1b07b0d678..6d1ffd2cfa 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -38,25 +38,25 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\Tag * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $user_id - * @property string $tag - * @property string $tagMode - * @property Carbon|null $date - * @property string|null $description - * @property float|null $latitude - * @property float|null $longitude - * @property int|null $zoomLevel - * @property-read Collection|Attachment[] $attachments - * @property-read int|null $attachments_count - * @property-read Collection|Location[] $locations - * @property-read int|null $locations_count + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $user_id + * @property string $tag + * @property string $tagMode + * @property Carbon|null $date + * @property string|null $description + * @property float|null $latitude + * @property float|null $longitude + * @property int|null $zoomLevel + * @property-read Collection|Attachment[] $attachments + * @property-read int|null $attachments_count + * @property-read Collection|Location[] $locations + * @property-read int|null $locations_count * @property-read Collection|TransactionJournal[] $transactionJournals - * @property-read int|null $transaction_journals_count - * @property-read User $user + * @property-read int|null $transaction_journals_count + * @property-read User $user * @method static \Illuminate\Database\Eloquent\Builder|Tag newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Tag newQuery() * @method static Builder|Tag onlyTrashed() @@ -75,7 +75,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static \Illuminate\Database\Eloquent\Builder|Tag whereZoomLevel($value) * @method static Builder|Tag withTrashed() * @method static Builder|Tag withoutTrashed() - * @property int|null $user_group_id + * @property int|null $user_group_id * @method static \Illuminate\Database\Eloquent\Builder|Tag whereUserGroupId($value) * @mixin Eloquent */ @@ -106,7 +106,7 @@ class Tag extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return Tag * @throws NotFoundHttpException @@ -126,6 +126,14 @@ class Tag extends Model throw new NotFoundHttpException(); } + /** + * @return BelongsTo + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + /** * @return MorphMany */ @@ -149,12 +157,4 @@ class Tag extends Model { return $this->belongsToMany(TransactionJournal::class); } - - /** - * @return BelongsTo - */ - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } } diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index 0d147a0f74..b726594471 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -37,31 +37,31 @@ use Illuminate\Database\Eloquent\SoftDeletes; /** * FireflyIII\Models\Transaction * - * @property int $id + * @property int $id * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property \Illuminate\Support\Carbon|null $deleted_at - * @property bool $reconciled - * @property int $account_id - * @property int $transaction_journal_id - * @property string|null $description - * @property int|null $transaction_currency_id - * @property string $modified - * @property string $modified_foreign - * @property string $date - * @property string $max_date - * @property string $amount - * @property string|null $foreign_amount - * @property int|null $foreign_currency_id - * @property int $identifier - * @property-read Account $account - * @property-read Collection|Budget[] $budgets - * @property-read int|null $budgets_count - * @property-read Collection|Category[] $categories - * @property-read int|null $categories_count - * @property-read TransactionCurrency|null $foreignCurrency - * @property-read TransactionCurrency|null $transactionCurrency - * @property-read TransactionJournal $transactionJournal + * @property bool $reconciled + * @property int $account_id + * @property int $transaction_journal_id + * @property string|null $description + * @property int|null $transaction_currency_id + * @property string $modified + * @property string $modified_foreign + * @property string $date + * @property string $max_date + * @property string $amount + * @property string|null $foreign_amount + * @property int|null $foreign_currency_id + * @property int $identifier + * @property-read Account $account + * @property-read Collection|Budget[] $budgets + * @property-read int|null $budgets_count + * @property-read Collection|Category[] $categories + * @property-read int|null $categories_count + * @property-read TransactionCurrency|null $foreignCurrency + * @property-read TransactionCurrency|null $transactionCurrency + * @property-read TransactionJournal $transactionJournal * @method static Builder|Transaction after(Carbon $date) * @method static Builder|Transaction before(Carbon $date) * @method static Builder|Transaction newModelQuery() @@ -84,7 +84,7 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @method static Builder|Transaction whereUpdatedAt($value) * @method static \Illuminate\Database\Query\Builder|Transaction withTrashed() * @method static \Illuminate\Database\Query\Builder|Transaction withoutTrashed() - * @property int $the_count + * @property int $the_count * @mixin Eloquent */ class Transaction extends Model @@ -123,29 +123,6 @@ class Transaction extends Model /** @var array Hidden from view */ protected $hidden = ['encrypted']; - /** - * Check if a table is joined. - * - * @param Builder $query - * @param string $table - * - * @return bool - */ - public static function isJoined(Builder $query, string $table): bool - { - $joins = $query->getQuery()->joins; - if (null === $joins) { - return false; - } - foreach ($joins as $join) { - if ($join->table === $table) { - return true; - } - } - - return false; - } - /** * Get the account this object belongs to. * @@ -190,8 +167,8 @@ class Transaction extends Model * Check for transactions AFTER a specified date. * * - * @param Builder $query - * @param Carbon $date + * @param Builder $query + * @param Carbon $date */ public function scopeAfter(Builder $query, Carbon $date): void { @@ -201,12 +178,35 @@ class Transaction extends Model $query->where('transaction_journals.date', '>=', $date->format('Y-m-d 00:00:00')); } + /** + * Check if a table is joined. + * + * @param Builder $query + * @param string $table + * + * @return bool + */ + public static function isJoined(Builder $query, string $table): bool + { + $joins = $query->getQuery()->joins; + if (null === $joins) { + return false; + } + foreach ($joins as $join) { + if ($join->table === $table) { + return true; + } + } + + return false; + } + /** * Check for transactions BEFORE the specified date. * * - * @param Builder $query - * @param Carbon $date + * @param Builder $query + * @param Carbon $date */ public function scopeBefore(Builder $query, Carbon $date): void { @@ -218,8 +218,8 @@ class Transaction extends Model /** * - * @param Builder $query - * @param array $types + * @param Builder $query + * @param array $types */ public function scopeTransactionTypes(Builder $query, array $types): void { @@ -235,7 +235,7 @@ class Transaction extends Model /** * - * @param mixed $value + * @param mixed $value */ public function setAmountAttribute($value): void { diff --git a/app/Models/TransactionCurrency.php b/app/Models/TransactionCurrency.php index f8abc83c2e..5d34e44419 100644 --- a/app/Models/TransactionCurrency.php +++ b/app/Models/TransactionCurrency.php @@ -35,21 +35,21 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\TransactionCurrency * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property bool $enabled - * @property string $code - * @property string $name - * @property string $symbol - * @property int $decimal_places - * @property-read Collection|BudgetLimit[] $budgetLimits - * @property-read int|null $budget_limits_count + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property bool $enabled + * @property string $code + * @property string $name + * @property string $symbol + * @property int $decimal_places + * @property-read Collection|BudgetLimit[] $budgetLimits + * @property-read int|null $budget_limits_count * @property-read Collection|TransactionJournal[] $transactionJournals - * @property-read int|null $transaction_journals_count - * @property-read Collection|Transaction[] $transactions - * @property-read int|null $transactions_count + * @property-read int|null $transaction_journals_count + * @property-read Collection|Transaction[] $transactions + * @property-read int|null $transactions_count * @method static \Illuminate\Database\Eloquent\Builder|TransactionCurrency newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|TransactionCurrency newQuery() * @method static Builder|TransactionCurrency onlyTrashed() @@ -90,7 +90,7 @@ class TransactionCurrency extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return TransactionCurrency * @throws NotFoundHttpException diff --git a/app/Models/TransactionGroup.php b/app/Models/TransactionGroup.php index bf6d727b54..0b6e998270 100644 --- a/app/Models/TransactionGroup.php +++ b/app/Models/TransactionGroup.php @@ -38,15 +38,15 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\TransactionGroup * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $user_id - * @property string|null $title + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $user_id + * @property string|null $title * @property-read Collection|TransactionJournal[] $transactionJournals - * @property-read int|null $transaction_journals_count - * @property-read User $user + * @property-read int|null $transaction_journals_count + * @property-read User $user * @method static \Illuminate\Database\Eloquent\Builder|TransactionGroup newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|TransactionGroup newQuery() * @method static Builder|TransactionGroup onlyTrashed() @@ -59,7 +59,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static \Illuminate\Database\Eloquent\Builder|TransactionGroup whereUserId($value) * @method static Builder|TransactionGroup withTrashed() * @method static Builder|TransactionGroup withoutTrashed() - * @property int|null $user_group_id + * @property int|null $user_group_id * @method static \Illuminate\Database\Eloquent\Builder|TransactionGroup whereUserGroupId($value) * @mixin Eloquent */ @@ -88,7 +88,7 @@ class TransactionGroup extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return TransactionGroup * @throws NotFoundHttpException @@ -115,14 +115,6 @@ class TransactionGroup extends Model throw new NotFoundHttpException(); } - /** - * @return HasMany - */ - public function transactionJournals(): HasMany - { - return $this->hasMany(TransactionJournal::class); - } - /** * @return BelongsTo */ @@ -130,4 +122,12 @@ class TransactionGroup extends Model { return $this->belongsTo(User::class); } + + /** + * @return HasMany + */ + public function transactionJournals(): HasMany + { + return $this->hasMany(TransactionJournal::class); + } } diff --git a/app/Models/TransactionJournal.php b/app/Models/TransactionJournal.php index 54a37027b0..a27efef9af 100644 --- a/app/Models/TransactionJournal.php +++ b/app/Models/TransactionJournal.php @@ -41,50 +41,50 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\TransactionJournal * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $user_id - * @property int $transaction_type_id - * @property int|null $transaction_group_id - * @property int|null $bill_id - * @property int|null $transaction_currency_id - * @property string $description - * @property Carbon $date - * @property Carbon|null $interest_date - * @property Carbon|null $book_date - * @property Carbon|null $process_date - * @property int $order - * @property int $tag_count - * @property string $transaction_type_type - * @property bool $encrypted - * @property bool $completed - * @property-read Collection|Attachment[] $attachments - * @property-read int|null $attachments_count - * @property-read Bill|null $bill - * @property-read Collection|Budget[] $budgets - * @property-read int|null $budgets_count - * @property-read Collection|Category[] $categories - * @property-read int|null $categories_count + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $user_id + * @property int $transaction_type_id + * @property int|null $transaction_group_id + * @property int|null $bill_id + * @property int|null $transaction_currency_id + * @property string $description + * @property Carbon $date + * @property Carbon|null $interest_date + * @property Carbon|null $book_date + * @property Carbon|null $process_date + * @property int $order + * @property int $tag_count + * @property string $transaction_type_type + * @property bool $encrypted + * @property bool $completed + * @property-read Collection|Attachment[] $attachments + * @property-read int|null $attachments_count + * @property-read Bill|null $bill + * @property-read Collection|Budget[] $budgets + * @property-read int|null $budgets_count + * @property-read Collection|Category[] $categories + * @property-read int|null $categories_count * @property-read Collection|TransactionJournalLink[] $destJournalLinks - * @property-read int|null $dest_journal_links_count - * @property-read Collection|Note[] $notes - * @property-read int|null $notes_count - * @property-read Collection|PiggyBankEvent[] $piggyBankEvents - * @property-read int|null $piggy_bank_events_count + * @property-read int|null $dest_journal_links_count + * @property-read Collection|Note[] $notes + * @property-read int|null $notes_count + * @property-read Collection|PiggyBankEvent[] $piggyBankEvents + * @property-read int|null $piggy_bank_events_count * @property-read Collection|TransactionJournalLink[] $sourceJournalLinks - * @property-read int|null $source_journal_links_count - * @property-read Collection|Tag[] $tags - * @property-read int|null $tags_count - * @property-read TransactionCurrency|null $transactionCurrency - * @property-read TransactionGroup|null $transactionGroup + * @property-read int|null $source_journal_links_count + * @property-read Collection|Tag[] $tags + * @property-read int|null $tags_count + * @property-read TransactionCurrency|null $transactionCurrency + * @property-read TransactionGroup|null $transactionGroup * @property-read Collection|TransactionJournalMeta[] $transactionJournalMeta - * @property-read int|null $transaction_journal_meta_count - * @property-read TransactionType $transactionType - * @property-read Collection|Transaction[] $transactions - * @property-read int|null $transactions_count - * @property-read User $user + * @property-read int|null $transaction_journal_meta_count + * @property-read TransactionType $transactionType + * @property-read Collection|Transaction[] $transactions + * @property-read int|null $transactions_count + * @property-read User $user * @method static EloquentBuilder|TransactionJournal after(Carbon $date) * @method static EloquentBuilder|TransactionJournal before(Carbon $date) * @method static EloquentBuilder|TransactionJournal newModelQuery() @@ -112,10 +112,10 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static EloquentBuilder|TransactionJournal whereUserId($value) * @method static \Illuminate\Database\Query\Builder|TransactionJournal withTrashed() * @method static \Illuminate\Database\Query\Builder|TransactionJournal withoutTrashed() - * @property-read Collection|Location[] $locations - * @property-read int|null $locations_count - * @property int $the_count - * @property int|null $user_group_id + * @property-read Collection|Location[] $locations + * @property-read int|null $locations_count + * @property int $the_count + * @property int|null $user_group_id * @method static EloquentBuilder|TransactionJournal whereUserGroupId($value) * @mixin Eloquent */ @@ -160,34 +160,10 @@ class TransactionJournal extends Model /** @var array Hidden from view */ protected $hidden = ['encrypted']; - /** - * Checks if tables are joined. - * - * - * @param Builder $query - * @param string $table - * - * @return bool - */ - public static function isJoined(Builder $query, string $table): bool - { - $joins = $query->getQuery()->joins; - if (null === $joins) { - return false; - } - foreach ($joins as $join) { - if ($join->table === $table) { - return true; - } - } - - return false; - } - /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return TransactionJournal * @throws NotFoundHttpException @@ -208,6 +184,14 @@ class TransactionJournal extends Model throw new NotFoundHttpException(); } + /** + * @return BelongsTo + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + /** * @return MorphMany */ @@ -286,8 +270,8 @@ class TransactionJournal extends Model /** * - * @param EloquentBuilder $query - * @param Carbon $date + * @param EloquentBuilder $query + * @param Carbon $date * * @return EloquentBuilder */ @@ -298,8 +282,8 @@ class TransactionJournal extends Model /** * - * @param EloquentBuilder $query - * @param Carbon $date + * @param EloquentBuilder $query + * @param Carbon $date * * @return EloquentBuilder */ @@ -310,8 +294,8 @@ class TransactionJournal extends Model /** * - * @param EloquentBuilder $query - * @param array $types + * @param EloquentBuilder $query + * @param array $types */ public function scopeTransactionTypes(EloquentBuilder $query, array $types): void { @@ -323,6 +307,30 @@ class TransactionJournal extends Model } } + /** + * Checks if tables are joined. + * + * + * @param Builder $query + * @param string $table + * + * @return bool + */ + public static function isJoined(Builder $query, string $table): bool + { + $joins = $query->getQuery()->joins; + if (null === $joins) { + return false; + } + foreach ($joins as $join) { + if ($join->table === $table) { + return true; + } + } + + return false; + } + /** * @return HasMany */ @@ -378,12 +386,4 @@ class TransactionJournal extends Model { return $this->hasMany(Transaction::class); } - - /** - * @return BelongsTo - */ - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } } diff --git a/app/Models/TransactionJournalLink.php b/app/Models/TransactionJournalLink.php index 70dcb1c7e5..30740c9990 100644 --- a/app/Models/TransactionJournalLink.php +++ b/app/Models/TransactionJournalLink.php @@ -35,20 +35,20 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\TransactionJournalLink * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property int $link_type_id - * @property int $source_id - * @property int $destination_id - * @property string|null $comment + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property int $link_type_id + * @property int $source_id + * @property int $destination_id + * @property string|null $comment * @property-read TransactionJournal $destination - * @property-read LinkType $linkType - * @property-read Collection|Note[] $notes - * @property-read int|null $notes_count + * @property-read LinkType $linkType + * @property-read Collection|Note[] $notes + * @property-read int|null $notes_count * @property-read TransactionJournal $source - * @property-read string $inward - * @property-read string $outward + * @property-read string $inward + * @property-read string $outward * @method static Builder|TransactionJournalLink newModelQuery() * @method static Builder|TransactionJournalLink newQuery() * @method static Builder|TransactionJournalLink query() @@ -79,7 +79,7 @@ class TransactionJournalLink extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return TransactionJournalLink * diff --git a/app/Models/TransactionJournalMeta.php b/app/Models/TransactionJournalMeta.php index 93195c34c4..7c27a31e88 100644 --- a/app/Models/TransactionJournalMeta.php +++ b/app/Models/TransactionJournalMeta.php @@ -33,14 +33,14 @@ use Illuminate\Support\Carbon; /** * FireflyIII\Models\TransactionJournalMeta * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property int $transaction_journal_id - * @property string $name - * @property mixed $data - * @property string $hash - * @property Carbon|null $deleted_at + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property int $transaction_journal_id + * @property string $name + * @property mixed $data + * @property string $hash + * @property Carbon|null $deleted_at * @property-read TransactionJournal $transactionJournal * @method static \Illuminate\Database\Eloquent\Builder|TransactionJournalMeta newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|TransactionJournalMeta newQuery() @@ -80,7 +80,7 @@ class TransactionJournalMeta extends Model /** * - * @param mixed $value + * @param mixed $value * * @return mixed */ @@ -91,7 +91,7 @@ class TransactionJournalMeta extends Model /** * - * @param mixed $value + * @param mixed $value */ public function setDataAttribute($value): void { diff --git a/app/Models/TransactionType.php b/app/Models/TransactionType.php index 4a83d3dc91..3fc2d21efc 100644 --- a/app/Models/TransactionType.php +++ b/app/Models/TransactionType.php @@ -35,13 +35,13 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\TransactionType * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property string $type + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property string $type * @property-read Collection|TransactionJournal[] $transactionJournals - * @property-read int|null $transaction_journals_count + * @property-read int|null $transaction_journals_count * @method static \Illuminate\Database\Eloquent\Builder|TransactionType newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|TransactionType newQuery() * @method static Builder|TransactionType onlyTrashed() @@ -78,7 +78,7 @@ class TransactionType extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $type + * @param string $type * * @return TransactionType * @throws NotFoundHttpException diff --git a/app/Models/UserGroup.php b/app/Models/UserGroup.php index 01093513cb..11ce5c77b4 100644 --- a/app/Models/UserGroup.php +++ b/app/Models/UserGroup.php @@ -34,13 +34,13 @@ use Illuminate\Support\Carbon; /** * Class UserGroup * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property string|null $deleted_at - * @property string $title + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property string|null $deleted_at + * @property string $title * @property-read Collection|GroupMembership[] $groupMemberships - * @property-read int|null $group_memberships_count + * @property-read int|null $group_memberships_count * @method static Builder|UserGroup newModelQuery() * @method static Builder|UserGroup newQuery() * @method static Builder|UserGroup query() @@ -49,11 +49,12 @@ use Illuminate\Support\Carbon; * @method static Builder|UserGroup whereId($value) * @method static Builder|UserGroup whereTitle($value) * @method static Builder|UserGroup whereUpdatedAt($value) - * @property-read Collection $accounts - * @property-read int|null $accounts_count - * @property-read Collection $accounts - * @property-read Collection $accounts - * @property-read Collection $accounts + * @property-read Collection $accounts + * @property-read int|null $accounts_count + * @property-read Collection $accounts + * @property-read Collection $accounts + * @property-read Collection $accounts + * @property-read Collection $accounts * @mixin Eloquent */ class UserGroup extends Model diff --git a/app/Models/UserRole.php b/app/Models/UserRole.php index b09c8d0a0a..da88f6987b 100644 --- a/app/Models/UserRole.php +++ b/app/Models/UserRole.php @@ -34,13 +34,13 @@ use Illuminate\Support\Carbon; /** * Class UserRole * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property string|null $deleted_at - * @property string $title + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property string|null $deleted_at + * @property string $title * @property-read Collection|GroupMembership[] $groupMemberships - * @property-read int|null $group_memberships_count + * @property-read int|null $group_memberships_count * @method static Builder|UserRole newModelQuery() * @method static Builder|UserRole newQuery() * @method static Builder|UserRole query() diff --git a/app/Models/Webhook.php b/app/Models/Webhook.php index 2fd92377cd..c928d35758 100644 --- a/app/Models/Webhook.php +++ b/app/Models/Webhook.php @@ -40,19 +40,19 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\Webhook * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $deleted_at - * @property int $user_id - * @property bool $active - * @property int $trigger - * @property int $response - * @property int $delivery - * @property string $url - * @property-read User $user + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property Carbon|null $deleted_at + * @property int $user_id + * @property bool $active + * @property int $trigger + * @property int $response + * @property int $delivery + * @property string $url + * @property-read User $user * @property-read Collection|WebhookMessage[] $webhookMessages - * @property-read int|null $webhook_messages_count + * @property-read int|null $webhook_messages_count * @method static Builder|Webhook newModelQuery() * @method static Builder|Webhook newQuery() * @method static \Illuminate\Database\Query\Builder|Webhook onlyTrashed() @@ -69,11 +69,11 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static Builder|Webhook whereUserId($value) * @method static \Illuminate\Database\Query\Builder|Webhook withTrashed() * @method static \Illuminate\Database\Query\Builder|Webhook withoutTrashed() - * @property string $title - * @property string $secret + * @property string $title + * @property string $secret * @method static Builder|Webhook whereSecret($value) * @method static Builder|Webhook whereTitle($value) - * @property int|null $user_group_id + * @property int|null $user_group_id * @method static Builder|Webhook whereUserGroupId($value) * @mixin Eloquent */ @@ -174,7 +174,7 @@ class Webhook extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return Webhook * @throws NotFoundHttpException diff --git a/app/Models/WebhookAttempt.php b/app/Models/WebhookAttempt.php index 0f9a04588e..2dd236663e 100644 --- a/app/Models/WebhookAttempt.php +++ b/app/Models/WebhookAttempt.php @@ -35,14 +35,14 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Class WebhookAttempt * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property string|null $deleted_at - * @property int $webhook_message_id - * @property int $status_code - * @property string|null $logs - * @property string|null $response + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property string|null $deleted_at + * @property int $webhook_message_id + * @property int $status_code + * @property string|null $logs + * @property string|null $response * @property-read WebhookMessage $webhookMessage * @method static \Illuminate\Database\Eloquent\Builder|WebhookAttempt newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|WebhookAttempt newQuery() @@ -67,7 +67,7 @@ class WebhookAttempt extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return WebhookAttempt * @throws NotFoundHttpException diff --git a/app/Models/WebhookMessage.php b/app/Models/WebhookMessage.php index b13333ddec..f04bafae99 100644 --- a/app/Models/WebhookMessage.php +++ b/app/Models/WebhookMessage.php @@ -37,18 +37,18 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FireflyIII\Models\WebhookMessage * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property string|null $deleted_at - * @property int $webhook_id - * @property bool $sent - * @property bool $errored - * @property int $attempts - * @property string $uuid - * @property array $message - * @property array|null $logs - * @property-read Webhook $webhook + * @property int $id + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property string|null $deleted_at + * @property int $webhook_id + * @property bool $sent + * @property bool $errored + * @property int $attempts + * @property string $uuid + * @property array $message + * @property array|null $logs + * @property-read Webhook $webhook * @method static Builder|WebhookMessage newModelQuery() * @method static Builder|WebhookMessage newQuery() * @method static Builder|WebhookMessage query() @@ -64,7 +64,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static Builder|WebhookMessage whereUuid($value) * @method static Builder|WebhookMessage whereWebhookId($value) * @property-read Collection|WebhookAttempt[] $webhookAttempts - * @property-read int|null $webhook_attempts_count + * @property-read int|null $webhook_attempts_count * @mixin Eloquent */ class WebhookMessage extends Model @@ -81,7 +81,7 @@ class WebhookMessage extends Model /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * - * @param string $value + * @param string $value * * @return WebhookMessage * @throws NotFoundHttpException diff --git a/app/Notifications/Admin/TestNotification.php b/app/Notifications/Admin/TestNotification.php index ad21a8d2d7..7ad8e1cbdd 100644 --- a/app/Notifications/Admin/TestNotification.php +++ b/app/Notifications/Admin/TestNotification.php @@ -51,7 +51,7 @@ class TestNotification extends Notification /** * Get the array representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function toArray($notifiable) @@ -64,7 +64,7 @@ class TestNotification extends Notification /** * Get the mail representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return MailMessage */ public function toMail($notifiable) @@ -77,7 +77,7 @@ class TestNotification extends Notification /** * Get the Slack representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return SlackMessage */ public function toSlack($notifiable) @@ -88,7 +88,7 @@ class TestNotification extends Notification /** * Get the notification's delivery channels. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function via($notifiable) diff --git a/app/Notifications/Admin/UserInvitation.php b/app/Notifications/Admin/UserInvitation.php index 5b17c60412..13c472f634 100644 --- a/app/Notifications/Admin/UserInvitation.php +++ b/app/Notifications/Admin/UserInvitation.php @@ -52,7 +52,7 @@ class UserInvitation extends Notification /** * Get the array representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function toArray($notifiable) @@ -65,7 +65,7 @@ class UserInvitation extends Notification /** * Get the mail representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return MailMessage */ public function toMail($notifiable) @@ -78,7 +78,7 @@ class UserInvitation extends Notification /** * Get the Slack representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return SlackMessage */ public function toSlack($notifiable) @@ -91,7 +91,7 @@ class UserInvitation extends Notification /** * Get the notification's delivery channels. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function via($notifiable) diff --git a/app/Notifications/Admin/UserRegistration.php b/app/Notifications/Admin/UserRegistration.php index a9636020a9..82d3389057 100644 --- a/app/Notifications/Admin/UserRegistration.php +++ b/app/Notifications/Admin/UserRegistration.php @@ -52,7 +52,7 @@ class UserRegistration extends Notification /** * Get the array representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function toArray($notifiable) @@ -65,7 +65,7 @@ class UserRegistration extends Notification /** * Get the mail representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return MailMessage */ public function toMail($notifiable) @@ -78,7 +78,7 @@ class UserRegistration extends Notification /** * Get the Slack representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return SlackMessage */ public function toSlack($notifiable) @@ -89,7 +89,7 @@ class UserRegistration extends Notification /** * Get the notification's delivery channels. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function via($notifiable) diff --git a/app/Notifications/Admin/VersionCheckResult.php b/app/Notifications/Admin/VersionCheckResult.php index a8d3ce7f1a..c2f26752f8 100644 --- a/app/Notifications/Admin/VersionCheckResult.php +++ b/app/Notifications/Admin/VersionCheckResult.php @@ -52,7 +52,7 @@ class VersionCheckResult extends Notification /** * Get the array representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function toArray($notifiable) @@ -65,7 +65,7 @@ class VersionCheckResult extends Notification /** * Get the mail representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return MailMessage */ public function toMail($notifiable) @@ -78,7 +78,7 @@ class VersionCheckResult extends Notification /** * Get the Slack representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return SlackMessage */ public function toSlack($notifiable) @@ -92,7 +92,7 @@ class VersionCheckResult extends Notification /** * Get the notification's delivery channels. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function via($notifiable) diff --git a/app/Notifications/User/BillReminder.php b/app/Notifications/User/BillReminder.php index 677dd6fa47..c719a92524 100644 --- a/app/Notifications/User/BillReminder.php +++ b/app/Notifications/User/BillReminder.php @@ -56,7 +56,7 @@ class BillReminder extends Notification /** * Get the array representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function toArray($notifiable) @@ -69,7 +69,7 @@ class BillReminder extends Notification /** * Get the mail representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return MailMessage */ public function toMail($notifiable) @@ -87,7 +87,7 @@ class BillReminder extends Notification /** * Get the Slack representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return SlackMessage */ public function toSlack($notifiable) @@ -109,7 +109,7 @@ class BillReminder extends Notification /** * Get the notification's delivery channels. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function via($notifiable) diff --git a/app/Notifications/User/NewAccessToken.php b/app/Notifications/User/NewAccessToken.php index 867c3fd4b9..42e4745414 100644 --- a/app/Notifications/User/NewAccessToken.php +++ b/app/Notifications/User/NewAccessToken.php @@ -45,7 +45,7 @@ class NewAccessToken extends Notification /** * Get the array representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function toArray($notifiable) @@ -58,7 +58,7 @@ class NewAccessToken extends Notification /** * Get the mail representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return MailMessage */ public function toMail($notifiable) @@ -71,7 +71,7 @@ class NewAccessToken extends Notification /** * Get the Slack representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return SlackMessage */ public function toSlack($notifiable) @@ -82,7 +82,7 @@ class NewAccessToken extends Notification /** * Get the notification's delivery channels. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function via($notifiable) diff --git a/app/Notifications/User/TransactionCreation.php b/app/Notifications/User/TransactionCreation.php index 102ab79087..223c0b1766 100644 --- a/app/Notifications/User/TransactionCreation.php +++ b/app/Notifications/User/TransactionCreation.php @@ -47,7 +47,7 @@ class TransactionCreation extends Notification /** * Get the array representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function toArray($notifiable) @@ -60,7 +60,7 @@ class TransactionCreation extends Notification /** * Get the mail representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return MailMessage */ public function toMail($notifiable) @@ -73,7 +73,7 @@ class TransactionCreation extends Notification /** * Get the notification's delivery channels. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function via($notifiable) diff --git a/app/Notifications/User/UserLogin.php b/app/Notifications/User/UserLogin.php index 243e1304cb..dd0b3aae2a 100644 --- a/app/Notifications/User/UserLogin.php +++ b/app/Notifications/User/UserLogin.php @@ -50,7 +50,7 @@ class UserLogin extends Notification /** * Get the array representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function toArray($notifiable) @@ -63,7 +63,7 @@ class UserLogin extends Notification /** * Get the mail representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return MailMessage */ public function toMail($notifiable) @@ -88,7 +88,7 @@ class UserLogin extends Notification /** * Get the Slack representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return SlackMessage */ public function toSlack($notifiable) @@ -110,7 +110,7 @@ class UserLogin extends Notification /** * Get the notification's delivery channels. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function via($notifiable) diff --git a/app/Notifications/User/UserNewPassword.php b/app/Notifications/User/UserNewPassword.php index 48f14421b1..d3373697c6 100644 --- a/app/Notifications/User/UserNewPassword.php +++ b/app/Notifications/User/UserNewPassword.php @@ -47,7 +47,7 @@ class UserNewPassword extends Notification /** * Get the array representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function toArray($notifiable) @@ -60,7 +60,7 @@ class UserNewPassword extends Notification /** * Get the mail representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return MailMessage */ public function toMail($notifiable) @@ -73,7 +73,7 @@ class UserNewPassword extends Notification /** * Get the notification's delivery channels. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function via($notifiable) diff --git a/app/Notifications/User/UserRegistration.php b/app/Notifications/User/UserRegistration.php index ba5e39348a..ed547fd267 100644 --- a/app/Notifications/User/UserRegistration.php +++ b/app/Notifications/User/UserRegistration.php @@ -44,7 +44,7 @@ class UserRegistration extends Notification /** * Get the array representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function toArray($notifiable) @@ -57,7 +57,7 @@ class UserRegistration extends Notification /** * Get the mail representation of the notification. * - * @param mixed $notifiable + * @param mixed $notifiable * @return MailMessage */ public function toMail($notifiable) @@ -70,7 +70,7 @@ class UserRegistration extends Notification /** * Get the notification's delivery channels. * - * @param mixed $notifiable + * @param mixed $notifiable * @return array */ public function via($notifiable) diff --git a/app/Providers/FireflySessionProvider.php b/app/Providers/FireflySessionProvider.php index 46db3ff7b0..f07474003c 100644 --- a/app/Providers/FireflySessionProvider.php +++ b/app/Providers/FireflySessionProvider.php @@ -44,6 +44,19 @@ class FireflySessionProvider extends ServiceProvider $this->app->singleton(StartFireflySession::class); } + /** + * Register the session manager instance. + */ + protected function registerSessionManager(): void + { + $this->app->singleton( + 'session', + function ($app) { + return new SessionManager($app); + } + ); + } + /** * Register the session driver instance. */ @@ -59,17 +72,4 @@ class FireflySessionProvider extends ServiceProvider } ); } - - /** - * Register the session manager instance. - */ - protected function registerSessionManager(): void - { - $this->app->singleton( - 'session', - function ($app) { - return new SessionManager($app); - } - ); - } } diff --git a/app/Providers/JournalServiceProvider.php b/app/Providers/JournalServiceProvider.php index 69b27ccf49..8a2ae5ae89 100644 --- a/app/Providers/JournalServiceProvider.php +++ b/app/Providers/JournalServiceProvider.php @@ -58,44 +58,6 @@ class JournalServiceProvider extends ServiceProvider $this->registerGroupCollector(); } - /** - * - */ - private function registerGroupCollector(): void - { - $this->app->bind( - GroupCollectorInterface::class, - static function (Application $app) { - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollector::class); - if ($app->auth->check()) { // @phpstan-ignore-line (phpstan does not understand the reference to auth) - $collector->setUser(auth()->user()); - } - - return $collector; - } - ); - } - - /** - * Register group repos. - */ - private function registerGroupRepository(): void - { - $this->app->bind( - TransactionGroupRepositoryInterface::class, - static function (Application $app) { - /** @var TransactionGroupRepositoryInterface $repository */ - $repository = app(TransactionGroupRepository::class); - if ($app->auth->check()) { // @phpstan-ignore-line (phpstan does not understand the reference to auth) - $repository->setUser(auth()->user()); - } - - return $repository; - } - ); - } - /** * Register repository. */ @@ -142,4 +104,42 @@ class JournalServiceProvider extends ServiceProvider } ); } + + /** + * Register group repos. + */ + private function registerGroupRepository(): void + { + $this->app->bind( + TransactionGroupRepositoryInterface::class, + static function (Application $app) { + /** @var TransactionGroupRepositoryInterface $repository */ + $repository = app(TransactionGroupRepository::class); + if ($app->auth->check()) { // @phpstan-ignore-line (phpstan does not understand the reference to auth) + $repository->setUser(auth()->user()); + } + + return $repository; + } + ); + } + + /** + * + */ + private function registerGroupCollector(): void + { + $this->app->bind( + GroupCollectorInterface::class, + static function (Application $app) { + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollector::class); + if ($app->auth->check()) { // @phpstan-ignore-line (phpstan does not understand the reference to auth) + $collector->setUser(auth()->user()); + } + + return $collector; + } + ); + } } diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index cdcb140bca..0eca49e48e 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -54,21 +54,11 @@ class AccountRepository implements AccountRepositoryInterface { private User $user; - /** - * @param array $types - * - * @return int - */ - public function count(array $types): int - { - return $this->user->accounts()->accountTypeIn($types)->count(); - } - /** * Moved here from account CRUD. * - * @param Account $account - * @param Account|null $moveTo + * @param Account $account + * @param Account|null $moveTo * * @return bool * @@ -86,7 +76,7 @@ class AccountRepository implements AccountRepositoryInterface /** * Find account with same name OR same IBAN or both, but not the same type or ID. * - * @param Collection $accounts + * @param Collection $accounts * * @return Collection */ @@ -117,16 +107,6 @@ class AccountRepository implements AccountRepositoryInterface return $result; } - /** - * @param int $accountId - * - * @return Account|null - */ - public function find(int $accountId): ?Account - { - return $this->user->accounts()->find($accountId); - } - /** * @inheritDoc */ @@ -153,8 +133,8 @@ class AccountRepository implements AccountRepositoryInterface } /** - * @param string $iban - * @param array $types + * @param string $iban + * @param array $types * * @return Account|null */ @@ -172,8 +152,8 @@ class AccountRepository implements AccountRepositoryInterface } /** - * @param string $name - * @param array $types + * @param string $name + * @param array $types * * @return Account|null */ @@ -200,32 +180,10 @@ class AccountRepository implements AccountRepositoryInterface return $account; } - /** - * @param Account $account - * - * @return TransactionCurrency|null - */ - public function getAccountCurrency(Account $account): ?TransactionCurrency - { - $type = $account->accountType->type; - $list = config('firefly.valid_currency_account_types'); - - // return null if not in this list. - if (!in_array($type, $list, true)) { - return null; - } - $currencyId = (int)$this->getMetaValue($account, 'currency_id'); - if ($currencyId > 0) { - return TransactionCurrency::find($currencyId); - } - - return null; - } - /** * Return account type or null if not found. * - * @param string $type + * @param string $type * * @return AccountType|null */ @@ -235,7 +193,7 @@ class AccountRepository implements AccountRepositoryInterface } /** - * @param array $accountIds + * @param array $accountIds * * @return Collection */ @@ -254,39 +212,7 @@ class AccountRepository implements AccountRepositoryInterface } /** - * @param array $types - * @param array|null $sort - * - * @return Collection - */ - public function getAccountsByType(array $types, ?array $sort = []): Collection - { - $res = array_intersect([AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT], $types); - $query = $this->user->accounts(); - if (0 !== count($types)) { - $query->accountTypeIn($types); - } - - // add sort parameters. At this point they're filtered to allowed fields to sort by: - if (0 !== count($sort)) { - foreach ($sort as $param) { - $query->orderBy($param[0], $param[1]); - } - } - - if (0 === count($sort)) { - if (0 !== count($res)) { - $query->orderBy('accounts.order', 'ASC'); - } - $query->orderBy('accounts.active', 'DESC'); - $query->orderBy('accounts.name', 'ASC'); - } - - return $query->get(['accounts.*']); - } - - /** - * @param array $types + * @param array $types * * @return Collection */ @@ -349,6 +275,16 @@ class AccountRepository implements AccountRepositoryInterface return $factory->findOrCreate('Cash account', $type->type); } + /** + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + /** * @inheritDoc */ @@ -362,7 +298,7 @@ class AccountRepository implements AccountRepositoryInterface } /** - * @param array $types + * @param array $types * * @return Collection */ @@ -395,35 +331,10 @@ class AccountRepository implements AccountRepositoryInterface return $account->locations()->first(); } - /** - * Return meta value for account. Null if not found. - * - * @param Account $account - * @param string $field - * - * @return null|string - */ - public function getMetaValue(Account $account, string $field): ?string - { - $result = $account->accountMeta->filter( - function (AccountMeta $meta) use ($field) { - return strtolower($meta->name) === strtolower($field); - } - ); - if (0 === $result->count()) { - return null; - } - if (1 === $result->count()) { - return (string)$result->first()->data; - } - - return null; - } - /** * Get note text or null. * - * @param Account $account + * @param Account $account * * @return null|string */ @@ -432,23 +343,10 @@ class AccountRepository implements AccountRepositoryInterface return $account->notes()->first()?->text; } - /** - * @param Account $account - * - * @return TransactionJournal|null - */ - public function getOpeningBalance(Account $account): ?TransactionJournal - { - return TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transactions.account_id', $account->id) - ->transactionTypes([TransactionType::OPENING_BALANCE]) - ->first(['transaction_journals.*']); - } - /** * Returns the amount of the opening balance for this account. * - * @param Account $account + * @param Account $account * * @return string|null */ @@ -472,7 +370,7 @@ class AccountRepository implements AccountRepositoryInterface /** * Return date of opening balance as string or null. * - * @param Account $account + * @param Account $account * * @return null|string */ @@ -485,7 +383,7 @@ class AccountRepository implements AccountRepositoryInterface } /** - * @param Account $account + * @param Account $account * * @return TransactionGroup|null */ @@ -497,7 +395,20 @@ class AccountRepository implements AccountRepositoryInterface } /** - * @param Account $account + * @param Account $account + * + * @return TransactionJournal|null + */ + public function getOpeningBalance(Account $account): ?TransactionJournal + { + return TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transactions.account_id', $account->id) + ->transactionTypes([TransactionType::OPENING_BALANCE]) + ->first(['transaction_journals.*']); + } + + /** + * @param Account $account * * @return Collection */ @@ -507,7 +418,7 @@ class AccountRepository implements AccountRepositoryInterface } /** - * @param Account $account + * @param Account $account * * @return Account|null * @@ -549,6 +460,73 @@ class AccountRepository implements AccountRepositoryInterface return $factory->create($data); } + /** + * @param Account $account + * + * @return TransactionCurrency|null + */ + public function getAccountCurrency(Account $account): ?TransactionCurrency + { + $type = $account->accountType->type; + $list = config('firefly.valid_currency_account_types'); + + // return null if not in this list. + if (!in_array($type, $list, true)) { + return null; + } + $currencyId = (int)$this->getMetaValue($account, 'currency_id'); + if ($currencyId > 0) { + return TransactionCurrency::find($currencyId); + } + + return null; + } + + /** + * Return meta value for account. Null if not found. + * + * @param Account $account + * @param string $field + * + * @return null|string + */ + public function getMetaValue(Account $account, string $field): ?string + { + $result = $account->accountMeta->filter( + function (AccountMeta $meta) use ($field) { + return strtolower($meta->name) === strtolower($field); + } + ); + if (0 === $result->count()) { + return null; + } + if (1 === $result->count()) { + return (string)$result->first()->data; + } + + return null; + } + + /** + * @param array $types + * + * @return int + */ + public function count(array $types): int + { + return $this->user->accounts()->accountTypeIn($types)->count(); + } + + /** + * @param int $accountId + * + * @return Account|null + */ + public function find(int $accountId): ?Account + { + return $this->user->accounts()->find($accountId); + } + /** * @inheritDoc */ @@ -566,7 +544,7 @@ class AccountRepository implements AccountRepositoryInterface } /** - * @param Account $account + * @param Account $account * * @return bool */ @@ -602,10 +580,56 @@ class AccountRepository implements AccountRepositoryInterface return $order; } + /** + * @param array $types + * @param array|null $sort + * + * @return Collection + */ + public function getAccountsByType(array $types, ?array $sort = []): Collection + { + $res = array_intersect([AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT], $types); + $query = $this->user->accounts(); + if (0 !== count($types)) { + $query->accountTypeIn($types); + } + + // add sort parameters. At this point they're filtered to allowed fields to sort by: + if (0 !== count($sort)) { + foreach ($sort as $param) { + $query->orderBy($param[0], $param[1]); + } + } + + if (0 === count($sort)) { + if (0 !== count($res)) { + $query->orderBy('accounts.order', 'ASC'); + } + $query->orderBy('accounts.active', 'DESC'); + $query->orderBy('accounts.name', 'ASC'); + } + + return $query->get(['accounts.*']); + } + /** * Returns the date of the very first transaction in this account. * - * @param Account $account + * @param Account $account + * + * @return Carbon|null + */ + public function oldestJournalDate(Account $account): ?Carbon + { + $journal = $this->oldestJournal($account); + + return $journal?->date; + } + + /** + * Returns the date of the very first transaction in this account. + * + * @param Account $account * * @return TransactionJournal|null */ @@ -625,20 +649,6 @@ class AccountRepository implements AccountRepositoryInterface return null; } - /** - * Returns the date of the very first transaction in this account. - * - * @param Account $account - * - * @return Carbon|null - */ - public function oldestJournalDate(Account $account): ?Carbon - { - $journal = $this->oldestJournal($account); - - return $journal?->date; - } - /** * @inheritDoc */ @@ -670,9 +680,9 @@ class AccountRepository implements AccountRepositoryInterface } /** - * @param string $query - * @param array $types - * @param int $limit + * @param string $query + * @param array $types + * @param int $limit * * @return Collection */ @@ -739,17 +749,7 @@ class AccountRepository implements AccountRepositoryInterface } /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - - /** - * @param array $data + * @param array $data * * @return Account * @throws FireflyException @@ -765,8 +765,8 @@ class AccountRepository implements AccountRepositoryInterface } /** - * @param Account $account - * @param array $data + * @param Account $account + * @param array $data * * @return Account * @throws FireflyException diff --git a/app/Repositories/Account/AccountRepositoryInterface.php b/app/Repositories/Account/AccountRepositoryInterface.php index 8a843d0257..4e71af2b63 100644 --- a/app/Repositories/Account/AccountRepositoryInterface.php +++ b/app/Repositories/Account/AccountRepositoryInterface.php @@ -42,7 +42,7 @@ interface AccountRepositoryInterface /** * Moved here from account CRUD. * - * @param array $types + * @param array $types * * @return int */ @@ -52,8 +52,8 @@ interface AccountRepositoryInterface /** * Moved here from account CRUD. * - * @param Account $account - * @param Account|null $moveTo + * @param Account $account + * @param Account|null $moveTo * * @return bool */ @@ -62,45 +62,45 @@ interface AccountRepositoryInterface /** * Find account with same name OR same IBAN or both, but not the same type or ID. * - * @param Collection $accounts + * @param Collection $accounts * * @return Collection */ public function expandWithDoubles(Collection $accounts): Collection; /** - * @param int $accountId + * @param int $accountId * * @return Account|null */ public function find(int $accountId): ?Account; /** - * @param string $number - * @param array $types + * @param string $number + * @param array $types * * @return Account|null */ public function findByAccountNumber(string $number, array $types): ?Account; /** - * @param string $iban - * @param array $types + * @param string $iban + * @param array $types * * @return Account|null */ public function findByIbanNull(string $iban, array $types): ?Account; /** - * @param string $name - * @param array $types + * @param string $name + * @param array $types * * @return Account|null */ public function findByName(string $name, array $types): ?Account; /** - * @param Account $account + * @param Account $account * * @return TransactionCurrency|null */ @@ -109,36 +109,36 @@ interface AccountRepositoryInterface /** * Return account type or null if not found. * - * @param string $type + * @param string $type * * @return AccountType|null */ public function getAccountTypeByType(string $type): ?AccountType; /** - * @param array $accountIds + * @param array $accountIds * * @return Collection */ public function getAccountsById(array $accountIds): Collection; /** - * @param array $types - * @param array|null $sort + * @param array $types + * @param array|null $sort * * @return Collection */ public function getAccountsByType(array $types, ?array $sort = []): Collection; /** - * @param array $types + * @param array $types * * @return Collection */ public function getActiveAccountsByType(array $types): Collection; /** - * @param Account $account + * @param Account $account * * @return Collection */ @@ -150,14 +150,14 @@ interface AccountRepositoryInterface public function getCashAccount(): Account; /** - * @param Account $account + * @param Account $account * * @return TransactionGroup|null */ public function getCreditTransactionGroup(Account $account): ?TransactionGroup; /** - * @param array $types + * @param array $types * * @return Collection */ @@ -166,7 +166,7 @@ interface AccountRepositoryInterface /** * Get account location, if any. * - * @param Account $account + * @param Account $account * * @return Location|null */ @@ -175,8 +175,8 @@ interface AccountRepositoryInterface /** * Return meta value for account. Null if not found. * - * @param Account $account - * @param string $field + * @param Account $account + * @param string $field * * @return null|string */ @@ -185,14 +185,14 @@ interface AccountRepositoryInterface /** * Get note text or null. * - * @param Account $account + * @param Account $account * * @return null|string */ public function getNoteText(Account $account): ?string; /** - * @param Account $account + * @param Account $account * * @return TransactionJournal|null * @@ -202,7 +202,7 @@ interface AccountRepositoryInterface /** * Returns the amount of the opening balance for this account. * - * @param Account $account + * @param Account $account * * @return string|null */ @@ -211,21 +211,21 @@ interface AccountRepositoryInterface /** * Return date of opening balance as string or null. * - * @param Account $account + * @param Account $account * * @return null|string */ public function getOpeningBalanceDate(Account $account): ?string; /** - * @param Account $account + * @param Account $account * * @return TransactionGroup|null */ public function getOpeningBalanceGroup(Account $account): ?TransactionGroup; /** - * @param Account $account + * @param Account $account * * @return Collection */ @@ -234,28 +234,28 @@ interface AccountRepositoryInterface /** * Find or create the opposing reconciliation account. * - * @param Account $account + * @param Account $account * * @return Account|null */ public function getReconciliation(Account $account): ?Account; /** - * @param Account $account + * @param Account $account * * @return Collection */ public function getUsedCurrencies(Account $account): Collection; /** - * @param Account $account + * @param Account $account * * @return bool */ public function isLiability(Account $account): bool; /** - * @param string $type + * @param string $type * * @return int */ @@ -264,7 +264,7 @@ interface AccountRepositoryInterface /** * Returns the date of the very first transaction in this account. * - * @param Account $account + * @param Account $account * * @return TransactionJournal|null */ @@ -273,7 +273,7 @@ interface AccountRepositoryInterface /** * Returns the date of the very first transaction in this account. * - * @param Account $account + * @param Account $account * * @return Carbon|null */ @@ -285,38 +285,38 @@ interface AccountRepositoryInterface public function resetAccountOrder(): void; /** - * @param string $query - * @param array $types - * @param int $limit + * @param string $query + * @param array $types + * @param int $limit * * @return Collection */ public function searchAccount(string $query, array $types, int $limit): Collection; /** - * @param string $query - * @param array $types - * @param int $limit + * @param string $query + * @param array $types + * @param int $limit * * @return Collection */ public function searchAccountNr(string $query, array $types, int $limit): Collection; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** - * @param array $data + * @param array $data * * @return Account */ public function store(array $data): Account; /** - * @param Account $account - * @param array $data + * @param Account $account + * @param array $data * * @return Account */ diff --git a/app/Repositories/Account/AccountTasker.php b/app/Repositories/Account/AccountTasker.php index aa47442631..bb34482089 100644 --- a/app/Repositories/Account/AccountTasker.php +++ b/app/Repositories/Account/AccountTasker.php @@ -43,9 +43,9 @@ class AccountTasker implements AccountTaskerInterface private User $user; /** - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return array * @throws FireflyException @@ -116,9 +116,9 @@ class AccountTasker implements AccountTaskerInterface } /** - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts * * @return array * @throws FireflyException @@ -153,51 +153,7 @@ class AccountTasker implements AccountTaskerInterface } /** - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts - * - * @return array - * @throws FireflyException - * @throws JsonException - */ - public function getIncomeReport(Carbon $start, Carbon $end, Collection $accounts): array - { - // get all incomes for the given accounts in the given period! - // also transfers! - // get all transactions: - - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector->setDestinationAccounts($accounts)->setRange($start, $end); - $collector->excludeSourceAccounts($accounts); - $collector->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])->withAccountInformation(); - $report = $this->groupIncomeBySource($collector->getExtractedJournals()); - - // sort the result - // Obtain a list of columns - $sum = []; - foreach ($report['accounts'] as $accountId => $row) { - $sum[$accountId] = (float)$row['sum']; // intentional float - } - - array_multisort($sum, SORT_DESC, $report['accounts']); - - return $report; - } - - /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - - /** - * @param array $array + * @param array $array * * @return array * @throws FireflyException @@ -260,7 +216,41 @@ class AccountTasker implements AccountTaskerInterface } /** - * @param array $array + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts + * + * @return array + * @throws FireflyException + * @throws JsonException + */ + public function getIncomeReport(Carbon $start, Carbon $end, Collection $accounts): array + { + // get all incomes for the given accounts in the given period! + // also transfers! + // get all transactions: + + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector->setDestinationAccounts($accounts)->setRange($start, $end); + $collector->excludeSourceAccounts($accounts); + $collector->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])->withAccountInformation(); + $report = $this->groupIncomeBySource($collector->getExtractedJournals()); + + // sort the result + // Obtain a list of columns + $sum = []; + foreach ($report['accounts'] as $accountId => $row) { + $sum[$accountId] = (float)$row['sum']; // intentional float + } + + array_multisort($sum, SORT_DESC, $report['accounts']); + + return $report; + } + + /** + * @param array $array * * @return array * @throws FireflyException @@ -320,4 +310,14 @@ class AccountTasker implements AccountTaskerInterface return $report; } + + /** + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } } diff --git a/app/Repositories/Account/AccountTaskerInterface.php b/app/Repositories/Account/AccountTaskerInterface.php index 64d9ea50e4..7bbb1c0c75 100644 --- a/app/Repositories/Account/AccountTaskerInterface.php +++ b/app/Repositories/Account/AccountTaskerInterface.php @@ -34,34 +34,34 @@ use Illuminate\Support\Collection; interface AccountTaskerInterface { /** - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return array */ public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): array; /** - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts * * @return array */ public function getExpenseReport(Carbon $start, Carbon $end, Collection $accounts): array; /** - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts * * @return array */ public function getIncomeReport(Carbon $start, Carbon $end, Collection $accounts): array; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; } diff --git a/app/Repositories/Account/OperationsRepository.php b/app/Repositories/Account/OperationsRepository.php index 9c1ed952f2..df5a0fa99e 100644 --- a/app/Repositories/Account/OperationsRepository.php +++ b/app/Repositories/Account/OperationsRepository.php @@ -44,9 +44,9 @@ class OperationsRepository implements OperationsRepositoryInterface * which have the specified accounts. It's grouped per currency, with as few details in the array * as possible. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts * * @return array */ @@ -57,141 +57,13 @@ class OperationsRepository implements OperationsRepositoryInterface return $this->sortByCurrency($journals, 'negative'); } - /** - * This method returns a list of all the deposit transaction journals (as arrays) set in that period - * which have the specified accounts. It's grouped per currency, with as few details in the array - * as possible. Amounts are always positive. - * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * - * @return array - */ - public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array - { - $journals = $this->getTransactions($start, $end, $accounts, TransactionType::DEPOSIT); - - return $this->sortByCurrency($journals, 'positive'); - } - - /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - - /** - * @inheritDoc - */ - public function sumExpenses( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $expense = null, - ?TransactionCurrency $currency = null - ): array { - $journals = $this->getTransactionsForSum(TransactionType::WITHDRAWAL, $start, $end, $accounts, $expense, $currency); - - return $this->groupByCurrency($journals, 'negative'); - } - - /** - * @inheritDoc - */ - public function sumExpensesByDestination( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $expense = null, - ?TransactionCurrency $currency = null - ): array { - $journals = $this->getTransactionsForSum(TransactionType::WITHDRAWAL, $start, $end, $accounts, $expense, $currency); - - return $this->groupByDirection($journals, 'destination', 'negative'); - } - - /** - * @inheritDoc - */ - public function sumExpensesBySource( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $expense = null, - ?TransactionCurrency $currency = null - ): array { - $journals = $this->getTransactionsForSum(TransactionType::WITHDRAWAL, $start, $end, $accounts, $expense, $currency); - - return $this->groupByDirection($journals, 'source', 'negative'); - } - - /** - * @inheritDoc - */ - public function sumIncome( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $revenue = null, - ?TransactionCurrency $currency = null - ): array { - $journals = $this->getTransactionsForSum(TransactionType::DEPOSIT, $start, $end, $accounts, $revenue, $currency); - - return $this->groupByCurrency($journals, 'positive'); - } - - /** - * @inheritDoc - */ - public function sumIncomeByDestination( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $revenue = null, - ?TransactionCurrency $currency = null - ): array { - $journals = $this->getTransactionsForSum(TransactionType::DEPOSIT, $start, $end, $accounts, $revenue, $currency); - - return $this->groupByDirection($journals, 'destination', 'positive'); - } - - /** - * @inheritDoc - */ - public function sumIncomeBySource( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $revenue = null, - ?TransactionCurrency $currency = null - ): array { - $journals = $this->getTransactionsForSum(TransactionType::DEPOSIT, $start, $end, $accounts, $revenue, $currency); - - return $this->groupByDirection($journals, 'source', 'positive'); - } - - /** - * @inheritDoc - */ - public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array - { - $journals = $this->getTransactionsForSum(TransactionType::TRANSFER, $start, $end, $accounts, null, $currency); - - return $this->groupByEither($journals); - } - /** * Collect transactions with some parameters * - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts - * @param string $type + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts + * @param string $type * * @return array */ @@ -207,21 +79,107 @@ class OperationsRepository implements OperationsRepositoryInterface } /** - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $opposing - * @param TransactionCurrency|null $currency - * @param string $type + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + + /** + * @param array $journals + * @param string $direction + * + * @return array + */ + private function sortByCurrency(array $journals, string $direction): array + { + $array = []; + foreach ($journals as $journal) { + $currencyId = (int)$journal['currency_id']; + $journalId = (int)$journal['transaction_journal_id']; + $array[$currencyId] = $array[$currencyId] ?? [ + + 'currency_id' => $journal['currency_id'], + 'currency_name' => $journal['currency_name'], + 'currency_symbol' => $journal['currency_symbol'], + 'currency_code' => $journal['currency_code'], + 'currency_decimal_places' => $journal['currency_decimal_places'], + 'transaction_journals' => [], + ]; + + $array[$currencyId]['transaction_journals'][$journalId] = [ + 'amount' => app('steam')->$direction((string)$journal['amount']), + 'date' => $journal['date'], + 'transaction_journal_id' => $journalId, + 'budget_name' => $journal['budget_name'], + 'category_name' => $journal['category_name'], + 'source_account_id' => $journal['source_account_id'], + 'source_account_name' => $journal['source_account_name'], + 'source_account_iban' => $journal['source_account_iban'], + 'destination_account_id' => $journal['destination_account_id'], + 'destination_account_name' => $journal['destination_account_name'], + 'destination_account_iban' => $journal['destination_account_iban'], + 'tags' => $journal['tags'], + 'description' => $journal['description'], + 'transaction_group_id' => $journal['transaction_group_id'], + ]; + } + + return $array; + } + + /** + * This method returns a list of all the deposit transaction journals (as arrays) set in that period + * which have the specified accounts. It's grouped per currency, with as few details in the array + * as possible. Amounts are always positive. + * + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * + * @return array + */ + public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array + { + $journals = $this->getTransactions($start, $end, $accounts, TransactionType::DEPOSIT); + + return $this->sortByCurrency($journals, 'positive'); + } + + /** + * @inheritDoc + */ + public function sumExpenses( + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $expense = null, + ?TransactionCurrency $currency = null + ): array { + $journals = $this->getTransactionsForSum(TransactionType::WITHDRAWAL, $start, $end, $accounts, $expense, $currency); + + return $this->groupByCurrency($journals, 'negative'); + } + + /** + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $opposing + * @param TransactionCurrency|null $currency + * @param string $type * * @return array */ private function getTransactionsForSum( - string $type, - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $opposing = null, + string $type, + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $opposing = null, ?TransactionCurrency $currency = null ): array { $start->startOfDay(); @@ -291,8 +249,8 @@ class OperationsRepository implements OperationsRepositoryInterface } /** - * @param array $journals - * @param string $direction + * @param array $journals + * @param string $direction * * @return array */ @@ -331,9 +289,24 @@ class OperationsRepository implements OperationsRepositoryInterface } /** - * @param array $journals - * @param string $direction - * @param string $method + * @inheritDoc + */ + public function sumExpensesByDestination( + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $expense = null, + ?TransactionCurrency $currency = null + ): array { + $journals = $this->getTransactionsForSum(TransactionType::WITHDRAWAL, $start, $end, $accounts, $expense, $currency); + + return $this->groupByDirection($journals, 'destination', 'negative'); + } + + /** + * @param array $journals + * @param string $direction + * @param string $method * * @return array */ @@ -378,7 +351,77 @@ class OperationsRepository implements OperationsRepositoryInterface } /** - * @param array $journals + * @inheritDoc + */ + public function sumExpensesBySource( + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $expense = null, + ?TransactionCurrency $currency = null + ): array { + $journals = $this->getTransactionsForSum(TransactionType::WITHDRAWAL, $start, $end, $accounts, $expense, $currency); + + return $this->groupByDirection($journals, 'source', 'negative'); + } + + /** + * @inheritDoc + */ + public function sumIncome( + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $revenue = null, + ?TransactionCurrency $currency = null + ): array { + $journals = $this->getTransactionsForSum(TransactionType::DEPOSIT, $start, $end, $accounts, $revenue, $currency); + + return $this->groupByCurrency($journals, 'positive'); + } + + /** + * @inheritDoc + */ + public function sumIncomeByDestination( + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $revenue = null, + ?TransactionCurrency $currency = null + ): array { + $journals = $this->getTransactionsForSum(TransactionType::DEPOSIT, $start, $end, $accounts, $revenue, $currency); + + return $this->groupByDirection($journals, 'destination', 'positive'); + } + + /** + * @inheritDoc + */ + public function sumIncomeBySource( + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $revenue = null, + ?TransactionCurrency $currency = null + ): array { + $journals = $this->getTransactionsForSum(TransactionType::DEPOSIT, $start, $end, $accounts, $revenue, $currency); + + return $this->groupByDirection($journals, 'source', 'positive'); + } + + /** + * @inheritDoc + */ + public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array + { + $journals = $this->getTransactionsForSum(TransactionType::TRANSFER, $start, $end, $accounts, null, $currency); + + return $this->groupByEither($journals); + } + + /** + * @param array $journals * * @return array */ @@ -401,8 +444,8 @@ class OperationsRepository implements OperationsRepositoryInterface } /** - * @param array $return - * @param array $journal + * @param array $return + * @param array $journal * * @return array */ @@ -497,47 +540,4 @@ class OperationsRepository implements OperationsRepositoryInterface return $return; } - - /** - * @param array $journals - * @param string $direction - * - * @return array - */ - private function sortByCurrency(array $journals, string $direction): array - { - $array = []; - foreach ($journals as $journal) { - $currencyId = (int)$journal['currency_id']; - $journalId = (int)$journal['transaction_journal_id']; - $array[$currencyId] = $array[$currencyId] ?? [ - - 'currency_id' => $journal['currency_id'], - 'currency_name' => $journal['currency_name'], - 'currency_symbol' => $journal['currency_symbol'], - 'currency_code' => $journal['currency_code'], - 'currency_decimal_places' => $journal['currency_decimal_places'], - 'transaction_journals' => [], - ]; - - $array[$currencyId]['transaction_journals'][$journalId] = [ - 'amount' => app('steam')->$direction((string)$journal['amount']), - 'date' => $journal['date'], - 'transaction_journal_id' => $journalId, - 'budget_name' => $journal['budget_name'], - 'category_name' => $journal['category_name'], - 'source_account_id' => $journal['source_account_id'], - 'source_account_name' => $journal['source_account_name'], - 'source_account_iban' => $journal['source_account_iban'], - 'destination_account_id' => $journal['destination_account_id'], - 'destination_account_name' => $journal['destination_account_name'], - 'destination_account_iban' => $journal['destination_account_iban'], - 'tags' => $journal['tags'], - 'description' => $journal['description'], - 'transaction_group_id' => $journal['transaction_group_id'], - ]; - } - - return $array; - } } diff --git a/app/Repositories/Account/OperationsRepositoryInterface.php b/app/Repositories/Account/OperationsRepositoryInterface.php index 2741d8b134..3e02b58cb8 100644 --- a/app/Repositories/Account/OperationsRepositoryInterface.php +++ b/app/Repositories/Account/OperationsRepositoryInterface.php @@ -39,9 +39,9 @@ interface OperationsRepositoryInterface * which have the specified accounts. It's grouped per currency, with as few details in the array * as possible. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts * * @return array */ @@ -52,140 +52,144 @@ interface OperationsRepositoryInterface * which have the specified accounts. It's grouped per currency, with as few details in the array * as possible. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts * * @return array */ public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** * Sum of withdrawal journals in period for a set of accounts, grouped per currency. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $expense - * @param TransactionCurrency|null $currency + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $expense + * @param TransactionCurrency|null $currency * * @return array */ public function sumExpenses( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $expense = null, + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $expense = null, ?TransactionCurrency $currency = null ): array; /** - * Sum of withdrawal journals in period for a set of accounts, grouped per destination / currency. Amounts are always negative. + * Sum of withdrawal journals in period for a set of accounts, grouped per destination / currency. Amounts are + * always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $expense - * @param TransactionCurrency|null $currency + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $expense + * @param TransactionCurrency|null $currency * * @return array */ public function sumExpensesByDestination( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $expense = null, + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $expense = null, ?TransactionCurrency $currency = null ): array; /** - * Sum of withdrawal journals in period for a set of accounts, grouped per source / currency. Amounts are always negative. + * Sum of withdrawal journals in period for a set of accounts, grouped per source / currency. Amounts are always + * negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $expense - * @param TransactionCurrency|null $currency + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $expense + * @param TransactionCurrency|null $currency * * @return array */ public function sumExpensesBySource( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $expense = null, + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $expense = null, ?TransactionCurrency $currency = null ): array; /** * Sum of income journals in period for a set of accounts, grouped per currency. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $revenue - * @param TransactionCurrency|null $currency + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $revenue + * @param TransactionCurrency|null $currency * * @return array */ public function sumIncome( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $revenue = null, + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $revenue = null, ?TransactionCurrency $currency = null ): array; /** - * Sum of income journals in period for a set of accounts, grouped per destination + currency. Amounts are always positive. + * Sum of income journals in period for a set of accounts, grouped per destination + currency. Amounts are always + * positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $revenue - * @param TransactionCurrency|null $currency + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $revenue + * @param TransactionCurrency|null $currency * * @return array */ public function sumIncomeByDestination( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $revenue = null, + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $revenue = null, ?TransactionCurrency $currency = null ): array; /** - * Sum of income journals in period for a set of accounts, grouped per source + currency. Amounts are always positive. + * Sum of income journals in period for a set of accounts, grouped per source + currency. Amounts are always + * positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $revenue - * @param TransactionCurrency|null $currency + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $revenue + * @param TransactionCurrency|null $currency * * @return array */ public function sumIncomeBySource( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $revenue = null, + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $revenue = null, ?TransactionCurrency $currency = null ): array; /** * Sum of transfers in period for a set of accounts, grouped per currency. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param TransactionCurrency|null $currency + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param TransactionCurrency|null $currency * * @return array */ diff --git a/app/Repositories/Administration/Account/AccountRepositoryInterface.php b/app/Repositories/Administration/Account/AccountRepositoryInterface.php index f853ac4ef8..2ef8719212 100644 --- a/app/Repositories/Administration/Account/AccountRepositoryInterface.php +++ b/app/Repositories/Administration/Account/AccountRepositoryInterface.php @@ -31,9 +31,9 @@ use Illuminate\Support\Collection; interface AccountRepositoryInterface { /** - * @param string $query - * @param array $types - * @param int $limit + * @param string $query + * @param array $types + * @param int $limit * * @return Collection */ diff --git a/app/Repositories/Attachment/AttachmentRepository.php b/app/Repositories/Attachment/AttachmentRepository.php index 2bc7c79258..3b65837c20 100644 --- a/app/Repositories/Attachment/AttachmentRepository.php +++ b/app/Repositories/Attachment/AttachmentRepository.php @@ -49,7 +49,7 @@ class AttachmentRepository implements AttachmentRepositoryInterface private $user; /** - * @param Attachment $attachment + * @param Attachment $attachment * * @return bool * @throws Exception @@ -71,28 +71,7 @@ class AttachmentRepository implements AttachmentRepositoryInterface } /** - * @param Attachment $attachment - * - * @return bool - */ - public function exists(Attachment $attachment): bool - { - /** @var Storage $disk */ - $disk = Storage::disk('upload'); - - return $disk->exists($attachment->fileName()); - } - - /** - * @return Collection - */ - public function get(): Collection - { - return $this->user->attachments()->get(); - } - - /** - * @param Attachment $attachment + * @param Attachment $attachment * * @return string */ @@ -116,10 +95,31 @@ class AttachmentRepository implements AttachmentRepositoryInterface return $unencryptedContent; } + /** + * @param Attachment $attachment + * + * @return bool + */ + public function exists(Attachment $attachment): bool + { + /** @var Storage $disk */ + $disk = Storage::disk('upload'); + + return $disk->exists($attachment->fileName()); + } + + /** + * @return Collection + */ + public function get(): Collection + { + return $this->user->attachments()->get(); + } + /** * Get attachment note text or empty string. * - * @param Attachment $attachment + * @param Attachment $attachment * * @return string|null */ @@ -134,17 +134,7 @@ class AttachmentRepository implements AttachmentRepositoryInterface } /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - - /** - * @param array $data + * @param array $data * * @return Attachment * @throws FireflyException @@ -163,8 +153,18 @@ class AttachmentRepository implements AttachmentRepositoryInterface } /** - * @param Attachment $attachment - * @param array $data + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + + /** + * @param Attachment $attachment + * @param array $data * * @return Attachment */ @@ -194,8 +194,8 @@ class AttachmentRepository implements AttachmentRepositoryInterface } /** - * @param Attachment $attachment - * @param string $note + * @param Attachment $attachment + * @param string $note * * @return bool */ diff --git a/app/Repositories/Attachment/AttachmentRepositoryInterface.php b/app/Repositories/Attachment/AttachmentRepositoryInterface.php index 119219a0d1..b3a8b879aa 100644 --- a/app/Repositories/Attachment/AttachmentRepositoryInterface.php +++ b/app/Repositories/Attachment/AttachmentRepositoryInterface.php @@ -35,14 +35,14 @@ use Illuminate\Support\Collection; interface AttachmentRepositoryInterface { /** - * @param Attachment $attachment + * @param Attachment $attachment * * @return bool */ public function destroy(Attachment $attachment): bool; /** - * @param Attachment $attachment + * @param Attachment $attachment * * @return bool */ @@ -54,7 +54,7 @@ interface AttachmentRepositoryInterface public function get(): Collection; /** - * @param Attachment $attachment + * @param Attachment $attachment * * @return string */ @@ -63,19 +63,19 @@ interface AttachmentRepositoryInterface /** * Get attachment note text or empty string. * - * @param Attachment $attachment + * @param Attachment $attachment * * @return string|null */ public function getNoteText(Attachment $attachment): ?string; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** - * @param array $data + * @param array $data * * @return Attachment * @throws FireflyException @@ -83,8 +83,8 @@ interface AttachmentRepositoryInterface public function store(array $data): Attachment; /** - * @param Attachment $attachment - * @param array $attachmentData + * @param Attachment $attachment + * @param array $attachmentData * * @return Attachment */ diff --git a/app/Repositories/AuditLogEntry/ALERepositoryInterface.php b/app/Repositories/AuditLogEntry/ALERepositoryInterface.php index 26117f8457..7221f699ac 100644 --- a/app/Repositories/AuditLogEntry/ALERepositoryInterface.php +++ b/app/Repositories/AuditLogEntry/ALERepositoryInterface.php @@ -34,13 +34,13 @@ use Illuminate\Support\Collection; interface ALERepositoryInterface { /** - * @param Model $model + * @param Model $model * @return Collection */ public function getForObject(Model $model): Collection; /** - * @param array $data + * @param array $data * @return AuditLogEntry */ public function store(array $data): AuditLogEntry; diff --git a/app/Repositories/Bill/BillRepository.php b/app/Repositories/Bill/BillRepository.php index f6d305842f..e1ebd24fe4 100644 --- a/app/Repositories/Bill/BillRepository.php +++ b/app/Repositories/Bill/BillRepository.php @@ -104,7 +104,7 @@ class BillRepository implements BillRepositoryInterface } /** - * @param Bill $bill + * @param Bill $bill * * @return bool * @@ -127,23 +127,11 @@ class BillRepository implements BillRepositoryInterface $this->user->bills()->delete(); } - /** - * Find a bill by ID. - * - * @param int $billId - * - * @return Bill|null - */ - public function find(int $billId): ?Bill - { - return $this->user->bills()->find($billId); - } - /** * Find bill by parameters. * - * @param int|null $billId - * @param string|null $billName + * @param int|null $billId + * @param string|null $billName * * @return Bill|null */ @@ -170,10 +158,22 @@ class BillRepository implements BillRepositoryInterface return null; } + /** + * Find a bill by ID. + * + * @param int $billId + * + * @return Bill|null + */ + public function find(int $billId): ?Bill + { + return $this->user->bills()->find($billId); + } + /** * Find a bill by name. * - * @param string $name + * @param string $name * * @return Bill|null */ @@ -182,21 +182,10 @@ class BillRepository implements BillRepositoryInterface return $this->user->bills()->where('name', $name)->first(['bills.*']); } - /** - * @return Collection - */ - public function getActiveBills(): Collection - { - return $this->user->bills() - ->where('active', true) - ->orderBy('bills.name', 'ASC') - ->get(['bills.*', DB::raw('((bills.amount_min + bills.amount_max) / 2) AS expectedAmount'),]); - } - /** * Get all attachments. * - * @param Bill $bill + * @param Bill $bill * * @return Collection */ @@ -230,7 +219,7 @@ class BillRepository implements BillRepositoryInterface } /** - * @param Collection $accounts + * @param Collection $accounts * * @return Collection */ @@ -278,7 +267,7 @@ class BillRepository implements BillRepositoryInterface /** * Get all bills with these ID's. * - * @param array $billIds + * @param array $billIds * * @return Collection */ @@ -290,7 +279,7 @@ class BillRepository implements BillRepositoryInterface /** * Get text or return empty string. * - * @param Bill $bill + * @param Bill $bill * * @return string */ @@ -306,7 +295,7 @@ class BillRepository implements BillRepositoryInterface } /** - * @param Bill $bill + * @param Bill $bill * * @return array */ @@ -341,7 +330,7 @@ class BillRepository implements BillRepositoryInterface // after loop, re-loop for avg. /** - * @var int $currencyId + * @var int $currencyId * @var array $arr */ foreach ($result as $currencyId => $arr) { @@ -352,7 +341,17 @@ class BillRepository implements BillRepositoryInterface } /** - * @param int $size + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + + /** + * @param int $size * * @return LengthAwarePaginator */ @@ -366,9 +365,9 @@ class BillRepository implements BillRepositoryInterface /** * The "paid dates" list is a list of dates of transaction journals that are linked to this bill. * - * @param Bill $bill - * @param Carbon $start - * @param Carbon $end + * @param Bill $bill + * @param Carbon $start + * @param Carbon $end * * @return Collection */ @@ -386,45 +385,10 @@ class BillRepository implements BillRepositoryInterface ); } - /** - * Between start and end, tells you on which date(s) the bill is expected to hit. - * - * @param Bill $bill - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - */ - public function getPayDatesInRange(Bill $bill, Carbon $start, Carbon $end): Collection - { - $set = new Collection(); - $currentStart = clone $start; - //Log::debug(sprintf('Now at bill "%s" (%s)', $bill->name, $bill->repeat_freq)); - //Log::debug(sprintf('First currentstart is %s', $currentStart->format('Y-m-d'))); - - while ($currentStart <= $end) { - //Log::debug(sprintf('Currentstart is now %s.', $currentStart->format('Y-m-d'))); - $nextExpectedMatch = $this->nextDateMatch($bill, $currentStart); - //Log::debug(sprintf('Next Date match after %s is %s', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d'))); - if ($nextExpectedMatch > $end) {// If nextExpectedMatch is after end, we continue - break; - } - $set->push(clone $nextExpectedMatch); - //Log::debug(sprintf('Now %d dates in set.', $set->count())); - $nextExpectedMatch->addDay(); - - //Log::debug(sprintf('Currentstart (%s) has become %s.', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d'))); - - $currentStart = clone $nextExpectedMatch; - } - - return $set; - } - /** * Return all rules for one bill * - * @param Bill $bill + * @param Bill $bill * * @return Collection */ @@ -443,7 +407,7 @@ class BillRepository implements BillRepositoryInterface * * 5 => [['id' => 1, 'title' => 'Some rule'],['id' => 2, 'title' => 'Some other rule']] * - * @param Collection $collection + * @param Collection $collection * * @return array */ @@ -468,8 +432,8 @@ class BillRepository implements BillRepositoryInterface } /** - * @param Bill $bill - * @param Carbon $date + * @param Bill $bill + * @param Carbon $date * * @return array */ @@ -483,8 +447,8 @@ class BillRepository implements BillRepositoryInterface $result = []; $journals = $bill->transactionJournals() - ->where('date', '>=', $date->year.'-01-01 00:00:00') - ->where('date', '<=', $date->year.'-12-31 23:59:59') + ->where('date', '>=', $date->year . '-01-01 00:00:00') + ->where('date', '<=', $date->year . '-12-31 23:59:59') ->get(); /** @var TransactionJournal $journal */ @@ -511,7 +475,7 @@ class BillRepository implements BillRepositoryInterface // after loop, re-loop for avg. /** - * @var int $currencyId + * @var int $currencyId * @var array $arr */ foreach ($result as $currencyId => $arr) { @@ -524,8 +488,8 @@ class BillRepository implements BillRepositoryInterface /** * Link a set of journals to a bill. * - * @param Bill $bill - * @param array $transactions + * @param Bill $bill + * @param array $transactions */ public function linkCollectionToBill(Bill $bill, array $transactions): void { @@ -538,40 +502,11 @@ class BillRepository implements BillRepositoryInterface } } - /** - * Given a bill and a date, this method will tell you at which moment this bill expects its next - * transaction. Whether or not it is there already, is not relevant. - * - * @param Bill $bill - * @param Carbon $date - * - * @return Carbon - */ - public function nextDateMatch(Bill $bill, Carbon $date): Carbon - { - $cache = new CacheProperties(); - $cache->addProperty($bill->id); - $cache->addProperty('nextDateMatch'); - $cache->addProperty($date); - if ($cache->has()) { - return $cache->get(); - } - // find the most recent date for this bill NOT in the future. Cache this date: - $start = clone $bill->date; - - while ($start < $date) { - $start = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip); - } - $cache->store($start); - - return $start; - } - /** * Given the date in $date, this method will return a moment in the future where the bill is expected to be paid. * - * @param Bill $bill - * @param Carbon $date + * @param Bill $bill + * @param Carbon $date * * @return Carbon * @throws JsonException @@ -587,12 +522,12 @@ class BillRepository implements BillRepositoryInterface } // find the most recent date for this bill NOT in the future. Cache this date: $start = clone $bill->date; - Log::debug('nextExpectedMatch: Start is '.$start->format('Y-m-d')); + Log::debug('nextExpectedMatch: Start is ' . $start->format('Y-m-d')); while ($start < $date) { Log::debug(sprintf('$start (%s) < $date (%s)', $start->format('Y-m-d'), $date->format('Y-m-d'))); $start = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip); - Log::debug('Start is now '.$start->format('Y-m-d')); + Log::debug('Start is now ' . $start->format('Y-m-d')); } $end = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip); @@ -606,14 +541,30 @@ class BillRepository implements BillRepositoryInterface $start = clone $end; $end = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip); } - Log::debug('nextExpectedMatch: Final start is '.$start->format('Y-m-d')); - Log::debug('nextExpectedMatch: Matching end is '.$end->format('Y-m-d')); + Log::debug('nextExpectedMatch: Final start is ' . $start->format('Y-m-d')); + Log::debug('nextExpectedMatch: Matching end is ' . $end->format('Y-m-d')); $cache->store($start); return $start; } + /** + * @param array $data + * + * @return Bill + * @throws FireflyException + * @throws JsonException + */ + public function store(array $data): Bill + { + /** @var BillFactory $factory */ + $factory = app(BillFactory::class); + $factory->setUser($this->user); + + return $factory->create($data); + } + /** * @inheritDoc */ @@ -625,8 +576,8 @@ class BillRepository implements BillRepositoryInterface } /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ @@ -659,32 +610,6 @@ class BillRepository implements BillRepositoryInterface $bill->save(); } - /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - - /** - * @param array $data - * - * @return Bill - * @throws FireflyException - * @throws JsonException - */ - public function store(array $data): Bill - { - /** @var BillFactory $factory */ - $factory = app(BillFactory::class); - $factory->setUser($this->user); - - return $factory->create($data); - } - /** * @inheritDoc */ @@ -724,6 +649,17 @@ class BillRepository implements BillRepositoryInterface return $return; } + /** + * @return Collection + */ + public function getActiveBills(): Collection + { + return $this->user->bills() + ->where('active', true) + ->orderBy('bills.name', 'ASC') + ->get(['bills.*', DB::raw('((bills.amount_min + bills.amount_max) / 2) AS expectedAmount'),]); + } + /** * @inheritDoc */ @@ -756,7 +692,71 @@ class BillRepository implements BillRepositoryInterface } /** - * @param Bill $bill + * Between start and end, tells you on which date(s) the bill is expected to hit. + * + * @param Bill $bill + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function getPayDatesInRange(Bill $bill, Carbon $start, Carbon $end): Collection + { + $set = new Collection(); + $currentStart = clone $start; + //Log::debug(sprintf('Now at bill "%s" (%s)', $bill->name, $bill->repeat_freq)); + //Log::debug(sprintf('First currentstart is %s', $currentStart->format('Y-m-d'))); + + while ($currentStart <= $end) { + //Log::debug(sprintf('Currentstart is now %s.', $currentStart->format('Y-m-d'))); + $nextExpectedMatch = $this->nextDateMatch($bill, $currentStart); + //Log::debug(sprintf('Next Date match after %s is %s', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d'))); + if ($nextExpectedMatch > $end) {// If nextExpectedMatch is after end, we continue + break; + } + $set->push(clone $nextExpectedMatch); + //Log::debug(sprintf('Now %d dates in set.', $set->count())); + $nextExpectedMatch->addDay(); + + //Log::debug(sprintf('Currentstart (%s) has become %s.', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d'))); + + $currentStart = clone $nextExpectedMatch; + } + + return $set; + } + + /** + * Given a bill and a date, this method will tell you at which moment this bill expects its next + * transaction. Whether or not it is there already, is not relevant. + * + * @param Bill $bill + * @param Carbon $date + * + * @return Carbon + */ + public function nextDateMatch(Bill $bill, Carbon $date): Carbon + { + $cache = new CacheProperties(); + $cache->addProperty($bill->id); + $cache->addProperty('nextDateMatch'); + $cache->addProperty($date); + if ($cache->has()) { + return $cache->get(); + } + // find the most recent date for this bill NOT in the future. Cache this date: + $start = clone $bill->date; + + while ($start < $date) { + $start = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip); + } + $cache->store($start); + + return $start; + } + + /** + * @param Bill $bill */ public function unlinkAll(Bill $bill): void { @@ -764,8 +764,8 @@ class BillRepository implements BillRepositoryInterface } /** - * @param Bill $bill - * @param array $data + * @param Bill $bill + * @param array $data * * @return Bill * @throws FireflyException diff --git a/app/Repositories/Bill/BillRepositoryInterface.php b/app/Repositories/Bill/BillRepositoryInterface.php index b9a67e73bd..471a6710b1 100644 --- a/app/Repositories/Bill/BillRepositoryInterface.php +++ b/app/Repositories/Bill/BillRepositoryInterface.php @@ -37,16 +37,16 @@ use Illuminate\Support\Collection; interface BillRepositoryInterface { /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ public function billEndsWith(string $query, int $limit): Collection; /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ @@ -58,7 +58,7 @@ interface BillRepositoryInterface public function correctOrder(): void; /** - * @param Bill $bill + * @param Bill $bill * * @return bool */ @@ -72,7 +72,7 @@ interface BillRepositoryInterface /** * Find a bill by ID. * - * @param int $billId + * @param int $billId * * @return Bill|null */ @@ -81,8 +81,8 @@ interface BillRepositoryInterface /** * Find bill by parameters. * - * @param int|null $billId - * @param string|null $billName + * @param int|null $billId + * @param string|null $billName * * @return Bill|null */ @@ -91,7 +91,7 @@ interface BillRepositoryInterface /** * Find a bill by name. * - * @param string $name + * @param string $name * * @return Bill|null */ @@ -105,7 +105,7 @@ interface BillRepositoryInterface /** * Get all attachments. * - * @param Bill $bill + * @param Bill $bill * * @return Collection */ @@ -119,7 +119,7 @@ interface BillRepositoryInterface /** * Gets the bills which have some kind of relevance to the accounts mentioned. * - * @param Collection $accounts + * @param Collection $accounts * * @return Collection */ @@ -128,7 +128,7 @@ interface BillRepositoryInterface /** * Get all bills with these ID's. * - * @param array $billIds + * @param array $billIds * * @return Collection */ @@ -137,30 +137,30 @@ interface BillRepositoryInterface /** * Get text or return empty string. * - * @param Bill $bill + * @param Bill $bill * * @return string */ public function getNoteText(Bill $bill): string; /** - * @param Bill $bill + * @param Bill $bill * * @return array */ public function getOverallAverage(Bill $bill): array; /** - * @param int $size + * @param int $size * * @return LengthAwarePaginator */ public function getPaginator(int $size): LengthAwarePaginator; /** - * @param Bill $bill - * @param Carbon $start - * @param Carbon $end + * @param Bill $bill + * @param Carbon $start + * @param Carbon $end * * @return Collection */ @@ -169,9 +169,9 @@ interface BillRepositoryInterface /** * Between start and end, tells you on which date(s) the bill is expected to hit. * - * @param Bill $bill - * @param Carbon $start - * @param Carbon $end + * @param Bill $bill + * @param Carbon $start + * @param Carbon $end * * @return Collection */ @@ -180,7 +180,7 @@ interface BillRepositoryInterface /** * Return all rules for one bill * - * @param Bill $bill + * @param Bill $bill * * @return Collection */ @@ -192,15 +192,15 @@ interface BillRepositoryInterface * * 5 => [['id' => 1, 'title' => 'Some rule'],['id' => 2, 'title' => 'Some other rule']] * - * @param Collection $collection + * @param Collection $collection * * @return array */ public function getRulesForBills(Collection $collection): array; /** - * @param Bill $bill - * @param Carbon $date + * @param Bill $bill + * @param Carbon $date * * @return array */ @@ -209,8 +209,8 @@ interface BillRepositoryInterface /** * Link a set of journals to a bill. * - * @param Bill $bill - * @param array $transactions + * @param Bill $bill + * @param array $transactions */ public function linkCollectionToBill(Bill $bill, array $transactions): void; @@ -218,39 +218,39 @@ interface BillRepositoryInterface * Given a bill and a date, this method will tell you at which moment this bill expects its next * transaction. Whether or not it is there already, is not relevant. * - * @param Bill $bill - * @param Carbon $date + * @param Bill $bill + * @param Carbon $date * * @return Carbon */ public function nextDateMatch(Bill $bill, Carbon $date): Carbon; /** - * @param Bill $bill - * @param Carbon $date + * @param Bill $bill + * @param Carbon $date * * @return Carbon */ public function nextExpectedMatch(Bill $bill, Carbon $date): Carbon; /** - * @param Bill $bill + * @param Bill $bill * * @return Bill */ public function removeObjectGroup(Bill $bill): Bill; /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ public function searchBill(string $query, int $limit): Collection; /** - * @param Bill $bill - * @param string $objectGroupTitle + * @param Bill $bill + * @param string $objectGroupTitle * * @return Bill */ @@ -259,18 +259,18 @@ interface BillRepositoryInterface /** * Set specific piggy bank to specific order. * - * @param Bill $bill - * @param int $order + * @param Bill $bill + * @param int $order */ public function setOrder(Bill $bill, int $order): void; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** - * @param array $data + * @param array $data * * @return Bill * @throws FireflyException @@ -280,8 +280,8 @@ interface BillRepositoryInterface /** * Collect multi-currency of sum of bills already paid. * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * @return array */ public function sumPaidInRange(Carbon $start, Carbon $end): array; @@ -289,20 +289,20 @@ interface BillRepositoryInterface /** * Collect multi-currency of sum of bills yet to pay. * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * @return array */ public function sumUnpaidInRange(Carbon $start, Carbon $end): array; /** - * @param Bill $bill + * @param Bill $bill */ public function unlinkAll(Bill $bill): void; /** - * @param Bill $bill - * @param array $data + * @param Bill $bill + * @param array $data * * @return Bill */ diff --git a/app/Repositories/Budget/AvailableBudgetRepository.php b/app/Repositories/Budget/AvailableBudgetRepository.php index 179c9fca87..9553a6f243 100644 --- a/app/Repositories/Budget/AvailableBudgetRepository.php +++ b/app/Repositories/Budget/AvailableBudgetRepository.php @@ -48,19 +48,27 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface } /** - * @param AvailableBudget $availableBudget + * @param AvailableBudget $availableBudget */ public function destroyAvailableBudget(AvailableBudget $availableBudget): void { $availableBudget->delete(); } + /** + * @inheritDoc + */ + public function findById(int $id): ?AvailableBudget + { + return $this->user->availableBudgets->find($id); + } + /** * Find existing AB. * - * @param TransactionCurrency $currency - * @param Carbon $start - * @param Carbon $end + * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end * * @return AvailableBudget|null */ @@ -74,18 +82,51 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface } /** - * @inheritDoc + * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end + * + * @return string */ - public function findById(int $id): ?AvailableBudget + public function getAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end): string { - return $this->user->availableBudgets->find($id); + $amount = '0'; + $availableBudget = $this->user->availableBudgets() + ->where('transaction_currency_id', $currency->id) + ->where('start_date', $start->format('Y-m-d')) + ->where('end_date', $end->format('Y-m-d'))->first(); + if (null !== $availableBudget) { + $amount = (string)$availableBudget->amount; + } + + return $amount; + } + + /** + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function getAvailableBudgetWithCurrency(Carbon $start, Carbon $end): array + { + $return = []; + $availableBudgets = $this->user->availableBudgets() + ->where('start_date', $start->format('Y-m-d')) + ->where('end_date', $end->format('Y-m-d'))->get(); + /** @var AvailableBudget $availableBudget */ + foreach ($availableBudgets as $availableBudget) { + $return[$availableBudget->transaction_currency_id] = $availableBudget->amount; + } + + return $return; } /** * Return a list of all available budgets (in all currencies) (for the selected period). * - * @param Carbon|null $start - * @param Carbon|null $end + * @param Carbon|null $start + * @param Carbon|null $end * * @return Collection */ @@ -104,51 +145,10 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface return $query->get(['available_budgets.*']); } - /** - * @param TransactionCurrency $currency - * @param Carbon $start - * @param Carbon $end - * - * @return string - */ - public function getAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end): string - { - $amount = '0'; - $availableBudget = $this->user->availableBudgets() - ->where('transaction_currency_id', $currency->id) - ->where('start_date', $start->format('Y-m-d')) - ->where('end_date', $end->format('Y-m-d'))->first(); - if (null !== $availableBudget) { - $amount = (string)$availableBudget->amount; - } - - return $amount; - } - - /** - * @param Carbon $start - * @param Carbon $end - * - * @return array - */ - public function getAvailableBudgetWithCurrency(Carbon $start, Carbon $end): array - { - $return = []; - $availableBudgets = $this->user->availableBudgets() - ->where('start_date', $start->format('Y-m-d')) - ->where('end_date', $end->format('Y-m-d'))->get(); - /** @var AvailableBudget $availableBudget */ - foreach ($availableBudgets as $availableBudget) { - $return[$availableBudget->transaction_currency_id] = $availableBudget->amount; - } - - return $return; - } - /** * Returns all available budget objects. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return Collection */ @@ -160,8 +160,8 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface /** * Returns all available budget objects. * - * @param Carbon|null $start - * @param Carbon|null $end + * @param Carbon|null $start + * @param Carbon|null $end * * @return Collection * @@ -193,10 +193,10 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface } /** - * @param TransactionCurrency $currency - * @param Carbon $start - * @param Carbon $end - * @param string $amount + * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end + * @param string $amount * * @return AvailableBudget * @deprecated @@ -221,9 +221,9 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface } /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void + public function setUser(User | Authenticatable | null $user): void { if (null !== $user) { $this->user = $user; @@ -231,7 +231,7 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface } /** - * @param array $data + * @param array $data * * @return AvailableBudget|null */ @@ -259,8 +259,8 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface } /** - * @param AvailableBudget $availableBudget - * @param array $data + * @param AvailableBudget $availableBudget + * @param array $data * * @return AvailableBudget */ @@ -275,8 +275,8 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface } /** - * @param AvailableBudget $availableBudget - * @param array $data + * @param AvailableBudget $availableBudget + * @param array $data * * @return AvailableBudget */ diff --git a/app/Repositories/Budget/AvailableBudgetRepositoryInterface.php b/app/Repositories/Budget/AvailableBudgetRepositoryInterface.php index a8cd88c105..56cd8172e1 100644 --- a/app/Repositories/Budget/AvailableBudgetRepositoryInterface.php +++ b/app/Repositories/Budget/AvailableBudgetRepositoryInterface.php @@ -41,23 +41,23 @@ interface AvailableBudgetRepositoryInterface public function destroyAll(): void; /** - * @param AvailableBudget $availableBudget + * @param AvailableBudget $availableBudget */ public function destroyAvailableBudget(AvailableBudget $availableBudget): void; /** * Find existing AB. * - * @param TransactionCurrency $currency - * @param Carbon $start - * @param Carbon $end + * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end * * @return AvailableBudget|null */ public function find(TransactionCurrency $currency, Carbon $start, Carbon $end): ?AvailableBudget; /** - * @param int $id + * @param int $id * * @return AvailableBudget|null */ @@ -66,17 +66,17 @@ interface AvailableBudgetRepositoryInterface /** * Return a list of all available budgets (in all currencies) (for the selected period). * - * @param Carbon|null $start - * @param Carbon|null $end + * @param Carbon|null $start + * @param Carbon|null $end * * @return Collection */ public function get(?Carbon $start = null, ?Carbon $end = null): Collection; /** - * @param TransactionCurrency $currency - * @param Carbon $start - * @param Carbon $end + * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end * * @return string * @deprecated @@ -84,8 +84,8 @@ interface AvailableBudgetRepositoryInterface public function getAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end): string; /** - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -94,7 +94,7 @@ interface AvailableBudgetRepositoryInterface /** * Returns all available budget objects. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return Collection */ @@ -103,8 +103,8 @@ interface AvailableBudgetRepositoryInterface /** * Returns all available budget objects. * - * @param Carbon|null $start - * @param Carbon|null $end + * @param Carbon|null $start + * @param Carbon|null $end * * @return Collection * @@ -114,19 +114,19 @@ interface AvailableBudgetRepositoryInterface /** * Get by transaction currency and date. Should always result in one entry or NULL. * - * @param Carbon $start - * @param Carbon $end - * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end + * @param TransactionCurrency $currency * * @return null|AvailableBudget */ public function getByCurrencyDate(Carbon $start, Carbon $end, TransactionCurrency $currency): ?AvailableBudget; /** - * @param TransactionCurrency $currency - * @param Carbon $start - * @param Carbon $end - * @param string $amount + * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end + * @param string $amount * * @return AvailableBudget * @deprecated @@ -134,28 +134,28 @@ interface AvailableBudgetRepositoryInterface public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): AvailableBudget; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** - * @param array $data + * @param array $data * * @return AvailableBudget|null */ public function store(array $data): ?AvailableBudget; /** - * @param AvailableBudget $availableBudget - * @param array $data + * @param AvailableBudget $availableBudget + * @param array $data * * @return AvailableBudget */ public function update(AvailableBudget $availableBudget, array $data): AvailableBudget; /** - * @param AvailableBudget $availableBudget - * @param array $data + * @param AvailableBudget $availableBudget + * @param array $data * * @return AvailableBudget */ diff --git a/app/Repositories/Budget/BudgetLimitRepository.php b/app/Repositories/Budget/BudgetLimitRepository.php index f80a99f305..23c41a4c1d 100644 --- a/app/Repositories/Budget/BudgetLimitRepository.php +++ b/app/Repositories/Budget/BudgetLimitRepository.php @@ -48,10 +48,10 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface * Tells you which amount has been budgeted (for the given budgets) * in the selected query. Returns a positive amount as a string. * - * @param Carbon $start - * @param Carbon $end - * @param TransactionCurrency $currency - * @param Collection|null $budgets + * @param Carbon $start + * @param Carbon $end + * @param TransactionCurrency $currency + * @param Collection|null $budgets * * @return string */ @@ -120,7 +120,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface /** * Destroy a budget limit. * - * @param BudgetLimit $budgetLimit + * @param BudgetLimit $budgetLimit */ public function destroyBudgetLimit(BudgetLimit $budgetLimit): void { @@ -128,24 +128,24 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface } /** - * @param Budget $budget - * @param TransactionCurrency $currency - * @param Carbon $start - * @param Carbon $end + * @param TransactionCurrency $currency + * @param Carbon|null $start + * @param Carbon|null $end * - * @return BudgetLimit|null + * @return Collection */ - public function find(Budget $budget, TransactionCurrency $currency, Carbon $start, Carbon $end): ?BudgetLimit + public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, Carbon $start = null, Carbon $end = null): Collection { - return $budget->budgetlimits() - ->where('transaction_currency_id', $currency->id) - ->where('start_date', $start->format('Y-m-d')) - ->where('end_date', $end->format('Y-m-d'))->first(); + return $this->getAllBudgetLimits($start, $end)->filter( + static function (BudgetLimit $budgetLimit) use ($currency) { + return $budgetLimit->transaction_currency_id === $currency->id; + } + ); } /** - * @param Carbon|null $start - * @param Carbon|null $end + * @param Carbon|null $start + * @param Carbon|null $end * * @return Collection */ @@ -212,25 +212,9 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface } /** - * @param TransactionCurrency $currency - * @param Carbon|null $start - * @param Carbon|null $end - * - * @return Collection - */ - public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, Carbon $start = null, Carbon $end = null): Collection - { - return $this->getAllBudgetLimits($start, $end)->filter( - static function (BudgetLimit $budgetLimit) use ($currency) { - return $budgetLimit->transaction_currency_id === $currency->id; - } - ); - } - - /** - * @param Budget $budget - * @param Carbon|null $start - * @param Carbon|null $end + * @param Budget $budget + * @param Carbon|null $start + * @param Carbon|null $end * * @return Collection */ @@ -288,9 +272,9 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface } /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void + public function setUser(User | Authenticatable | null $user): void { if (null !== $user) { $this->user = $user; @@ -298,7 +282,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface } /** - * @param array $data + * @param array $data * * @return BudgetLimit * @throws FireflyException @@ -347,8 +331,24 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface } /** - * @param BudgetLimit $budgetLimit - * @param array $data + * @param Budget $budget + * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end + * + * @return BudgetLimit|null + */ + public function find(Budget $budget, TransactionCurrency $currency, Carbon $start, Carbon $end): ?BudgetLimit + { + return $budget->budgetlimits() + ->where('transaction_currency_id', $currency->id) + ->where('start_date', $start->format('Y-m-d')) + ->where('end_date', $end->format('Y-m-d'))->first(); + } + + /** + * @param BudgetLimit $budgetLimit + * @param array $data * * @return BudgetLimit * @throws FireflyException @@ -384,10 +384,10 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface } /** - * @param Budget $budget - * @param Carbon $start - * @param Carbon $end - * @param string $amount + * @param Budget $budget + * @param Carbon $start + * @param Carbon $end + * @param string $amount * * @return BudgetLimit|null * diff --git a/app/Repositories/Budget/BudgetLimitRepositoryInterface.php b/app/Repositories/Budget/BudgetLimitRepositoryInterface.php index 0c21bbdb09..7ddd85cadf 100644 --- a/app/Repositories/Budget/BudgetLimitRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetLimitRepositoryInterface.php @@ -40,10 +40,10 @@ interface BudgetLimitRepositoryInterface * Tells you which amount has been budgeted (for the given budgets) * in the selected query. Returns a positive amount as a string. * - * @param Carbon $start - * @param Carbon $end - * @param TransactionCurrency $currency - * @param Collection|null $budgets + * @param Carbon $start + * @param Carbon $end + * @param TransactionCurrency $currency + * @param Collection|null $budgets * * @return string */ @@ -57,15 +57,15 @@ interface BudgetLimitRepositoryInterface /** * Destroy a budget limit. * - * @param BudgetLimit $budgetLimit + * @param BudgetLimit $budgetLimit */ public function destroyBudgetLimit(BudgetLimit $budgetLimit): void; /** - * @param Budget $budget - * @param TransactionCurrency $currency - * @param Carbon $start - * @param Carbon $end + * @param Budget $budget + * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end * * @return BudgetLimit|null */ @@ -74,56 +74,56 @@ interface BudgetLimitRepositoryInterface /** * TODO this method is not multi currency aware. * - * @param Carbon|null $start - * @param Carbon|null $end + * @param Carbon|null $start + * @param Carbon|null $end * * @return Collection */ public function getAllBudgetLimits(Carbon $start = null, Carbon $end = null): Collection; /** - * @param TransactionCurrency $currency - * @param Carbon|null $start - * @param Carbon|null $end + * @param TransactionCurrency $currency + * @param Carbon|null $start + * @param Carbon|null $end * * @return Collection */ public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, Carbon $start = null, Carbon $end = null): Collection; /** - * @param Budget $budget - * @param Carbon|null $start - * @param Carbon|null $end + * @param Budget $budget + * @param Carbon|null $start + * @param Carbon|null $end * * @return Collection */ public function getBudgetLimits(Budget $budget, Carbon $start = null, Carbon $end = null): Collection; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** - * @param array $data + * @param array $data * * @return BudgetLimit */ public function store(array $data): BudgetLimit; /** - * @param BudgetLimit $budgetLimit - * @param array $data + * @param BudgetLimit $budgetLimit + * @param array $data * * @return BudgetLimit */ public function update(BudgetLimit $budgetLimit, array $data): BudgetLimit; /** - * @param Budget $budget - * @param Carbon $start - * @param Carbon $end - * @param string $amount + * @param Budget $budget + * @param Carbon $start + * @param Carbon $end + * @param string $amount * * @return BudgetLimit|null */ diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index 7f55513f71..8be55d8617 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -144,6 +144,65 @@ class BudgetRepository implements BudgetRepositoryInterface return $return; } + /** + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + + /** + * @return Collection + */ + public function getActiveBudgets(): Collection + { + return $this->user->budgets()->where('active', true) + ->orderBy('order', 'ASC') + ->orderBy('name', 'ASC') + ->get(); + } + + /** + * How many days of this budget limit are between start and end? + * + * @param BudgetLimit $limit + * @param Carbon $start + * @param Carbon $end + * @return int + */ + private function daysInOverlap(BudgetLimit $limit, Carbon $start, Carbon $end): int + { + // start1 = $start + // start2 = $limit->start_date + // start1 = $end + // start2 = $limit->end_date + + // limit is larger than start and end (inclusive) + // |-----------| + // |----------------| + if ($start->gte($limit->start_date) && $end->lte($limit->end_date)) { + return $start->diffInDays($end) + 1; // add one day + } + // limit starts earlier and limit ends first: + // |-----------| + // |-------| + if ($limit->start_date->lte($start) && $limit->end_date->lte($end)) { + // return days in the range $start-$limit_end + return $start->diffInDays($limit->end_date) + 1; // add one day, the day itself + } + // limit starts later and limit ends earlier + // |-----------| + // |-------| + if ($limit->start_date->gte($start) && $limit->end_date->gte($end)) { + // return days in the range $limit_start - $end + return $limit->start_date->diffInDays($end) + 1; // add one day, the day itself + } + return 0; + } + /** * @inheritDoc */ @@ -208,7 +267,7 @@ class BudgetRepository implements BudgetRepositoryInterface BudgetLimit::where('amount', 0)->delete(); $budgets = $this->getActiveBudgets(); /** - * @var int $index + * @var int $index * @var Budget $budget */ foreach ($budgets as $index => $budget) { @@ -222,7 +281,191 @@ class BudgetRepository implements BudgetRepositoryInterface } /** - * @param Budget $budget + * @param Budget $budget + * @param array $data + * + * @return Budget + * @throws FireflyException + * @throws JsonException + */ + public function update(Budget $budget, array $data): Budget + { + Log::debug('Now in update()'); + + $oldName = $budget->name; + if (array_key_exists('name', $data)) { + $budget->name = $data['name']; + $this->updateRuleActions($oldName, $budget->name); + $this->updateRuleTriggers($oldName, $budget->name); + } + if (array_key_exists('active', $data)) { + $budget->active = $data['active']; + } + if (array_key_exists('notes', $data)) { + $this->setNoteText($budget, (string)$data['notes']); + } + $budget->save(); + + // update or create auto-budget: + $autoBudget = $this->getAutoBudget($budget); + + // first things first: delete when no longer required: + $autoBudgetType = array_key_exists('auto_budget_type', $data) ? $data['auto_budget_type'] : null; + + if (0 === $autoBudgetType && null !== $autoBudget) { + // delete! + $autoBudget->delete(); + + return $budget; + } + if (0 === $autoBudgetType && null === $autoBudget) { + return $budget; + } + if (null === $autoBudgetType && null === $autoBudget) { + return $budget; + } + $this->updateAutoBudget($budget, $data); + + return $budget; + } + + /** + * @param string $oldName + * @param string $newName + */ + private function updateRuleActions(string $oldName, string $newName): void + { + $types = ['set_budget',]; + $actions = RuleAction::leftJoin('rules', 'rules.id', '=', 'rule_actions.rule_id') + ->where('rules.user_id', $this->user->id) + ->whereIn('rule_actions.action_type', $types) + ->where('rule_actions.action_value', $oldName) + ->get(['rule_actions.*']); + Log::debug(sprintf('Found %d actions to update.', $actions->count())); + /** @var RuleAction $action */ + foreach ($actions as $action) { + $action->action_value = $newName; + $action->save(); + Log::debug(sprintf('Updated action %d: %s', $action->id, $action->action_value)); + } + } + + /** + * @param string $oldName + * @param string $newName + */ + private function updateRuleTriggers(string $oldName, string $newName): void + { + $types = ['budget_is',]; + $triggers = RuleTrigger::leftJoin('rules', 'rules.id', '=', 'rule_triggers.rule_id') + ->where('rules.user_id', $this->user->id) + ->whereIn('rule_triggers.trigger_type', $types) + ->where('rule_triggers.trigger_value', $oldName) + ->get(['rule_triggers.*']); + Log::debug(sprintf('Found %d triggers to update.', $triggers->count())); + /** @var RuleTrigger $trigger */ + foreach ($triggers as $trigger) { + $trigger->trigger_value = $newName; + $trigger->save(); + Log::debug(sprintf('Updated trigger %d: %s', $trigger->id, $trigger->trigger_value)); + } + } + + /** + * @param Budget $budget + * @param string $text + * @return void + */ + private function setNoteText(Budget $budget, string $text): void + { + $dbNote = $budget->notes()->first(); + if ('' !== $text) { + if (null === $dbNote) { + $dbNote = new Note(); + $dbNote->noteable()->associate($budget); + } + $dbNote->text = trim($text); + $dbNote->save(); + + return; + } + if (null !== $dbNote) { + $dbNote->delete(); + } + } + + /** + * @inheritDoc + */ + public function getAutoBudget(Budget $budget): ?AutoBudget + { + return $budget->autoBudgets()->first(); + } + + /** + * @param Budget $budget + * @param array $data + * @throws FireflyException + * @throws JsonException + */ + private function updateAutoBudget(Budget $budget, array $data): void + { + // update or create auto-budget: + $autoBudget = $this->getAutoBudget($budget); + + // grab default currency: + $currency = app('amount')->getDefaultCurrencyByUser($this->user); + + if (null === $autoBudget) { + // at this point it's a blind assumption auto_budget_type is 1 or 2. + $autoBudget = new AutoBudget(); + $autoBudget->auto_budget_type = $data['auto_budget_type']; + $autoBudget->budget_id = $budget->id; + $autoBudget->transaction_currency_id = $currency->id; + } + + // set or update the currency. + if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) { + $repos = app(CurrencyRepositoryInterface::class); + $currencyId = (int)($data['currency_id'] ?? 0); + $currencyCode = (string)($data['currency_code'] ?? ''); + $currency = $repos->find($currencyId); + if (null === $currency) { + $currency = $repos->findByCodeNull($currencyCode); + } + if (null !== $currency) { + $autoBudget->transaction_currency_id = $currency->id; + } + } + + // change values if submitted or presented: + if (array_key_exists('auto_budget_type', $data)) { + $autoBudget->auto_budget_type = $data['auto_budget_type']; + } + if (array_key_exists('auto_budget_amount', $data)) { + $autoBudget->amount = $data['auto_budget_amount']; + } + if (array_key_exists('auto_budget_period', $data)) { + $autoBudget->period = $data['auto_budget_period']; + } + + $autoBudget->save(); + } + + /** + * Find a budget or return NULL + * + * @param int|null $budgetId |null + * + * @return Budget|null + */ + public function find(int $budgetId = null): ?Budget + { + return $this->user->budgets()->find($budgetId); + } + + /** + * @param Budget $budget * * @return bool */ @@ -251,6 +494,15 @@ class BudgetRepository implements BudgetRepositoryInterface } } + /** + * @return Collection + */ + public function getBudgets(): Collection + { + return $this->user->budgets()->orderBy('order', 'ASC') + ->orderBy('name', 'ASC')->get(); + } + /** * @inheritDoc */ @@ -263,20 +515,8 @@ class BudgetRepository implements BudgetRepositoryInterface } /** - * Find a budget or return NULL - * - * @param int|null $budgetId |null - * - * @return Budget|null - */ - public function find(int $budgetId = null): ?Budget - { - return $this->user->budgets()->find($budgetId); - } - - /** - * @param int|null $budgetId - * @param string|null $budgetName + * @param int|null $budgetId + * @param string|null $budgetName * * @return Budget|null */ @@ -300,7 +540,7 @@ class BudgetRepository implements BudgetRepositoryInterface /** * Find budget by name. * - * @param string|null $name + * @param string|null $name * * @return Budget|null */ @@ -318,7 +558,7 @@ class BudgetRepository implements BudgetRepositoryInterface * This method returns the oldest journal or transaction date known to this budget. * Will cache result. * - * @param Budget $budget + * @param Budget $budget * * @return Carbon|null */ @@ -332,17 +572,6 @@ class BudgetRepository implements BudgetRepositoryInterface return null; } - /** - * @return Collection - */ - public function getActiveBudgets(): Collection - { - return $this->user->budgets()->where('active', true) - ->orderBy('order', 'ASC') - ->orderBy('name', 'ASC') - ->get(); - } - /** * @inheritDoc */ @@ -364,27 +593,10 @@ class BudgetRepository implements BudgetRepositoryInterface ); } - /** - * @inheritDoc - */ - public function getAutoBudget(Budget $budget): ?AutoBudget - { - return $budget->autoBudgets()->first(); - } - - /** - * @return Collection - */ - public function getBudgets(): Collection - { - return $this->user->budgets()->orderBy('order', 'ASC') - ->orderBy('name', 'ASC')->get(); - } - /** * Get all budgets with these ID's. * - * @param array $budgetIds + * @param array $budgetIds * * @return Collection */ @@ -403,11 +615,6 @@ class BudgetRepository implements BudgetRepositoryInterface ->orderBy('name', 'ASC')->where('active', 0)->get(); } - public function getMaxOrder(): int - { - return (int)$this->user->budgets()->max('order'); - } - /** * @inheritDoc */ @@ -422,8 +629,8 @@ class BudgetRepository implements BudgetRepositoryInterface } /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ @@ -440,8 +647,8 @@ class BudgetRepository implements BudgetRepositoryInterface } /** - * @param Budget $budget - * @param int $order + * @param Budget $budget + * @param int $order */ public function setBudgetOrder(Budget $budget, int $order): void { @@ -449,16 +656,6 @@ class BudgetRepository implements BudgetRepositoryInterface $budget->save(); } - /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - /** * @inheritDoc */ @@ -586,7 +783,7 @@ class BudgetRepository implements BudgetRepositoryInterface } /** - * @param array $data + * @param array $data * * @return Budget * @throws FireflyException @@ -676,205 +873,8 @@ class BudgetRepository implements BudgetRepositoryInterface return $newBudget; } - /** - * @param Budget $budget - * @param array $data - * - * @return Budget - * @throws FireflyException - * @throws JsonException - */ - public function update(Budget $budget, array $data): Budget + public function getMaxOrder(): int { - Log::debug('Now in update()'); - - $oldName = $budget->name; - if (array_key_exists('name', $data)) { - $budget->name = $data['name']; - $this->updateRuleActions($oldName, $budget->name); - $this->updateRuleTriggers($oldName, $budget->name); - } - if (array_key_exists('active', $data)) { - $budget->active = $data['active']; - } - if (array_key_exists('notes', $data)) { - $this->setNoteText($budget, (string)$data['notes']); - } - $budget->save(); - - // update or create auto-budget: - $autoBudget = $this->getAutoBudget($budget); - - // first things first: delete when no longer required: - $autoBudgetType = array_key_exists('auto_budget_type', $data) ? $data['auto_budget_type'] : null; - - if (0 === $autoBudgetType && null !== $autoBudget) { - // delete! - $autoBudget->delete(); - - return $budget; - } - if (0 === $autoBudgetType && null === $autoBudget) { - return $budget; - } - if (null === $autoBudgetType && null === $autoBudget) { - return $budget; - } - $this->updateAutoBudget($budget, $data); - - return $budget; - } - - /** - * How many days of this budget limit are between start and end? - * - * @param BudgetLimit $limit - * @param Carbon $start - * @param Carbon $end - * @return int - */ - private function daysInOverlap(BudgetLimit $limit, Carbon $start, Carbon $end): int - { - // start1 = $start - // start2 = $limit->start_date - // start1 = $end - // start2 = $limit->end_date - - // limit is larger than start and end (inclusive) - // |-----------| - // |----------------| - if ($start->gte($limit->start_date) && $end->lte($limit->end_date)) { - return $start->diffInDays($end) + 1; // add one day - } - // limit starts earlier and limit ends first: - // |-----------| - // |-------| - if ($limit->start_date->lte($start) && $limit->end_date->lte($end)) { - // return days in the range $start-$limit_end - return $start->diffInDays($limit->end_date) + 1; // add one day, the day itself - } - // limit starts later and limit ends earlier - // |-----------| - // |-------| - if ($limit->start_date->gte($start) && $limit->end_date->gte($end)) { - // return days in the range $limit_start - $end - return $limit->start_date->diffInDays($end) + 1; // add one day, the day itself - } - return 0; - } - - /** - * @param Budget $budget - * @param string $text - * @return void - */ - private function setNoteText(Budget $budget, string $text): void - { - $dbNote = $budget->notes()->first(); - if ('' !== $text) { - if (null === $dbNote) { - $dbNote = new Note(); - $dbNote->noteable()->associate($budget); - } - $dbNote->text = trim($text); - $dbNote->save(); - - return; - } - if (null !== $dbNote) { - $dbNote->delete(); - } - } - - /** - * @param Budget $budget - * @param array $data - * @throws FireflyException - * @throws JsonException - */ - private function updateAutoBudget(Budget $budget, array $data): void - { - // update or create auto-budget: - $autoBudget = $this->getAutoBudget($budget); - - // grab default currency: - $currency = app('amount')->getDefaultCurrencyByUser($this->user); - - if (null === $autoBudget) { - // at this point it's a blind assumption auto_budget_type is 1 or 2. - $autoBudget = new AutoBudget(); - $autoBudget->auto_budget_type = $data['auto_budget_type']; - $autoBudget->budget_id = $budget->id; - $autoBudget->transaction_currency_id = $currency->id; - } - - // set or update the currency. - if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) { - $repos = app(CurrencyRepositoryInterface::class); - $currencyId = (int)($data['currency_id'] ?? 0); - $currencyCode = (string)($data['currency_code'] ?? ''); - $currency = $repos->find($currencyId); - if (null === $currency) { - $currency = $repos->findByCodeNull($currencyCode); - } - if (null !== $currency) { - $autoBudget->transaction_currency_id = $currency->id; - } - } - - // change values if submitted or presented: - if (array_key_exists('auto_budget_type', $data)) { - $autoBudget->auto_budget_type = $data['auto_budget_type']; - } - if (array_key_exists('auto_budget_amount', $data)) { - $autoBudget->amount = $data['auto_budget_amount']; - } - if (array_key_exists('auto_budget_period', $data)) { - $autoBudget->period = $data['auto_budget_period']; - } - - $autoBudget->save(); - } - - /** - * @param string $oldName - * @param string $newName - */ - private function updateRuleActions(string $oldName, string $newName): void - { - $types = ['set_budget',]; - $actions = RuleAction::leftJoin('rules', 'rules.id', '=', 'rule_actions.rule_id') - ->where('rules.user_id', $this->user->id) - ->whereIn('rule_actions.action_type', $types) - ->where('rule_actions.action_value', $oldName) - ->get(['rule_actions.*']); - Log::debug(sprintf('Found %d actions to update.', $actions->count())); - /** @var RuleAction $action */ - foreach ($actions as $action) { - $action->action_value = $newName; - $action->save(); - Log::debug(sprintf('Updated action %d: %s', $action->id, $action->action_value)); - } - } - - /** - * @param string $oldName - * @param string $newName - */ - private function updateRuleTriggers(string $oldName, string $newName): void - { - $types = ['budget_is',]; - $triggers = RuleTrigger::leftJoin('rules', 'rules.id', '=', 'rule_triggers.rule_id') - ->where('rules.user_id', $this->user->id) - ->whereIn('rule_triggers.trigger_type', $types) - ->where('rule_triggers.trigger_value', $oldName) - ->get(['rule_triggers.*']); - Log::debug(sprintf('Found %d triggers to update.', $triggers->count())); - /** @var RuleTrigger $trigger */ - foreach ($triggers as $trigger) { - $trigger->trigger_value = $newName; - $trigger->save(); - Log::debug(sprintf('Updated trigger %d: %s', $trigger->id, $trigger->trigger_value)); - } + return (int)$this->user->budgets()->max('order'); } } diff --git a/app/Repositories/Budget/BudgetRepositoryInterface.php b/app/Repositories/Budget/BudgetRepositoryInterface.php index b8766620b6..a372953416 100644 --- a/app/Repositories/Budget/BudgetRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetRepositoryInterface.php @@ -37,16 +37,16 @@ use Illuminate\Support\Collection; interface BudgetRepositoryInterface { /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ public function budgetEndsWith(string $query, int $limit): Collection; /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ @@ -55,8 +55,8 @@ interface BudgetRepositoryInterface /** * Returns the amount that is budgeted in a period. * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * @return array */ public function budgetedInPeriod(Carbon $start, Carbon $end): array; @@ -64,9 +64,9 @@ interface BudgetRepositoryInterface /** * Returns the amount that is budgeted in a period. * - * @param Budget $budget - * @param Carbon $start - * @param Carbon $end + * @param Budget $budget + * @param Carbon $start + * @param Carbon $end * @return array */ public function budgetedInPeriodForBudget(Budget $budget, Carbon $start, Carbon $end): array; @@ -77,7 +77,7 @@ interface BudgetRepositoryInterface public function cleanupBudgets(): bool; /** - * @param Budget $budget + * @param Budget $budget * * @return bool */ @@ -89,21 +89,21 @@ interface BudgetRepositoryInterface public function destroyAll(): void; /** - * @param Budget $budget + * @param Budget $budget */ public function destroyAutoBudget(Budget $budget): void; /** * - * @param int|null $budgetId + * @param int|null $budgetId * * @return Budget|null */ public function find(int $budgetId = null): ?Budget; /** - * @param int|null $budgetId - * @param string|null $budgetName + * @param int|null $budgetId + * @param string|null $budgetName * * @return Budget|null */ @@ -112,7 +112,7 @@ interface BudgetRepositoryInterface /** * Find budget by name. * - * @param string|null $name + * @param string|null $name * * @return Budget|null */ @@ -122,7 +122,7 @@ interface BudgetRepositoryInterface * This method returns the oldest journal or transaction date known to this budget. * Will cache result. * - * @param Budget $budget + * @param Budget $budget * * @return Carbon|null */ @@ -134,14 +134,14 @@ interface BudgetRepositoryInterface public function getActiveBudgets(): Collection; /** - * @param Budget $budget + * @param Budget $budget * * @return Collection */ public function getAttachments(Budget $budget): Collection; /** - * @param Budget $budget + * @param Budget $budget * * @return AutoBudget|null */ @@ -155,7 +155,7 @@ interface BudgetRepositoryInterface /** * Get all budgets with these ID's. * - * @param array $budgetIds + * @param array $budgetIds * * @return Collection */ @@ -172,35 +172,35 @@ interface BudgetRepositoryInterface public function getMaxOrder(): int; /** - * @param Budget $budget + * @param Budget $budget * @return string|null */ public function getNoteText(Budget $budget): ?string; /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ public function searchBudget(string $query, int $limit): Collection; /** - * @param Budget $budget - * @param int $order + * @param Budget $budget + * @param int $order */ public function setBudgetOrder(Budget $budget, int $order): void; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** * Used in the v2 API to calculate the amount of money spent in all active budgets. * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -214,7 +214,7 @@ interface BudgetRepositoryInterface public function spentInPeriodForBudget(Budget $budget, Carbon $start, Carbon $end): array; /** - * @param array $data + * @param array $data * * @return Budget * @throws FireflyException @@ -222,8 +222,8 @@ interface BudgetRepositoryInterface public function store(array $data): Budget; /** - * @param Budget $budget - * @param array $data + * @param Budget $budget + * @param array $data * * @return Budget */ diff --git a/app/Repositories/Budget/NoBudgetRepository.php b/app/Repositories/Budget/NoBudgetRepository.php index 96f99746fd..037a3c3a08 100644 --- a/app/Repositories/Budget/NoBudgetRepository.php +++ b/app/Repositories/Budget/NoBudgetRepository.php @@ -41,9 +41,9 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface private $user; /** - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -87,19 +87,9 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface } /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - - /** - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return array * @deprecated @@ -148,14 +138,24 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface return $return; } + /** + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + /** * TODO this method does not include multi currency. It just counts. * TODO this probably also applies to the other "sumExpenses" methods. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param TransactionCurrency|null $currency + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param TransactionCurrency|null $currency * * @return array */ diff --git a/app/Repositories/Budget/NoBudgetRepositoryInterface.php b/app/Repositories/Budget/NoBudgetRepositoryInterface.php index 0ee20f50ef..579d37eec2 100644 --- a/app/Repositories/Budget/NoBudgetRepositoryInterface.php +++ b/app/Repositories/Budget/NoBudgetRepositoryInterface.php @@ -35,9 +35,9 @@ use Illuminate\Support\Collection; interface NoBudgetRepositoryInterface { /** - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return array * @deprecated @@ -45,14 +45,14 @@ interface NoBudgetRepositoryInterface public function getNoBudgetPeriodReport(Collection $accounts, Carbon $start, Carbon $end): array; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return array * @deprecated @@ -60,10 +60,10 @@ interface NoBudgetRepositoryInterface public function spentInPeriodWoBudgetMc(Collection $accounts, Carbon $start, Carbon $end): array; /** - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param TransactionCurrency|null $currency + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param TransactionCurrency|null $currency * * @return array */ diff --git a/app/Repositories/Budget/OperationsRepository.php b/app/Repositories/Budget/OperationsRepository.php index 12c2080081..30a1bc2d3c 100644 --- a/app/Repositories/Budget/OperationsRepository.php +++ b/app/Repositories/Budget/OperationsRepository.php @@ -47,7 +47,7 @@ class OperationsRepository implements OperationsRepositoryInterface * A method that returns the amount of money budgeted per day for this budget, * on average. * - * @param Budget $budget + * @param Budget $budget * * @return string */ @@ -78,10 +78,10 @@ class OperationsRepository implements OperationsRepositoryInterface * This method is being used to generate the budget overview in the year/multi-year report. Its used * in both the year/multi-year budget overview AND in the accompanying chart. * - * @param Collection $budgets - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $budgets + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return array * @deprecated @@ -129,10 +129,10 @@ class OperationsRepository implements OperationsRepositoryInterface * which have the specified budget set to them. It's grouped per currency, with as few details in the array * as possible. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $budgets + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $budgets * * @return array */ @@ -201,9 +201,9 @@ class OperationsRepository implements OperationsRepositoryInterface } /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void + public function setUser(User | Authenticatable | null $user): void { if (null !== $user) { $this->user = $user; @@ -211,10 +211,21 @@ class OperationsRepository implements OperationsRepositoryInterface } /** - * @param Collection $budgets - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @return Collection + */ + private function getBudgets(): Collection + { + /** @var BudgetRepositoryInterface $repos */ + $repos = app(BudgetRepositoryInterface::class); + + return $repos->getActiveBudgets(); + } + + /** + * @param Collection $budgets + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return array * @deprecated @@ -272,19 +283,19 @@ class OperationsRepository implements OperationsRepositoryInterface } /** - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $budgets - * @param TransactionCurrency|null $currency + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $budgets + * @param TransactionCurrency|null $currency * @return array * @deprecated */ public function sumExpenses( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $budgets = null, + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $budgets = null, ?TransactionCurrency $currency = null ): array { //Log::debug(sprintf('Now in %s', __METHOD__)); @@ -379,9 +390,9 @@ class OperationsRepository implements OperationsRepositoryInterface * For now, simply refer to whichever repository holds this function. * TODO perhaps better in the future. * - * @param Budget $budget - * @param Carbon|null $start - * @param Carbon|null $end + * @param Budget $budget + * @param Carbon|null $start + * @param Carbon|null $end * * @return Collection */ @@ -392,15 +403,4 @@ class OperationsRepository implements OperationsRepositoryInterface return $blRepository->getBudgetLimits($budget, $start, $end); } - - /** - * @return Collection - */ - private function getBudgets(): Collection - { - /** @var BudgetRepositoryInterface $repos */ - $repos = app(BudgetRepositoryInterface::class); - - return $repos->getActiveBudgets(); - } } diff --git a/app/Repositories/Budget/OperationsRepositoryInterface.php b/app/Repositories/Budget/OperationsRepositoryInterface.php index 2771c548dc..1e2ab042f8 100644 --- a/app/Repositories/Budget/OperationsRepositoryInterface.php +++ b/app/Repositories/Budget/OperationsRepositoryInterface.php @@ -39,17 +39,17 @@ interface OperationsRepositoryInterface * A method that returns the amount of money budgeted per day for this budget, * on average. * - * @param Budget $budget + * @param Budget $budget * * @return string */ public function budgetedPerDay(Budget $budget): string; /** - * @param Collection $budgets - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $budgets + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return array * @deprecated @@ -61,28 +61,28 @@ interface OperationsRepositoryInterface * which have the specified budget set to them. It's grouped per currency, with as few details in the array * as possible. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $budgets + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $budgets * * @return array */ public function listExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $budgets = null): array; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** * Return multi-currency spent information. * - * @param Collection $budgets - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $budgets + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return array * @deprecated @@ -91,20 +91,21 @@ interface OperationsRepositoryInterface /** * TODO this method was marked as deprecated but I'm not sure why. - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $budgets - * @param TransactionCurrency|null $currency + * + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $budgets + * @param TransactionCurrency|null $currency * * @return array * */ public function sumExpenses( - Carbon $start, - Carbon $end, - ?Collection $accounts = null, - ?Collection $budgets = null, + Carbon $start, + Carbon $end, + ?Collection $accounts = null, + ?Collection $budgets = null, ?TransactionCurrency $currency = null ): array; } diff --git a/app/Repositories/Category/CategoryRepository.php b/app/Repositories/Category/CategoryRepository.php index 3e46a18f9d..d922fe3658 100644 --- a/app/Repositories/Category/CategoryRepository.php +++ b/app/Repositories/Category/CategoryRepository.php @@ -75,7 +75,7 @@ class CategoryRepository implements CategoryRepositoryInterface } /** - * @param Category $category + * @param Category $category * * @return bool * @@ -107,32 +107,18 @@ class CategoryRepository implements CategoryRepositoryInterface } /** - * Find a category or return NULL + * Returns a list of all the categories belonging to a user. * - * @param int $categoryId - * - * @return Category|null + * @return Collection */ - public function find(int $categoryId): ?Category + public function getCategories(): Collection { - return $this->user->categories()->find($categoryId); + return $this->user->categories()->with(['attachments'])->orderBy('name', 'ASC')->get(); } /** - * Find a category. - * - * @param string $name - * - * @return Category|null - */ - public function findByName(string $name): ?Category - { - return $this->user->categories()->where('name', $name)->first(['categories.*']); - } - - /** - * @param int|null $categoryId - * @param string|null $categoryName + * @param int|null $categoryId + * @param string|null $categoryName * * @return Category|null * @throws FireflyException @@ -159,154 +145,31 @@ class CategoryRepository implements CategoryRepositoryInterface } /** - * @param Category $category + * Find a category or return NULL * - * @return Carbon|null + * @param int $categoryId * + * @return Category|null */ - public function firstUseDate(Category $category): ?Carbon + public function find(int $categoryId): ?Category { - $firstJournalDate = $this->getFirstJournalDate($category); - $firstTransactionDate = $this->getFirstTransactionDate($category); - - if (null === $firstTransactionDate && null === $firstJournalDate) { - return null; - } - if (null === $firstTransactionDate) { - return $firstJournalDate; - } - if (null === $firstJournalDate) { - return $firstTransactionDate; - } - - if ($firstTransactionDate < $firstJournalDate) { - return $firstTransactionDate; - } - - return $firstJournalDate; + return $this->user->categories()->find($categoryId); } /** - * @inheritDoc - */ - public function getAttachments(Category $category): Collection - { - $set = $category->attachments()->get(); - - /** @var Storage $disk */ - $disk = Storage::disk('upload'); - - return $set->each( - static function (Attachment $attachment) use ($disk) { - $notes = $attachment->notes()->first(); - $attachment->file_exists = $disk->exists($attachment->fileName()); - $attachment->notes = $notes ? $notes->text : ''; - - return $attachment; - } - ); - } - - /** - * Get all categories with ID's. + * Find a category. * - * @param array $categoryIds + * @param string $name * - * @return Collection + * @return Category|null */ - public function getByIds(array $categoryIds): Collection + public function findByName(string $name): ?Category { - return $this->user->categories()->whereIn('id', $categoryIds)->get(); + return $this->user->categories()->where('name', $name)->first(['categories.*']); } /** - * Returns a list of all the categories belonging to a user. - * - * @return Collection - */ - public function getCategories(): Collection - { - return $this->user->categories()->with(['attachments'])->orderBy('name', 'ASC')->get(); - } - - /** - * @inheritDoc - */ - public function getNoteText(Category $category): ?string - { - $dbNote = $category->notes()->first(); - if (null === $dbNote) { - return null; - } - - return $dbNote->text; - } - - /** - * @param Category $category - * @param Collection $accounts - * - * @return Carbon|null - * @throws Exception - */ - public function lastUseDate(Category $category, Collection $accounts): ?Carbon - { - $lastJournalDate = $this->getLastJournalDate($category, $accounts); - $lastTransactionDate = $this->getLastTransactionDate($category, $accounts); - - if (null === $lastTransactionDate && null === $lastJournalDate) { - return null; - } - if (null === $lastTransactionDate) { - return $lastJournalDate; - } - if (null === $lastJournalDate) { - return $lastTransactionDate; - } - - if ($lastTransactionDate > $lastJournalDate) { - return $lastTransactionDate; - } - - return $lastJournalDate; - } - - /** - * @param Category $category - */ - public function removeNotes(Category $category): void - { - $category->notes()->delete(); - } - - /** - * @param string $query - * @param int $limit - * - * @return Collection - */ - public function searchCategory(string $query, int $limit): Collection - { - $search = $this->user->categories(); - if ('' !== $query) { - $search->where('name', 'LIKE', sprintf('%%%s%%', $query)); - } - - return $search->take($limit)->get(); - } - - /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - - /** - * @param array $data + * @param array $data * * @return Category * @throws FireflyException @@ -334,19 +197,21 @@ class CategoryRepository implements CategoryRepositoryInterface } /** - * @param Category $category - * @param array $data - * - * @return Category - * @throws Exception + * @param User|Authenticatable|null $user */ - public function update(Category $category, array $data): Category + public function setUser(User | Authenticatable | null $user): void { - /** @var CategoryUpdateService $service */ - $service = app(CategoryUpdateService::class); - $service->setUser($this->user); + if (null !== $user) { + $this->user = $user; + } + } - return $service->update($category, $data); + /** + * @param Category $category + */ + public function removeNotes(Category $category): void + { + $category->notes()->delete(); } /** @@ -364,7 +229,35 @@ class CategoryRepository implements CategoryRepositoryInterface } /** - * @param Category $category + * @param Category $category + * + * @return Carbon|null + * + */ + public function firstUseDate(Category $category): ?Carbon + { + $firstJournalDate = $this->getFirstJournalDate($category); + $firstTransactionDate = $this->getFirstTransactionDate($category); + + if (null === $firstTransactionDate && null === $firstJournalDate) { + return null; + } + if (null === $firstTransactionDate) { + return $firstJournalDate; + } + if (null === $firstJournalDate) { + return $firstTransactionDate; + } + + if ($firstTransactionDate < $firstJournalDate) { + return $firstTransactionDate; + } + + return $firstJournalDate; + } + + /** + * @param Category $category * * @return Carbon|null */ @@ -381,7 +274,7 @@ class CategoryRepository implements CategoryRepositoryInterface } /** - * @param Category $category + * @param Category $category * * @return Carbon|null */ @@ -401,8 +294,83 @@ class CategoryRepository implements CategoryRepositoryInterface } /** - * @param Category $category - * @param Collection $accounts + * @inheritDoc + */ + public function getAttachments(Category $category): Collection + { + $set = $category->attachments()->get(); + + /** @var Storage $disk */ + $disk = Storage::disk('upload'); + + return $set->each( + static function (Attachment $attachment) use ($disk) { + $notes = $attachment->notes()->first(); + $attachment->file_exists = $disk->exists($attachment->fileName()); + $attachment->notes = $notes ? $notes->text : ''; + + return $attachment; + } + ); + } + + /** + * Get all categories with ID's. + * + * @param array $categoryIds + * + * @return Collection + */ + public function getByIds(array $categoryIds): Collection + { + return $this->user->categories()->whereIn('id', $categoryIds)->get(); + } + + /** + * @inheritDoc + */ + public function getNoteText(Category $category): ?string + { + $dbNote = $category->notes()->first(); + if (null === $dbNote) { + return null; + } + + return $dbNote->text; + } + + /** + * @param Category $category + * @param Collection $accounts + * + * @return Carbon|null + * @throws Exception + */ + public function lastUseDate(Category $category, Collection $accounts): ?Carbon + { + $lastJournalDate = $this->getLastJournalDate($category, $accounts); + $lastTransactionDate = $this->getLastTransactionDate($category, $accounts); + + if (null === $lastTransactionDate && null === $lastJournalDate) { + return null; + } + if (null === $lastTransactionDate) { + return $lastJournalDate; + } + if (null === $lastJournalDate) { + return $lastTransactionDate; + } + + if ($lastTransactionDate > $lastJournalDate) { + return $lastTransactionDate; + } + + return $lastJournalDate; + } + + /** + * @param Category $category + * @param Collection $accounts * * @return Carbon|null */ @@ -425,8 +393,8 @@ class CategoryRepository implements CategoryRepositoryInterface } /** - * @param Category $category - * @param Collection $accounts + * @param Category $category + * @param Collection $accounts * * @return Carbon|null * @throws Exception @@ -449,4 +417,36 @@ class CategoryRepository implements CategoryRepositoryInterface return null; } + + /** + * @param string $query + * @param int $limit + * + * @return Collection + */ + public function searchCategory(string $query, int $limit): Collection + { + $search = $this->user->categories(); + if ('' !== $query) { + $search->where('name', 'LIKE', sprintf('%%%s%%', $query)); + } + + return $search->take($limit)->get(); + } + + /** + * @param Category $category + * @param array $data + * + * @return Category + * @throws Exception + */ + public function update(Category $category, array $data): Category + { + /** @var CategoryUpdateService $service */ + $service = app(CategoryUpdateService::class); + $service->setUser($this->user); + + return $service->update($category, $data); + } } diff --git a/app/Repositories/Category/CategoryRepositoryInterface.php b/app/Repositories/Category/CategoryRepositoryInterface.php index aefbeeecdd..4f4d2e0afe 100644 --- a/app/Repositories/Category/CategoryRepositoryInterface.php +++ b/app/Repositories/Category/CategoryRepositoryInterface.php @@ -36,23 +36,23 @@ use Illuminate\Support\Collection; interface CategoryRepositoryInterface { /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ public function categoryEndsWith(string $query, int $limit): Collection; /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ public function categoryStartsWith(string $query, int $limit): Collection; /** - * @param Category $category + * @param Category $category * * @return bool */ @@ -66,7 +66,7 @@ interface CategoryRepositoryInterface /** * Find a category or return NULL * - * @param int $categoryId + * @param int $categoryId * * @return Category|null */ @@ -75,29 +75,29 @@ interface CategoryRepositoryInterface /** * Find a category. * - * @param string $name + * @param string $name * * @return Category|null */ public function findByName(string $name): ?Category; /** - * @param int|null $categoryId - * @param string|null $categoryName + * @param int|null $categoryId + * @param string|null $categoryName * * @return Category|null */ public function findCategory(?int $categoryId, ?string $categoryName): ?Category; /** - * @param Category $category + * @param Category $category * * @return Carbon|null */ public function firstUseDate(Category $category): ?Carbon; /** - * @param Category $category + * @param Category $category * * @return Collection */ @@ -106,7 +106,7 @@ interface CategoryRepositoryInterface /** * Get all categories with ID's. * - * @param array $categoryIds + * @param array $categoryIds * * @return Collection */ @@ -120,7 +120,7 @@ interface CategoryRepositoryInterface public function getCategories(): Collection; /** - * @param Category $category + * @param Category $category * * @return string|null */ @@ -129,8 +129,8 @@ interface CategoryRepositoryInterface /** * Return most recent transaction(journal) date or null when never used before. * - * @param Category $category - * @param Collection $accounts + * @param Category $category + * @param Collection $accounts * * @return Carbon|null */ @@ -139,25 +139,25 @@ interface CategoryRepositoryInterface /** * Remove notes. * - * @param Category $category + * @param Category $category */ public function removeNotes(Category $category): void; /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ public function searchCategory(string $query, int $limit): Collection; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** - * @param array $data + * @param array $data * * @return Category * @throws FireflyException @@ -165,16 +165,16 @@ interface CategoryRepositoryInterface public function store(array $data): Category; /** - * @param Category $category - * @param array $data + * @param Category $category + * @param array $data * * @return Category */ public function update(Category $category, array $data): Category; /** - * @param Category $category - * @param string $notes + * @param Category $category + * @param string $notes */ public function updateNotes(Category $category, string $notes): void; } diff --git a/app/Repositories/Category/NoCategoryRepository.php b/app/Repositories/Category/NoCategoryRepository.php index 1b5d64b2b0..f43f674c87 100644 --- a/app/Repositories/Category/NoCategoryRepository.php +++ b/app/Repositories/Category/NoCategoryRepository.php @@ -43,9 +43,9 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface * which have no category set to them. It's grouped per currency, with as few details in the array * as possible. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts * * @return array */ @@ -90,14 +90,24 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface return $array; } + /** + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + /** * This method returns a list of all the deposit transaction journals (as arrays) set in that period * which have no category set to them. It's grouped per currency, with as few details in the array * as possible. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts * * @return array */ @@ -142,22 +152,12 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface return $array; } - /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - /** * Sum of withdrawal journals in period without a category, grouped per currency. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts * * @return array */ @@ -192,9 +192,9 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface /** * Sum of income journals in period without a category, grouped per currency. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts * * @return array */ diff --git a/app/Repositories/Category/NoCategoryRepositoryInterface.php b/app/Repositories/Category/NoCategoryRepositoryInterface.php index d01207ebf6..a227c8262a 100644 --- a/app/Repositories/Category/NoCategoryRepositoryInterface.php +++ b/app/Repositories/Category/NoCategoryRepositoryInterface.php @@ -39,9 +39,9 @@ interface NoCategoryRepositoryInterface * which have no category set to them. It's grouped per currency, with as few details in the array * as possible. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts * * @return array */ @@ -52,25 +52,25 @@ interface NoCategoryRepositoryInterface * which have no category set to them. It's grouped per currency, with as few details in the array * as possible. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts * * @return array */ public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** * Sum of withdrawal journals in period without a category, grouped per currency. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts * * @return array */ @@ -79,9 +79,9 @@ interface NoCategoryRepositoryInterface /** * Sum of income journals in period without a category, grouped per currency. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts * * @return array */ @@ -90,9 +90,9 @@ interface NoCategoryRepositoryInterface /** * Sum of transfers in period without a category, grouped per currency. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts * * @return array */ diff --git a/app/Repositories/Category/OperationsRepository.php b/app/Repositories/Category/OperationsRepository.php index 25770c93fd..5f917cb081 100644 --- a/app/Repositories/Category/OperationsRepository.php +++ b/app/Repositories/Category/OperationsRepository.php @@ -45,10 +45,10 @@ class OperationsRepository implements OperationsRepositoryInterface * * First currency, then categories. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $categories + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $categories * * @return array */ @@ -116,15 +116,35 @@ class OperationsRepository implements OperationsRepositoryInterface return $array; } + /** + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + + /** + * Returns a list of all the categories belonging to a user. + * + * @return Collection + */ + private function getCategories(): Collection + { + return $this->user->categories()->get(); + } + /** * This method returns a list of all the deposit transaction journals (as arrays) set in that period * which have the specified category set to them. It's grouped per currency, with as few details in the array * as possible. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $categories + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $categories * * @return array */ @@ -321,23 +341,13 @@ class OperationsRepository implements OperationsRepositoryInterface return $array; } - /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - /** * Sum of withdrawal journals in period for a set of categories, grouped per currency. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $categories + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $categories * * @return array */ @@ -378,10 +388,10 @@ class OperationsRepository implements OperationsRepositoryInterface /** * Sum of income journals in period for a set of categories, grouped per currency. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $categories + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $categories * * @return array */ @@ -421,10 +431,10 @@ class OperationsRepository implements OperationsRepositoryInterface /** * Sum of income journals in period for a set of categories, grouped per currency. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $categories + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $categories * * @return array */ @@ -460,14 +470,4 @@ class OperationsRepository implements OperationsRepositoryInterface return $array; } - - /** - * Returns a list of all the categories belonging to a user. - * - * @return Collection - */ - private function getCategories(): Collection - { - return $this->user->categories()->get(); - } } diff --git a/app/Repositories/Category/OperationsRepositoryInterface.php b/app/Repositories/Category/OperationsRepositoryInterface.php index 45db040c73..2738df0d6a 100644 --- a/app/Repositories/Category/OperationsRepositoryInterface.php +++ b/app/Repositories/Category/OperationsRepositoryInterface.php @@ -39,10 +39,10 @@ interface OperationsRepositoryInterface * which have the specified category set to them. It's grouped per currency, with as few details in the array * as possible. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $categories + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $categories * * @return array */ @@ -53,10 +53,10 @@ interface OperationsRepositoryInterface * which have the specified category set to them. It's grouped per currency, with as few details in the array * as possible. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $categories + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $categories * * @return array */ @@ -68,10 +68,10 @@ interface OperationsRepositoryInterface * It excludes any transfers between the listed accounts. * It's grouped per currency, with as few details in the array as possible. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts - * @param Collection|null $categories + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts + * @param Collection|null $categories * * @return array */ @@ -83,27 +83,27 @@ interface OperationsRepositoryInterface * It excludes any transfers between the listed accounts. * It's grouped per currency, with as few details in the array as possible. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts - * @param Collection|null $categories + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts + * @param Collection|null $categories * * @return array */ public function listTransferredOut(Carbon $start, Carbon $end, Collection $accounts, ?Collection $categories = null): array; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** * Sum of withdrawal journals in period for a set of categories, grouped per currency. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $categories + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $categories * * @return array */ @@ -112,10 +112,10 @@ interface OperationsRepositoryInterface /** * Sum of income journals in period for a set of categories, grouped per currency. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $categories + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $categories * * @return array */ @@ -124,10 +124,10 @@ interface OperationsRepositoryInterface /** * Sum of transfers in period for a set of categories, grouped per currency. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $categories + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $categories * * @return array */ diff --git a/app/Repositories/Currency/CurrencyRepository.php b/app/Repositories/Currency/CurrencyRepository.php index 64b60f284f..eddf0404f8 100644 --- a/app/Repositories/Currency/CurrencyRepository.php +++ b/app/Repositories/Currency/CurrencyRepository.php @@ -52,20 +52,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface private User $user; /** - * @param TransactionCurrency $currency - * - * @return int - */ - public function countJournals(TransactionCurrency $currency): int - { - $count = $currency->transactions()->whereNull('deleted_at')->count() + $currency->transactionJournals()->whereNull('deleted_at')->count(); - - // also count foreign: - return $count + Transaction::where('foreign_currency_id', $currency->id)->count(); - } - - /** - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return bool * @throws FireflyException @@ -78,7 +65,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface } /** - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return string|null * @throws FireflyException @@ -166,7 +153,36 @@ class CurrencyRepository implements CurrencyRepositoryInterface } /** - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency + * + * @return int + */ + public function countJournals(TransactionCurrency $currency): int + { + $count = $currency->transactions()->whereNull('deleted_at')->count() + $currency->transactionJournals()->whereNull('deleted_at')->count(); + + // also count foreign: + return $count + Transaction::where('foreign_currency_id', $currency->id)->count(); + } + + /** + * @return Collection + */ + public function getAll(): Collection + { + return TransactionCurrency::orderBy('code', 'ASC')->get(); + } + + /** + * @return Collection + */ + public function get(): Collection + { + return TransactionCurrency::where('enabled', true)->orderBy('code', 'ASC')->get(); + } + + /** + * @param TransactionCurrency $currency * * @return bool */ @@ -186,7 +202,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface /** * Disables a currency * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency */ public function disable(TransactionCurrency $currency): void { @@ -194,16 +210,6 @@ class CurrencyRepository implements CurrencyRepositoryInterface $currency->save(); } - /** - * @param TransactionCurrency $currency - * Enables a currency - */ - public function enable(TransactionCurrency $currency): void - { - $currency->enabled = true; - $currency->save(); - } - /** * @inheritDoc */ @@ -224,34 +230,20 @@ class CurrencyRepository implements CurrencyRepositoryInterface } /** - * Find by ID, return NULL if not found. - * - * @param int $currencyId - * - * @return TransactionCurrency|null + * @param TransactionCurrency $currency + * Enables a currency */ - public function find(int $currencyId): ?TransactionCurrency + public function enable(TransactionCurrency $currency): void { - return TransactionCurrency::find($currencyId); - } - - /** - * Find by currency code, return NULL if unfound. - * - * @param string $currencyCode - * - * @return TransactionCurrency|null - */ - public function findByCode(string $currencyCode): ?TransactionCurrency - { - return TransactionCurrency::where('code', $currencyCode)->first(); + $currency->enabled = true; + $currency->save(); } /** * Find by currency code, return NULL if unfound. * Used in Import Currency! * - * @param string $currencyCode + * @param string $currencyCode * * @return TransactionCurrency|null * @deprecated @@ -264,7 +256,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface /** * Find by currency name. * - * @param string $currencyName + * @param string $currencyName * * @return TransactionCurrency|null */ @@ -277,7 +269,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface * Find by currency name or return null. * Used in Import Currency! * - * @param string $currencyName + * @param string $currencyName * * @return TransactionCurrency|null * @deprecated @@ -290,7 +282,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface /** * Find by currency symbol. * - * @param string $currencySymbol + * @param string $currencySymbol * * @return TransactionCurrency|null */ @@ -303,7 +295,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface * Find by currency symbol or return NULL * Used in Import Currency! * - * @param string $currencySymbol + * @param string $currencySymbol * * @return TransactionCurrency|null * @deprecated @@ -316,8 +308,8 @@ class CurrencyRepository implements CurrencyRepositoryInterface /** * Find by object, ID or code. Returns user default or system default. * - * @param int|null $currencyId - * @param string|null $currencyCode + * @param int|null $currencyId + * @param string|null $currencyCode * * @return TransactionCurrency * @throws FireflyException @@ -348,8 +340,8 @@ class CurrencyRepository implements CurrencyRepositoryInterface /** * Find by object, ID or code. Returns NULL if nothing found. * - * @param int|null $currencyId - * @param string|null $currencyCode + * @param int|null $currencyId + * @param string|null $currencyCode * * @return TransactionCurrency|null */ @@ -370,23 +362,31 @@ class CurrencyRepository implements CurrencyRepositoryInterface } /** - * @return Collection + * Find by ID, return NULL if not found. + * + * @param int $currencyId + * + * @return TransactionCurrency|null */ - public function get(): Collection + public function find(int $currencyId): ?TransactionCurrency { - return TransactionCurrency::where('enabled', true)->orderBy('code', 'ASC')->get(); + return TransactionCurrency::find($currencyId); } /** - * @return Collection + * Find by currency code, return NULL if unfound. + * + * @param string $currencyCode + * + * @return TransactionCurrency|null */ - public function getAll(): Collection + public function findByCode(string $currencyCode): ?TransactionCurrency { - return TransactionCurrency::orderBy('code', 'ASC')->get(); + return TransactionCurrency::where('code', $currencyCode)->first(); } /** - * @param array $ids + * @param array $ids * * @return Collection */ @@ -396,7 +396,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface } /** - * @param Preference $preference + * @param Preference $preference * * @return TransactionCurrency */ @@ -413,9 +413,9 @@ class CurrencyRepository implements CurrencyRepositoryInterface /** * Get currency exchange rate. * - * @param TransactionCurrency $fromCurrency - * @param TransactionCurrency $toCurrency - * @param Carbon $date + * @param TransactionCurrency $fromCurrency + * @param TransactionCurrency $toCurrency + * @param Carbon $date * * @return CurrencyExchangeRate|null */ @@ -451,8 +451,8 @@ class CurrencyRepository implements CurrencyRepositoryInterface } /** - * @param string $search - * @param int $limit + * @param string $search + * @param int $limit * * @return Collection */ @@ -468,10 +468,11 @@ class CurrencyRepository implements CurrencyRepositoryInterface /** * TODO must be a factory - * @param TransactionCurrency $fromCurrency - * @param TransactionCurrency $toCurrency - * @param Carbon $date - * @param float $rate + * + * @param TransactionCurrency $fromCurrency + * @param TransactionCurrency $toCurrency + * @param Carbon $date + * @param float $rate * @return CurrencyExchangeRate */ public function setExchangeRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date, float $rate): CurrencyExchangeRate @@ -488,9 +489,9 @@ class CurrencyRepository implements CurrencyRepositoryInterface } /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void + public function setUser(User | Authenticatable | null $user): void { if (null !== $user) { $this->user = $user; @@ -498,7 +499,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface } /** - * @param array $data + * @param array $data * * @return TransactionCurrency * @throws FireflyException @@ -517,8 +518,8 @@ class CurrencyRepository implements CurrencyRepositoryInterface } /** - * @param TransactionCurrency $currency - * @param array $data + * @param TransactionCurrency $currency + * @param array $data * * @return TransactionCurrency */ diff --git a/app/Repositories/Currency/CurrencyRepositoryInterface.php b/app/Repositories/Currency/CurrencyRepositoryInterface.php index eab7f80549..2c170e2992 100644 --- a/app/Repositories/Currency/CurrencyRepositoryInterface.php +++ b/app/Repositories/Currency/CurrencyRepositoryInterface.php @@ -38,14 +38,14 @@ use Illuminate\Support\Collection; interface CurrencyRepositoryInterface { /** - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return int */ public function countJournals(TransactionCurrency $currency): int; /** - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return bool */ @@ -54,14 +54,14 @@ interface CurrencyRepositoryInterface /** * Currency is in use where exactly. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return string|null */ public function currencyInUseAt(TransactionCurrency $currency): ?string; /** - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return bool */ @@ -70,14 +70,14 @@ interface CurrencyRepositoryInterface /** * Disables a currency * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency */ public function disable(TransactionCurrency $currency): void; /** * Enables a currency * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency */ public function enable(TransactionCurrency $currency): void; @@ -89,7 +89,7 @@ interface CurrencyRepositoryInterface /** * Find by ID, return NULL if not found. * - * @param int $currencyId + * @param int $currencyId * * @return TransactionCurrency|null */ @@ -98,7 +98,7 @@ interface CurrencyRepositoryInterface /** * Find by currency code, return NULL if unfound. * - * @param string $currencyCode + * @param string $currencyCode * * @return TransactionCurrency|null */ @@ -107,7 +107,7 @@ interface CurrencyRepositoryInterface /** * Find by currency code, return NULL if unfound. * - * @param string $currencyCode + * @param string $currencyCode * * @return TransactionCurrency|null */ @@ -116,7 +116,7 @@ interface CurrencyRepositoryInterface /** * Find by currency name. * - * @param string $currencyName + * @param string $currencyName * * @return TransactionCurrency|null */ @@ -125,7 +125,7 @@ interface CurrencyRepositoryInterface /** * Find by currency name. * - * @param string $currencyName + * @param string $currencyName * * @return TransactionCurrency|null */ @@ -134,7 +134,7 @@ interface CurrencyRepositoryInterface /** * Find by currency symbol. * - * @param string $currencySymbol + * @param string $currencySymbol * * @return TransactionCurrency|null */ @@ -143,7 +143,7 @@ interface CurrencyRepositoryInterface /** * Find by currency symbol. * - * @param string $currencySymbol + * @param string $currencySymbol * * @return TransactionCurrency|null */ @@ -152,8 +152,8 @@ interface CurrencyRepositoryInterface /** * Find by object, ID or code. Returns user default or system default. * - * @param int|null $currencyId - * @param string|null $currencyCode + * @param int|null $currencyId + * @param string|null $currencyCode * * @return TransactionCurrency */ @@ -162,8 +162,8 @@ interface CurrencyRepositoryInterface /** * Find by object, ID or code. Returns NULL if nothing found. * - * @param int|null $currencyId - * @param string|null $currencyCode + * @param int|null $currencyId + * @param string|null $currencyCode * * @return TransactionCurrency|null */ @@ -180,14 +180,14 @@ interface CurrencyRepositoryInterface public function getAll(): Collection; /** - * @param array $ids + * @param array $ids * * @return Collection */ public function getByIds(array $ids): Collection; /** - * @param Preference $preference + * @param Preference $preference * * @return TransactionCurrency */ @@ -196,24 +196,24 @@ interface CurrencyRepositoryInterface /** * Get currency exchange rate. * - * @param TransactionCurrency $fromCurrency - * @param TransactionCurrency $toCurrency - * @param Carbon $date + * @param TransactionCurrency $fromCurrency + * @param TransactionCurrency $toCurrency + * @param Carbon $date * * @return CurrencyExchangeRate|null */ public function getExchangeRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date): ?CurrencyExchangeRate; /** - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return bool */ public function isFallbackCurrency(TransactionCurrency $currency): bool; /** - * @param string $search - * @param int $limit + * @param string $search + * @param int $limit * * @return Collection */ @@ -221,21 +221,22 @@ interface CurrencyRepositoryInterface /** * TODO must be a factory - * @param TransactionCurrency $fromCurrency - * @param TransactionCurrency $toCurrency - * @param Carbon $date - * @param float $rate + * + * @param TransactionCurrency $fromCurrency + * @param TransactionCurrency $toCurrency + * @param Carbon $date + * @param float $rate * @return CurrencyExchangeRate */ public function setExchangeRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date, float $rate): CurrencyExchangeRate; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** - * @param array $data + * @param array $data * * @return TransactionCurrency * @throws FireflyException @@ -243,8 +244,8 @@ interface CurrencyRepositoryInterface public function store(array $data): TransactionCurrency; /** - * @param TransactionCurrency $currency - * @param array $data + * @param TransactionCurrency $currency + * @param array $data * * @return TransactionCurrency */ diff --git a/app/Repositories/Journal/JournalAPIRepository.php b/app/Repositories/Journal/JournalAPIRepository.php index 13340f54a3..6eb5f743a1 100644 --- a/app/Repositories/Journal/JournalAPIRepository.php +++ b/app/Repositories/Journal/JournalAPIRepository.php @@ -42,7 +42,7 @@ class JournalAPIRepository implements JournalAPIRepositoryInterface /** * Returns transaction by ID. Used to validate attachments. * - * @param int $transactionId + * @param int $transactionId * * @return Transaction|null */ @@ -59,7 +59,7 @@ class JournalAPIRepository implements JournalAPIRepositoryInterface * * Return all attachments for journal. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return Collection */ @@ -94,7 +94,7 @@ class JournalAPIRepository implements JournalAPIRepositoryInterface /** * Get all piggy bank events for a journal. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return Collection */ @@ -111,9 +111,9 @@ class JournalAPIRepository implements JournalAPIRepositoryInterface } /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void + public function setUser(User | Authenticatable | null $user): void { if (null !== $user) { $this->user = $user; diff --git a/app/Repositories/Journal/JournalAPIRepositoryInterface.php b/app/Repositories/Journal/JournalAPIRepositoryInterface.php index e828aeea33..30a1f0b3fd 100644 --- a/app/Repositories/Journal/JournalAPIRepositoryInterface.php +++ b/app/Repositories/Journal/JournalAPIRepositoryInterface.php @@ -37,7 +37,7 @@ interface JournalAPIRepositoryInterface /** * Returns transaction by ID. Used to validate attachments. * - * @param int $transactionId + * @param int $transactionId * * @return Transaction|null */ @@ -46,7 +46,7 @@ interface JournalAPIRepositoryInterface /** * Return all attachments for journal. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return Collection */ @@ -55,7 +55,7 @@ interface JournalAPIRepositoryInterface /** * Return all journal links for journal. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return Collection */ @@ -64,14 +64,14 @@ interface JournalAPIRepositoryInterface /** * Get all piggy bank events for a journal. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return Collection */ public function getPiggyBankEvents(TransactionJournal $journal): Collection; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; } diff --git a/app/Repositories/Journal/JournalCLIRepository.php b/app/Repositories/Journal/JournalCLIRepository.php index 2ce476df6a..8f37b8f1fd 100644 --- a/app/Repositories/Journal/JournalCLIRepository.php +++ b/app/Repositories/Journal/JournalCLIRepository.php @@ -40,7 +40,7 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface /** * Get all transaction journals with a specific type, regardless of user. * - * @param array $types + * @param array $types * * @return Collection */ @@ -55,7 +55,7 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface /** * Return the ID of the budget linked to the journal (if any) or the transactions (if any). * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return int */ @@ -76,7 +76,7 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface /** * Return the ID of the category linked to the journal (if any) or to the transactions (if any). * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return int */ @@ -107,8 +107,8 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface /** * Return Carbon value of a meta field (or NULL). * - * @param TransactionJournal $journal - * @param string $field + * @param TransactionJournal $journal + * @param string $field * * @return null|Carbon */ @@ -137,8 +137,8 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface /** * Return value of a meta field (or NULL) as a string. * - * @param TransactionJournal $journal - * @param string $field + * @param TransactionJournal $journal + * @param string $field * * @return null|string */ @@ -177,7 +177,7 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface /** * Return text of a note attached to journal, or NULL * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return string|null */ @@ -218,7 +218,7 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface /** * Return all tags as strings in an array. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return array */ @@ -228,9 +228,9 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface } /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void + public function setUser(User | Authenticatable | null $user): void { // empty } diff --git a/app/Repositories/Journal/JournalCLIRepositoryInterface.php b/app/Repositories/Journal/JournalCLIRepositoryInterface.php index 6b2aa4cb86..ca43bb908e 100644 --- a/app/Repositories/Journal/JournalCLIRepositoryInterface.php +++ b/app/Repositories/Journal/JournalCLIRepositoryInterface.php @@ -37,7 +37,7 @@ interface JournalCLIRepositoryInterface /** * Get all transaction journals with a specific type, regardless of user. * - * @param array $types + * @param array $types * * @return Collection */ @@ -46,7 +46,7 @@ interface JournalCLIRepositoryInterface /** * Return the ID of the budget linked to the journal (if any) or the transactions (if any). * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return int */ @@ -55,7 +55,7 @@ interface JournalCLIRepositoryInterface /** * Return the ID of the category linked to the journal (if any) or to the transactions (if any). * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return int */ @@ -71,8 +71,8 @@ interface JournalCLIRepositoryInterface /** * Return Carbon value of a meta field (or NULL). * - * @param TransactionJournal $journal - * @param string $field + * @param TransactionJournal $journal + * @param string $field * * @return null|Carbon */ @@ -81,8 +81,8 @@ interface JournalCLIRepositoryInterface /** * Return value of a meta field (or NULL). * - * @param TransactionJournal $journal - * @param string $field + * @param TransactionJournal $journal + * @param string $field * * @return null|string */ @@ -91,7 +91,7 @@ interface JournalCLIRepositoryInterface /** * Return text of a note attached to journal, or NULL * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return string|null */ @@ -108,14 +108,14 @@ interface JournalCLIRepositoryInterface /** * Return all tags as strings in an array. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return array */ public function getTags(TransactionJournal $journal): array; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; } diff --git a/app/Repositories/Journal/JournalRepository.php b/app/Repositories/Journal/JournalRepository.php index 6b5fd4a6b1..7b2a2b5f88 100644 --- a/app/Repositories/Journal/JournalRepository.php +++ b/app/Repositories/Journal/JournalRepository.php @@ -49,7 +49,7 @@ class JournalRepository implements JournalRepositoryInterface private $user; /** - * @param TransactionGroup $transactionGroup + * @param TransactionGroup $transactionGroup * */ public function destroyGroup(TransactionGroup $transactionGroup): void @@ -60,7 +60,7 @@ class JournalRepository implements JournalRepositoryInterface } /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal * */ public function destroyJournal(TransactionJournal $journal): void @@ -70,18 +70,6 @@ class JournalRepository implements JournalRepositoryInterface $service->destroy($journal); } - /** - * Find a specific journal. - * - * @param int $journalId - * - * @return TransactionJournal|null - */ - public function find(int $journalId): ?TransactionJournal - { - return $this->user->transactionJournals()->find($journalId); - } - /** * @inheritDoc */ @@ -128,7 +116,7 @@ class JournalRepository implements JournalRepositoryInterface /** * Return total amount of journal. Is always positive. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return string */ @@ -165,7 +153,7 @@ class JournalRepository implements JournalRepositoryInterface } /** - * @param TransactionJournalLink $link + * @param TransactionJournalLink $link * * @return string */ @@ -183,8 +171,8 @@ class JournalRepository implements JournalRepositoryInterface /** * Return Carbon value of a meta field (or NULL). * - * @param int $journalId - * @param string $field + * @param int $journalId + * @param string $field * * @return null|Carbon */ @@ -224,7 +212,7 @@ class JournalRepository implements JournalRepositoryInterface } /** - * @param int $journalId + * @param int $journalId */ public function reconcileById(int $journalId): void { @@ -233,11 +221,23 @@ class JournalRepository implements JournalRepositoryInterface $journal?->transactions()->update(['reconciled' => true]); } + /** + * Find a specific journal. + * + * @param int $journalId + * + * @return TransactionJournal|null + */ + public function find(int $journalId): ?TransactionJournal + { + return $this->user->transactionJournals()->find($journalId); + } + /** * Search in journal descriptions. * - * @param string $search - * @param int $limit + * @param string $search + * @param int $limit * * @return Collection */ @@ -253,9 +253,9 @@ class JournalRepository implements JournalRepositoryInterface } /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void + public function setUser(User | Authenticatable | null $user): void { if (null !== $user) { $this->user = $user; @@ -265,8 +265,8 @@ class JournalRepository implements JournalRepositoryInterface /** * Update budget for a journal. * - * @param TransactionJournal $journal - * @param int $budgetId + * @param TransactionJournal $journal + * @param int $budgetId * * @return TransactionJournal */ @@ -290,8 +290,8 @@ class JournalRepository implements JournalRepositoryInterface /** * Update category for a journal. * - * @param TransactionJournal $journal - * @param string $category + * @param TransactionJournal $journal + * @param string $category * * @return TransactionJournal */ @@ -314,8 +314,8 @@ class JournalRepository implements JournalRepositoryInterface /** * Update tag(s) for a journal. * - * @param TransactionJournal $journal - * @param array $tags + * @param TransactionJournal $journal + * @param array $tags * * @return TransactionJournal */ diff --git a/app/Repositories/Journal/JournalRepositoryInterface.php b/app/Repositories/Journal/JournalRepositoryInterface.php index de844443f6..8133d5d02f 100644 --- a/app/Repositories/Journal/JournalRepositoryInterface.php +++ b/app/Repositories/Journal/JournalRepositoryInterface.php @@ -41,28 +41,28 @@ interface JournalRepositoryInterface /** * Deletes a transaction group. * - * @param TransactionGroup $transactionGroup + * @param TransactionGroup $transactionGroup */ public function destroyGroup(TransactionGroup $transactionGroup): void; /** * Deletes a journal. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal */ public function destroyJournal(TransactionJournal $journal): void; /** * Find a specific journal. * - * @param int $journalId + * @param int $journalId * * @return TransactionJournal|null */ public function find(int $journalId): ?TransactionJournal; /** - * @param array $types + * @param array $types * * @return Collection */ @@ -78,7 +78,7 @@ interface JournalRepositoryInterface /** * Returns the destination account of the journal. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return Account * @throws FireflyException @@ -88,7 +88,7 @@ interface JournalRepositoryInterface /** * Return total amount of journal. Is always positive. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return string */ @@ -100,7 +100,7 @@ interface JournalRepositoryInterface public function getLast(): ?TransactionJournal; /** - * @param TransactionJournalLink $link + * @param TransactionJournalLink $link * * @return string */ @@ -109,8 +109,8 @@ interface JournalRepositoryInterface /** * Return Carbon value of a meta field (or NULL). * - * @param int $journalId - * @param string $field + * @param int $journalId + * @param string $field * * @return null|Carbon */ @@ -119,7 +119,7 @@ interface JournalRepositoryInterface /** * Returns the source account of the journal. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return Account * @throws FireflyException @@ -129,30 +129,30 @@ interface JournalRepositoryInterface /** * TODO Maybe to account repository? Do this wen reconcile is API only. * - * @param int $journalId + * @param int $journalId */ public function reconcileById(int $journalId): void; /** * Search in journal descriptions. * - * @param string $search - * @param int $limit + * @param string $search + * @param int $limit * * @return Collection */ public function searchJournalDescriptions(string $search, int $limit): Collection; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** * Update budget for a journal. * - * @param TransactionJournal $journal - * @param int $budgetId + * @param TransactionJournal $journal + * @param int $budgetId * * @return TransactionJournal */ @@ -161,8 +161,8 @@ interface JournalRepositoryInterface /** * Update category for a journal. * - * @param TransactionJournal $journal - * @param string $category + * @param TransactionJournal $journal + * @param string $category * * @return TransactionJournal */ @@ -171,8 +171,8 @@ interface JournalRepositoryInterface /** * Update tag(s) for a journal. * - * @param TransactionJournal $journal - * @param array $tags + * @param TransactionJournal $journal + * @param array $tags * * @return TransactionJournal */ diff --git a/app/Repositories/LinkType/LinkTypeRepository.php b/app/Repositories/LinkType/LinkTypeRepository.php index 596990606a..0c0d43f725 100644 --- a/app/Repositories/LinkType/LinkTypeRepository.php +++ b/app/Repositories/LinkType/LinkTypeRepository.php @@ -43,7 +43,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface private User $user; /** - * @param LinkType $linkType + * @param LinkType $linkType * * @return int */ @@ -53,8 +53,8 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface } /** - * @param LinkType $linkType - * @param LinkType|null $moveTo + * @param LinkType $linkType + * @param LinkType|null $moveTo * * @return bool */ @@ -69,7 +69,29 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface } /** - * @param TransactionJournalLink $link + * @param LinkType $linkType + * @param array $data + * + * @return LinkType + */ + public function update(LinkType $linkType, array $data): LinkType + { + if (array_key_exists('name', $data) && '' !== (string)$data['name']) { + $linkType->name = $data['name']; + } + if (array_key_exists('inward', $data) && '' !== (string)$data['inward']) { + $linkType->inward = $data['inward']; + } + if (array_key_exists('outward', $data) && '' !== (string)$data['outward']) { + $linkType->outward = $data['outward']; + } + $linkType->save(); + + return $linkType; + } + + /** + * @param TransactionJournalLink $link * * @return bool * @throws Exception @@ -82,35 +104,11 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface return true; } - /** - * @param int $linkTypeId - * - * @return LinkType|null - */ - public function find(int $linkTypeId): ?LinkType - { - return LinkType::find($linkTypeId); - } - - /** - * @param string|null $name - * - * @return LinkType|null - */ - public function findByName(string $name = null): ?LinkType - { - if (null === $name) { - return null; - } - - return LinkType::where('name', $name)->first(); - } - /** * Check if link exists between journals. * - * @param TransactionJournal $one - * @param TransactionJournal $two + * @param TransactionJournal $one + * @param TransactionJournal $two * * @return bool */ @@ -123,34 +121,10 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface return $count + $opposingCount > 0; } - /** - * See if such a link already exists (and get it). - * - * @param LinkType $linkType - * @param TransactionJournal $inward - * @param TransactionJournal $outward - * - * @return TransactionJournalLink|null - */ - public function findSpecificLink(LinkType $linkType, TransactionJournal $inward, TransactionJournal $outward): ?TransactionJournalLink - { - return TransactionJournalLink::where('link_type_id', $linkType->id) - ->where('source_id', $inward->id) - ->where('destination_id', $outward->id)->first(); - } - - /** - * @return Collection - */ - public function get(): Collection - { - return LinkType::orderBy('name', 'ASC')->get(); - } - /** * Return array of all journal ID's for this type of link. * - * @param LinkType $linkType + * @param LinkType $linkType * * @return array */ @@ -163,10 +137,18 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface return array_unique(array_merge($sources, $destinations)); } + /** + * @return Collection + */ + public function get(): Collection + { + return LinkType::orderBy('name', 'ASC')->get(); + } + /** * Returns all the journal links (of a specific type). * - * @param LinkType|null $linkType + * @param LinkType|null $linkType * * @return Collection */ @@ -200,7 +182,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface /** * Return list of existing connections. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return Collection */ @@ -218,9 +200,9 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface } /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void + public function setUser(User | Authenticatable | null $user): void { if (null !== $user) { $this->user = $user; @@ -228,7 +210,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface } /** - * @param array $data + * @param array $data * * @return LinkType */ @@ -247,9 +229,9 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface /** * Store link between two journals. * - * @param array $information - * @param TransactionJournal $inward - * @param TransactionJournal $outward + * @param array $information + * @param TransactionJournal $inward + * @param TransactionJournal $outward * * @return TransactionJournalLink|null * @throws Exception @@ -294,18 +276,65 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface } /** - * @param TransactionJournalLink $link + * @param int $linkTypeId * - * @return bool + * @return LinkType|null */ - public function switchLink(TransactionJournalLink $link): bool + public function find(int $linkTypeId): ?LinkType { - $source = $link->source_id; - $link->source_id = $link->destination_id; - $link->destination_id = $source; - $link->save(); + return LinkType::find($linkTypeId); + } - return true; + /** + * @param string|null $name + * + * @return LinkType|null + */ + public function findByName(string $name = null): ?LinkType + { + if (null === $name) { + return null; + } + + return LinkType::where('name', $name)->first(); + } + + /** + * See if such a link already exists (and get it). + * + * @param LinkType $linkType + * @param TransactionJournal $inward + * @param TransactionJournal $outward + * + * @return TransactionJournalLink|null + */ + public function findSpecificLink(LinkType $linkType, TransactionJournal $inward, TransactionJournal $outward): ?TransactionJournalLink + { + return TransactionJournalLink::where('link_type_id', $linkType->id) + ->where('source_id', $inward->id) + ->where('destination_id', $outward->id)->first(); + } + + /** + * @param TransactionJournalLink $link + * @param string $text + * + * @throws Exception + */ + private function setNoteText(TransactionJournalLink $link, string $text): void + { + $dbNote = $link->notes()->first(); + if ('' !== $text) { + if (null === $dbNote) { + $dbNote = new Note(); + $dbNote->noteable()->associate($link); + } + $dbNote->text = trim($text); + $dbNote->save(); + + return; + } + $dbNote?->delete(); } /** @@ -323,32 +352,25 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface } /** - * @param LinkType $linkType - * @param array $data + * @param TransactionJournalLink $link * - * @return LinkType + * @return bool */ - public function update(LinkType $linkType, array $data): LinkType + public function switchLink(TransactionJournalLink $link): bool { - if (array_key_exists('name', $data) && '' !== (string)$data['name']) { - $linkType->name = $data['name']; - } - if (array_key_exists('inward', $data) && '' !== (string)$data['inward']) { - $linkType->inward = $data['inward']; - } - if (array_key_exists('outward', $data) && '' !== (string)$data['outward']) { - $linkType->outward = $data['outward']; - } - $linkType->save(); + $source = $link->source_id; + $link->source_id = $link->destination_id; + $link->destination_id = $source; + $link->save(); - return $linkType; + return true; } /** * Update an existing transaction journal link. * - * @param TransactionJournalLink $journalLink - * @param array $data + * @param TransactionJournalLink $journalLink + * @param array $data * * @return TransactionJournalLink * @throws Exception @@ -375,26 +397,4 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface return $journalLink; } - - /** - * @param TransactionJournalLink $link - * @param string $text - * - * @throws Exception - */ - private function setNoteText(TransactionJournalLink $link, string $text): void - { - $dbNote = $link->notes()->first(); - if ('' !== $text) { - if (null === $dbNote) { - $dbNote = new Note(); - $dbNote->noteable()->associate($link); - } - $dbNote->text = trim($text); - $dbNote->save(); - - return; - } - $dbNote?->delete(); - } } diff --git a/app/Repositories/LinkType/LinkTypeRepositoryInterface.php b/app/Repositories/LinkType/LinkTypeRepositoryInterface.php index 54f984b09a..b2941331f8 100644 --- a/app/Repositories/LinkType/LinkTypeRepositoryInterface.php +++ b/app/Repositories/LinkType/LinkTypeRepositoryInterface.php @@ -36,29 +36,29 @@ use Illuminate\Support\Collection; interface LinkTypeRepositoryInterface { /** - * @param LinkType $linkType + * @param LinkType $linkType * * @return int */ public function countJournals(LinkType $linkType): int; /** - * @param LinkType $linkType - * @param LinkType|null $moveTo + * @param LinkType $linkType + * @param LinkType|null $moveTo * * @return bool */ public function destroy(LinkType $linkType, LinkType $moveTo = null): bool; /** - * @param TransactionJournalLink $link + * @param TransactionJournalLink $link * * @return bool */ public function destroyLink(TransactionJournalLink $link): bool; /** - * @param int $linkTypeId + * @param int $linkTypeId * * @return LinkType|null */ @@ -67,7 +67,7 @@ interface LinkTypeRepositoryInterface /** * Find link type by name. * - * @param string|null $name + * @param string|null $name * * @return LinkType|null */ @@ -76,8 +76,8 @@ interface LinkTypeRepositoryInterface /** * Check if link exists between journals. * - * @param TransactionJournal $one - * @param TransactionJournal $two + * @param TransactionJournal $one + * @param TransactionJournal $two * * @return bool */ @@ -86,9 +86,9 @@ interface LinkTypeRepositoryInterface /** * See if such a link already exists (and get it). * - * @param LinkType $linkType - * @param TransactionJournal $inward - * @param TransactionJournal $outward + * @param LinkType $linkType + * @param TransactionJournal $inward + * @param TransactionJournal $outward * * @return TransactionJournalLink|null */ @@ -102,14 +102,14 @@ interface LinkTypeRepositoryInterface /** * Return array of all journal ID's for this type of link. * - * @param LinkType $linkType + * @param LinkType $linkType * * @return array */ public function getJournalIds(LinkType $linkType): array; /** - * @param LinkType|null $linkType + * @param LinkType|null $linkType * * @return Collection */ @@ -118,19 +118,19 @@ interface LinkTypeRepositoryInterface /** * Return list of existing connections. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return Collection */ public function getLinks(TransactionJournal $journal): Collection; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** - * @param array $data + * @param array $data * * @return LinkType */ @@ -139,31 +139,31 @@ interface LinkTypeRepositoryInterface /** * Store link between two journals. * - * @param array $information - * @param TransactionJournal $inward - * @param TransactionJournal $outward + * @param array $information + * @param TransactionJournal $inward + * @param TransactionJournal $outward * * @return TransactionJournalLink|null */ public function storeLink(array $information, TransactionJournal $inward, TransactionJournal $outward): ?TransactionJournalLink; /** - * @param TransactionJournalLink $link + * @param TransactionJournalLink $link * * @return bool */ public function switchLink(TransactionJournalLink $link): bool; /** - * @param int $linkId + * @param int $linkId * * @return bool */ public function switchLinkById(int $linkId): bool; /** - * @param LinkType $linkType - * @param array $data + * @param LinkType $linkType + * @param array $data * * @return LinkType */ @@ -172,8 +172,8 @@ interface LinkTypeRepositoryInterface /** * Update an existing transaction journal link. * - * @param TransactionJournalLink $journalLink - * @param array $data + * @param TransactionJournalLink $journalLink + * @param array $data * * @return TransactionJournalLink */ diff --git a/app/Repositories/ObjectGroup/CreatesObjectGroups.php b/app/Repositories/ObjectGroup/CreatesObjectGroups.php index d4736cb73d..7cf5550675 100644 --- a/app/Repositories/ObjectGroup/CreatesObjectGroups.php +++ b/app/Repositories/ObjectGroup/CreatesObjectGroups.php @@ -32,17 +32,7 @@ use FireflyIII\Models\ObjectGroup; trait CreatesObjectGroups { /** - * @param string $title - * - * @return null|ObjectGroup - */ - protected function findObjectGroup(string $title): ?ObjectGroup - { - return $this->user->objectGroups()->where('title', $title)->first(); - } - - /** - * @param int $groupId + * @param int $groupId * * @return ObjectGroup|null */ @@ -52,7 +42,7 @@ trait CreatesObjectGroups } /** - * @param string $title + * @param string $title * * @return ObjectGroup|null */ @@ -82,7 +72,7 @@ trait CreatesObjectGroups } /** - * @param string $title + * @param string $title * * @return bool */ @@ -90,4 +80,14 @@ trait CreatesObjectGroups { return 1 === $this->user->objectGroups()->where('title', $title)->count(); } + + /** + * @param string $title + * + * @return null|ObjectGroup + */ + protected function findObjectGroup(string $title): ?ObjectGroup + { + return $this->user->objectGroups()->where('title', $title)->first(); + } } diff --git a/app/Repositories/ObjectGroup/ObjectGroupRepository.php b/app/Repositories/ObjectGroup/ObjectGroupRepository.php index a18feb55b1..a82c9b7f9d 100644 --- a/app/Repositories/ObjectGroup/ObjectGroupRepository.php +++ b/app/Repositories/ObjectGroup/ObjectGroupRepository.php @@ -53,6 +53,17 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface } } + /** + * @inheritDoc + */ + public function get(): Collection + { + return $this->user->objectGroups() + ->with(['piggyBanks', 'bills']) + ->orderBy('order', 'ASC') + ->orderBy('title', 'ASC')->get(); + } + /** * @inheritDoc */ @@ -82,17 +93,6 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface $objectGroup->delete(); } - /** - * @inheritDoc - */ - public function get(): Collection - { - return $this->user->objectGroups() - ->with(['piggyBanks', 'bills']) - ->orderBy('order', 'ASC') - ->orderBy('title', 'ASC')->get(); - } - /** * @inheritDoc */ @@ -131,8 +131,8 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface } /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ @@ -151,6 +151,34 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface return $dbQuery->take($limit)->get(['object_groups.*']); } + /** + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + + /** + * @inheritDoc + */ + public function update(ObjectGroup $objectGroup, array $data): ObjectGroup + { + if (array_key_exists('title', $data)) { + $objectGroup->title = $data['title']; + } + + if (array_key_exists('order', $data)) { + $this->setOrder($objectGroup, (int)$data['order']); + } + + $objectGroup->save(); + + return $objectGroup; + } + /** * @inheritDoc */ @@ -179,32 +207,4 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface return $objectGroup; } - - /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - - /** - * @inheritDoc - */ - public function update(ObjectGroup $objectGroup, array $data): ObjectGroup - { - if (array_key_exists('title', $data)) { - $objectGroup->title = $data['title']; - } - - if (array_key_exists('order', $data)) { - $this->setOrder($objectGroup, (int)$data['order']); - } - - $objectGroup->save(); - - return $objectGroup; - } } diff --git a/app/Repositories/ObjectGroup/ObjectGroupRepositoryInterface.php b/app/Repositories/ObjectGroup/ObjectGroupRepositoryInterface.php index 0b1de76abb..6f0c2382c0 100644 --- a/app/Repositories/ObjectGroup/ObjectGroupRepositoryInterface.php +++ b/app/Repositories/ObjectGroup/ObjectGroupRepositoryInterface.php @@ -45,7 +45,7 @@ interface ObjectGroupRepositoryInterface public function deleteEmpty(): void; /** - * @param ObjectGroup $objectGroup + * @param ObjectGroup $objectGroup */ public function destroy(ObjectGroup $objectGroup): void; @@ -55,14 +55,14 @@ interface ObjectGroupRepositoryInterface public function get(): Collection; /** - * @param ObjectGroup $objectGroup + * @param ObjectGroup $objectGroup * * @return Collection */ public function getBills(ObjectGroup $objectGroup): Collection; /** - * @param ObjectGroup $objectGroup + * @param ObjectGroup $objectGroup * * @return Collection */ @@ -74,29 +74,29 @@ interface ObjectGroupRepositoryInterface public function resetOrder(): void; /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ public function search(string $query, int $limit): Collection; /** - * @param ObjectGroup $objectGroup - * @param int $newOrder + * @param ObjectGroup $objectGroup + * @param int $newOrder * * @return ObjectGroup */ public function setOrder(ObjectGroup $objectGroup, int $newOrder): ObjectGroup; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** - * @param ObjectGroup $objectGroup - * @param array $data + * @param ObjectGroup $objectGroup + * @param array $data * * @return ObjectGroup */ diff --git a/app/Repositories/PiggyBank/ModifiesPiggyBanks.php b/app/Repositories/PiggyBank/ModifiesPiggyBanks.php index 00507a6aa0..492213f307 100644 --- a/app/Repositories/PiggyBank/ModifiesPiggyBanks.php +++ b/app/Repositories/PiggyBank/ModifiesPiggyBanks.php @@ -43,10 +43,38 @@ trait ModifiesPiggyBanks { use CreatesObjectGroups; + public function addAmountToRepetition(PiggyBankRepetition $repetition, string $amount, TransactionJournal $journal): void + { + Log::debug(sprintf('addAmountToRepetition: %s', $amount)); + if (-1 === bccomp($amount, '0')) { + Log::debug('Remove amount.'); + $this->removeAmount($repetition->piggyBank, bcmul($amount, '-1'), $journal); + } + if (1 === bccomp($amount, '0')) { + Log::debug('Add amount.'); + $this->addAmount($repetition->piggyBank, $amount, $journal); + } + } + + public function removeAmount(PiggyBank $piggyBank, string $amount, ?TransactionJournal $journal = null): bool + { + $repetition = $this->getRepetition($piggyBank); + if (null === $repetition) { + return false; + } + $repetition->currentamount = bcsub($repetition->currentamount, $amount); + $repetition->save(); + + Log::debug('addAmount [a]: Trigger change for negative amount.'); + event(new ChangedPiggyBankAmount($piggyBank, bcmul($amount, '-1'), $journal, null)); + + return true; + } + /** - * @param PiggyBank $piggyBank - * @param string $amount - * @param TransactionJournal|null $journal + * @param PiggyBank $piggyBank + * @param string $amount + * @param TransactionJournal|null $journal * @return bool */ public function addAmount(PiggyBank $piggyBank, string $amount, ?TransactionJournal $journal = null): bool @@ -65,22 +93,9 @@ trait ModifiesPiggyBanks return true; } - public function addAmountToRepetition(PiggyBankRepetition $repetition, string $amount, TransactionJournal $journal): void - { - Log::debug(sprintf('addAmountToRepetition: %s', $amount)); - if (-1 === bccomp($amount, '0')) { - Log::debug('Remove amount.'); - $this->removeAmount($repetition->piggyBank, bcmul($amount, '-1'), $journal); - } - if (1 === bccomp($amount, '0')) { - Log::debug('Add amount.'); - $this->addAmount($repetition->piggyBank, $amount, $journal); - } - } - /** - * @param PiggyBank $piggyBank - * @param string $amount + * @param PiggyBank $piggyBank + * @param string $amount * * @return bool * @throws JsonException @@ -110,8 +125,8 @@ trait ModifiesPiggyBanks } /** - * @param PiggyBank $piggyBank - * @param string $amount + * @param PiggyBank $piggyBank + * @param string $amount * * @return bool */ @@ -127,7 +142,7 @@ trait ModifiesPiggyBanks } /** - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return bool * @throws Exception @@ -140,21 +155,6 @@ trait ModifiesPiggyBanks return true; } - public function removeAmount(PiggyBank $piggyBank, string $amount, ?TransactionJournal $journal = null): bool - { - $repetition = $this->getRepetition($piggyBank); - if (null === $repetition) { - return false; - } - $repetition->currentamount = bcsub($repetition->currentamount, $amount); - $repetition->save(); - - Log::debug('addAmount [a]: Trigger change for negative amount.'); - event(new ChangedPiggyBankAmount($piggyBank, bcmul($amount, '-1'), $journal, null)); - - return true; - } - /** * @inheritDoc */ @@ -166,25 +166,8 @@ trait ModifiesPiggyBanks } /** - * Correct order of piggies in case of issues. - */ - public function resetOrder(): void - { - $set = $this->user->piggyBanks()->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']); - $current = 1; - foreach ($set as $piggyBank) { - if ((int)$piggyBank->order !== $current) { - Log::debug(sprintf('Piggy bank #%d ("%s") was at place %d but should be on %d', $piggyBank->id, $piggyBank->name, $piggyBank->order, $current)); - $piggyBank->order = $current; - $piggyBank->save(); - } - $current++; - } - } - - /** - * @param PiggyBank $piggyBank - * @param string $amount + * @param PiggyBank $piggyBank + * @param string $amount * * @return PiggyBank */ @@ -228,35 +211,7 @@ trait ModifiesPiggyBanks } /** - * @inheritDoc - */ - public function setOrder(PiggyBank $piggyBank, int $newOrder): bool - { - $oldOrder = (int)$piggyBank->order; - Log::debug(sprintf('Will move piggy bank #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder)); - if ($newOrder > $oldOrder) { - $this->user->piggyBanks()->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder) - ->where('piggy_banks.id', '!=', $piggyBank->id) - ->decrement('piggy_banks.order'); - $piggyBank->order = $newOrder; - Log::debug(sprintf('Order of piggy #%d ("%s") is now %d', $piggyBank->id, $piggyBank->name, $newOrder)); - $piggyBank->save(); - - return true; - } - - $this->user->piggyBanks()->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder) - ->where('piggy_banks.id', '!=', $piggyBank->id) - ->increment('piggy_banks.order'); - $piggyBank->order = $newOrder; - Log::debug(sprintf('Order of piggy #%d ("%s") is now %d', $piggyBank->id, $piggyBank->name, $newOrder)); - $piggyBank->save(); - - return true; - } - - /** - * @param array $data + * @param array $data * * @return PiggyBank * @throws FireflyException @@ -320,8 +275,78 @@ trait ModifiesPiggyBanks } /** - * @param PiggyBank $piggyBank - * @param array $data + * Correct order of piggies in case of issues. + */ + public function resetOrder(): void + { + $set = $this->user->piggyBanks()->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']); + $current = 1; + foreach ($set as $piggyBank) { + if ((int)$piggyBank->order !== $current) { + Log::debug(sprintf('Piggy bank #%d ("%s") was at place %d but should be on %d', $piggyBank->id, $piggyBank->name, $piggyBank->order, $current)); + $piggyBank->order = $current; + $piggyBank->save(); + } + $current++; + } + } + + /** + * @inheritDoc + */ + public function setOrder(PiggyBank $piggyBank, int $newOrder): bool + { + $oldOrder = (int)$piggyBank->order; + Log::debug(sprintf('Will move piggy bank #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder)); + if ($newOrder > $oldOrder) { + $this->user->piggyBanks()->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder) + ->where('piggy_banks.id', '!=', $piggyBank->id) + ->decrement('piggy_banks.order'); + $piggyBank->order = $newOrder; + Log::debug(sprintf('Order of piggy #%d ("%s") is now %d', $piggyBank->id, $piggyBank->name, $newOrder)); + $piggyBank->save(); + + return true; + } + + $this->user->piggyBanks()->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder) + ->where('piggy_banks.id', '!=', $piggyBank->id) + ->increment('piggy_banks.order'); + $piggyBank->order = $newOrder; + Log::debug(sprintf('Order of piggy #%d ("%s") is now %d', $piggyBank->id, $piggyBank->name, $newOrder)); + $piggyBank->save(); + + return true; + } + + /** + * @param PiggyBank $piggyBank + * @param string $note + * + * @return bool + */ + private function updateNote(PiggyBank $piggyBank, string $note): bool + { + if ('' === $note) { + $dbNote = $piggyBank->notes()->first(); + $dbNote?->delete(); + + return true; + } + $dbNote = $piggyBank->notes()->first(); + if (null === $dbNote) { + $dbNote = new Note(); + $dbNote->noteable()->associate($piggyBank); + } + $dbNote->text = trim($note); + $dbNote->save(); + + return true; + } + + /** + * @param PiggyBank $piggyBank + * @param array $data * * @return PiggyBank */ @@ -389,33 +414,8 @@ trait ModifiesPiggyBanks } /** - * @param PiggyBank $piggyBank - * @param string $note - * - * @return bool - */ - private function updateNote(PiggyBank $piggyBank, string $note): bool - { - if ('' === $note) { - $dbNote = $piggyBank->notes()->first(); - $dbNote?->delete(); - - return true; - } - $dbNote = $piggyBank->notes()->first(); - if (null === $dbNote) { - $dbNote = new Note(); - $dbNote->noteable()->associate($piggyBank); - } - $dbNote->text = trim($note); - $dbNote->save(); - - return true; - } - - /** - * @param PiggyBank $piggyBank - * @param array $data + * @param PiggyBank $piggyBank + * @param array $data * * @return PiggyBank */ diff --git a/app/Repositories/PiggyBank/PiggyBankRepository.php b/app/Repositories/PiggyBank/PiggyBankRepository.php index cc69b49c8e..95288dd956 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepository.php +++ b/app/Repositories/PiggyBank/PiggyBankRepository.php @@ -59,31 +59,8 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface } /** - * @param int $piggyBankId - * - * @return PiggyBank|null - */ - public function find(int $piggyBankId): ?PiggyBank - { - // phpstan doesn't get the Model. - return $this->user->piggyBanks()->find($piggyBankId); // @phpstan-ignore-line - } - - /** - * Find by name or return NULL. - * - * @param string $name - * - * @return PiggyBank|null - */ - public function findByName(string $name): ?PiggyBank - { - return $this->user->piggyBanks()->where('piggy_banks.name', $name)->first(['piggy_banks.*']); - } - - /** - * @param int|null $piggyBankId - * @param string|null $piggyBankName + * @param int|null $piggyBankId + * @param string|null $piggyBankName * * @return PiggyBank|null */ @@ -112,6 +89,29 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface return null; } + /** + * @param int $piggyBankId + * + * @return PiggyBank|null + */ + public function find(int $piggyBankId): ?PiggyBank + { + // phpstan doesn't get the Model. + return $this->user->piggyBanks()->find($piggyBankId); // @phpstan-ignore-line + } + + /** + * Find by name or return NULL. + * + * @param string $name + * + * @return PiggyBank|null + */ + public function findByName(string $name): ?PiggyBank + { + return $this->user->piggyBanks()->where('piggy_banks.name', $name)->first(['piggy_banks.*']); + } + /** * @inheritDoc */ @@ -136,7 +136,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface /** * Get current amount saved in piggy bank. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return string */ @@ -151,7 +151,17 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface } /** - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank + * + * @return PiggyBankRepetition|null + */ + public function getRepetition(PiggyBank $piggyBank): ?PiggyBankRepetition + { + return $piggyBank->piggyBankRepetitions()->first(); + } + + /** + * @param PiggyBank $piggyBank * * @return Collection */ @@ -163,9 +173,9 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface /** * Used for connecting to a piggy bank. * - * @param PiggyBank $piggyBank - * @param PiggyBankRepetition $repetition - * @param TransactionJournal $journal + * @param PiggyBank $piggyBank + * @param PiggyBankRepetition $repetition + * @param TransactionJournal $journal * * @return string * @throws FireflyException @@ -264,6 +274,16 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface return (string)$amount; } + /** + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + /** * @return int */ @@ -275,7 +295,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface /** * Return note for piggy bank. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return string */ @@ -290,6 +310,26 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface return $note->text; } + /** + * Also add amount in name. + * + * @return Collection + */ + public function getPiggyBanksWithAmount(): Collection + { + $currency = app('amount')->getDefaultCurrency(); + + $set = $this->getPiggyBanks(); + + /** @var PiggyBank $piggy */ + foreach ($set as $piggy) { + $currentAmount = $this->getRepetition($piggy)->currentamount ?? '0'; + $piggy->name = $piggy->name . ' (' . app('amount')->formatAnything($currency, $currentAmount, false) . ')'; + } + + return $set; + } + /** * @return Collection */ @@ -306,40 +346,10 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface ->orderBy('order', 'ASC')->get(); } - /** - * Also add amount in name. - * - * @return Collection - */ - public function getPiggyBanksWithAmount(): Collection - { - $currency = app('amount')->getDefaultCurrency(); - - $set = $this->getPiggyBanks(); - - /** @var PiggyBank $piggy */ - foreach ($set as $piggy) { - $currentAmount = $this->getRepetition($piggy)->currentamount ?? '0'; - $piggy->name = $piggy->name.' ('.app('amount')->formatAnything($currency, $currentAmount, false).')'; - } - - return $set; - } - - /** - * @param PiggyBank $piggyBank - * - * @return PiggyBankRepetition|null - */ - public function getRepetition(PiggyBank $piggyBank): ?PiggyBankRepetition - { - return $piggyBank->piggyBankRepetitions()->first(); - } - /** * Returns the suggested amount the user should save per month, or "". * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return string * @@ -374,8 +384,8 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface /** * Get for piggy account what is left to put in piggies. * - * @param PiggyBank $piggyBank - * @param Carbon $date + * @param PiggyBank $piggyBank + * @param Carbon $date * * @return string * @throws JsonException @@ -412,14 +422,4 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface return $search->take($limit)->get(); } - - /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } } diff --git a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php index ac03d76fab..81c55cce98 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php +++ b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php @@ -38,9 +38,9 @@ use Illuminate\Support\Collection; interface PiggyBankRepositoryInterface { /** - * @param PiggyBank $piggyBank - * @param string $amount - * @param TransactionJournal|null $journal + * @param PiggyBank $piggyBank + * @param string $amount + * @param TransactionJournal|null $journal * @return bool */ public function addAmount(PiggyBank $piggyBank, string $amount, ?TransactionJournal $journal = null): bool; @@ -48,16 +48,16 @@ interface PiggyBankRepositoryInterface public function addAmountToRepetition(PiggyBankRepetition $repetition, string $amount, TransactionJournal $journal): void; /** - * @param PiggyBank $piggyBank - * @param string $amount + * @param PiggyBank $piggyBank + * @param string $amount * * @return bool */ public function canAddAmount(PiggyBank $piggyBank, string $amount): bool; /** - * @param PiggyBank $piggyBank - * @param string $amount + * @param PiggyBank $piggyBank + * @param string $amount * * @return bool */ @@ -66,7 +66,7 @@ interface PiggyBankRepositoryInterface /** * Destroy piggy bank. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return bool */ @@ -78,7 +78,7 @@ interface PiggyBankRepositoryInterface public function destroyAll(): void; /** - * @param int $piggyBankId + * @param int $piggyBankId * * @return PiggyBank|null */ @@ -87,22 +87,22 @@ interface PiggyBankRepositoryInterface /** * Find by name or return NULL. * - * @param string $name + * @param string $name * * @return PiggyBank|null */ public function findByName(string $name): ?PiggyBank; /** - * @param int|null $piggyBankId - * @param string|null $piggyBankName + * @param int|null $piggyBankId + * @param string|null $piggyBankName * * @return PiggyBank|null */ public function findPiggyBank(?int $piggyBankId, ?string $piggyBankName): ?PiggyBank; /** - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return Collection */ @@ -111,7 +111,7 @@ interface PiggyBankRepositoryInterface /** * Get current amount saved in piggy bank. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return string */ @@ -120,7 +120,7 @@ interface PiggyBankRepositoryInterface /** * Get all events. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return Collection */ @@ -129,9 +129,9 @@ interface PiggyBankRepositoryInterface /** * Used for connecting to a piggy bank. * - * @param PiggyBank $piggyBank - * @param PiggyBankRepetition $repetition - * @param TransactionJournal $journal + * @param PiggyBank $piggyBank + * @param PiggyBankRepetition $repetition + * @param TransactionJournal $journal * * @return string */ @@ -147,7 +147,7 @@ interface PiggyBankRepositoryInterface /** * Return note for piggy bank. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return string */ @@ -168,7 +168,7 @@ interface PiggyBankRepositoryInterface public function getPiggyBanksWithAmount(): Collection; /** - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return PiggyBankRepetition|null */ @@ -177,7 +177,7 @@ interface PiggyBankRepositoryInterface /** * Returns the suggested amount the user should save per month, or "". * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return string */ @@ -186,23 +186,23 @@ interface PiggyBankRepositoryInterface /** * Get for piggy account what is left to put in piggies. * - * @param PiggyBank $piggyBank - * @param Carbon $date + * @param PiggyBank $piggyBank + * @param Carbon $date * * @return string */ public function leftOnAccount(PiggyBank $piggyBank, Carbon $date): string; /** - * @param PiggyBank $piggyBank - * @param string $amount - * @param TransactionJournal|null $journal + * @param PiggyBank $piggyBank + * @param string $amount + * @param TransactionJournal|null $journal * @return bool */ public function removeAmount(PiggyBank $piggyBank, string $amount, ?TransactionJournal $journal = null): bool; /** - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return PiggyBank */ @@ -216,24 +216,24 @@ interface PiggyBankRepositoryInterface /** * Search for piggy banks. * - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ public function searchPiggyBank(string $query, int $limit): Collection; /** - * @param PiggyBank $piggyBank - * @param string $amount + * @param PiggyBank $piggyBank + * @param string $amount * * @return PiggyBank */ public function setCurrentAmount(PiggyBank $piggyBank, string $amount): PiggyBank; /** - * @param PiggyBank $piggyBank - * @param string $objectGroupTitle + * @param PiggyBank $piggyBank + * @param string $objectGroupTitle * * @return PiggyBank */ @@ -242,22 +242,22 @@ interface PiggyBankRepositoryInterface /** * Set specific piggy bank to specific order. * - * @param PiggyBank $piggyBank - * @param int $newOrder + * @param PiggyBank $piggyBank + * @param int $newOrder * * @return bool */ public function setOrder(PiggyBank $piggyBank, int $newOrder): bool; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** * Store new piggy bank. * - * @param array $data + * @param array $data * * @return PiggyBank * @throws FireflyException @@ -267,8 +267,8 @@ interface PiggyBankRepositoryInterface /** * Update existing piggy bank. * - * @param PiggyBank $piggyBank - * @param array $data + * @param PiggyBank $piggyBank + * @param array $data * * @return PiggyBank */ diff --git a/app/Repositories/Recurring/RecurringRepository.php b/app/Repositories/Recurring/RecurringRepository.php index 324aedc59d..5b49d3b6fc 100644 --- a/app/Repositories/Recurring/RecurringRepository.php +++ b/app/Repositories/Recurring/RecurringRepository.php @@ -68,8 +68,8 @@ class RecurringRepository implements RecurringRepositoryInterface public function createdPreviously(Recurrence $recurrence, Carbon $date): bool { // if not, loop set and try to read the recurrence_date. If it matches start or end, return it as well. - $set = - TransactionJournalMeta::where(function (Builder $q1) use ($recurrence) { + $set + = TransactionJournalMeta::where(function (Builder $q1) use ($recurrence) { $q1->where('name', 'recurrence_id'); $q1->where('data', json_encode((string)$recurrence->id)); })->get(['journal_meta.transaction_journal_id']); @@ -92,10 +92,25 @@ class RecurringRepository implements RecurringRepositoryInterface return false; } + /** + * Returns all of the user's recurring transactions. + * + * @return Collection + */ + public function get(): Collection + { + return $this->user->recurrences() + ->with(['TransactionCurrency', 'TransactionType', 'RecurrenceRepetitions', 'RecurrenceTransactions']) + ->orderBy('active', 'DESC') + ->orderBy('transaction_type_id', 'ASC') + ->orderBy('title', 'ASC') + ->get(); + } + /** * Destroy a recurring transaction. * - * @param Recurrence $recurrence + * @param Recurrence $recurrence */ public function destroy(Recurrence $recurrence): void { @@ -112,21 +127,6 @@ class RecurringRepository implements RecurringRepositoryInterface $this->user->recurrences()->delete(); } - /** - * Returns all of the user's recurring transactions. - * - * @return Collection - */ - public function get(): Collection - { - return $this->user->recurrences() - ->with(['TransactionCurrency', 'TransactionType', 'RecurrenceRepetitions', 'RecurrenceTransactions']) - ->orderBy('active', 'DESC') - ->orderBy('transaction_type_id', 'ASC') - ->orderBy('title', 'ASC') - ->get(); - } - /** * Get ALL recurring transactions. * @@ -160,7 +160,7 @@ class RecurringRepository implements RecurringRepositoryInterface /** * Get the budget ID from a recurring transaction transaction. * - * @param RecurrenceTransaction $recTransaction + * @param RecurrenceTransaction $recTransaction * * @return null|int */ @@ -180,7 +180,7 @@ class RecurringRepository implements RecurringRepositoryInterface /** * Get the category from a recurring transaction transaction. * - * @param RecurrenceTransaction $recTransaction + * @param RecurrenceTransaction $recTransaction * * @return null|int */ @@ -200,7 +200,7 @@ class RecurringRepository implements RecurringRepositoryInterface /** * Get the category from a recurring transaction transaction. * - * @param RecurrenceTransaction $recTransaction + * @param RecurrenceTransaction $recTransaction * * @return null|string */ @@ -220,9 +220,9 @@ class RecurringRepository implements RecurringRepositoryInterface /** * Returns the journals created for this recurrence, possibly limited by time. * - * @param Recurrence $recurrence - * @param Carbon|null $start - * @param Carbon|null $end + * @param Recurrence $recurrence + * @param Carbon|null $start + * @param Carbon|null $end * * @return int */ @@ -232,7 +232,7 @@ class RecurringRepository implements RecurringRepositoryInterface ->where('transaction_journals.user_id', $recurrence->user_id) ->whereNull('transaction_journals.deleted_at') ->where('journal_meta.name', 'recurrence_id') - ->where('journal_meta.data', '"'.$recurrence->id.'"'); + ->where('journal_meta.data', '"' . $recurrence->id . '"'); if (null !== $start) { $query->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00')); } @@ -245,7 +245,7 @@ class RecurringRepository implements RecurringRepositoryInterface /** * Get journal ID's for journals created by this recurring transaction. * - * @param Recurrence $recurrence + * @param Recurrence $recurrence * * @return array */ @@ -261,7 +261,7 @@ class RecurringRepository implements RecurringRepositoryInterface /** * Get the notes. * - * @param Recurrence $recurrence + * @param Recurrence $recurrence * * @return string */ @@ -277,46 +277,7 @@ class RecurringRepository implements RecurringRepositoryInterface } /** - * Generate events in the date range. - * - * @param RecurrenceRepetition $repetition - * @param Carbon $start - * @param Carbon $end - * - * @return array - * - */ - public function getOccurrencesInRange(RecurrenceRepetition $repetition, Carbon $start, Carbon $end): array - { - $occurrences = []; - $mutator = clone $start; - $mutator->startOfDay(); - $skipMod = $repetition->repetition_skip + 1; - Log::debug(sprintf('Calculating occurrences for rep type "%s"', $repetition->repetition_type)); - Log::debug(sprintf('Mutator is now: %s', $mutator->format('Y-m-d'))); - - if ('daily' === $repetition->repetition_type) { - $occurrences = $this->getDailyInRange($mutator, $end, $skipMod); - } - if ('weekly' === $repetition->repetition_type) { - $occurrences = $this->getWeeklyInRange($mutator, $end, $skipMod, $repetition->repetition_moment); - } - if ('monthly' === $repetition->repetition_type) { - $occurrences = $this->getMonthlyInRange($mutator, $end, $skipMod, $repetition->repetition_moment); - } - if ('ndom' === $repetition->repetition_type) { - $occurrences = $this->getNdomInRange($mutator, $end, $skipMod, $repetition->repetition_moment); - } - if ('yearly' === $repetition->repetition_type) { - $occurrences = $this->getYearlyInRange($mutator, $end, $skipMod, $repetition->repetition_moment); - } - - // filter out all the weekend days: - return $this->filterWeekends($repetition, $occurrences); - } - - /** - * @param RecurrenceTransaction $transaction + * @param RecurrenceTransaction $transaction * * @return int|null */ @@ -336,7 +297,7 @@ class RecurringRepository implements RecurringRepositoryInterface /** * Get the tags from the recurring transaction. * - * @param RecurrenceTransaction $transaction + * @param RecurrenceTransaction $transaction * * @return array * @throws JsonException @@ -355,9 +316,9 @@ class RecurringRepository implements RecurringRepositoryInterface } /** - * @param Recurrence $recurrence - * @param int $page - * @param int $pageSize + * @param Recurrence $recurrence + * @param int $page + * @param int $pageSize * * @return LengthAwarePaginator */ @@ -385,7 +346,17 @@ class RecurringRepository implements RecurringRepositoryInterface } /** - * @param Recurrence $recurrence + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + + /** + * @param Recurrence $recurrence * * @return Collection */ @@ -420,9 +391,9 @@ class RecurringRepository implements RecurringRepositoryInterface /** * Calculate the next X iterations starting on the date given in $date. * - * @param RecurrenceRepetition $repetition - * @param Carbon $date - * @param int $count + * @param RecurrenceRepetition $repetition + * @param Carbon $date + * @param int $count * * @return array * @@ -457,10 +428,10 @@ class RecurringRepository implements RecurringRepositoryInterface * * Only returns them of they are after $afterDate * - * @param RecurrenceRepetition $repetition - * @param Carbon $date - * @param Carbon $afterDate - * @param int $count + * @param RecurrenceRepetition $repetition + * @param Carbon $date + * @param Carbon $afterDate + * @param int $count * * @return array */ @@ -494,10 +465,31 @@ class RecurringRepository implements RecurringRepositoryInterface return $this->filterMaxDate($repeatUntil, $occurrences); } + /** + * @param Carbon|null $max + * @param array $occurrences + * + * @return array + */ + private function filterMaxDate(?Carbon $max, array $occurrences): array + { + if (null === $max) { + return $occurrences; + } + $filtered = []; + foreach ($occurrences as $date) { + if ($date->lte($max)) { + $filtered[] = $date; + } + } + + return $filtered; + } + /** * Parse the repetition in a string that is user readable. * - * @param RecurrenceRepetition $repetition + * @param RecurrenceRepetition $repetition * * @return string * @throws FireflyException @@ -571,17 +563,7 @@ class RecurringRepository implements RecurringRepositoryInterface } /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - - /** - * @param array $data + * @param array $data * * @return Recurrence * @throws FireflyException @@ -623,11 +605,50 @@ class RecurringRepository implements RecurringRepositoryInterface return 0; } + /** + * Generate events in the date range. + * + * @param RecurrenceRepetition $repetition + * @param Carbon $start + * @param Carbon $end + * + * @return array + * + */ + public function getOccurrencesInRange(RecurrenceRepetition $repetition, Carbon $start, Carbon $end): array + { + $occurrences = []; + $mutator = clone $start; + $mutator->startOfDay(); + $skipMod = $repetition->repetition_skip + 1; + Log::debug(sprintf('Calculating occurrences for rep type "%s"', $repetition->repetition_type)); + Log::debug(sprintf('Mutator is now: %s', $mutator->format('Y-m-d'))); + + if ('daily' === $repetition->repetition_type) { + $occurrences = $this->getDailyInRange($mutator, $end, $skipMod); + } + if ('weekly' === $repetition->repetition_type) { + $occurrences = $this->getWeeklyInRange($mutator, $end, $skipMod, $repetition->repetition_moment); + } + if ('monthly' === $repetition->repetition_type) { + $occurrences = $this->getMonthlyInRange($mutator, $end, $skipMod, $repetition->repetition_moment); + } + if ('ndom' === $repetition->repetition_type) { + $occurrences = $this->getNdomInRange($mutator, $end, $skipMod, $repetition->repetition_moment); + } + if ('yearly' === $repetition->repetition_type) { + $occurrences = $this->getYearlyInRange($mutator, $end, $skipMod, $repetition->repetition_moment); + } + + // filter out all the weekend days: + return $this->filterWeekends($repetition, $occurrences); + } + /** * Update a recurring transaction. * - * @param Recurrence $recurrence - * @param array $data + * @param Recurrence $recurrence + * @param array $data * * @return Recurrence * @throws FireflyException @@ -639,25 +660,4 @@ class RecurringRepository implements RecurringRepositoryInterface return $service->update($recurrence, $data); } - - /** - * @param Carbon|null $max - * @param array $occurrences - * - * @return array - */ - private function filterMaxDate(?Carbon $max, array $occurrences): array - { - if (null === $max) { - return $occurrences; - } - $filtered = []; - foreach ($occurrences as $date) { - if ($date->lte($max)) { - $filtered[] = $date; - } - } - - return $filtered; - } } diff --git a/app/Repositories/Recurring/RecurringRepositoryInterface.php b/app/Repositories/Recurring/RecurringRepositoryInterface.php index 14e483c05c..041ba85726 100644 --- a/app/Repositories/Recurring/RecurringRepositoryInterface.php +++ b/app/Repositories/Recurring/RecurringRepositoryInterface.php @@ -40,8 +40,8 @@ use Illuminate\Support\Collection; interface RecurringRepositoryInterface { /** - * @param Recurrence $recurrence - * @param Carbon $date + * @param Recurrence $recurrence + * @param Carbon $date * @return bool */ public function createdPreviously(Recurrence $recurrence, Carbon $date): bool; @@ -49,7 +49,7 @@ interface RecurringRepositoryInterface /** * Destroy a recurring transaction. * - * @param Recurrence $recurrence + * @param Recurrence $recurrence */ public function destroy(Recurrence $recurrence): void; @@ -75,7 +75,7 @@ interface RecurringRepositoryInterface /** * Get the category from a recurring transaction transaction. * - * @param RecurrenceTransaction $recTransaction + * @param RecurrenceTransaction $recTransaction * * @return null|int */ @@ -84,7 +84,7 @@ interface RecurringRepositoryInterface /** * Get the budget ID from a recurring transaction transaction. * - * @param RecurrenceTransaction $recTransaction + * @param RecurrenceTransaction $recTransaction * * @return null|int */ @@ -93,7 +93,7 @@ interface RecurringRepositoryInterface /** * Get the category from a recurring transaction transaction. * - * @param RecurrenceTransaction $recTransaction + * @param RecurrenceTransaction $recTransaction * * @return null|int */ @@ -102,7 +102,7 @@ interface RecurringRepositoryInterface /** * Get the category from a recurring transaction transaction. * - * @param RecurrenceTransaction $recTransaction + * @param RecurrenceTransaction $recTransaction * * @return null|string */ @@ -111,9 +111,9 @@ interface RecurringRepositoryInterface /** * Returns the count of journals created for this recurrence, possibly limited by time. * - * @param Recurrence $recurrence - * @param Carbon|null $start - * @param Carbon|null $end + * @param Recurrence $recurrence + * @param Carbon|null $start + * @param Carbon|null $end * * @return int */ @@ -122,7 +122,7 @@ interface RecurringRepositoryInterface /** * Get journal ID's for journals created by this recurring transaction. * - * @param Recurrence $recurrence + * @param Recurrence $recurrence * * @return array */ @@ -131,7 +131,7 @@ interface RecurringRepositoryInterface /** * Get the notes. * - * @param Recurrence $recurrence + * @param Recurrence $recurrence * * @return string */ @@ -140,16 +140,16 @@ interface RecurringRepositoryInterface /** * Generate events in the date range. * - * @param RecurrenceRepetition $repetition - * @param Carbon $start - * @param Carbon $end + * @param RecurrenceRepetition $repetition + * @param Carbon $start + * @param Carbon $end * * @return array */ public function getOccurrencesInRange(RecurrenceRepetition $repetition, Carbon $start, Carbon $end): array; /** - * @param RecurrenceTransaction $transaction + * @param RecurrenceTransaction $transaction * * @return int|null */ @@ -158,23 +158,23 @@ interface RecurringRepositoryInterface /** * Get the tags from the recurring transaction. * - * @param RecurrenceTransaction $transaction + * @param RecurrenceTransaction $transaction * * @return array */ public function getTags(RecurrenceTransaction $transaction): array; /** - * @param Recurrence $recurrence - * @param int $page - * @param int $pageSize + * @param Recurrence $recurrence + * @param int $page + * @param int $pageSize * * @return LengthAwarePaginator */ public function getTransactionPaginator(Recurrence $recurrence, int $page, int $pageSize): LengthAwarePaginator; /** - * @param Recurrence $recurrence + * @param Recurrence $recurrence * * @return Collection */ @@ -184,9 +184,9 @@ interface RecurringRepositoryInterface * Calculate the next X iterations starting on the date given in $date. * Returns an array of Carbon objects. * - * @param RecurrenceRepetition $repetition - * @param Carbon $date - * @param int $count + * @param RecurrenceRepetition $repetition + * @param Carbon $date + * @param int $count * * @return array * @throws FireflyException @@ -199,10 +199,10 @@ interface RecurringRepositoryInterface * * Only returns them of they are after $afterDate * - * @param RecurrenceRepetition $repetition - * @param Carbon $date - * @param Carbon $afterDate - * @param int $count + * @param RecurrenceRepetition $repetition + * @param Carbon $date + * @param Carbon $afterDate + * @param int $count * * @return array * @throws FireflyException @@ -212,29 +212,29 @@ interface RecurringRepositoryInterface /** * Parse the repetition in a string that is user readable. * - * @param RecurrenceRepetition $repetition + * @param RecurrenceRepetition $repetition * * @return string */ public function repetitionDescription(RecurrenceRepetition $repetition): string; /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ public function searchRecurrence(string $query, int $limit): Collection; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** * Store a new recurring transaction. * - * @param array $data + * @param array $data * * @return Recurrence * @throws FireflyException @@ -244,8 +244,8 @@ interface RecurringRepositoryInterface /** * Calculate how many transactions are to be expected from this recurrence. * - * @param Recurrence $recurrence - * @param RecurrenceRepetition $repetition + * @param Recurrence $recurrence + * @param RecurrenceRepetition $repetition * * @return int */ @@ -254,8 +254,8 @@ interface RecurringRepositoryInterface /** * Update a recurring transaction. * - * @param Recurrence $recurrence - * @param array $data + * @param Recurrence $recurrence + * @param array $data * * @return Recurrence */ diff --git a/app/Repositories/Rule/RuleRepository.php b/app/Repositories/Rule/RuleRepository.php index afbf6ef786..46e8a84afb 100644 --- a/app/Repositories/Rule/RuleRepository.php +++ b/app/Repositories/Rule/RuleRepository.php @@ -46,15 +46,7 @@ class RuleRepository implements RuleRepositoryInterface private $user; /** - * @return int - */ - public function count(): int - { - return $this->user->rules()->count(); - } - - /** - * @param Rule $rule + * @param Rule $rule * * @return bool * @throws Exception @@ -100,16 +92,6 @@ class RuleRepository implements RuleRepositoryInterface return $newRule; } - /** - * @param int $ruleId - * - * @return Rule|null - */ - public function find(int $ruleId): ?Rule - { - return $this->user->rules()->find($ruleId); - } - /** * Get all the users rules. * @@ -131,7 +113,7 @@ class RuleRepository implements RuleRepositoryInterface } /** - * @param RuleGroup $ruleGroup + * @param RuleGroup $ruleGroup * * @return int */ @@ -141,7 +123,7 @@ class RuleRepository implements RuleRepositoryInterface } /** - * @param Rule $rule + * @param Rule $rule * * @return string * @@ -151,14 +133,22 @@ class RuleRepository implements RuleRepositoryInterface { $count = $rule->ruleTriggers()->count(); if (0 === $count) { - throw new FireflyException('Rules should have more than zero triggers, rule #'.$rule->id.' has none!'); + throw new FireflyException('Rules should have more than zero triggers, rule #' . $rule->id . ' has none!'); } return $rule->ruleTriggers()->where('trigger_type', 'user_action')->first()->trigger_value; } /** - * @param Rule $rule + * @return int + */ + public function count(): int + { + return $this->user->rules()->count(); + } + + /** + * @param Rule $rule * * @return Collection */ @@ -168,7 +158,7 @@ class RuleRepository implements RuleRepositoryInterface } /** - * @param Rule $rule + * @param Rule $rule * * @return Collection */ @@ -254,43 +244,6 @@ class RuleRepository implements RuleRepositoryInterface return $filtered; } - /** - * @inheritDoc - */ - public function maxOrder(RuleGroup $ruleGroup): int - { - return (int)$ruleGroup->rules()->max('order'); - } - - /** - * @inheritDoc - */ - public function moveRule(Rule $rule, RuleGroup $ruleGroup, int $order): Rule - { - if ($rule->rule_group_id !== $ruleGroup->id) { - $rule->rule_group_id = $ruleGroup->id; - } - $rule->save(); - $rule->refresh(); - $this->setOrder($rule, $order); - - return $rule; - } - - /** - * @param RuleGroup $ruleGroup - * - * @return bool - */ - public function resetRuleOrder(RuleGroup $ruleGroup): bool - { - $groupRepository = app(RuleGroupRepositoryInterface::class); - $groupRepository->setUser($ruleGroup->user); - $groupRepository->resetRuleOrder($ruleGroup); - - return true; - } - /** * @inheritDoc */ @@ -307,53 +260,7 @@ class RuleRepository implements RuleRepositoryInterface } /** - * @inheritDoc - */ - public function setOrder(Rule $rule, int $newOrder): void - { - $oldOrder = (int)$rule->order; - $groupId = (int)$rule->rule_group_id; - $maxOrder = $this->maxOrder($rule->ruleGroup); - $newOrder = $newOrder > $maxOrder ? $maxOrder + 1 : $newOrder; - Log::debug(sprintf('New order will be %d', $newOrder)); - - if ($newOrder > $oldOrder) { - $this->user->rules() - ->where('rules.rule_group_id', $groupId) - ->where('rules.order', '<=', $newOrder) - ->where('rules.order', '>', $oldOrder) - ->where('rules.id', '!=', $rule->id) - ->decrement('rules.order'); - $rule->order = $newOrder; - Log::debug(sprintf('Order of rule #%d ("%s") is now %d', $rule->id, $rule->title, $newOrder)); - $rule->save(); - - return; - } - - $this->user->rules() - ->where('rules.rule_group_id', $groupId) - ->where('rules.order', '>=', $newOrder) - ->where('rules.order', '<', $oldOrder) - ->where('rules.id', '!=', $rule->id) - ->increment('rules.order'); - $rule->order = $newOrder; - Log::debug(sprintf('Order of rule #%d ("%s") is now %d', $rule->id, $rule->title, $newOrder)); - $rule->save(); - } - - /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - - /** - * @param array $data + * @param array $data * * @return Rule * @throws FireflyException @@ -407,28 +314,140 @@ class RuleRepository implements RuleRepositoryInterface } /** - * @param Rule $rule - * @param array $values + * @param int $ruleId * - * @return RuleAction + * @return Rule|null */ - public function storeAction(Rule $rule, array $values): RuleAction + public function find(int $ruleId): ?Rule { - $ruleAction = new RuleAction(); - $ruleAction->rule()->associate($rule); - $ruleAction->order = $values['order']; - $ruleAction->active = $values['active']; - $ruleAction->stop_processing = $values['stop_processing']; - $ruleAction->action_type = $values['action']; - $ruleAction->action_value = $values['value'] ?? ''; - $ruleAction->save(); - - return $ruleAction; + return $this->user->rules()->find($ruleId); } /** - * @param Rule $rule - * @param array $values + * @param string $moment + * @param Rule $rule + */ + private function setRuleTrigger(string $moment, Rule $rule): void + { + /** @var RuleTrigger|null $trigger */ + $trigger = $rule->ruleTriggers()->where('trigger_type', 'user_action')->first(); + if (null !== $trigger) { + $trigger->trigger_value = $moment; + $trigger->save(); + + return; + } + $trigger = new RuleTrigger(); + $trigger->order = 0; + $trigger->trigger_type = 'user_action'; + $trigger->trigger_value = $moment; + $trigger->rule_id = $rule->id; + $trigger->active = true; + $trigger->stop_processing = false; + $trigger->save(); + } + + /** + * @param RuleGroup $ruleGroup + * + * @return bool + */ + public function resetRuleOrder(RuleGroup $ruleGroup): bool + { + $groupRepository = app(RuleGroupRepositoryInterface::class); + $groupRepository->setUser($ruleGroup->user); + $groupRepository->resetRuleOrder($ruleGroup); + + return true; + } + + /** + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + + /** + * @inheritDoc + */ + public function setOrder(Rule $rule, int $newOrder): void + { + $oldOrder = (int)$rule->order; + $groupId = (int)$rule->rule_group_id; + $maxOrder = $this->maxOrder($rule->ruleGroup); + $newOrder = $newOrder > $maxOrder ? $maxOrder + 1 : $newOrder; + Log::debug(sprintf('New order will be %d', $newOrder)); + + if ($newOrder > $oldOrder) { + $this->user->rules() + ->where('rules.rule_group_id', $groupId) + ->where('rules.order', '<=', $newOrder) + ->where('rules.order', '>', $oldOrder) + ->where('rules.id', '!=', $rule->id) + ->decrement('rules.order'); + $rule->order = $newOrder; + Log::debug(sprintf('Order of rule #%d ("%s") is now %d', $rule->id, $rule->title, $newOrder)); + $rule->save(); + + return; + } + + $this->user->rules() + ->where('rules.rule_group_id', $groupId) + ->where('rules.order', '>=', $newOrder) + ->where('rules.order', '<', $oldOrder) + ->where('rules.id', '!=', $rule->id) + ->increment('rules.order'); + $rule->order = $newOrder; + Log::debug(sprintf('Order of rule #%d ("%s") is now %d', $rule->id, $rule->title, $newOrder)); + $rule->save(); + } + + /** + * @inheritDoc + */ + public function maxOrder(RuleGroup $ruleGroup): int + { + return (int)$ruleGroup->rules()->max('order'); + } + + /** + * @param Rule $rule + * @param array $data + * + * @return void + */ + private function storeTriggers(Rule $rule, array $data): void + { + $order = 1; + foreach ($data['triggers'] as $trigger) { + $value = $trigger['value'] ?? ''; + $stopProcessing = $trigger['stop_processing'] ?? false; + $active = $trigger['active'] ?? true; + $type = $trigger['type']; + if (true === ($trigger['prohibited'] ?? false) && !str_starts_with($type, '-')) { + $type = sprintf('-%s', $type); + } + + $triggerValues = [ + 'action' => $type, + 'value' => $value, + 'stop_processing' => $stopProcessing, + 'order' => $order, + 'active' => $active, + ]; + $this->storeTrigger($rule, $triggerValues); + ++$order; + } + } + + /** + * @param Rule $rule + * @param array $values * * @return RuleTrigger */ @@ -447,8 +466,53 @@ class RuleRepository implements RuleRepositoryInterface } /** - * @param Rule $rule - * @param array $data + * @param Rule $rule + * @param array $data + * + * @return void + */ + private function storeActions(Rule $rule, array $data): void + { + $order = 1; + foreach ($data['actions'] as $action) { + $value = $action['value'] ?? ''; + $stopProcessing = $action['stop_processing'] ?? false; + $active = $action['active'] ?? true; + $actionValues = [ + 'action' => $action['type'], + 'value' => $value, + 'stop_processing' => $stopProcessing, + 'order' => $order, + 'active' => $active, + ]; + $this->storeAction($rule, $actionValues); + ++$order; + } + } + + /** + * @param Rule $rule + * @param array $values + * + * @return RuleAction + */ + public function storeAction(Rule $rule, array $values): RuleAction + { + $ruleAction = new RuleAction(); + $ruleAction->rule()->associate($rule); + $ruleAction->order = $values['order']; + $ruleAction->active = $values['active']; + $ruleAction->stop_processing = $values['stop_processing']; + $ruleAction->action_type = $values['action']; + $ruleAction->action_value = $values['value'] ?? ''; + $ruleAction->save(); + + return $ruleAction; + } + + /** + * @param Rule $rule + * @param array $data * * @return Rule */ @@ -505,81 +569,17 @@ class RuleRepository implements RuleRepositoryInterface } /** - * @param string $moment - * @param Rule $rule + * @inheritDoc */ - private function setRuleTrigger(string $moment, Rule $rule): void + public function moveRule(Rule $rule, RuleGroup $ruleGroup, int $order): Rule { - /** @var RuleTrigger|null $trigger */ - $trigger = $rule->ruleTriggers()->where('trigger_type', 'user_action')->first(); - if (null !== $trigger) { - $trigger->trigger_value = $moment; - $trigger->save(); - - return; + if ($rule->rule_group_id !== $ruleGroup->id) { + $rule->rule_group_id = $ruleGroup->id; } - $trigger = new RuleTrigger(); - $trigger->order = 0; - $trigger->trigger_type = 'user_action'; - $trigger->trigger_value = $moment; - $trigger->rule_id = $rule->id; - $trigger->active = true; - $trigger->stop_processing = false; - $trigger->save(); - } + $rule->save(); + $rule->refresh(); + $this->setOrder($rule, $order); - /** - * @param Rule $rule - * @param array $data - * - * @return void - */ - private function storeActions(Rule $rule, array $data): void - { - $order = 1; - foreach ($data['actions'] as $action) { - $value = $action['value'] ?? ''; - $stopProcessing = $action['stop_processing'] ?? false; - $active = $action['active'] ?? true; - $actionValues = [ - 'action' => $action['type'], - 'value' => $value, - 'stop_processing' => $stopProcessing, - 'order' => $order, - 'active' => $active, - ]; - $this->storeAction($rule, $actionValues); - ++$order; - } - } - - /** - * @param Rule $rule - * @param array $data - * - * @return void - */ - private function storeTriggers(Rule $rule, array $data): void - { - $order = 1; - foreach ($data['triggers'] as $trigger) { - $value = $trigger['value'] ?? ''; - $stopProcessing = $trigger['stop_processing'] ?? false; - $active = $trigger['active'] ?? true; - $type = $trigger['type']; - if (true === ($trigger['prohibited'] ?? false) && !str_starts_with($type, '-')) { - $type = sprintf('-%s', $type); - } - - $triggerValues = [ - 'action' => $type, - 'value' => $value, - 'stop_processing' => $stopProcessing, - 'order' => $order, - 'active' => $active, - ]; - $this->storeTrigger($rule, $triggerValues); - ++$order; - } + return $rule; } } diff --git a/app/Repositories/Rule/RuleRepositoryInterface.php b/app/Repositories/Rule/RuleRepositoryInterface.php index 9c70180933..a38590c6de 100644 --- a/app/Repositories/Rule/RuleRepositoryInterface.php +++ b/app/Repositories/Rule/RuleRepositoryInterface.php @@ -42,21 +42,21 @@ interface RuleRepositoryInterface public function count(): int; /** - * @param Rule $rule + * @param Rule $rule * * @return bool */ public function destroy(Rule $rule): bool; /** - * @param Rule $rule + * @param Rule $rule * * @return Rule */ public function duplicate(Rule $rule): Rule; /** - * @param int $ruleId + * @param int $ruleId * * @return Rule|null */ @@ -75,28 +75,28 @@ interface RuleRepositoryInterface public function getFirstRuleGroup(): RuleGroup; /** - * @param RuleGroup $ruleGroup + * @param RuleGroup $ruleGroup * * @return int */ public function getHighestOrderInRuleGroup(RuleGroup $ruleGroup): int; /** - * @param Rule $rule + * @param Rule $rule * * @return string */ public function getPrimaryTrigger(Rule $rule): string; /** - * @param Rule $rule + * @param Rule $rule * * @return Collection */ public function getRuleActions(Rule $rule): Collection; /** - * @param Rule $rule + * @param Rule $rule * * @return Collection */ @@ -105,7 +105,7 @@ interface RuleRepositoryInterface /** * Return search query for rule. * - * @param Rule $rule + * @param Rule $rule * * @return string */ @@ -126,73 +126,73 @@ interface RuleRepositoryInterface public function getUpdateRules(): Collection; /** - * @param RuleGroup $ruleGroup + * @param RuleGroup $ruleGroup * * @return int */ public function maxOrder(RuleGroup $ruleGroup): int; /** - * @param Rule $rule - * @param RuleGroup $ruleGroup - * @param int $order + * @param Rule $rule + * @param RuleGroup $ruleGroup + * @param int $order * * @return Rule */ public function moveRule(Rule $rule, RuleGroup $ruleGroup, int $order): Rule; /** - * @param RuleGroup $ruleGroup + * @param RuleGroup $ruleGroup * * @return bool */ public function resetRuleOrder(RuleGroup $ruleGroup): bool; /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ public function searchRule(string $query, int $limit): Collection; /** - * @param Rule $rule - * @param int $newOrder + * @param Rule $rule + * @param int $newOrder */ public function setOrder(Rule $rule, int $newOrder): void; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** - * @param array $data + * @param array $data * * @return Rule */ public function store(array $data): Rule; /** - * @param Rule $rule - * @param array $values + * @param Rule $rule + * @param array $values * * @return RuleAction */ public function storeAction(Rule $rule, array $values): RuleAction; /** - * @param Rule $rule - * @param array $values + * @param Rule $rule + * @param array $values * * @return RuleTrigger */ public function storeTrigger(Rule $rule, array $values): RuleTrigger; /** - * @param Rule $rule - * @param array $data + * @param Rule $rule + * @param array $data * * @return Rule */ diff --git a/app/Repositories/RuleGroup/RuleGroupRepository.php b/app/Repositories/RuleGroup/RuleGroupRepository.php index 8d9132f2c0..b60e0035cc 100644 --- a/app/Repositories/RuleGroup/RuleGroupRepository.php +++ b/app/Repositories/RuleGroup/RuleGroupRepository.php @@ -63,6 +63,14 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface } } + /** + * @return Collection + */ + public function get(): Collection + { + return $this->user->ruleGroups()->orderBy('order', 'ASC')->get(); + } + /** * @return int */ @@ -72,8 +80,8 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface } /** - * @param RuleGroup $ruleGroup - * @param RuleGroup|null $moveTo + * @param RuleGroup $ruleGroup + * @param RuleGroup|null $moveTo * * @return bool * @throws Exception @@ -101,6 +109,108 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface return true; } + /** + * @return bool + */ + public function resetOrder(): bool + { + $set = $this->user + ->ruleGroups() + ->whereNull('deleted_at') + ->orderBy('order', 'ASC') + ->orderBy('title', 'DESC') + ->get(); + $count = 1; + /** @var RuleGroup $entry */ + foreach ($set as $entry) { + if ($entry->order !== $count) { + $entry->order = $count; + $entry->save(); + } + + // also update rules in group. + $this->resetRuleOrder($entry); + + ++$count; + } + + return true; + } + + /** + * @param RuleGroup $ruleGroup + * + * @return bool + */ + public function resetRuleOrder(RuleGroup $ruleGroup): bool + { + $set = $ruleGroup->rules() + ->orderBy('order', 'ASC') + ->orderBy('title', 'DESC') + ->orderBy('updated_at', 'DESC') + ->get(['rules.*']); + $count = 1; + /** @var Rule $entry */ + foreach ($set as $entry) { + if ((int)$entry->order !== $count) { + Log::debug(sprintf('Rule #%d was on spot %d but must be on spot %d', $entry->id, $entry->order, $count)); + $entry->order = $count; + $entry->save(); + } + $this->resetRuleActionOrder($entry); + $this->resetRuleTriggerOrder($entry); + + ++$count; + } + + return true; + } + + /** + * @param Rule $rule + */ + private function resetRuleActionOrder(Rule $rule): void + { + $actions = $rule->ruleActions() + ->orderBy('order', 'ASC') + ->orderBy('active', 'DESC') + ->orderBy('action_type', 'ASC') + ->get(); + $index = 1; + /** @var RuleAction $action */ + foreach ($actions as $action) { + if ((int)$action->order !== $index) { + $action->order = $index; + $action->save(); + Log::debug(sprintf('Rule action #%d was on spot %d but must be on spot %d', $action->id, $action->order, $index)); + } + $index++; + } + } + + /** + * @param Rule $rule + */ + private function resetRuleTriggerOrder(Rule $rule): void + { + $triggers = $rule->ruleTriggers() + ->orderBy('order', 'ASC') + ->orderBy('active', 'DESC') + ->orderBy('trigger_type', 'ASC') + ->get(); + $index = 1; + /** @var RuleTrigger $trigger */ + foreach ($triggers as $trigger) { + $order = (int)$trigger->order; + if ($order !== $index) { + $trigger->order = $index; + $trigger->save(); + Log::debug(sprintf('Rule trigger #%d was on spot %d but must be on spot %d', $trigger->id, $order, $index)); + } + $index++; + } + } + /** * @inheritDoc */ @@ -115,7 +225,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface } /** - * @param int $ruleGroupId + * @param int $ruleGroupId * * @return RuleGroup|null */ @@ -125,7 +235,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface } /** - * @param string $title + * @param string $title * * @return RuleGroup|null */ @@ -134,14 +244,6 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface return $this->user->ruleGroups()->where('title', $title)->first(); } - /** - * @return Collection - */ - public function get(): Collection - { - return $this->user->ruleGroups()->orderBy('order', 'ASC')->get(); - } - /** * @return Collection */ @@ -151,7 +253,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface } /** - * @param RuleGroup $group + * @param RuleGroup $group * * @return Collection */ @@ -163,7 +265,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface } /** - * @param RuleGroup $group + * @param RuleGroup $group * * @return Collection */ @@ -178,7 +280,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface } /** - * @param RuleGroup $group + * @param RuleGroup $group * * @return Collection */ @@ -193,7 +295,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface } /** - * @param string|null $filter + * @param string|null $filter * * @return Collection */ @@ -255,7 +357,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface } /** - * @param string|null $filter + * @param string|null $filter * * @return Collection */ @@ -308,7 +410,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface } /** - * @param RuleGroup $group + * @param RuleGroup $group * * @return Collection */ @@ -326,63 +428,6 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface return (int)$this->user->ruleGroups()->where('active', true)->max('order'); } - /** - * @return bool - */ - public function resetOrder(): bool - { - $set = $this->user - ->ruleGroups() - ->whereNull('deleted_at') - ->orderBy('order', 'ASC') - ->orderBy('title', 'DESC') - ->get(); - $count = 1; - /** @var RuleGroup $entry */ - foreach ($set as $entry) { - if ($entry->order !== $count) { - $entry->order = $count; - $entry->save(); - } - - // also update rules in group. - $this->resetRuleOrder($entry); - - ++$count; - } - - return true; - } - - /** - * @param RuleGroup $ruleGroup - * - * @return bool - */ - public function resetRuleOrder(RuleGroup $ruleGroup): bool - { - $set = $ruleGroup->rules() - ->orderBy('order', 'ASC') - ->orderBy('title', 'DESC') - ->orderBy('updated_at', 'DESC') - ->get(['rules.*']); - $count = 1; - /** @var Rule $entry */ - foreach ($set as $entry) { - if ((int)$entry->order !== $count) { - Log::debug(sprintf('Rule #%d was on spot %d but must be on spot %d', $entry->id, $entry->order, $count)); - $entry->order = $count; - $entry->save(); - } - $this->resetRuleActionOrder($entry); - $this->resetRuleTriggerOrder($entry); - - ++$count; - } - - return true; - } - /** * @inheritDoc */ @@ -398,6 +443,41 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface return $search->take($limit)->get(['id', 'title', 'description']); } + /** + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + + /** + * @param array $data + * + * @return RuleGroup + */ + public function store(array $data): RuleGroup + { + $newRuleGroup = new RuleGroup( + [ + 'user_id' => $this->user->id, + 'title' => $data['title'], + 'description' => $data['description'], + 'order' => 31337, + 'active' => array_key_exists('active', $data) ? $data['active'] : true, + ] + ); + $newRuleGroup->save(); + $this->resetOrder(); + if (array_key_exists('order', $data)) { + $this->setOrder($newRuleGroup, $data['order']); + } + + return $newRuleGroup; + } + /** * @inheritDoc */ @@ -425,43 +505,8 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface } /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - - /** - * @param array $data - * - * @return RuleGroup - */ - public function store(array $data): RuleGroup - { - $newRuleGroup = new RuleGroup( - [ - 'user_id' => $this->user->id, - 'title' => $data['title'], - 'description' => $data['description'], - 'order' => 31337, - 'active' => array_key_exists('active', $data) ? $data['active'] : true, - ] - ); - $newRuleGroup->save(); - $this->resetOrder(); - if (array_key_exists('order', $data)) { - $this->setOrder($newRuleGroup, $data['order']); - } - - return $newRuleGroup; - } - - /** - * @param RuleGroup $ruleGroup - * @param array $data + * @param RuleGroup $ruleGroup + * @param array $data * * @return RuleGroup */ @@ -487,49 +532,4 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface return $ruleGroup; } - - /** - * @param Rule $rule - */ - private function resetRuleActionOrder(Rule $rule): void - { - $actions = $rule->ruleActions() - ->orderBy('order', 'ASC') - ->orderBy('active', 'DESC') - ->orderBy('action_type', 'ASC') - ->get(); - $index = 1; - /** @var RuleAction $action */ - foreach ($actions as $action) { - if ((int)$action->order !== $index) { - $action->order = $index; - $action->save(); - Log::debug(sprintf('Rule action #%d was on spot %d but must be on spot %d', $action->id, $action->order, $index)); - } - $index++; - } - } - - /** - * @param Rule $rule - */ - private function resetRuleTriggerOrder(Rule $rule): void - { - $triggers = $rule->ruleTriggers() - ->orderBy('order', 'ASC') - ->orderBy('active', 'DESC') - ->orderBy('trigger_type', 'ASC') - ->get(); - $index = 1; - /** @var RuleTrigger $trigger */ - foreach ($triggers as $trigger) { - $order = (int)$trigger->order; - if ($order !== $index) { - $trigger->order = $index; - $trigger->save(); - Log::debug(sprintf('Rule trigger #%d was on spot %d but must be on spot %d', $trigger->id, $order, $index)); - } - $index++; - } - } } diff --git a/app/Repositories/RuleGroup/RuleGroupRepositoryInterface.php b/app/Repositories/RuleGroup/RuleGroupRepositoryInterface.php index 9ab7eeabcd..9bb34dfc2e 100644 --- a/app/Repositories/RuleGroup/RuleGroupRepositoryInterface.php +++ b/app/Repositories/RuleGroup/RuleGroupRepositoryInterface.php @@ -44,8 +44,8 @@ interface RuleGroupRepositoryInterface public function count(): int; /** - * @param RuleGroup $ruleGroup - * @param RuleGroup|null $moveTo + * @param RuleGroup $ruleGroup + * @param RuleGroup|null $moveTo * * @return bool */ @@ -57,14 +57,14 @@ interface RuleGroupRepositoryInterface public function destroyAll(): void; /** - * @param int $ruleGroupId + * @param int $ruleGroupId * * @return RuleGroup|null */ public function find(int $ruleGroupId): ?RuleGroup; /** - * @param string $title + * @param string $title * * @return RuleGroup|null */ @@ -83,21 +83,21 @@ interface RuleGroupRepositoryInterface public function getActiveGroups(): Collection; /** - * @param RuleGroup $group + * @param RuleGroup $group * * @return Collection */ public function getActiveRules(RuleGroup $group): Collection; /** - * @param RuleGroup $group + * @param RuleGroup $group * * @return Collection */ public function getActiveStoreRules(RuleGroup $group): Collection; /** - * @param RuleGroup $group + * @param RuleGroup $group * * @return Collection */ @@ -106,7 +106,7 @@ interface RuleGroupRepositoryInterface /** * Also inactive groups. * - * @param string|null $filter + * @param string|null $filter * * @return Collection */ @@ -118,14 +118,14 @@ interface RuleGroupRepositoryInterface public function getHighestOrderRuleGroup(): int; /** - * @param string|null $filter + * @param string|null $filter * * @return Collection */ public function getRuleGroupsWithRules(?string $filter): Collection; /** - * @param RuleGroup $group + * @param RuleGroup $group * * @return Collection */ @@ -144,41 +144,41 @@ interface RuleGroupRepositoryInterface public function resetOrder(): bool; /** - * @param RuleGroup $ruleGroup + * @param RuleGroup $ruleGroup * * @return bool */ public function resetRuleOrder(RuleGroup $ruleGroup): bool; /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ public function searchRuleGroup(string $query, int $limit): Collection; /** - * @param RuleGroup $ruleGroup - * @param int $newOrder + * @param RuleGroup $ruleGroup + * @param int $newOrder */ public function setOrder(RuleGroup $ruleGroup, int $newOrder): void; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** - * @param array $data + * @param array $data * * @return RuleGroup */ public function store(array $data): RuleGroup; /** - * @param RuleGroup $ruleGroup - * @param array $data + * @param RuleGroup $ruleGroup + * @param array $data * * @return RuleGroup */ diff --git a/app/Repositories/Tag/OperationsRepository.php b/app/Repositories/Tag/OperationsRepository.php index dad14b79ed..874afc2f4e 100644 --- a/app/Repositories/Tag/OperationsRepository.php +++ b/app/Repositories/Tag/OperationsRepository.php @@ -47,10 +47,10 @@ class OperationsRepository implements OperationsRepositoryInterface * which have the specified tag(s) set to them. It's grouped per currency, with as few details in the array * as possible. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $tags + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $tags * * @return array * @throws ContainerExceptionInterface @@ -119,15 +119,37 @@ class OperationsRepository implements OperationsRepositoryInterface return $array; } + /** + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + + /** + * @return Collection + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + private function getTags(): Collection + { + $repository = app(TagRepositoryInterface::class); + + return $repository->get(); + } + /** * This method returns a list of all the deposit transaction journals (as arrays) set in that period * which have the specified tag(s) set to them. It's grouped per currency, with as few details in the array * as possible. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $tags + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $tags * * @return array * @throws ContainerExceptionInterface @@ -197,23 +219,13 @@ class OperationsRepository implements OperationsRepositoryInterface return $array; } - /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - /** * Sum of withdrawal journals in period for a set of tags, grouped per currency. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $tags + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $tags * * @return array * @throws FireflyException @@ -226,10 +238,10 @@ class OperationsRepository implements OperationsRepositoryInterface /** * Sum of income journals in period for a set of tags, grouped per currency. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $tags + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $tags * * @return array * @throws FireflyException @@ -238,16 +250,4 @@ class OperationsRepository implements OperationsRepositoryInterface { throw new FireflyException(sprintf('%s is not yet implemented.', __METHOD__)); } - - /** - * @return Collection - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - private function getTags(): Collection - { - $repository = app(TagRepositoryInterface::class); - - return $repository->get(); - } } diff --git a/app/Repositories/Tag/OperationsRepositoryInterface.php b/app/Repositories/Tag/OperationsRepositoryInterface.php index 6e1b6cba24..aecd897518 100644 --- a/app/Repositories/Tag/OperationsRepositoryInterface.php +++ b/app/Repositories/Tag/OperationsRepositoryInterface.php @@ -40,10 +40,10 @@ interface OperationsRepositoryInterface * which have the specified tag(s) set to them. It's grouped per currency, with as few details in the array * as possible. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $tags + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $tags * * @return array */ @@ -54,27 +54,27 @@ interface OperationsRepositoryInterface * which have the specified tag(s) set to them. It's grouped per currency, with as few details in the array * as possible. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $tags + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $tags * * @return array */ public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $tags = null): array; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** * Sum of withdrawal journals in period for a set of tags, grouped per currency. Amounts are always negative. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $tags + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $tags * * @return array */ @@ -83,10 +83,10 @@ interface OperationsRepositoryInterface /** * Sum of income journals in period for a set of tags, grouped per currency. Amounts are always positive. * - * @param Carbon $start - * @param Carbon $end - * @param Collection|null $accounts - * @param Collection|null $tags + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $tags * * @return array */ diff --git a/app/Repositories/Tag/TagRepository.php b/app/Repositories/Tag/TagRepository.php index 2691cb8a31..6b64f7e81f 100644 --- a/app/Repositories/Tag/TagRepository.php +++ b/app/Repositories/Tag/TagRepository.php @@ -56,7 +56,7 @@ class TagRepository implements TagRepositoryInterface } /** - * @param Tag $tag + * @param Tag $tag * * @return bool * @throws Exception @@ -84,9 +84,17 @@ class TagRepository implements TagRepositoryInterface } /** - * @param Tag $tag - * @param Carbon $start - * @param Carbon $end + * @return Collection + */ + public function get(): Collection + { + return $this->user->tags()->orderBy('tag', 'ASC')->get(); + } + + /** + * @param Tag $tag + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -102,7 +110,17 @@ class TagRepository implements TagRepositoryInterface } /** - * @param int $tagId + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + + /** + * @param int $tagId * * @return Tag|null */ @@ -112,7 +130,7 @@ class TagRepository implements TagRepositoryInterface } /** - * @param string $tag + * @param string $tag * * @return Tag|null */ @@ -123,7 +141,7 @@ class TagRepository implements TagRepositoryInterface } /** - * @param Tag $tag + * @param Tag $tag * * @return Carbon|null */ @@ -133,14 +151,6 @@ class TagRepository implements TagRepositoryInterface return $tag->transactionJournals()->orderBy('date', 'ASC')->first()?->date; } - /** - * @return Collection - */ - public function get(): Collection - { - return $this->user->tags()->orderBy('tag', 'ASC')->get(); - } - /** * @inheritDoc */ @@ -162,16 +172,7 @@ class TagRepository implements TagRepositoryInterface } /** - * @inheritDoc - */ - public function getLocation(Tag $tag): ?Location - { - /** @var Location|null */ - return $tag->locations()->first(); - } - - /** - * @param int|null $year + * @param int|null $year * * @return array */ @@ -188,7 +189,7 @@ class TagRepository implements TagRepositoryInterface if (null !== $year) { Log::debug(sprintf('Get tags with year %s.', $year)); - $tagQuery->where('tags.date', '>=', $year.'-01-01 00:00:00')->where('tags.date', '<=', $year.'-12-31 23:59:59'); + $tagQuery->where('tags.date', '>=', $year . '-01-01 00:00:00')->where('tags.date', '<=', $year . '-12-31 23:59:59'); } $collection = $tagQuery->get(); $return = []; @@ -208,9 +209,9 @@ class TagRepository implements TagRepositoryInterface } /** - * @param Tag $tag - * @param Carbon $start - * @param Carbon $end + * @param Tag $tag + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -226,7 +227,7 @@ class TagRepository implements TagRepositoryInterface } /** - * @param Tag $tag + * @param Tag $tag * * @return Carbon|null */ @@ -259,7 +260,7 @@ class TagRepository implements TagRepositoryInterface /** * Find one or more tags based on the query. * - * @param string $query + * @param string $query * * @return Collection */ @@ -273,8 +274,8 @@ class TagRepository implements TagRepositoryInterface /** * Search the users tags. * - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ @@ -291,17 +292,7 @@ class TagRepository implements TagRepositoryInterface } /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - - /** - * @param array $data + * @param array $data * * @return Tag */ @@ -315,9 +306,9 @@ class TagRepository implements TagRepositoryInterface } /** - * @param Tag $tag - * @param Carbon|null $start - * @param Carbon|null $end + * @param Tag $tag + * @param Carbon|null $start + * @param Carbon|null $end * * @return array * @@ -385,9 +376,9 @@ class TagRepository implements TagRepositoryInterface } /** - * @param Tag $tag - * @param Carbon $start - * @param Carbon $end + * @param Tag $tag + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -402,8 +393,8 @@ class TagRepository implements TagRepositoryInterface } /** - * @param Tag $tag - * @param array $data + * @param Tag $tag + * @param array $data * * @return Tag */ @@ -455,4 +446,13 @@ class TagRepository implements TagRepositoryInterface return $tag; } + + /** + * @inheritDoc + */ + public function getLocation(Tag $tag): ?Location + { + /** @var Location|null */ + return $tag->locations()->first(); + } } diff --git a/app/Repositories/Tag/TagRepositoryInterface.php b/app/Repositories/Tag/TagRepositoryInterface.php index 1f5a0b3804..8343eb4725 100644 --- a/app/Repositories/Tag/TagRepositoryInterface.php +++ b/app/Repositories/Tag/TagRepositoryInterface.php @@ -43,7 +43,7 @@ interface TagRepositoryInterface /** * This method destroys a tag. * - * @param Tag $tag + * @param Tag $tag * * @return bool */ @@ -55,30 +55,30 @@ interface TagRepositoryInterface public function destroyAll(): void; /** - * @param Tag $tag - * @param Carbon $start - * @param Carbon $end + * @param Tag $tag + * @param Carbon $start + * @param Carbon $end * * @return array */ public function expenseInPeriod(Tag $tag, Carbon $start, Carbon $end): array; /** - * @param int $tagId + * @param int $tagId * * @return Tag|null */ public function find(int $tagId): ?Tag; /** - * @param string $tag + * @param string $tag * * @return Tag|null */ public function findByTag(string $tag): ?Tag; /** - * @param Tag $tag + * @param Tag $tag * * @return Carbon|null */ @@ -92,7 +92,7 @@ interface TagRepositoryInterface public function get(): Collection; /** - * @param Tag $tag + * @param Tag $tag * * @return Collection */ @@ -101,30 +101,30 @@ interface TagRepositoryInterface /** * Return location, or NULL. * - * @param Tag $tag + * @param Tag $tag * * @return Location|null */ public function getLocation(Tag $tag): ?Location; /** - * @param int|null $year + * @param int|null $year * * @return array */ public function getTagsInYear(?int $year): array; /** - * @param Tag $tag - * @param Carbon $start - * @param Carbon $end + * @param Tag $tag + * @param Carbon $start + * @param Carbon $end * * @return array */ public function incomeInPeriod(Tag $tag, Carbon $start, Carbon $end): array; /** - * @param Tag $tag + * @param Tag $tag * * @return Carbon|null */ @@ -147,7 +147,7 @@ interface TagRepositoryInterface /** * Find one or more tags based on the query. * - * @param string $query + * @param string $query * * @return Collection */ @@ -156,22 +156,22 @@ interface TagRepositoryInterface /** * Search the users tags. * - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ public function searchTags(string $query, int $limit): Collection; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** * This method stores a tag. * - * @param array $data + * @param array $data * * @return Tag */ @@ -180,18 +180,18 @@ interface TagRepositoryInterface /** * Calculates various amounts in tag. * - * @param Tag $tag - * @param Carbon|null $start - * @param Carbon|null $end + * @param Tag $tag + * @param Carbon|null $start + * @param Carbon|null $end * * @return array */ public function sumsOfTag(Tag $tag, ?Carbon $start, ?Carbon $end): array; /** - * @param Tag $tag - * @param Carbon $start - * @param Carbon $end + * @param Tag $tag + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -200,8 +200,8 @@ interface TagRepositoryInterface /** * Update a tag. * - * @param Tag $tag - * @param array $data + * @param Tag $tag + * @param array $data * * @return Tag */ diff --git a/app/Repositories/TransactionGroup/TransactionGroupRepository.php b/app/Repositories/TransactionGroup/TransactionGroupRepository.php index 442b408a06..860d03187d 100644 --- a/app/Repositories/TransactionGroup/TransactionGroupRepository.php +++ b/app/Repositories/TransactionGroup/TransactionGroupRepository.php @@ -70,7 +70,19 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface } /** - * @param TransactionGroup $group + * Find a transaction group by its ID. + * + * @param int $groupId + * + * @return TransactionGroup|null + */ + public function find(int $groupId): ?TransactionGroup + { + return $this->user->transactionGroups()->find($groupId); + } + + /** + * @param TransactionGroup $group */ public function destroy(TransactionGroup $group): void { @@ -95,21 +107,59 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface } /** - * Find a transaction group by its ID. + * @param TransactionJournal $journal * - * @param int $groupId - * - * @return TransactionGroup|null + * @return array */ - public function find(int $groupId): ?TransactionGroup + private function expandJournal(TransactionJournal $journal): array { - return $this->user->transactionGroups()->find($groupId); + $array = $journal->toArray(); + $array['transactions'] = []; + $array['meta'] = $journal->transactionJournalMeta->toArray(); + $array['tags'] = $journal->tags->toArray(); + $array['categories'] = $journal->categories->toArray(); + $array['budgets'] = $journal->budgets->toArray(); + $array['notes'] = $journal->notes->toArray(); + $array['locations'] = []; + $array['attachments'] = $journal->attachments->toArray(); + $array['links'] = []; + $array['piggy_bank_events'] = $journal->piggyBankEvents->toArray(); + + /** @var Transaction $transaction */ + foreach ($journal->transactions as $transaction) { + $array['transactions'][] = $this->expandTransaction($transaction); + } + + return $array; + } + + /** + * @param Transaction $transaction + * + * @return array + */ + private function expandTransaction(Transaction $transaction): array + { + $array = $transaction->toArray(); + $array['account'] = $transaction->account->toArray(); + $array['budgets'] = []; + $array['categories'] = []; + + foreach ($transaction->categories as $category) { + $array['categories'][] = $category->toArray(); + } + + foreach ($transaction->budgets as $budget) { + $array['budgets'][] = $budget->toArray(); + } + + return $array; } /** * Return all attachments for all journals in the group. * - * @param TransactionGroup $group + * @param TransactionGroup $group * * @return array */ @@ -139,10 +189,40 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface return $result; } + /** + * @param User|Authenticatable|null $user + */ + public function setUser(User | Authenticatable | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } + + /** + * Get the note text for a journal (by ID). + * + * @param int $journalId + * + * @return string|null + */ + public function getNoteText(int $journalId): ?string + { + /** @var Note|null $note */ + $note = Note::where('noteable_id', $journalId) + ->where('noteable_type', TransactionJournal::class) + ->first(); + if (null === $note) { + return null; + } + + return $note->text; + } + /** * Return all journal links for all journals in the group. * - * @param TransactionGroup $group + * @param TransactionGroup $group * * @return array */ @@ -197,6 +277,58 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface return $return; } + /** + * @param TransactionJournal $journal + * + * @return string + */ + private function getFormattedAmount(TransactionJournal $journal): string + { + /** @var Transaction $transaction */ + $transaction = $journal->transactions->first(); + $currency = $transaction->transactionCurrency; + $type = $journal->transactionType->type; + $amount = app('steam')->positive($transaction->amount); + $return = ''; + if (TransactionType::WITHDRAWAL === $type) { + $return = app('amount')->formatAnything($currency, app('steam')->negative($amount)); + } + if (TransactionType::WITHDRAWAL !== $type) { + $return = app('amount')->formatAnything($currency, $amount); + } + + return $return; + } + + /** + * @param TransactionJournal $journal + * + * @return string + */ + private function getFormattedForeignAmount(TransactionJournal $journal): string + { + /** @var Transaction $transaction */ + $transaction = $journal->transactions->first(); + if (null === $transaction->foreign_amount || '' === $transaction->foreign_amount) { + return ''; + } + if (0 === bccomp('0', $transaction->foreign_amount)) { + return ''; + } + $currency = $transaction->foreignCurrency; + $type = $journal->transactionType->type; + $amount = app('steam')->positive($transaction->foreign_amount); + $return = ''; + if (TransactionType::WITHDRAWAL === $type) { + $return = app('amount')->formatAnything($currency, app('steam')->negative($amount)); + } + if (TransactionType::WITHDRAWAL !== $type) { + $return = app('amount')->formatAnything($currency, $amount); + } + + return $return; + } + /** * @inheritDoc */ @@ -211,8 +343,8 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface /** * Return object with all found meta field things as Carbon objects. * - * @param int $journalId - * @param array $fields + * @param int $journalId + * @param array $fields * * @return NullArrayObject * @throws Exception @@ -236,8 +368,8 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface /** * Return object with all found meta field things. * - * @param int $journalId - * @param array $fields + * @param int $journalId + * @param array $fields * * @return NullArrayObject */ @@ -257,30 +389,10 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface return new NullArrayObject($return); } - /** - * Get the note text for a journal (by ID). - * - * @param int $journalId - * - * @return string|null - */ - public function getNoteText(int $journalId): ?string - { - /** @var Note|null $note */ - $note = Note::where('noteable_id', $journalId) - ->where('noteable_type', TransactionJournal::class) - ->first(); - if (null === $note) { - return null; - } - - return $note->text; - } - /** * Return all piggy bank events for all journals in the group. * - * @param TransactionGroup $group + * @param TransactionGroup $group * * @return array * @throws FireflyException @@ -337,7 +449,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface /** * Get the tags for a journal (by ID). * - * @param int $journalId + * @param int $journalId * * @return array */ @@ -353,17 +465,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface } /** - * @param User|Authenticatable|null $user - */ - public function setUser(User|Authenticatable|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - - /** - * @param array $data + * @param array $data * * @return TransactionGroup * @throws DuplicateTransactionException @@ -389,8 +491,8 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface } /** - * @param TransactionGroup $transactionGroup - * @param array $data + * @param TransactionGroup $transactionGroup + * @param array $data * * @return TransactionGroup * @@ -404,106 +506,4 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface return $service->update($transactionGroup, $data); } - - /** - * @param TransactionJournal $journal - * - * @return array - */ - private function expandJournal(TransactionJournal $journal): array - { - $array = $journal->toArray(); - $array['transactions'] = []; - $array['meta'] = $journal->transactionJournalMeta->toArray(); - $array['tags'] = $journal->tags->toArray(); - $array['categories'] = $journal->categories->toArray(); - $array['budgets'] = $journal->budgets->toArray(); - $array['notes'] = $journal->notes->toArray(); - $array['locations'] = []; - $array['attachments'] = $journal->attachments->toArray(); - $array['links'] = []; - $array['piggy_bank_events'] = $journal->piggyBankEvents->toArray(); - - /** @var Transaction $transaction */ - foreach ($journal->transactions as $transaction) { - $array['transactions'][] = $this->expandTransaction($transaction); - } - - return $array; - } - - /** - * @param Transaction $transaction - * - * @return array - */ - private function expandTransaction(Transaction $transaction): array - { - $array = $transaction->toArray(); - $array['account'] = $transaction->account->toArray(); - $array['budgets'] = []; - $array['categories'] = []; - - foreach ($transaction->categories as $category) { - $array['categories'][] = $category->toArray(); - } - - foreach ($transaction->budgets as $budget) { - $array['budgets'][] = $budget->toArray(); - } - - return $array; - } - - /** - * @param TransactionJournal $journal - * - * @return string - */ - private function getFormattedAmount(TransactionJournal $journal): string - { - /** @var Transaction $transaction */ - $transaction = $journal->transactions->first(); - $currency = $transaction->transactionCurrency; - $type = $journal->transactionType->type; - $amount = app('steam')->positive($transaction->amount); - $return = ''; - if (TransactionType::WITHDRAWAL === $type) { - $return = app('amount')->formatAnything($currency, app('steam')->negative($amount)); - } - if (TransactionType::WITHDRAWAL !== $type) { - $return = app('amount')->formatAnything($currency, $amount); - } - - return $return; - } - - /** - * @param TransactionJournal $journal - * - * @return string - */ - private function getFormattedForeignAmount(TransactionJournal $journal): string - { - /** @var Transaction $transaction */ - $transaction = $journal->transactions->first(); - if (null === $transaction->foreign_amount || '' === $transaction->foreign_amount) { - return ''; - } - if (0 === bccomp('0', $transaction->foreign_amount)) { - return ''; - } - $currency = $transaction->foreignCurrency; - $type = $journal->transactionType->type; - $amount = app('steam')->positive($transaction->foreign_amount); - $return = ''; - if (TransactionType::WITHDRAWAL === $type) { - $return = app('amount')->formatAnything($currency, app('steam')->negative($amount)); - } - if (TransactionType::WITHDRAWAL !== $type) { - $return = app('amount')->formatAnything($currency, $amount); - } - - return $return; - } } diff --git a/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php b/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php index e1e6ee8ca4..8056677ee9 100644 --- a/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php +++ b/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php @@ -38,21 +38,21 @@ use Illuminate\Support\Collection; interface TransactionGroupRepositoryInterface { /** - * @param int $journalId + * @param int $journalId * * @return int */ public function countAttachments(int $journalId): int; /** - * @param TransactionGroup $group + * @param TransactionGroup $group */ public function destroy(TransactionGroup $group): void; /** * Return a group and expand all meta data etc. * - * @param TransactionGroup $group + * @param TransactionGroup $group * * @return array */ @@ -61,7 +61,7 @@ interface TransactionGroupRepositoryInterface /** * Find a transaction group by its ID. * - * @param int $groupId + * @param int $groupId * * @return TransactionGroup|null */ @@ -70,7 +70,7 @@ interface TransactionGroupRepositoryInterface /** * Return all attachments for all journals in the group. * - * @param TransactionGroup $group + * @param TransactionGroup $group * * @return array */ @@ -79,7 +79,7 @@ interface TransactionGroupRepositoryInterface /** * Return all journal links for all journals in the group. * - * @param TransactionGroup $group + * @param TransactionGroup $group * * @return array */ @@ -88,7 +88,7 @@ interface TransactionGroupRepositoryInterface /** * Get the location of a journal or NULL. * - * @param int $journalId + * @param int $journalId * * @return Location|null */ @@ -97,8 +97,8 @@ interface TransactionGroupRepositoryInterface /** * Return object with all found meta field things as Carbon objects. * - * @param int $journalId - * @param array $fields + * @param int $journalId + * @param array $fields * * @return NullArrayObject */ @@ -107,8 +107,8 @@ interface TransactionGroupRepositoryInterface /** * Return object with all found meta field things. * - * @param int $journalId - * @param array $fields + * @param int $journalId + * @param array $fields * * @return NullArrayObject */ @@ -117,7 +117,7 @@ interface TransactionGroupRepositoryInterface /** * Get the note text for a journal (by ID). * - * @param int $journalId + * @param int $journalId * * @return string|null */ @@ -126,7 +126,7 @@ interface TransactionGroupRepositoryInterface /** * Return all piggy bank events for all journals in the group. * - * @param TransactionGroup $group + * @param TransactionGroup $group * * @return array */ @@ -135,7 +135,7 @@ interface TransactionGroupRepositoryInterface /** * Get the tags for a journal (by ID) as Tag objects. * - * @param int $journalId + * @param int $journalId * * @return Collection */ @@ -144,21 +144,21 @@ interface TransactionGroupRepositoryInterface /** * Get the tags for a journal (by ID). * - * @param int $journalId + * @param int $journalId * * @return array */ public function getTags(int $journalId): array; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** * Create a new transaction group. * - * @param array $data + * @param array $data * * @return TransactionGroup * @throws DuplicateTransactionException @@ -169,8 +169,8 @@ interface TransactionGroupRepositoryInterface /** * Update an existing transaction group. * - * @param TransactionGroup $transactionGroup - * @param array $data + * @param TransactionGroup $transactionGroup + * @param array $data * * @return TransactionGroup */ diff --git a/app/Repositories/TransactionType/TransactionTypeRepository.php b/app/Repositories/TransactionType/TransactionTypeRepository.php index e7b33a689d..e5db6a1308 100644 --- a/app/Repositories/TransactionType/TransactionTypeRepository.php +++ b/app/Repositories/TransactionType/TransactionTypeRepository.php @@ -33,20 +33,8 @@ use Illuminate\Support\Facades\Log; class TransactionTypeRepository implements TransactionTypeRepositoryInterface { /** - * @param string $type - * - * @return TransactionType|null - */ - public function findByType(string $type): ?TransactionType - { - $search = ucfirst($type); - - return TransactionType::whereType($search)->first(); - } - - /** - * @param TransactionType|null $type - * @param string|null $typeString + * @param TransactionType|null $type + * @param string|null $typeString * * @return TransactionType */ @@ -69,8 +57,20 @@ class TransactionTypeRepository implements TransactionTypeRepositoryInterface } /** - * @param string $query - * @param int $limit + * @param string $type + * + * @return TransactionType|null + */ + public function findByType(string $type): ?TransactionType + { + $search = ucfirst($type); + + return TransactionType::whereType($search)->first(); + } + + /** + * @param string $query + * @param int $limit * * @return Collection */ diff --git a/app/Repositories/TransactionType/TransactionTypeRepositoryInterface.php b/app/Repositories/TransactionType/TransactionTypeRepositoryInterface.php index f0a1e4c19a..ff4c4b296f 100644 --- a/app/Repositories/TransactionType/TransactionTypeRepositoryInterface.php +++ b/app/Repositories/TransactionType/TransactionTypeRepositoryInterface.php @@ -32,23 +32,23 @@ use Illuminate\Support\Collection; interface TransactionTypeRepositoryInterface { /** - * @param string $type + * @param string $type * * @return TransactionType|null */ public function findByType(string $type): ?TransactionType; /** - * @param TransactionType|null $type - * @param string|null $typeString + * @param TransactionType|null $type + * @param string|null $typeString * * @return TransactionType */ public function findTransactionType(?TransactionType $type, ?string $typeString): TransactionType; /** - * @param string $query - * @param int $limit + * @param string $query + * @param int $limit * * @return Collection */ diff --git a/app/Repositories/User/UserRepository.php b/app/Repositories/User/UserRepository.php index 7edcb9b254..73b9c1edad 100644 --- a/app/Repositories/User/UserRepository.php +++ b/app/Repositories/User/UserRepository.php @@ -43,45 +43,12 @@ use Str; */ class UserRepository implements UserRepositoryInterface { - /** - * @return Collection - */ - public function all(): Collection - { - return User::orderBy('id', 'DESC')->get(['users.*']); - } - - /** - * @param User $user - * @param string $role - * - * @return bool - */ - public function attachRole(User $user, string $role): bool - { - $roleObject = Role::where('name', $role)->first(); - if (null === $roleObject) { - Log::error(sprintf('Could not find role "%s" in attachRole()', $role)); - - return false; - } - - try { - $user->roles()->attach($roleObject); - } catch (QueryException $e) { - // don't care - Log::error(sprintf('Query exception when giving user a role: %s', $e->getMessage())); - } - - return true; - } - /** * This updates the users email address and records some things so it can be confirmed or undone later. * The user is blocked until the change is confirmed. * - * @param User $user - * @param string $newEmail + * @param User $user + * @param string $newEmail * * @return bool * @throws Exception @@ -94,7 +61,7 @@ class UserRepository implements UserRepositoryInterface // save old email as pref app('preferences')->setForUser($user, 'previous_email_latest', $oldEmail); - app('preferences')->setForUser($user, 'previous_email_'.date('Y-m-d-H-i-s'), $oldEmail); + app('preferences')->setForUser($user, 'previous_email_' . date('Y-m-d-H-i-s'), $oldEmail); // set undo and confirm token: app('preferences')->setForUser($user, 'email_change_undo_token', bin2hex(random_bytes(16))); @@ -110,8 +77,8 @@ class UserRepository implements UserRepositoryInterface } /** - * @param User $user - * @param string $password + * @param User $user + * @param string $password * * @return bool */ @@ -124,9 +91,9 @@ class UserRepository implements UserRepositoryInterface } /** - * @param User $user - * @param bool $isBlocked - * @param string $code + * @param User $user + * @param bool $isBlocked + * @param string $code * * @return bool */ @@ -141,17 +108,9 @@ class UserRepository implements UserRepositoryInterface } /** - * @return int - */ - public function count(): int - { - return $this->all()->count(); - } - - /** - * @param string $name - * @param string $displayName - * @param string $description + * @param string $name + * @param string $displayName + * @param string $description * * @return Role */ @@ -160,6 +119,32 @@ class UserRepository implements UserRepositoryInterface return Role::create(['name' => $name, 'display_name' => $displayName, 'description' => $description]); } + /** + * @inheritDoc + */ + public function deleteInvite(InvitedUser $invite): void + { + Log::debug(sprintf('Deleting invite #%d', $invite->id)); + $invite->delete(); + } + + /** + * @param User $user + * + * @return bool + * @throws Exception + */ + public function destroy(User $user): bool + { + Log::debug(sprintf('Calling delete() on user %d', $user->id)); + + $user->groupMemberships()->delete(); + $user->delete(); + $this->deleteEmptyGroups(); + + return true; + } + /** * @inheritDoc */ @@ -177,43 +162,23 @@ class UserRepository implements UserRepositoryInterface } /** - * @inheritDoc + * @return int */ - public function deleteInvite(InvitedUser $invite): void + public function count(): int { - Log::debug(sprintf('Deleting invite #%d', $invite->id)); - $invite->delete(); + return $this->all()->count(); } /** - * @param User $user - * - * @return bool - * @throws Exception + * @return Collection */ - public function destroy(User $user): bool + public function all(): Collection { - Log::debug(sprintf('Calling delete() on user %d', $user->id)); - - $user->groupMemberships()->delete(); - $user->delete(); - $this->deleteEmptyGroups(); - - return true; + return User::orderBy('id', 'DESC')->get(['users.*']); } /** - * @param int $userId - * - * @return User|null - */ - public function find(int $userId): ?User - { - return User::find($userId); - } - - /** - * @param string $email + * @param string $email * * @return User|null */ @@ -241,17 +206,7 @@ class UserRepository implements UserRepositoryInterface } /** - * @param string $role - * - * @return Role|null - */ - public function getRole(string $role): ?Role - { - return Role::where('name', $role)->first(); - } - - /** - * @param User $user + * @param User $user * * @return string|null */ @@ -287,10 +242,20 @@ class UserRepository implements UserRepositoryInterface return $roles; } + /** + * @param int $userId + * + * @return User|null + */ + public function find(int $userId): ?User + { + return User::find($userId); + } + /** * Return basic user information. * - * @param User $user + * @param User $user * * @return array */ @@ -325,12 +290,12 @@ class UserRepository implements UserRepositoryInterface } /** - * @param User|Authenticatable|null $user - * @param string $role + * @param User|Authenticatable|null $user + * @param string $role * * @return bool */ - public function hasRole(User|Authenticatable|null $user, string $role): bool + public function hasRole(User | Authenticatable | null $user, string $role): bool { if (null === $user) { return false; @@ -348,7 +313,7 @@ class UserRepository implements UserRepositoryInterface /** * @inheritDoc */ - public function inviteUser(User|Authenticatable|null $user, string $email): InvitedUser + public function inviteUser(User | Authenticatable | null $user, string $email): InvitedUser { $now = today(config('app.timezone')); $now->addDays(2); @@ -375,26 +340,11 @@ class UserRepository implements UserRepositoryInterface } } - /** - * Remove any role the user has. - * - * @param User $user - * @param string $role - */ - public function removeRole(User $user, string $role): void - { - $roleObj = $this->getRole($role); - if (null === $roleObj) { - return; - } - $user->roles()->detach($roleObj->id); - } - /** * Set MFA code. * - * @param User $user - * @param string|null $code + * @param User $user + * @param string|null $code */ public function setMFACode(User $user, ?string $code): void { @@ -403,7 +353,7 @@ class UserRepository implements UserRepositoryInterface } /** - * @param array $data + * @param array $data * * @return User */ @@ -426,7 +376,32 @@ class UserRepository implements UserRepositoryInterface } /** - * @param User $user + * @param User $user + * @param string $role + * + * @return bool + */ + public function attachRole(User $user, string $role): bool + { + $roleObject = Role::where('name', $role)->first(); + if (null === $roleObject) { + Log::error(sprintf('Could not find role "%s" in attachRole()', $role)); + + return false; + } + + try { + $user->roles()->attach($roleObject); + } catch (QueryException $e) { + // don't care + Log::error(sprintf('Query exception when giving user a role: %s', $e->getMessage())); + } + + return true; + } + + /** + * @param User $user */ public function unblockUser(User $user): void { @@ -438,8 +413,8 @@ class UserRepository implements UserRepositoryInterface /** * Update user info. * - * @param User $user - * @param array $data + * @param User $user + * @param array $data * * @return User * @throws FireflyException @@ -464,11 +439,11 @@ class UserRepository implements UserRepositoryInterface } /** - * This updates the users email address. Same as changeEmail just without most logging. This makes sure that the undo/confirm routine can't catch this one. - * The user is NOT blocked. + * This updates the users email address. Same as changeEmail just without most logging. This makes sure that the + * undo/confirm routine can't catch this one. The user is NOT blocked. * - * @param User $user - * @param string $newEmail + * @param User $user + * @param string $newEmail * * @return bool * @throws FireflyException @@ -483,7 +458,7 @@ class UserRepository implements UserRepositoryInterface // save old email as pref app('preferences')->setForUser($user, 'admin_previous_email_latest', $oldEmail); - app('preferences')->setForUser($user, 'admin_previous_email_'.date('Y-m-d-H-i-s'), $oldEmail); + app('preferences')->setForUser($user, 'admin_previous_email_' . date('Y-m-d-H-i-s'), $oldEmail); $user->email = $newEmail; $user->save(); @@ -491,6 +466,31 @@ class UserRepository implements UserRepositoryInterface return true; } + /** + * Remove any role the user has. + * + * @param User $user + * @param string $role + */ + public function removeRole(User $user, string $role): void + { + $roleObj = $this->getRole($role); + if (null === $roleObj) { + return; + } + $user->roles()->detach($roleObj->id); + } + + /** + * @param string $role + * + * @return Role|null + */ + public function getRole(string $role): ?Role + { + return Role::where('name', $role)->first(); + } + /** * @inheritDoc */ diff --git a/app/Repositories/User/UserRepositoryInterface.php b/app/Repositories/User/UserRepositoryInterface.php index 7e5269cf41..f3fd794a20 100644 --- a/app/Repositories/User/UserRepositoryInterface.php +++ b/app/Repositories/User/UserRepositoryInterface.php @@ -44,8 +44,8 @@ interface UserRepositoryInterface /** * Gives a user a role. * - * @param User $user - * @param string $role + * @param User $user + * @param string $role * * @return bool */ @@ -55,8 +55,8 @@ interface UserRepositoryInterface * This updates the users email address and records some things so it can be confirmed or undone later. * The user is blocked until the change is confirmed. * - * @param User $user - * @param string $newEmail + * @param User $user + * @param string $newEmail * * @return bool * @see updateEmail @@ -65,17 +65,17 @@ interface UserRepositoryInterface public function changeEmail(User $user, string $newEmail): bool; /** - * @param User $user - * @param string $password + * @param User $user + * @param string $password * * @return mixed */ public function changePassword(User $user, string $password); /** - * @param User $user - * @param bool $isBlocked - * @param string $code + * @param User $user + * @param bool $isBlocked + * @param string $code * * @return bool */ @@ -89,9 +89,9 @@ interface UserRepositoryInterface public function count(): int; /** - * @param string $name - * @param string $displayName - * @param string $description + * @param string $name + * @param string $displayName + * @param string $description * * @return Role */ @@ -103,27 +103,27 @@ interface UserRepositoryInterface public function deleteEmptyGroups(): void; /** - * @param InvitedUser $invite + * @param InvitedUser $invite * @return void */ public function deleteInvite(InvitedUser $invite): void; /** - * @param User $user + * @param User $user * * @return bool */ public function destroy(User $user): bool; /** - * @param int $userId + * @param int $userId * * @return User|null */ public function find(int $userId): ?User; /** - * @param string $email + * @param string $email * * @return User|null */ @@ -142,22 +142,22 @@ interface UserRepositoryInterface public function getInvitedUsers(): Collection; /** - * @param string $role + * @param string $role * * @return Role|null */ public function getRole(string $role): ?Role; /** - * @param User $user + * @param User $user * * @return string|null */ public function getRoleByUser(User $user): ?string; /** - * @param User $user - * @param int $groupId + * @param User $user + * @param int $groupId * @return array */ public function getRolesInGroup(User $user, int $groupId): array; @@ -165,29 +165,29 @@ interface UserRepositoryInterface /** * Return basic user information. * - * @param User $user + * @param User $user * * @return array */ public function getUserData(User $user): array; /** - * @param User|Authenticatable|null $user - * @param string $role + * @param User|Authenticatable|null $user + * @param string $role * * @return bool */ - public function hasRole(User|Authenticatable|null $user, string $role): bool; + public function hasRole(User | Authenticatable | null $user, string $role): bool; /** - * @param User|Authenticatable|null $user - * @param string $email + * @param User|Authenticatable|null $user + * @param string $email * @return InvitedUser */ - public function inviteUser(User|Authenticatable|null $user, string $email): InvitedUser; + public function inviteUser(User | Authenticatable | null $user, string $email): InvitedUser; /** - * @param string $code + * @param string $code * @return void */ public function redeemCode(string $code): void; @@ -195,47 +195,47 @@ interface UserRepositoryInterface /** * Remove any role the user has. * - * @param User $user - * @param string $role + * @param User $user + * @param string $role */ public function removeRole(User $user, string $role): void; /** * Set MFA code. * - * @param User $user - * @param string|null $code + * @param User $user + * @param string|null $code */ public function setMFACode(User $user, ?string $code): void; /** - * @param array $data + * @param array $data * * @return User */ public function store(array $data): User; /** - * @param User $user + * @param User $user */ public function unblockUser(User $user): void; /** * Update user info. * - * @param User $user - * @param array $data + * @param User $user + * @param array $data * * @return User */ public function update(User $user, array $data): User; /** - * This updates the users email address. Same as changeEmail just without most logging. This makes sure that the undo/confirm routine can't catch this one. - * The user is NOT blocked. + * This updates the users email address. Same as changeEmail just without most logging. This makes sure that the + * undo/confirm routine can't catch this one. The user is NOT blocked. * - * @param User $user - * @param string $newEmail + * @param User $user + * @param string $newEmail * * @return bool * @see changeEmail @@ -244,7 +244,7 @@ interface UserRepositoryInterface public function updateEmail(User $user, string $newEmail): bool; /** - * @param string $code + * @param string $code * @return bool */ public function validateInviteCode(string $code): bool; diff --git a/app/Repositories/Webhook/WebhookRepository.php b/app/Repositories/Webhook/WebhookRepository.php index 8cb8ad83ff..931638aecd 100644 --- a/app/Repositories/Webhook/WebhookRepository.php +++ b/app/Repositories/Webhook/WebhookRepository.php @@ -105,9 +105,9 @@ class WebhookRepository implements WebhookRepositoryInterface } /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void + public function setUser(User | Authenticatable | null $user): void { if (null !== $user) { $this->user = $user; diff --git a/app/Repositories/Webhook/WebhookRepositoryInterface.php b/app/Repositories/Webhook/WebhookRepositoryInterface.php index 9b2c21e3ba..c0dd28c6ae 100644 --- a/app/Repositories/Webhook/WebhookRepositoryInterface.php +++ b/app/Repositories/Webhook/WebhookRepositoryInterface.php @@ -43,56 +43,56 @@ interface WebhookRepositoryInterface public function all(): Collection; /** - * @param Webhook $webhook + * @param Webhook $webhook */ public function destroy(Webhook $webhook): void; /** - * @param WebhookAttempt $attempt + * @param WebhookAttempt $attempt */ public function destroyAttempt(WebhookAttempt $attempt): void; /** - * @param WebhookMessage $message + * @param WebhookMessage $message */ public function destroyMessage(WebhookMessage $message): void; /** - * @param WebhookMessage $webhookMessage + * @param WebhookMessage $webhookMessage * * @return Collection */ public function getAttempts(WebhookMessage $webhookMessage): Collection; /** - * @param Webhook $webhook + * @param Webhook $webhook * * @return Collection */ public function getMessages(Webhook $webhook): Collection; /** - * @param Webhook $webhook + * @param Webhook $webhook * * @return Collection */ public function getReadyMessages(Webhook $webhook): Collection; /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user */ - public function setUser(User|Authenticatable|null $user): void; + public function setUser(User | Authenticatable | null $user): void; /** - * @param array $data + * @param array $data * * @return Webhook */ public function store(array $data): Webhook; /** - * @param Webhook $webhook - * @param array $data + * @param Webhook $webhook + * @param array $data * * @return Webhook */ diff --git a/app/Rules/BelongsUser.php b/app/Rules/BelongsUser.php index 02edad3149..9229fc3fa7 100644 --- a/app/Rules/BelongsUser.php +++ b/app/Rules/BelongsUser.php @@ -62,8 +62,8 @@ class BelongsUser implements Rule /** * Determine if the validation rule passes. * - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * * @return bool * @throws FireflyException @@ -93,9 +93,53 @@ class BelongsUser implements Rule } /** - * @param string $class - * @param string $field - * @param string $value + * @param string $attribute + * + * @return string + */ + private function parseAttribute(string $attribute): string + { + $parts = explode('.', $attribute); + if (1 === count($parts)) { + return $attribute; + } + if (3 === count($parts)) { + return $parts[2]; + } + + return $attribute; + } + + /** + * @param int $value + * + * @return bool + */ + private function validatePiggyBankId(int $value): bool + { + $count = PiggyBank::leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id') + ->where('piggy_banks.id', '=', $value) + ->where('accounts.user_id', '=', auth()->user()->id)->count(); + + return 1 === $count; + } + + /** + * @param string $value + * + * @return bool + */ + private function validatePiggyBankName(string $value): bool + { + $count = $this->countField(PiggyBank::class, 'name', $value); + + return 1 === $count; + } + + /** + * @param string $class + * @param string $field + * @param string $value * * @return int * @@ -126,41 +170,7 @@ class BelongsUser implements Rule } /** - * @param string $attribute - * - * @return string - */ - private function parseAttribute(string $attribute): string - { - $parts = explode('.', $attribute); - if (1 === count($parts)) { - return $attribute; - } - if (3 === count($parts)) { - return $parts[2]; - } - - return $attribute; - } - - /** - * @param int $value - * - * @return bool - */ - private function validateAccountId(int $value): bool - { - if (0 === $value) { - // its ok to submit 0. other checks will fail. - return true; - } - $count = Account::where('id', '=', $value)->where('user_id', '=', auth()->user()->id)->count(); - - return 1 === $count; - } - - /** - * @param int $value + * @param int $value * * @return bool */ @@ -175,59 +185,7 @@ class BelongsUser implements Rule } /** - * @param string $value - * - * @return bool - */ - private function validateBillName(string $value): bool - { - $count = $this->countField(Bill::class, 'name', $value); - Log::debug(sprintf('Result of countField for bill name "%s" is %d', $value, $count)); - - return 1 === $count; - } - - /** - * @param int $value - * - * @return bool - */ - private function validateBudgetId(int $value): bool - { - if (0 === $value) { - return true; - } - $count = Budget::where('id', '=', $value)->where('user_id', '=', auth()->user()->id)->count(); - - return 1 === $count; - } - - /** - * @param string $value - * - * @return bool - */ - private function validateBudgetName(string $value): bool - { - $count = $this->countField(Budget::class, 'name', $value); - - return 1 === $count; - } - - /** - * @param int $value - * - * @return bool - */ - private function validateCategoryId(int $value): bool - { - $count = Category::where('id', '=', $value)->where('user_id', '=', auth()->user()->id)->count(); - - return 1 === $count; - } - - /** - * @param int $value + * @param int $value * * @return bool */ @@ -242,27 +200,69 @@ class BelongsUser implements Rule } /** - * @param int $value + * @param string $value * * @return bool */ - private function validatePiggyBankId(int $value): bool + private function validateBillName(string $value): bool { - $count = PiggyBank::leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id') - ->where('piggy_banks.id', '=', $value) - ->where('accounts.user_id', '=', auth()->user()->id)->count(); + $count = $this->countField(Bill::class, 'name', $value); + Log::debug(sprintf('Result of countField for bill name "%s" is %d', $value, $count)); return 1 === $count; } /** - * @param string $value + * @param int $value * * @return bool */ - private function validatePiggyBankName(string $value): bool + private function validateBudgetId(int $value): bool { - $count = $this->countField(PiggyBank::class, 'name', $value); + if (0 === $value) { + return true; + } + $count = Budget::where('id', '=', $value)->where('user_id', '=', auth()->user()->id)->count(); + + return 1 === $count; + } + + /** + * @param int $value + * + * @return bool + */ + private function validateCategoryId(int $value): bool + { + $count = Category::where('id', '=', $value)->where('user_id', '=', auth()->user()->id)->count(); + + return 1 === $count; + } + + /** + * @param string $value + * + * @return bool + */ + private function validateBudgetName(string $value): bool + { + $count = $this->countField(Budget::class, 'name', $value); + + return 1 === $count; + } + + /** + * @param int $value + * + * @return bool + */ + private function validateAccountId(int $value): bool + { + if (0 === $value) { + // its ok to submit 0. other checks will fail. + return true; + } + $count = Account::where('id', '=', $value)->where('user_id', '=', auth()->user()->id)->count(); return 1 === $count; } diff --git a/app/Rules/IsAssetAccountId.php b/app/Rules/IsAssetAccountId.php index 731fa8a421..46d2e04e42 100644 --- a/app/Rules/IsAssetAccountId.php +++ b/app/Rules/IsAssetAccountId.php @@ -46,8 +46,8 @@ class IsAssetAccountId implements Rule /** * Determine if the validation rule passes. * - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * * @return bool */ diff --git a/app/Rules/IsBoolean.php b/app/Rules/IsBoolean.php index 5ab13d58fd..3019b38ad5 100644 --- a/app/Rules/IsBoolean.php +++ b/app/Rules/IsBoolean.php @@ -44,8 +44,8 @@ class IsBoolean implements Rule /** * Determine if the validation rule passes. * - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * * @return bool */ diff --git a/app/Rules/IsDateOrTime.php b/app/Rules/IsDateOrTime.php index 4acdaf9362..8a6132ae58 100644 --- a/app/Rules/IsDateOrTime.php +++ b/app/Rules/IsDateOrTime.php @@ -48,8 +48,8 @@ class IsDateOrTime implements Rule /** * Determine if the validation rule passes. * - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * * @return bool */ diff --git a/app/Rules/IsTransferAccount.php b/app/Rules/IsTransferAccount.php index 2451c5f7fd..8cf7d14b05 100644 --- a/app/Rules/IsTransferAccount.php +++ b/app/Rules/IsTransferAccount.php @@ -47,8 +47,8 @@ class IsTransferAccount implements Rule /** * Determine if the validation rule passes. * - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * * @return bool */ diff --git a/app/Rules/IsValidAttachmentModel.php b/app/Rules/IsValidAttachmentModel.php index 0628d959da..fa21c25991 100644 --- a/app/Rules/IsValidAttachmentModel.php +++ b/app/Rules/IsValidAttachmentModel.php @@ -54,7 +54,7 @@ class IsValidAttachmentModel implements Rule * IsValidAttachmentModel constructor. * * - * @param string $model + * @param string $model */ public function __construct(string $model) { @@ -62,6 +62,20 @@ class IsValidAttachmentModel implements Rule $this->model = $model; } + /** + * @param string $model + * + * @return string + */ + private function normalizeModel(string $model): string + { + $search = ['FireflyIII\Models\\']; + $replace = ''; + $model = str_replace($search, $replace, $model); + + return sprintf('FireflyIII\Models\%s', $model); + } + /** * Get the validation error message. * @@ -75,8 +89,8 @@ class IsValidAttachmentModel implements Rule /** * Determine if the validation rule passes. * - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * * @return bool */ @@ -106,21 +120,7 @@ class IsValidAttachmentModel implements Rule } /** - * @param string $model - * - * @return string - */ - private function normalizeModel(string $model): string - { - $search = ['FireflyIII\Models\\']; - $replace = ''; - $model = str_replace($search, $replace, $model); - - return sprintf('FireflyIII\Models\%s', $model); - } - - /** - * @param int $value + * @param int $value * * @return bool */ @@ -134,7 +134,7 @@ class IsValidAttachmentModel implements Rule } /** - * @param int $value + * @param int $value * * @return bool */ @@ -148,7 +148,7 @@ class IsValidAttachmentModel implements Rule } /** - * @param int $value + * @param int $value * * @return bool */ @@ -162,7 +162,7 @@ class IsValidAttachmentModel implements Rule } /** - * @param int $value + * @param int $value * * @return bool */ @@ -176,7 +176,7 @@ class IsValidAttachmentModel implements Rule } /** - * @param int $value + * @param int $value * * @return bool */ @@ -189,7 +189,7 @@ class IsValidAttachmentModel implements Rule } /** - * @param int $value + * @param int $value * * @return bool */ @@ -203,7 +203,7 @@ class IsValidAttachmentModel implements Rule } /** - * @param int $value + * @param int $value * * @return bool */ @@ -217,7 +217,7 @@ class IsValidAttachmentModel implements Rule } /** - * @param int $value + * @param int $value * * @return bool */ diff --git a/app/Rules/IsValidBulkClause.php b/app/Rules/IsValidBulkClause.php index 6211463fca..7a8bda7692 100644 --- a/app/Rules/IsValidBulkClause.php +++ b/app/Rules/IsValidBulkClause.php @@ -37,7 +37,7 @@ class IsValidBulkClause implements Rule private array $rules; /** - * @param string $type + * @param string $type */ public function __construct(string $type) { @@ -54,8 +54,8 @@ class IsValidBulkClause implements Rule } /** - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * * @return bool */ @@ -72,7 +72,7 @@ class IsValidBulkClause implements Rule /** * Does basic rule based validation. * - * @param string $value + * @param string $value * * @return bool */ @@ -94,7 +94,7 @@ class IsValidBulkClause implements Rule } /** * @var string $arrayKey - * @var mixed $arrayValue + * @var mixed $arrayValue */ foreach ($array[$clause] as $arrayKey => $arrayValue) { if (!array_key_exists($arrayKey, $this->rules[$clause])) { diff --git a/app/Rules/LessThanPiggyTarget.php b/app/Rules/LessThanPiggyTarget.php index 8ac44f63f5..e19589ea74 100644 --- a/app/Rules/LessThanPiggyTarget.php +++ b/app/Rules/LessThanPiggyTarget.php @@ -44,8 +44,8 @@ class LessThanPiggyTarget implements Rule /** * Determine if the validation rule passes. * - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * * @return bool */ diff --git a/app/Rules/UniqueAccountNumber.php b/app/Rules/UniqueAccountNumber.php index 8124146bea..c9aaddafe8 100644 --- a/app/Rules/UniqueAccountNumber.php +++ b/app/Rules/UniqueAccountNumber.php @@ -41,8 +41,8 @@ class UniqueAccountNumber implements Rule * Create a new rule instance. * * - * @param Account|null $account - * @param string|null $expectedType + * @param Account|null $account + * @param string|null $expectedType */ public function __construct(?Account $account, ?string $expectedType) { @@ -76,8 +76,8 @@ class UniqueAccountNumber implements Rule /** * Determine if the validation rule passes. * - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * * @return bool * @@ -114,28 +114,6 @@ class UniqueAccountNumber implements Rule return true; } - /** - * @param string $type - * @param string $accountNumber - * - * @return int - */ - private function countHits(string $type, string $accountNumber): int - { - $query = AccountMeta::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id') - ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') - ->where('accounts.user_id', auth()->user()->id) - ->where('account_types.type', $type) - ->where('account_meta.name', '=', 'account_number') - ->where('account_meta.data', json_encode($accountNumber)); - - if (null !== $this->account) { - $query->where('accounts.id', '!=', $this->account->id); - } - - return $query->count(); - } - /** * @return array * @@ -161,4 +139,26 @@ class UniqueAccountNumber implements Rule return $maxCounts; } + + /** + * @param string $type + * @param string $accountNumber + * + * @return int + */ + private function countHits(string $type, string $accountNumber): int + { + $query = AccountMeta::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id') + ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') + ->where('accounts.user_id', auth()->user()->id) + ->where('account_types.type', $type) + ->where('account_meta.name', '=', 'account_number') + ->where('account_meta.data', json_encode($accountNumber)); + + if (null !== $this->account) { + $query->where('accounts.id', '!=', $this->account->id); + } + + return $query->count(); + } } diff --git a/app/Rules/UniqueIban.php b/app/Rules/UniqueIban.php index ed3c5879e7..6a0c3940cb 100644 --- a/app/Rules/UniqueIban.php +++ b/app/Rules/UniqueIban.php @@ -41,8 +41,8 @@ class UniqueIban implements ValidationRule * Create a new rule instance. * * - * @param Account|null $account - * @param string|null $expectedType + * @param Account|null $account + * @param string|null $expectedType */ public function __construct(?Account $account, ?string $expectedType) { @@ -78,11 +78,21 @@ class UniqueIban implements ValidationRule return (string)trans('validation.unique_iban_for_user'); } + /** + * @inheritDoc + */ + public function validate(string $attribute, mixed $value, Closure $fail): void + { + if (!$this->passes($attribute, $value)) { + $fail((string)trans('validation.unique_iban_for_user')); + } + } + /** * Determine if the validation rule passes. * - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * * @return bool * @@ -118,42 +128,6 @@ class UniqueIban implements ValidationRule return true; } - /** - * @inheritDoc - */ - public function validate(string $attribute, mixed $value, Closure $fail): void - { - if (!$this->passes($attribute, $value)) { - $fail((string)trans('validation.unique_iban_for_user')); - } - } - - /** - * @param string $type - * @param string $iban - * - * @return int - */ - private function countHits(string $type, string $iban): int - { - $typesArray = [$type]; - if ('liabilities' === $type) { - $typesArray = [AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]; - } - $query - = auth()->user() - ->accounts() - ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') - ->where('accounts.iban', $iban) - ->whereIn('account_types.type', $typesArray); - - if (null !== $this->account) { - $query->where('accounts.id', '!=', $this->account->id); - } - - return $query->count(); - } - /** * @return array * @@ -180,4 +154,30 @@ class UniqueIban implements ValidationRule return $maxCounts; } + + /** + * @param string $type + * @param string $iban + * + * @return int + */ + private function countHits(string $type, string $iban): int + { + $typesArray = [$type]; + if ('liabilities' === $type) { + $typesArray = [AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]; + } + $query + = auth()->user() + ->accounts() + ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') + ->where('accounts.iban', $iban) + ->whereIn('account_types.type', $typesArray); + + if (null !== $this->account) { + $query->where('accounts.id', '!=', $this->account->id); + } + + return $query->count(); + } } diff --git a/app/Rules/ValidJournals.php b/app/Rules/ValidJournals.php index d10785f2d0..11e56e89cf 100644 --- a/app/Rules/ValidJournals.php +++ b/app/Rules/ValidJournals.php @@ -48,8 +48,8 @@ class ValidJournals implements Rule /** * Determine if the validation rule passes. * - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * * @return bool * diff --git a/app/Rules/ValidRecurrenceRepetitionType.php b/app/Rules/ValidRecurrenceRepetitionType.php index afac72c46b..508835a5fb 100644 --- a/app/Rules/ValidRecurrenceRepetitionType.php +++ b/app/Rules/ValidRecurrenceRepetitionType.php @@ -45,8 +45,8 @@ class ValidRecurrenceRepetitionType implements Rule /** * Determine if the validation rule passes. * - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * * @return bool * diff --git a/app/Rules/ValidRecurrenceRepetitionValue.php b/app/Rules/ValidRecurrenceRepetitionValue.php index 0d696bb5fe..10ec16ea84 100644 --- a/app/Rules/ValidRecurrenceRepetitionValue.php +++ b/app/Rules/ValidRecurrenceRepetitionValue.php @@ -48,8 +48,8 @@ class ValidRecurrenceRepetitionValue implements Rule /** * Determine if the validation rule passes. * - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * * @return bool * @@ -86,7 +86,7 @@ class ValidRecurrenceRepetitionValue implements Rule } /** - * @param string $value + * @param string $value * * @return bool */ @@ -98,7 +98,7 @@ class ValidRecurrenceRepetitionValue implements Rule } /** - * @param string $value + * @param string $value * * @return bool * @@ -119,7 +119,7 @@ class ValidRecurrenceRepetitionValue implements Rule } /** - * @param string $value + * @param string $value * * @return bool */ @@ -131,7 +131,7 @@ class ValidRecurrenceRepetitionValue implements Rule } /** - * @param string $value + * @param string $value * * @return bool */ diff --git a/app/Services/FireflyIIIOrg/Update/UpdateRequest.php b/app/Services/FireflyIIIOrg/Update/UpdateRequest.php index f6359ed824..2f09340c09 100644 --- a/app/Services/FireflyIIIOrg/Update/UpdateRequest.php +++ b/app/Services/FireflyIIIOrg/Update/UpdateRequest.php @@ -37,7 +37,7 @@ use JsonException; class UpdateRequest implements UpdateRequestInterface { /** - * @param string $channel + * @param string $channel * * @return array */ @@ -64,7 +64,7 @@ class UpdateRequest implements UpdateRequestInterface } /** - * @param string $channel + * @param string $channel * * @return array */ @@ -134,7 +134,7 @@ class UpdateRequest implements UpdateRequestInterface } /** - * @param array $information + * @param array $information * * @return array */ diff --git a/app/Services/FireflyIIIOrg/Update/UpdateRequestInterface.php b/app/Services/FireflyIIIOrg/Update/UpdateRequestInterface.php index e616837222..de0e8f294b 100644 --- a/app/Services/FireflyIIIOrg/Update/UpdateRequestInterface.php +++ b/app/Services/FireflyIIIOrg/Update/UpdateRequestInterface.php @@ -30,7 +30,7 @@ namespace FireflyIII\Services\FireflyIIIOrg\Update; interface UpdateRequestInterface { /** - * @param string $channel + * @param string $channel * * @return array */ diff --git a/app/Services/Internal/Destroy/AccountDestroyService.php b/app/Services/Internal/Destroy/AccountDestroyService.php index 49b4b17902..5decf97a8c 100644 --- a/app/Services/Internal/Destroy/AccountDestroyService.php +++ b/app/Services/Internal/Destroy/AccountDestroyService.php @@ -40,8 +40,8 @@ use stdClass; class AccountDestroyService { /** - * @param Account $account - * @param Account|null $moveTo + * @param Account $account + * @param Account|null $moveTo * * @return void */ @@ -71,60 +71,7 @@ class AccountDestroyService } /** - * @param Account $account - * @param Account $moveTo - */ - public function moveTransactions(Account $account, Account $moveTo): void - { - Log::debug(sprintf('Move from account #%d to #%d', $account->id, $moveTo->id)); - DB::table('transactions')->where('account_id', $account->id)->update(['account_id' => $moveTo->id]); - - $collection = Transaction::groupBy('transaction_journal_id', 'account_id') - ->where('account_id', $moveTo->id) - ->get(['transaction_journal_id', 'account_id', DB::raw('count(*) as the_count')]); - if (0 === $collection->count()) { - return; - } - - /** @var JournalDestroyService $service */ - $service = app(JournalDestroyService::class); - $user = $account->user; - /** @var stdClass $row */ - foreach ($collection as $row) { - if ((int)$row->the_count > 1) { - $journalId = (int)$row->transaction_journal_id; - $journal = $user->transactionJournals()->find($journalId); - if (null !== $journal) { - Log::debug(sprintf('Deleted journal #%d because it has the same source as destination.', $journal->id)); - $service->destroy($journal); - } - } - } - } - - /** - * @param Account $account - */ - private function destroyJournals(Account $account): void - { - /** @var JournalDestroyService $service */ - $service = app(JournalDestroyService::class); - - Log::debug('Now trigger account delete response #'.$account->id); - /** @var Transaction $transaction */ - foreach ($account->transactions()->get() as $transaction) { - Log::debug('Now at transaction #'.$transaction->id); - /** @var TransactionJournal $journal */ - $journal = $transaction->transactionJournal()->first(); - if (null !== $journal) { - Log::debug('Call for deletion of journal #'.$journal->id); - $service->destroy($journal); - } - } - } - - /** - * @param Account $account + * @param Account $account */ private function destroyOpeningBalance(Account $account): void { @@ -160,7 +107,70 @@ class AccountDestroyService } /** - * @param Account $account + * @param Account $account + * @param Account $moveTo + */ + public function moveTransactions(Account $account, Account $moveTo): void + { + Log::debug(sprintf('Move from account #%d to #%d', $account->id, $moveTo->id)); + DB::table('transactions')->where('account_id', $account->id)->update(['account_id' => $moveTo->id]); + + $collection = Transaction::groupBy('transaction_journal_id', 'account_id') + ->where('account_id', $moveTo->id) + ->get(['transaction_journal_id', 'account_id', DB::raw('count(*) as the_count')]); + if (0 === $collection->count()) { + return; + } + + /** @var JournalDestroyService $service */ + $service = app(JournalDestroyService::class); + $user = $account->user; + /** @var stdClass $row */ + foreach ($collection as $row) { + if ((int)$row->the_count > 1) { + $journalId = (int)$row->transaction_journal_id; + $journal = $user->transactionJournals()->find($journalId); + if (null !== $journal) { + Log::debug(sprintf('Deleted journal #%d because it has the same source as destination.', $journal->id)); + $service->destroy($journal); + } + } + } + } + + /** + * @param Account $account + * @param Account $moveTo + */ + private function updateRecurrences(Account $account, Account $moveTo): void + { + DB::table('recurrences_transactions')->where('source_id', $account->id)->update(['source_id' => $moveTo->id]); + DB::table('recurrences_transactions')->where('destination_id', $account->id)->update(['destination_id' => $moveTo->id]); + } + + /** + * @param Account $account + */ + private function destroyJournals(Account $account): void + { + /** @var JournalDestroyService $service */ + $service = app(JournalDestroyService::class); + + Log::debug('Now trigger account delete response #' . $account->id); + /** @var Transaction $transaction */ + foreach ($account->transactions()->get() as $transaction) { + Log::debug('Now at transaction #' . $transaction->id); + /** @var TransactionJournal $journal */ + $journal = $transaction->transactionJournal()->first(); + if (null !== $journal) { + Log::debug('Call for deletion of journal #' . $journal->id); + $service->destroy($journal); + } + } + } + + /** + * @param Account $account */ private function destroyRecurrences(Account $account): void { @@ -177,14 +187,4 @@ class AccountDestroyService $destroyService->destroyById((int)$recurrenceId); } } - - /** - * @param Account $account - * @param Account $moveTo - */ - private function updateRecurrences(Account $account, Account $moveTo): void - { - DB::table('recurrences_transactions')->where('source_id', $account->id)->update(['source_id' => $moveTo->id]); - DB::table('recurrences_transactions')->where('destination_id', $account->id)->update(['destination_id' => $moveTo->id]); - } } diff --git a/app/Services/Internal/Destroy/BillDestroyService.php b/app/Services/Internal/Destroy/BillDestroyService.php index af92b7b229..6b0f48b007 100644 --- a/app/Services/Internal/Destroy/BillDestroyService.php +++ b/app/Services/Internal/Destroy/BillDestroyService.php @@ -31,7 +31,7 @@ use FireflyIII\Models\Bill; class BillDestroyService { /** - * @param Bill $bill + * @param Bill $bill */ public function destroy(Bill $bill): void { diff --git a/app/Services/Internal/Destroy/BudgetDestroyService.php b/app/Services/Internal/Destroy/BudgetDestroyService.php index 187319f62f..d9675f743a 100644 --- a/app/Services/Internal/Destroy/BudgetDestroyService.php +++ b/app/Services/Internal/Destroy/BudgetDestroyService.php @@ -34,7 +34,7 @@ use FireflyIII\Models\Budget; class BudgetDestroyService { /** - * @param Budget $budget + * @param Budget $budget */ public function destroy(Budget $budget): void { diff --git a/app/Services/Internal/Destroy/CategoryDestroyService.php b/app/Services/Internal/Destroy/CategoryDestroyService.php index db7f156bd7..36c2f74ef4 100644 --- a/app/Services/Internal/Destroy/CategoryDestroyService.php +++ b/app/Services/Internal/Destroy/CategoryDestroyService.php @@ -34,7 +34,7 @@ use FireflyIII\Models\Category; class CategoryDestroyService { /** - * @param Category $category + * @param Category $category */ public function destroy(Category $category): void { diff --git a/app/Services/Internal/Destroy/CurrencyDestroyService.php b/app/Services/Internal/Destroy/CurrencyDestroyService.php index 5c188e1300..4a2295d32a 100644 --- a/app/Services/Internal/Destroy/CurrencyDestroyService.php +++ b/app/Services/Internal/Destroy/CurrencyDestroyService.php @@ -33,7 +33,7 @@ use FireflyIII\Models\TransactionCurrency; class CurrencyDestroyService { /** - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency */ public function destroy(TransactionCurrency $currency): void { diff --git a/app/Services/Internal/Destroy/JournalDestroyService.php b/app/Services/Internal/Destroy/JournalDestroyService.php index a8a0d79b80..0c52c769bd 100644 --- a/app/Services/Internal/Destroy/JournalDestroyService.php +++ b/app/Services/Internal/Destroy/JournalDestroyService.php @@ -37,7 +37,7 @@ use Illuminate\Support\Facades\Log; class JournalDestroyService { /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal */ public function destroy(TransactionJournal $journal): void { diff --git a/app/Services/Internal/Destroy/RecurrenceDestroyService.php b/app/Services/Internal/Destroy/RecurrenceDestroyService.php index a91a8bef43..8937b13815 100644 --- a/app/Services/Internal/Destroy/RecurrenceDestroyService.php +++ b/app/Services/Internal/Destroy/RecurrenceDestroyService.php @@ -31,10 +31,24 @@ use FireflyIII\Models\RecurrenceTransaction; */ class RecurrenceDestroyService { + /** + * Delete recurrence by ID + * + * @param int $recurrenceId + */ + public function destroyById(int $recurrenceId): void + { + $recurrence = Recurrence::find($recurrenceId); + if (null === $recurrence) { + return; + } + $this->destroy($recurrence); + } + /** * Delete recurrence. * - * @param Recurrence $recurrence + * @param Recurrence $recurrence * */ public function destroy(Recurrence $recurrence): void @@ -53,18 +67,4 @@ class RecurrenceDestroyService // delete recurrence $recurrence->delete(); } - - /** - * Delete recurrence by ID - * - * @param int $recurrenceId - */ - public function destroyById(int $recurrenceId): void - { - $recurrence = Recurrence::find($recurrenceId); - if (null === $recurrence) { - return; - } - $this->destroy($recurrence); - } } diff --git a/app/Services/Internal/Destroy/TransactionGroupDestroyService.php b/app/Services/Internal/Destroy/TransactionGroupDestroyService.php index 82174ce567..6ef875d46b 100644 --- a/app/Services/Internal/Destroy/TransactionGroupDestroyService.php +++ b/app/Services/Internal/Destroy/TransactionGroupDestroyService.php @@ -35,7 +35,7 @@ use Illuminate\Support\Facades\Log; class TransactionGroupDestroyService { /** - * @param TransactionGroup $transactionGroup + * @param TransactionGroup $transactionGroup */ public function destroy(TransactionGroup $transactionGroup): void { diff --git a/app/Services/Internal/Support/AccountServiceTrait.php b/app/Services/Internal/Support/AccountServiceTrait.php index 67d9a19c74..5bb3c41703 100644 --- a/app/Services/Internal/Support/AccountServiceTrait.php +++ b/app/Services/Internal/Support/AccountServiceTrait.php @@ -51,7 +51,7 @@ trait AccountServiceTrait protected AccountRepositoryInterface $accountRepository; /** - * @param null|string $iban + * @param null|string $iban * * @return null|string */ @@ -76,7 +76,7 @@ trait AccountServiceTrait /** * Returns true if the data in the array is submitted but empty. * - * @param array $data + * @param array $data * * @return bool */ @@ -104,8 +104,8 @@ trait AccountServiceTrait * * TODO this method treats expense accounts and liabilities the same way (tries to save interest) * - * @param Account $account - * @param array $data + * @param Account $account + * @param array $data * */ public function updateMetaData(Account $account, array $data): void @@ -164,8 +164,8 @@ trait AccountServiceTrait } /** - * @param Account $account - * @param string $note + * @param Account $account + * @param string $note * * @return bool */ @@ -192,7 +192,7 @@ trait AccountServiceTrait /** * Verify if array contains valid data to possibly store or update the opening balance. * - * @param array $data + * @param array $data * * @return bool */ @@ -214,99 +214,8 @@ trait AccountServiceTrait } /** - * @param Account $account - * @param string $openingBalance - * @param Carbon $openingBalanceDate - * - * @return TransactionGroup - * @throws FireflyException - * @throws JsonException - */ - protected function createCreditTransaction(Account $account, string $openingBalance, Carbon $openingBalanceDate): TransactionGroup - { - Log::debug('Now going to create an createCreditTransaction.'); - - if (0 === bccomp($openingBalance, '0')) { - Log::debug('Amount is zero, so will not make an liability credit group.'); - throw new FireflyException('Amount for new liability credit was unexpectedly 0.'); - } - - $language = app('preferences')->getForUser($account->user, 'language', 'en_US')->data; - - // set source and/or destination based on whether the amount is positive or negative. - // first, assume the amount is positive and go from there: - // if amount is positive ("I am owed this debt"), source is special account, destination is the liability. - $sourceId = null; - $sourceName = trans('firefly.liability_credit_description', ['account' => $account->name], $language); - $destId = $account->id; - $destName = null; - if (-1 === bccomp($openingBalance, '0')) { - // amount is negative, reverse it - $sourceId = $account->id; - $sourceName = null; - $destId = null; - $destName = trans('firefly.liability_credit_description', ['account' => $account->name], $language); - } - - // amount must be positive for the transaction to work. - $amount = app('steam')->positive($openingBalance); - - // get or grab currency: - $currency = $this->accountRepository->getAccountCurrency($account); - if (null === $currency) { - $currency = app('default')->getDefaultCurrencyByUser($account->user); - } - - // submit to factory: - $submission = [ - 'group_title' => null, - 'user' => $account->user_id, - 'transactions' => [ - [ - 'type' => 'Liability credit', - 'date' => $openingBalanceDate, - 'source_id' => $sourceId, - 'source_name' => $sourceName, - 'destination_id' => $destId, - 'destination_name' => $destName, - 'user' => $account->user_id, - 'currency_id' => $currency->id, - 'order' => 0, - 'amount' => $amount, - 'foreign_amount' => null, - 'description' => trans('firefly.liability_credit_description', ['account' => $account->name]), - 'budget_id' => null, - 'budget_name' => null, - 'category_id' => null, - 'category_name' => null, - 'piggy_bank_id' => null, - 'piggy_bank_name' => null, - 'reconciled' => false, - 'notes' => null, - 'tags' => [], - ], - ], - ]; - Log::debug('Going for submission in createCreditTransaction', $submission); - - /** @var TransactionGroupFactory $factory */ - $factory = app(TransactionGroupFactory::class); - $factory->setUser($account->user); - - try { - $group = $factory->create($submission); - } catch (DuplicateTransactionException $e) { - Log::error($e->getMessage()); - Log::error($e->getTraceAsString()); - throw new FireflyException($e->getMessage(), 0, $e); - } - - return $group; - } - - /** - * @param Account $account - * @param array $data + * @param Account $account + * @param array $data * * @return TransactionGroup * @throws FireflyException @@ -398,9 +307,369 @@ trait AccountServiceTrait } /** - * @param Account $account - * @param string $openingBalance - * @param Carbon $openingBalanceDate + * Delete TransactionGroup with liability credit in it. + * + * @param Account $account + */ + protected function deleteCreditTransaction(Account $account): void + { + Log::debug(sprintf('deleteCreditTransaction() for account #%d', $account->id)); + $creditGroup = $this->getCreditTransaction($account); + + if (null !== $creditGroup) { + Log::debug('Credit journal found, delete journal.'); + /** @var TransactionGroupDestroyService $service */ + $service = app(TransactionGroupDestroyService::class); + $service->destroy($creditGroup); + } + } + + /** + * Returns the credit transaction group, or NULL if it does not exist. + * + * @param Account $account + * + * @return TransactionGroup|null + */ + protected function getCreditTransaction(Account $account): ?TransactionGroup + { + Log::debug(sprintf('Now at %s', __METHOD__)); + + return $this->accountRepository->getCreditTransactionGroup($account); + } + + /** + * Delete TransactionGroup with opening balance in it. + * + * @param Account $account + */ + protected function deleteOBGroup(Account $account): void + { + Log::debug(sprintf('deleteOB() for account #%d', $account->id)); + $openingBalanceGroup = $this->getOBGroup($account); + + // opening balance data? update it! + if (null !== $openingBalanceGroup) { + Log::debug('Opening balance journal found, delete journal.'); + /** @var TransactionGroupDestroyService $service */ + $service = app(TransactionGroupDestroyService::class); + $service->destroy($openingBalanceGroup); + } + } + + /** + * Returns the opening balance group, or NULL if it does not exist. + * + * @param Account $account + * + * @return TransactionGroup|null + */ + protected function getOBGroup(Account $account): ?TransactionGroup + { + return $this->accountRepository->getOpeningBalanceGroup($account); + } + + /** + * @param int $currencyId + * @param string $currencyCode + * + * @return TransactionCurrency + * @throws FireflyException + * @throws JsonException + */ + protected function getCurrency(int $currencyId, string $currencyCode): TransactionCurrency + { + // find currency, or use default currency instead. + /** @var TransactionCurrencyFactory $factory */ + $factory = app(TransactionCurrencyFactory::class); + /** @var TransactionCurrency|null $currency */ + $currency = $factory->find($currencyId, $currencyCode); + + if (null === $currency) { + // use default currency: + $currency = app('amount')->getDefaultCurrencyByUser($this->user); + } + $currency->enabled = true; + $currency->save(); + + return $currency; + } + + /** + * Create the opposing "credit liability" transaction for credit liabilities. + * + * + * @throws FireflyException + */ + protected function updateCreditTransaction(Account $account, string $direction, string $openingBalance, Carbon $openingBalanceDate): TransactionGroup + { + Log::debug(sprintf('Now in %s', __METHOD__)); + + if (0 === bccomp($openingBalance, '0')) { + Log::debug('Amount is zero, so will not update liability credit/debit group.'); + throw new FireflyException('Amount for update liability credit/debit was unexpectedly 0.'); + } + // if direction is "debit" (i owe this debt), amount is negative. + // which means the liability will have a negative balance which the user must fill. + $openingBalance = app('steam')->negative($openingBalance); + + // if direction is "credit" (I am owed this debt), amount is positive. + // which means the liability will have a positive balance which is drained when its paid back into any asset. + if ('credit' === $direction) { + $openingBalance = app('steam')->positive($openingBalance); + } + + // create if not exists: + $clGroup = $this->getCreditTransaction($account); + if (null === $clGroup) { + return $this->createCreditTransaction($account, $openingBalance, $openingBalanceDate); + } + // if exists, update: + $currency = $this->accountRepository->getAccountCurrency($account); + if (null === $currency) { + $currency = app('default')->getDefaultCurrencyByUser($account->user); + } + + // simply grab the first journal and change it: + $journal = $this->getObJournal($clGroup); + $clTransaction = $this->getOBTransaction($journal, $account); + $accountTransaction = $this->getNotOBTransaction($journal, $account); + $journal->date = $openingBalanceDate; + $journal->transactionCurrency()->associate($currency); + + // account always gains money: + $accountTransaction->amount = app('steam')->positive($openingBalance); + $accountTransaction->transaction_currency_id = $currency->id; + + // CL account always loses money: + $clTransaction->amount = app('steam')->negative($openingBalance); + $clTransaction->transaction_currency_id = $currency->id; + // save both + $accountTransaction->save(); + $clTransaction->save(); + $journal->save(); + $clGroup->refresh(); + + return $clGroup; + } + + /** + * @param Account $account + * @param string $openingBalance + * @param Carbon $openingBalanceDate + * + * @return TransactionGroup + * @throws FireflyException + * @throws JsonException + */ + protected function createCreditTransaction(Account $account, string $openingBalance, Carbon $openingBalanceDate): TransactionGroup + { + Log::debug('Now going to create an createCreditTransaction.'); + + if (0 === bccomp($openingBalance, '0')) { + Log::debug('Amount is zero, so will not make an liability credit group.'); + throw new FireflyException('Amount for new liability credit was unexpectedly 0.'); + } + + $language = app('preferences')->getForUser($account->user, 'language', 'en_US')->data; + + // set source and/or destination based on whether the amount is positive or negative. + // first, assume the amount is positive and go from there: + // if amount is positive ("I am owed this debt"), source is special account, destination is the liability. + $sourceId = null; + $sourceName = trans('firefly.liability_credit_description', ['account' => $account->name], $language); + $destId = $account->id; + $destName = null; + if (-1 === bccomp($openingBalance, '0')) { + // amount is negative, reverse it + $sourceId = $account->id; + $sourceName = null; + $destId = null; + $destName = trans('firefly.liability_credit_description', ['account' => $account->name], $language); + } + + // amount must be positive for the transaction to work. + $amount = app('steam')->positive($openingBalance); + + // get or grab currency: + $currency = $this->accountRepository->getAccountCurrency($account); + if (null === $currency) { + $currency = app('default')->getDefaultCurrencyByUser($account->user); + } + + // submit to factory: + $submission = [ + 'group_title' => null, + 'user' => $account->user_id, + 'transactions' => [ + [ + 'type' => 'Liability credit', + 'date' => $openingBalanceDate, + 'source_id' => $sourceId, + 'source_name' => $sourceName, + 'destination_id' => $destId, + 'destination_name' => $destName, + 'user' => $account->user_id, + 'currency_id' => $currency->id, + 'order' => 0, + 'amount' => $amount, + 'foreign_amount' => null, + 'description' => trans('firefly.liability_credit_description', ['account' => $account->name]), + 'budget_id' => null, + 'budget_name' => null, + 'category_id' => null, + 'category_name' => null, + 'piggy_bank_id' => null, + 'piggy_bank_name' => null, + 'reconciled' => false, + 'notes' => null, + 'tags' => [], + ], + ], + ]; + Log::debug('Going for submission in createCreditTransaction', $submission); + + /** @var TransactionGroupFactory $factory */ + $factory = app(TransactionGroupFactory::class); + $factory->setUser($account->user); + + try { + $group = $factory->create($submission); + } catch (DuplicateTransactionException $e) { + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); + throw new FireflyException($e->getMessage(), 0, $e); + } + + return $group; + } + + /** + * TODO refactor to "getfirstjournal" + * + * @param TransactionGroup $group + * + * @return TransactionJournal + * @throws FireflyException + */ + private function getObJournal(TransactionGroup $group): TransactionJournal + { + /** @var TransactionJournal $journal */ + $journal = $group->transactionJournals()->first(); + if (null === $journal) { + throw new FireflyException(sprintf('Group #%d has no OB journal', $group->id)); + } + + return $journal; + } + + /** + * TODO Rename to getOpposingTransaction + * + * @param TransactionJournal $journal + * @param Account $account + * + * @return Transaction + * @throws FireflyException + */ + private function getOBTransaction(TransactionJournal $journal, Account $account): Transaction + { + /** @var Transaction $transaction */ + $transaction = $journal->transactions()->where('account_id', '!=', $account->id)->first(); + if (null === $transaction) { + throw new FireflyException(sprintf('Could not get OB transaction for journal #%d', $journal->id)); + } + + return $transaction; + } + + /** + * @param TransactionJournal $journal + * @param Account $account + * + * @return Transaction + * @throws FireflyException + */ + private function getNotOBTransaction(TransactionJournal $journal, Account $account): Transaction + { + /** @var Transaction $transaction */ + $transaction = $journal->transactions()->where('account_id', $account->id)->first(); + if (null === $transaction) { + throw new FireflyException(sprintf('Could not get non-OB transaction for journal #%d', $journal->id)); + } + + return $transaction; + } + + /** + * Update or create the opening balance group. + * Since opening balance and date can still be empty strings, it may fail. + * + * @param Account $account + * @param string $openingBalance + * @param Carbon $openingBalanceDate + * + * @return TransactionGroup + * @throws FireflyException + */ + protected function updateOBGroupV2(Account $account, string $openingBalance, Carbon $openingBalanceDate): TransactionGroup + { + Log::debug(sprintf('Now in %s', __METHOD__)); + // create if not exists: + $obGroup = $this->getOBGroup($account); + if (null === $obGroup) { + return $this->createOBGroupV2($account, $openingBalance, $openingBalanceDate); + } + Log::debug('Update OB group'); + + // if exists, update: + $currency = $this->accountRepository->getAccountCurrency($account); + if (null === $currency) { + $currency = app('default')->getDefaultCurrencyByUser($account->user); + } + + // simply grab the first journal and change it: + $journal = $this->getObJournal($obGroup); + $obTransaction = $this->getOBTransaction($journal, $account); + $accountTransaction = $this->getNotOBTransaction($journal, $account); + $journal->date = $openingBalanceDate; + $journal->transactionCurrency()->associate($currency); + + + // if amount is negative: + if (1 === bccomp('0', $openingBalance)) { + Log::debug('Amount is negative.'); + // account transaction loses money: + $accountTransaction->amount = app('steam')->negative($openingBalance); + $accountTransaction->transaction_currency_id = $currency->id; + + // OB account transaction gains money + $obTransaction->amount = app('steam')->positive($openingBalance); + $obTransaction->transaction_currency_id = $currency->id; + } + if (-1 === bccomp('0', $openingBalance)) { + Log::debug('Amount is positive.'); + // account gains money: + $accountTransaction->amount = app('steam')->positive($openingBalance); + $accountTransaction->transaction_currency_id = $currency->id; + + // OB account loses money: + $obTransaction->amount = app('steam')->negative($openingBalance); + $obTransaction->transaction_currency_id = $currency->id; + } + // save both + $accountTransaction->save(); + $obTransaction->save(); + $journal->save(); + $obGroup->refresh(); + + return $obGroup; + } + + /** + * @param Account $account + * @param string $openingBalance + * @param Carbon $openingBalanceDate * * @return TransactionGroup * @throws FireflyException @@ -488,273 +757,4 @@ trait AccountServiceTrait return $group; } - - /** - * Delete TransactionGroup with liability credit in it. - * - * @param Account $account - */ - protected function deleteCreditTransaction(Account $account): void - { - Log::debug(sprintf('deleteCreditTransaction() for account #%d', $account->id)); - $creditGroup = $this->getCreditTransaction($account); - - if (null !== $creditGroup) { - Log::debug('Credit journal found, delete journal.'); - /** @var TransactionGroupDestroyService $service */ - $service = app(TransactionGroupDestroyService::class); - $service->destroy($creditGroup); - } - } - - /** - * Delete TransactionGroup with opening balance in it. - * - * @param Account $account - */ - protected function deleteOBGroup(Account $account): void - { - Log::debug(sprintf('deleteOB() for account #%d', $account->id)); - $openingBalanceGroup = $this->getOBGroup($account); - - // opening balance data? update it! - if (null !== $openingBalanceGroup) { - Log::debug('Opening balance journal found, delete journal.'); - /** @var TransactionGroupDestroyService $service */ - $service = app(TransactionGroupDestroyService::class); - $service->destroy($openingBalanceGroup); - } - } - - /** - * Returns the credit transaction group, or NULL if it does not exist. - * - * @param Account $account - * - * @return TransactionGroup|null - */ - protected function getCreditTransaction(Account $account): ?TransactionGroup - { - Log::debug(sprintf('Now at %s', __METHOD__)); - - return $this->accountRepository->getCreditTransactionGroup($account); - } - - /** - * @param int $currencyId - * @param string $currencyCode - * - * @return TransactionCurrency - * @throws FireflyException - * @throws JsonException - */ - protected function getCurrency(int $currencyId, string $currencyCode): TransactionCurrency - { - // find currency, or use default currency instead. - /** @var TransactionCurrencyFactory $factory */ - $factory = app(TransactionCurrencyFactory::class); - /** @var TransactionCurrency|null $currency */ - $currency = $factory->find($currencyId, $currencyCode); - - if (null === $currency) { - // use default currency: - $currency = app('amount')->getDefaultCurrencyByUser($this->user); - } - $currency->enabled = true; - $currency->save(); - - return $currency; - } - - /** - * Returns the opening balance group, or NULL if it does not exist. - * - * @param Account $account - * - * @return TransactionGroup|null - */ - protected function getOBGroup(Account $account): ?TransactionGroup - { - return $this->accountRepository->getOpeningBalanceGroup($account); - } - - /** - * Create the opposing "credit liability" transaction for credit liabilities. - * - * - * @throws FireflyException - */ - protected function updateCreditTransaction(Account $account, string $direction, string $openingBalance, Carbon $openingBalanceDate): TransactionGroup - { - Log::debug(sprintf('Now in %s', __METHOD__)); - - if (0 === bccomp($openingBalance, '0')) { - Log::debug('Amount is zero, so will not update liability credit/debit group.'); - throw new FireflyException('Amount for update liability credit/debit was unexpectedly 0.'); - } - // if direction is "debit" (i owe this debt), amount is negative. - // which means the liability will have a negative balance which the user must fill. - $openingBalance = app('steam')->negative($openingBalance); - - // if direction is "credit" (I am owed this debt), amount is positive. - // which means the liability will have a positive balance which is drained when its paid back into any asset. - if ('credit' === $direction) { - $openingBalance = app('steam')->positive($openingBalance); - } - - // create if not exists: - $clGroup = $this->getCreditTransaction($account); - if (null === $clGroup) { - return $this->createCreditTransaction($account, $openingBalance, $openingBalanceDate); - } - // if exists, update: - $currency = $this->accountRepository->getAccountCurrency($account); - if (null === $currency) { - $currency = app('default')->getDefaultCurrencyByUser($account->user); - } - - // simply grab the first journal and change it: - $journal = $this->getObJournal($clGroup); - $clTransaction = $this->getOBTransaction($journal, $account); - $accountTransaction = $this->getNotOBTransaction($journal, $account); - $journal->date = $openingBalanceDate; - $journal->transactionCurrency()->associate($currency); - - // account always gains money: - $accountTransaction->amount = app('steam')->positive($openingBalance); - $accountTransaction->transaction_currency_id = $currency->id; - - // CL account always loses money: - $clTransaction->amount = app('steam')->negative($openingBalance); - $clTransaction->transaction_currency_id = $currency->id; - // save both - $accountTransaction->save(); - $clTransaction->save(); - $journal->save(); - $clGroup->refresh(); - - return $clGroup; - } - - /** - * Update or create the opening balance group. - * Since opening balance and date can still be empty strings, it may fail. - * - * @param Account $account - * @param string $openingBalance - * @param Carbon $openingBalanceDate - * - * @return TransactionGroup - * @throws FireflyException - */ - protected function updateOBGroupV2(Account $account, string $openingBalance, Carbon $openingBalanceDate): TransactionGroup - { - Log::debug(sprintf('Now in %s', __METHOD__)); - // create if not exists: - $obGroup = $this->getOBGroup($account); - if (null === $obGroup) { - return $this->createOBGroupV2($account, $openingBalance, $openingBalanceDate); - } - Log::debug('Update OB group'); - - // if exists, update: - $currency = $this->accountRepository->getAccountCurrency($account); - if (null === $currency) { - $currency = app('default')->getDefaultCurrencyByUser($account->user); - } - - // simply grab the first journal and change it: - $journal = $this->getObJournal($obGroup); - $obTransaction = $this->getOBTransaction($journal, $account); - $accountTransaction = $this->getNotOBTransaction($journal, $account); - $journal->date = $openingBalanceDate; - $journal->transactionCurrency()->associate($currency); - - - // if amount is negative: - if (1 === bccomp('0', $openingBalance)) { - Log::debug('Amount is negative.'); - // account transaction loses money: - $accountTransaction->amount = app('steam')->negative($openingBalance); - $accountTransaction->transaction_currency_id = $currency->id; - - // OB account transaction gains money - $obTransaction->amount = app('steam')->positive($openingBalance); - $obTransaction->transaction_currency_id = $currency->id; - } - if (-1 === bccomp('0', $openingBalance)) { - Log::debug('Amount is positive.'); - // account gains money: - $accountTransaction->amount = app('steam')->positive($openingBalance); - $accountTransaction->transaction_currency_id = $currency->id; - - // OB account loses money: - $obTransaction->amount = app('steam')->negative($openingBalance); - $obTransaction->transaction_currency_id = $currency->id; - } - // save both - $accountTransaction->save(); - $obTransaction->save(); - $journal->save(); - $obGroup->refresh(); - - return $obGroup; - } - - /** - * @param TransactionJournal $journal - * @param Account $account - * - * @return Transaction - * @throws FireflyException - */ - private function getNotOBTransaction(TransactionJournal $journal, Account $account): Transaction - { - /** @var Transaction $transaction */ - $transaction = $journal->transactions()->where('account_id', $account->id)->first(); - if (null === $transaction) { - throw new FireflyException(sprintf('Could not get non-OB transaction for journal #%d', $journal->id)); - } - - return $transaction; - } - - /** - * TODO Rename to getOpposingTransaction - * - * @param TransactionJournal $journal - * @param Account $account - * - * @return Transaction - * @throws FireflyException - */ - private function getOBTransaction(TransactionJournal $journal, Account $account): Transaction - { - /** @var Transaction $transaction */ - $transaction = $journal->transactions()->where('account_id', '!=', $account->id)->first(); - if (null === $transaction) { - throw new FireflyException(sprintf('Could not get OB transaction for journal #%d', $journal->id)); - } - - return $transaction; - } - - /** - * TODO refactor to "getfirstjournal" - * - * @param TransactionGroup $group - * - * @return TransactionJournal - * @throws FireflyException - */ - private function getObJournal(TransactionGroup $group): TransactionJournal - { - /** @var TransactionJournal $journal */ - $journal = $group->transactionJournals()->first(); - if (null === $journal) { - throw new FireflyException(sprintf('Group #%d has no OB journal', $group->id)); - } - - return $journal; - } } diff --git a/app/Services/Internal/Support/BillServiceTrait.php b/app/Services/Internal/Support/BillServiceTrait.php index bfe6e37299..a30385423b 100644 --- a/app/Services/Internal/Support/BillServiceTrait.php +++ b/app/Services/Internal/Support/BillServiceTrait.php @@ -36,9 +36,9 @@ use Illuminate\Support\Facades\Log; trait BillServiceTrait { /** - * @param Bill $bill - * @param string $oldName - * @param string $newName + * @param Bill $bill + * @param string $oldName + * @param string $newName */ public function updateBillActions(Bill $bill, string $oldName, string $newName): void { @@ -59,8 +59,8 @@ trait BillServiceTrait } /** - * @param Bill $bill - * @param string $note + * @param Bill $bill + * @param string $note * * @return bool */ diff --git a/app/Services/Internal/Support/CreditRecalculateService.php b/app/Services/Internal/Support/CreditRecalculateService.php index 53a5360b8e..a4bad60032 100644 --- a/app/Services/Internal/Support/CreditRecalculateService.php +++ b/app/Services/Internal/Support/CreditRecalculateService.php @@ -73,23 +73,23 @@ class CreditRecalculateService } /** - * @param Account|null $account + * */ - public function setAccount(?Account $account): void + private function processGroup(): void { - $this->account = $account; + /** @var TransactionJournal $journal */ + foreach ($this->group->transactionJournals as $journal) { + try { + $this->findByJournal($journal); + } catch (FireflyException $e) { + Log::error($e->getTraceAsString()); + Log::error(sprintf('Could not find work account for transaction group #%d.', $this->group->id)); + } + } } /** - * @param TransactionGroup $group - */ - public function setGroup(TransactionGroup $group): void - { - $this->group = $group; - } - - /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @throws FireflyException */ @@ -109,8 +109,19 @@ class CreditRecalculateService } /** - * @param TransactionJournal $journal - * @param string $direction + * @param TransactionJournal $journal + * + * @return Account + * @throws FireflyException + */ + private function getSourceAccount(TransactionJournal $journal): Account + { + return $this->getAccountByDirection($journal, '<'); + } + + /** + * @param TransactionJournal $journal + * @param string $direction * * @return Account * @throws FireflyException @@ -131,7 +142,7 @@ class CreditRecalculateService } /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return Account * @throws FireflyException @@ -141,17 +152,6 @@ class CreditRecalculateService return $this->getAccountByDirection($journal, '>'); } - /** - * @param TransactionJournal $journal - * - * @return Account - * @throws FireflyException - */ - private function getSourceAccount(TransactionJournal $journal): Account - { - return $this->getAccountByDirection($journal, '<'); - } - /** * */ @@ -166,24 +166,47 @@ class CreditRecalculateService /** * */ - private function processGroup(): void + private function processWork(): void { - /** @var TransactionJournal $journal */ - foreach ($this->group->transactionJournals as $journal) { - try { - $this->findByJournal($journal); - } catch (FireflyException $e) { - Log::error($e->getTraceAsString()); - Log::error(sprintf('Could not find work account for transaction group #%d.', $this->group->id)); - } + $this->repository = app(AccountRepositoryInterface::class); + foreach ($this->work as $account) { + $this->processWorkAccount($account); } } /** - * @param Account $account - * @param string $direction - * @param Transaction $transaction - * @param string $amount + * @param Account $account + */ + private function processWorkAccount(Account $account): void + { + // get opening balance (if present) + $this->repository->setUser($account->user); + $startOfDebt = $this->repository->getOpeningBalanceAmount($account) ?? '0'; + $leftOfDebt = app('steam')->positive($startOfDebt); + + /** @var AccountMetaFactory $factory */ + $factory = app(AccountMetaFactory::class); + + // amount is positive or negative, doesn't matter. + $factory->crud($account, 'start_of_debt', $startOfDebt); + + // get direction of liability: + $direction = (string)$this->repository->getMetaValue($account, 'liability_direction'); + + // now loop all transactions (except opening balance and credit thing) + $transactions = $account->transactions()->get(); + /** @var Transaction $transaction */ + foreach ($transactions as $transaction) { + $leftOfDebt = $this->processTransaction($account, $direction, $transaction, $leftOfDebt); + } + $factory->crud($account, 'current_debt', $leftOfDebt); + } + + /** + * @param Account $account + * @param string $direction + * @param Transaction $transaction + * @param string $amount * * @return string */ @@ -277,41 +300,18 @@ class CreditRecalculateService } /** - * + * @param Account|null $account */ - private function processWork(): void + public function setAccount(?Account $account): void { - $this->repository = app(AccountRepositoryInterface::class); - foreach ($this->work as $account) { - $this->processWorkAccount($account); - } + $this->account = $account; } /** - * @param Account $account + * @param TransactionGroup $group */ - private function processWorkAccount(Account $account): void + public function setGroup(TransactionGroup $group): void { - // get opening balance (if present) - $this->repository->setUser($account->user); - $startOfDebt = $this->repository->getOpeningBalanceAmount($account) ?? '0'; - $leftOfDebt = app('steam')->positive($startOfDebt); - - /** @var AccountMetaFactory $factory */ - $factory = app(AccountMetaFactory::class); - - // amount is positive or negative, doesn't matter. - $factory->crud($account, 'start_of_debt', $startOfDebt); - - // get direction of liability: - $direction = (string)$this->repository->getMetaValue($account, 'liability_direction'); - - // now loop all transactions (except opening balance and credit thing) - $transactions = $account->transactions()->get(); - /** @var Transaction $transaction */ - foreach ($transactions as $transaction) { - $leftOfDebt = $this->processTransaction($account, $direction, $transaction, $leftOfDebt); - } - $factory->crud($account, 'current_debt', $leftOfDebt); + $this->group = $group; } } diff --git a/app/Services/Internal/Support/JournalServiceTrait.php b/app/Services/Internal/Support/JournalServiceTrait.php index cedbbfcf93..4241f58e80 100644 --- a/app/Services/Internal/Support/JournalServiceTrait.php +++ b/app/Services/Internal/Support/JournalServiceTrait.php @@ -49,9 +49,9 @@ trait JournalServiceTrait private TagFactory $tagFactory; /** - * @param string $transactionType - * @param string $direction - * @param array $data + * @param string $transactionType + * @param string $direction + * @param array $data * * @return Account|null * @throws FireflyException @@ -118,159 +118,152 @@ trait JournalServiceTrait } /** - * @param string $amount + * @param array $data + * @param array $types * - * @return string - * @throws FireflyException + * @return Account|null */ - protected function getAmount(string $amount): string + private function findAccountById(array $data, array $types): ?Account { - if ('' === $amount) { - throw new FireflyException(sprintf('The amount cannot be an empty string: "%s"', $amount)); - } - Log::debug(sprintf('Now in getAmount("%s")', $amount)); - if (0 === bccomp('0', $amount)) { - throw new FireflyException(sprintf('The amount seems to be zero: "%s"', $amount)); - } - - return $amount; - } - - /** - * @param string|null $amount - * - * @return string|null - */ - protected function getForeignAmount(?string $amount): ?string - { - if (null === $amount) { - Log::debug('No foreign amount info in array. Return NULL'); - - return null; - } - if ('' === $amount) { - Log::debug('Foreign amount is empty string, return NULL.'); - - return null; - } - if (0 === bccomp('0', $amount)) { - Log::debug('Foreign amount is 0.0, return NULL.'); - - return null; - } - Log::debug(sprintf('Foreign amount is %s', $amount)); - - return $amount; - } - - /** - * @param TransactionJournal $journal - * @param NullArrayObject $data - * - - */ - protected function storeBudget(TransactionJournal $journal, NullArrayObject $data): void - { - if (TransactionType::WITHDRAWAL !== $journal->transactionType->type) { - $journal->budgets()->sync([]); - - return; - } - $budget = $this->budgetRepository->findBudget($data['budget_id'], $data['budget_name']); - if (null !== $budget) { - Log::debug(sprintf('Link budget #%d to journal #%d', $budget->id, $journal->id)); - $journal->budgets()->sync([$budget->id]); - - return; - } - // if the budget is NULL, sync empty. - $journal->budgets()->sync([]); - } - - /** - * @param TransactionJournal $journal - * @param NullArrayObject $data - * - - */ - protected function storeCategory(TransactionJournal $journal, NullArrayObject $data): void - { - $category = $this->categoryRepository->findCategory($data['category_id'], $data['category_name']); - if (null !== $category) { - Log::debug(sprintf('Link category #%d to journal #%d', $category->id, $journal->id)); - $journal->categories()->sync([$category->id]); - - return; - } - // if the category is NULL, sync empty. - $journal->categories()->sync([]); - } - - /** - * @param TransactionJournal $journal - * @param string|null $notes - * - - */ - protected function storeNotes(TransactionJournal $journal, ?string $notes): void - { - $notes = (string)$notes; - $note = $journal->notes()->first(); - if ('' !== $notes) { - if (null === $note) { - $note = new Note(); - $note->noteable()->associate($journal); + // first attempt, find by ID. + if (null !== $data['id']) { + $search = $this->accountRepository->find((int)$data['id']); + if (null !== $search && in_array($search->accountType->type, $types, true)) { + Log::debug( + sprintf('Found "account_id" object: #%d, "%s" of type %s (1)', $search->id, $search->name, $search->accountType->type) + ); + return $search; } - $note->text = $notes; - $note->save(); - Log::debug(sprintf('Stored notes for journal #%d', $journal->id)); - - return; - } - if ('' === $notes && null !== $note) { - // try to delete existing notes. - $note->delete(); - } - } - - /** - * Link tags to journal. - * - * @param TransactionJournal $journal - * @param array|null $tags - * - - */ - protected function storeTags(TransactionJournal $journal, ?array $tags): void - { - Log::debug('Now in storeTags()', $tags ?? []); - $this->tagFactory->setUser($journal->user); - $set = []; - if (!is_array($tags)) { - Log::debug('Tags is not an array, break.'); - - return; - } - Log::debug('Start of loop.'); - foreach ($tags as $string) { - $string = (string)$string; - Log::debug(sprintf('Now at tag "%s"', $string)); - if ('' !== $string) { - $tag = $this->tagFactory->findOrCreate($string); - if (null !== $tag) { - $set[] = $tag->id; - } + if (null !== $search && 0 === count($types)) { + Log::debug( + sprintf('Found "account_id" object: #%d, "%s" of type %s (2)', $search->id, $search->name, $search->accountType->type) + ); + return $search; } } - Log::debug('End of loop.'); - Log::debug(sprintf('Total nr. of tags: %d', count($tags)), $tags); - $journal->tags()->sync($set); + Log::debug(sprintf('Found no account by ID #%d of types', $data['id']), $types); + return null; } /** - * @param Account|null $account - * @param array $data - * @param string $preferredType + * @param Account|null $account + * @param array $data + * @param array $types + * + * @return Account|null + */ + private function findAccountByIban(?Account $account, array $data, array $types): ?Account + { + if (null !== $account) { + Log::debug(sprintf('Already have account #%d ("%s"), return that.', $account->id, $account->name)); + return $account; + } + if (null === $data['iban'] || '' === $data['iban']) { + Log::debug('IBAN is empty, will not search for IBAN.'); + return null; + } + // find by preferred type. + $source = $this->accountRepository->findByIbanNull($data['iban'], [$types[0]]); + // or any expected type. + $source = $source ?? $this->accountRepository->findByIbanNull($data['iban'], $types); + + if (null !== $source) { + Log::debug(sprintf('Found "account_iban" object: #%d, %s', $source->id, $source->name)); + + return $source; + } + Log::debug(sprintf('Found no account with IBAN "%s" of expected types', $data['iban']), $types); + return null; + } + + /** + * @param Account|null $account + * @param array $data + * @param array $types + * + * @return Account|null + */ + private function findAccountByNumber(?Account $account, array $data, array $types): ?Account + { + if (null !== $account) { + Log::debug(sprintf('Already have account #%d ("%s"), return that.', $account->id, $account->name)); + return $account; + } + if (null === $data['number'] || '' === $data['number']) { + Log::debug('Account number is empty, will not search for account number.'); + return null; + } + // find by preferred type. + $source = $this->accountRepository->findByAccountNumber((string)$data['number'], [$types[0]]); + + // or any expected type. + $source = $source ?? $this->accountRepository->findByAccountNumber((string)$data['number'], $types); + + if (null !== $source) { + Log::debug(sprintf('Found account: #%d, %s', $source->id, $source->name)); + + return $source; + } + + Log::debug(sprintf('Found no account with account number "%s" of expected types', $data['number']), $types); + return null; + } + + /** + * @param Account|null $account + * @param array $data + * @param array $types + * + * @return Account|null + */ + private function findAccountByName(?Account $account, array $data, array $types): ?Account + { + if (null !== $account) { + Log::debug(sprintf('Already have account #%d ("%s"), return that.', $account->id, $account->name)); + return $account; + } + if (null === $data['name'] || '' === $data['name']) { + Log::debug('Account name is empty, will not search for account name.'); + return null; + } + + // find by preferred type. + $source = $this->accountRepository->findByName($data['name'], [$types[0]]); + + // or any expected type. + $source = $source ?? $this->accountRepository->findByName($data['name'], $types); + + if (null !== $source) { + Log::debug(sprintf('Found "account_name" object: #%d, %s', $source->id, $source->name)); + + return $source; + } + Log::debug(sprintf('Found no account with account name "%s" of expected types', $data['name']), $types); + return null; + } + + /** + * @param array $types + * @return null|string + */ + private function getCreatableType(array $types): ?string + { + $result = null; + $list = config('firefly.dynamic_creation_allowed'); + /** @var string $type */ + foreach ($types as $type) { + if (true === in_array($type, $list, true)) { + $result = $type; + break; + } + } + return $result; + } + + /** + * @param Account|null $account + * @param array $data + * @param string $preferredType * * @return Account|null * @throws FireflyException @@ -341,134 +334,9 @@ trait JournalServiceTrait } /** - * @param Account|null $account - * @param array $data - * @param array $types - * - * @return Account|null - */ - private function findAccountByIban(?Account $account, array $data, array $types): ?Account - { - if (null !== $account) { - Log::debug(sprintf('Already have account #%d ("%s"), return that.', $account->id, $account->name)); - return $account; - } - if (null === $data['iban'] || '' === $data['iban']) { - Log::debug('IBAN is empty, will not search for IBAN.'); - return null; - } - // find by preferred type. - $source = $this->accountRepository->findByIbanNull($data['iban'], [$types[0]]); - // or any expected type. - $source = $source ?? $this->accountRepository->findByIbanNull($data['iban'], $types); - - if (null !== $source) { - Log::debug(sprintf('Found "account_iban" object: #%d, %s', $source->id, $source->name)); - - return $source; - } - Log::debug(sprintf('Found no account with IBAN "%s" of expected types', $data['iban']), $types); - return null; - } - - /** - * @param array $data - * @param array $types - * - * @return Account|null - */ - private function findAccountById(array $data, array $types): ?Account - { - // first attempt, find by ID. - if (null !== $data['id']) { - $search = $this->accountRepository->find((int)$data['id']); - if (null !== $search && in_array($search->accountType->type, $types, true)) { - Log::debug( - sprintf('Found "account_id" object: #%d, "%s" of type %s (1)', $search->id, $search->name, $search->accountType->type) - ); - return $search; - } - if (null !== $search && 0 === count($types)) { - Log::debug( - sprintf('Found "account_id" object: #%d, "%s" of type %s (2)', $search->id, $search->name, $search->accountType->type) - ); - return $search; - } - } - Log::debug(sprintf('Found no account by ID #%d of types', $data['id']), $types); - return null; - } - - /** - * @param Account|null $account - * @param array $data - * @param array $types - * - * @return Account|null - */ - private function findAccountByName(?Account $account, array $data, array $types): ?Account - { - if (null !== $account) { - Log::debug(sprintf('Already have account #%d ("%s"), return that.', $account->id, $account->name)); - return $account; - } - if (null === $data['name'] || '' === $data['name']) { - Log::debug('Account name is empty, will not search for account name.'); - return null; - } - - // find by preferred type. - $source = $this->accountRepository->findByName($data['name'], [$types[0]]); - - // or any expected type. - $source = $source ?? $this->accountRepository->findByName($data['name'], $types); - - if (null !== $source) { - Log::debug(sprintf('Found "account_name" object: #%d, %s', $source->id, $source->name)); - - return $source; - } - Log::debug(sprintf('Found no account with account name "%s" of expected types', $data['name']), $types); - return null; - } - - /** - * @param Account|null $account - * @param array $data - * @param array $types - * - * @return Account|null - */ - private function findAccountByNumber(?Account $account, array $data, array $types): ?Account - { - if (null !== $account) { - Log::debug(sprintf('Already have account #%d ("%s"), return that.', $account->id, $account->name)); - return $account; - } - if (null === $data['number'] || '' === $data['number']) { - Log::debug('Account number is empty, will not search for account number.'); - return null; - } - // find by preferred type. - $source = $this->accountRepository->findByAccountNumber((string)$data['number'], [$types[0]]); - - // or any expected type. - $source = $source ?? $this->accountRepository->findByAccountNumber((string)$data['number'], $types); - - if (null !== $source) { - Log::debug(sprintf('Found account: #%d, %s', $source->id, $source->name)); - - return $source; - } - - Log::debug(sprintf('Found no account with account number "%s" of expected types', $data['number']), $types); - return null; - } - - /** - * @param Account|null $account - * @param array $data - * @param array $types + * @param Account|null $account + * @param array $data + * @param array $types * * @return Account|null */ @@ -484,20 +352,152 @@ trait JournalServiceTrait } /** - * @param array $types - * @return null|string + * @param string $amount + * + * @return string + * @throws FireflyException */ - private function getCreatableType(array $types): ?string + protected function getAmount(string $amount): string { - $result = null; - $list = config('firefly.dynamic_creation_allowed'); - /** @var string $type */ - foreach ($types as $type) { - if (true === in_array($type, $list, true)) { - $result = $type; - break; + if ('' === $amount) { + throw new FireflyException(sprintf('The amount cannot be an empty string: "%s"', $amount)); + } + Log::debug(sprintf('Now in getAmount("%s")', $amount)); + if (0 === bccomp('0', $amount)) { + throw new FireflyException(sprintf('The amount seems to be zero: "%s"', $amount)); + } + + return $amount; + } + + /** + * @param string|null $amount + * + * @return string|null + */ + protected function getForeignAmount(?string $amount): ?string + { + if (null === $amount) { + Log::debug('No foreign amount info in array. Return NULL'); + + return null; + } + if ('' === $amount) { + Log::debug('Foreign amount is empty string, return NULL.'); + + return null; + } + if (0 === bccomp('0', $amount)) { + Log::debug('Foreign amount is 0.0, return NULL.'); + + return null; + } + Log::debug(sprintf('Foreign amount is %s', $amount)); + + return $amount; + } + + /** + * @param TransactionJournal $journal + * @param NullArrayObject $data + * + + */ + protected function storeBudget(TransactionJournal $journal, NullArrayObject $data): void + { + if (TransactionType::WITHDRAWAL !== $journal->transactionType->type) { + $journal->budgets()->sync([]); + + return; + } + $budget = $this->budgetRepository->findBudget($data['budget_id'], $data['budget_name']); + if (null !== $budget) { + Log::debug(sprintf('Link budget #%d to journal #%d', $budget->id, $journal->id)); + $journal->budgets()->sync([$budget->id]); + + return; + } + // if the budget is NULL, sync empty. + $journal->budgets()->sync([]); + } + + /** + * @param TransactionJournal $journal + * @param NullArrayObject $data + * + + */ + protected function storeCategory(TransactionJournal $journal, NullArrayObject $data): void + { + $category = $this->categoryRepository->findCategory($data['category_id'], $data['category_name']); + if (null !== $category) { + Log::debug(sprintf('Link category #%d to journal #%d', $category->id, $journal->id)); + $journal->categories()->sync([$category->id]); + + return; + } + // if the category is NULL, sync empty. + $journal->categories()->sync([]); + } + + /** + * @param TransactionJournal $journal + * @param string|null $notes + * + + */ + protected function storeNotes(TransactionJournal $journal, ?string $notes): void + { + $notes = (string)$notes; + $note = $journal->notes()->first(); + if ('' !== $notes) { + if (null === $note) { + $note = new Note(); + $note->noteable()->associate($journal); + } + $note->text = $notes; + $note->save(); + Log::debug(sprintf('Stored notes for journal #%d', $journal->id)); + + return; + } + if ('' === $notes && null !== $note) { + // try to delete existing notes. + $note->delete(); + } + } + + /** + * Link tags to journal. + * + * @param TransactionJournal $journal + * @param array|null $tags + * + + */ + protected function storeTags(TransactionJournal $journal, ?array $tags): void + { + Log::debug('Now in storeTags()', $tags ?? []); + $this->tagFactory->setUser($journal->user); + $set = []; + if (!is_array($tags)) { + Log::debug('Tags is not an array, break.'); + + return; + } + Log::debug('Start of loop.'); + foreach ($tags as $string) { + $string = (string)$string; + Log::debug(sprintf('Now at tag "%s"', $string)); + if ('' !== $string) { + $tag = $this->tagFactory->findOrCreate($string); + if (null !== $tag) { + $set[] = $tag->id; + } } } - return $result; + Log::debug('End of loop.'); + Log::debug(sprintf('Total nr. of tags: %d', count($tags)), $tags); + $journal->tags()->sync($set); } } diff --git a/app/Services/Internal/Support/LocationServiceTrait.php b/app/Services/Internal/Support/LocationServiceTrait.php index 4652928a2b..c2e1766e68 100644 --- a/app/Services/Internal/Support/LocationServiceTrait.php +++ b/app/Services/Internal/Support/LocationServiceTrait.php @@ -33,8 +33,8 @@ use Illuminate\Database\Eloquent\Model; trait LocationServiceTrait { /** - * @param Model $model - * @param array $data + * @param Model $model + * @param array $data * * @return Location|null */ diff --git a/app/Services/Internal/Support/RecurringTransactionTrait.php b/app/Services/Internal/Support/RecurringTransactionTrait.php index 576517da3c..324764f1b4 100644 --- a/app/Services/Internal/Support/RecurringTransactionTrait.php +++ b/app/Services/Internal/Support/RecurringTransactionTrait.php @@ -50,8 +50,8 @@ use JsonException; trait RecurringTransactionTrait { /** - * @param Recurrence $recurrence - * @param string $note + * @param Recurrence $recurrence + * @param string $note * * @return bool */ @@ -77,8 +77,8 @@ trait RecurringTransactionTrait } /** - * @param Recurrence $recurrence - * @param array $repetitions + * @param Recurrence $recurrence + * @param array $repetitions */ protected function createRepetitions(Recurrence $recurrence, array $repetitions): void { @@ -99,8 +99,8 @@ trait RecurringTransactionTrait /** * Store transactions of a recurring transactions. It's complex but readable. * - * @param Recurrence $recurrence - * @param array $transactions + * @param Recurrence $recurrence + * @param array $transactions * * @throws FireflyException * @throws JsonException @@ -180,35 +180,9 @@ trait RecurringTransactionTrait } /** - * @param Recurrence $recurrence - * - - */ - protected function deleteRepetitions(Recurrence $recurrence): void - { - $recurrence->recurrenceRepetitions()->delete(); - } - - /** - * @param Recurrence $recurrence - * - - */ - protected function deleteTransactions(Recurrence $recurrence): void - { - Log::debug('deleteTransactions()'); - /** @var RecurrenceTransaction $transaction */ - foreach ($recurrence->recurrenceTransactions as $transaction) { - $transaction->recurrenceTransactionMeta()->delete(); - - $transaction->delete(); - } - } - - /** - * @param array $expectedTypes - * @param int|null $accountId - * @param string|null $accountName + * @param array $expectedTypes + * @param int|null $accountId + * @param string|null $accountName * * @return Account * @throws JsonException @@ -257,78 +231,8 @@ trait RecurringTransactionTrait } /** - * @param RecurrenceTransaction $transaction - * @param int $piggyId - */ - protected function updatePiggyBank(RecurrenceTransaction $transaction, int $piggyId): void - { - /** @var PiggyBankFactory $factory */ - $factory = app(PiggyBankFactory::class); - $factory->setUser($transaction->recurrence->user); - $piggyBank = $factory->find($piggyId, null); - if (null !== $piggyBank) { - /** @var RecurrenceMeta|null $entry */ - $entry = $transaction->recurrenceTransactionMeta()->where('name', 'piggy_bank_id')->first(); - if (null === $entry) { - $entry = RecurrenceTransactionMeta::create(['rt_id' => $transaction->id, 'name' => 'piggy_bank_id', 'value' => $piggyBank->id]); - } - $entry->value = $piggyBank->id; - $entry->save(); - } - if (null === $piggyBank) { - // delete if present - $transaction->recurrenceTransactionMeta()->where('name', 'piggy_bank_id')->delete(); - } - } - - - /** - * @param RecurrenceTransaction $transaction - * @param array $tags - */ - protected function updateTags(RecurrenceTransaction $transaction, array $tags): void - { - if (0 !== count($tags)) { - /** @var RecurrenceMeta|null $entry */ - $entry = $transaction->recurrenceTransactionMeta()->where('name', 'tags')->first(); - if (null === $entry) { - $entry = RecurrenceTransactionMeta::create(['rt_id' => $transaction->id, 'name' => 'tags', 'value' => json_encode($tags)]); - } - $entry->value = json_encode($tags); - $entry->save(); - } - if (0 === count($tags)) { - // delete if present - $transaction->recurrenceTransactionMeta()->where('name', 'tags')->delete(); - } - } - - /** - * @param RecurrenceTransaction $transaction - * @param int $billId - */ - private function setBill(RecurrenceTransaction $transaction, int $billId): void - { - $billFactory = app(BillFactory::class); - $billFactory->setUser($transaction->recurrence->user); - $bill = $billFactory->find($billId, null); - if (null === $bill) { - return; - } - - $meta = $transaction->recurrenceTransactionMeta()->where('name', 'bill_id')->first(); - if (null === $meta) { - $meta = new RecurrenceTransactionMeta(); - $meta->rt_id = $transaction->id; - $meta->name = 'bill_id'; - } - $meta->value = $bill->id; - $meta->save(); - } - - /** - * @param RecurrenceTransaction $transaction - * @param int $budgetId + * @param RecurrenceTransaction $transaction + * @param int $budgetId */ private function setBudget(RecurrenceTransaction $transaction, int $budgetId): void { @@ -350,8 +254,31 @@ trait RecurringTransactionTrait } /** - * @param RecurrenceTransaction $transaction - * @param int $categoryId + * @param RecurrenceTransaction $transaction + * @param int $billId + */ + private function setBill(RecurrenceTransaction $transaction, int $billId): void + { + $billFactory = app(BillFactory::class); + $billFactory->setUser($transaction->recurrence->user); + $bill = $billFactory->find($billId, null); + if (null === $bill) { + return; + } + + $meta = $transaction->recurrenceTransactionMeta()->where('name', 'bill_id')->first(); + if (null === $meta) { + $meta = new RecurrenceTransactionMeta(); + $meta->rt_id = $transaction->id; + $meta->name = 'bill_id'; + } + $meta->value = $bill->id; + $meta->save(); + } + + /** + * @param RecurrenceTransaction $transaction + * @param int $categoryId */ private function setCategory(RecurrenceTransaction $transaction, int $categoryId): void { @@ -375,4 +302,76 @@ trait RecurringTransactionTrait $meta->value = $category->id; $meta->save(); } + + /** + * @param RecurrenceTransaction $transaction + * @param int $piggyId + */ + protected function updatePiggyBank(RecurrenceTransaction $transaction, int $piggyId): void + { + /** @var PiggyBankFactory $factory */ + $factory = app(PiggyBankFactory::class); + $factory->setUser($transaction->recurrence->user); + $piggyBank = $factory->find($piggyId, null); + if (null !== $piggyBank) { + /** @var RecurrenceMeta|null $entry */ + $entry = $transaction->recurrenceTransactionMeta()->where('name', 'piggy_bank_id')->first(); + if (null === $entry) { + $entry = RecurrenceTransactionMeta::create(['rt_id' => $transaction->id, 'name' => 'piggy_bank_id', 'value' => $piggyBank->id]); + } + $entry->value = $piggyBank->id; + $entry->save(); + } + if (null === $piggyBank) { + // delete if present + $transaction->recurrenceTransactionMeta()->where('name', 'piggy_bank_id')->delete(); + } + } + + /** + * @param RecurrenceTransaction $transaction + * @param array $tags + */ + protected function updateTags(RecurrenceTransaction $transaction, array $tags): void + { + if (0 !== count($tags)) { + /** @var RecurrenceMeta|null $entry */ + $entry = $transaction->recurrenceTransactionMeta()->where('name', 'tags')->first(); + if (null === $entry) { + $entry = RecurrenceTransactionMeta::create(['rt_id' => $transaction->id, 'name' => 'tags', 'value' => json_encode($tags)]); + } + $entry->value = json_encode($tags); + $entry->save(); + } + if (0 === count($tags)) { + // delete if present + $transaction->recurrenceTransactionMeta()->where('name', 'tags')->delete(); + } + } + + /** + * @param Recurrence $recurrence + * + + */ + protected function deleteRepetitions(Recurrence $recurrence): void + { + $recurrence->recurrenceRepetitions()->delete(); + } + + /** + * @param Recurrence $recurrence + * + + */ + protected function deleteTransactions(Recurrence $recurrence): void + { + Log::debug('deleteTransactions()'); + /** @var RecurrenceTransaction $transaction */ + foreach ($recurrence->recurrenceTransactions as $transaction) { + $transaction->recurrenceTransactionMeta()->delete(); + + $transaction->delete(); + } + } } diff --git a/app/Services/Internal/Support/TransactionTypeTrait.php b/app/Services/Internal/Support/TransactionTypeTrait.php index 1e5c0457da..d06f93af88 100644 --- a/app/Services/Internal/Support/TransactionTypeTrait.php +++ b/app/Services/Internal/Support/TransactionTypeTrait.php @@ -38,7 +38,7 @@ trait TransactionTypeTrait * Get the transaction type. Since this is mandatory, will throw an exception when nothing comes up. Will always * use TransactionType repository. * - * @param string $type + * @param string $type * * @return TransactionType * @throws FireflyException diff --git a/app/Services/Internal/Update/AccountUpdateService.php b/app/Services/Internal/Update/AccountUpdateService.php index 0cddf3d427..75fb2b9ea9 100644 --- a/app/Services/Internal/Update/AccountUpdateService.php +++ b/app/Services/Internal/Update/AccountUpdateService.php @@ -63,19 +63,11 @@ class AccountUpdateService $this->accountRepository = app(AccountRepositoryInterface::class); } - /** - * @param User $user - */ - public function setUser(User $user): void - { - $this->user = $user; - } - /** * Update account data. * - * @param Account $account - * @param array $data + * @param Account $account + * @param array $data * * @return Account * @throws FireflyException @@ -122,8 +114,83 @@ class AccountUpdateService } /** - * @param Account $account - * @param array $data + * @param User $user + */ + public function setUser(User $user): void + { + $this->user = $user; + } + + /** + * @param Account $account + * @param array $data + * + * @return Account + */ + private function updateAccount(Account $account, array $data): Account + { + // update the account itself: + if (array_key_exists('name', $data)) { + $account->name = $data['name']; + } + if (array_key_exists('active', $data)) { + $account->active = $data['active']; + } + if (array_key_exists('iban', $data)) { + $account->iban = app('steam')->filterSpaces((string)$data['iban']); + } + + // set liability, but account must already be a liability. + //$liabilityType = $data['liability_type'] ?? ''; + if ($this->isLiability($account) && array_key_exists('liability_type', $data)) { + $type = $this->getAccountType($data['liability_type']); + $account->account_type_id = $type->id; + } + // set liability, alternative method used in v1 layout: + + if ($this->isLiability($account) && array_key_exists('account_type_id', $data)) { + $type = AccountType::find((int)$data['account_type_id']); + + if (null !== $type && in_array($type->type, config('firefly.valid_liabilities'), true)) { + $account->account_type_id = $type->id; + } + } + + // update virtual balance (could be set to zero if empty string). + if (array_key_exists('virtual_balance', $data) && null !== $data['virtual_balance']) { + $account->virtual_balance = '' === trim($data['virtual_balance']) ? '0' : $data['virtual_balance']; + } + + $account->save(); + + return $account; + } + + /** + * @param Account $account + * + * @return bool + */ + private function isLiability(Account $account): bool + { + $type = $account->accountType->type; + + return in_array($type, [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE], true); + } + + /** + * @param string $type + * + * @return AccountType + */ + private function getAccountType(string $type): AccountType + { + return AccountType::whereType(ucfirst($type))->first(); + } + + /** + * @param Account $account + * @param array $data * * @return Account */ @@ -174,16 +241,6 @@ class AccountUpdateService return $account; } - /** - * @param string $type - * - * @return AccountType - */ - private function getAccountType(string $type): AccountType - { - return AccountType::whereType(ucfirst($type))->first(); - } - private function getTypeIds(array $array): array { $return = []; @@ -198,65 +255,8 @@ class AccountUpdateService } /** - * @param Account $account - * - * @return bool - */ - private function isLiability(Account $account): bool - { - $type = $account->accountType->type; - - return in_array($type, [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE], true); - } - - /** - * @param Account $account - * @param array $data - * - * @return Account - */ - private function updateAccount(Account $account, array $data): Account - { - // update the account itself: - if (array_key_exists('name', $data)) { - $account->name = $data['name']; - } - if (array_key_exists('active', $data)) { - $account->active = $data['active']; - } - if (array_key_exists('iban', $data)) { - $account->iban = app('steam')->filterSpaces((string)$data['iban']); - } - - // set liability, but account must already be a liability. - //$liabilityType = $data['liability_type'] ?? ''; - if ($this->isLiability($account) && array_key_exists('liability_type', $data)) { - $type = $this->getAccountType($data['liability_type']); - $account->account_type_id = $type->id; - } - // set liability, alternative method used in v1 layout: - - if ($this->isLiability($account) && array_key_exists('account_type_id', $data)) { - $type = AccountType::find((int)$data['account_type_id']); - - if (null !== $type && in_array($type->type, config('firefly.valid_liabilities'), true)) { - $account->account_type_id = $type->id; - } - } - - // update virtual balance (could be set to zero if empty string). - if (array_key_exists('virtual_balance', $data) && null !== $data['virtual_balance']) { - $account->virtual_balance = '' === trim($data['virtual_balance']) ? '0' : $data['virtual_balance']; - } - - $account->save(); - - return $account; - } - - /** - * @param Account $account - * @param array $data + * @param Account $account + * @param array $data */ private function updateLocation(Account $account, array $data): void { @@ -285,8 +285,8 @@ class AccountUpdateService } /** - * @param Account $account - * @param array $data + * @param Account $account + * @param array $data * * @throws FireflyException */ @@ -321,7 +321,7 @@ class AccountUpdateService } /** - * @param Account $account + * @param Account $account * * @throws FireflyException */ diff --git a/app/Services/Internal/Update/BillUpdateService.php b/app/Services/Internal/Update/BillUpdateService.php index d53bcf32e7..025bdf4f0d 100644 --- a/app/Services/Internal/Update/BillUpdateService.php +++ b/app/Services/Internal/Update/BillUpdateService.php @@ -47,8 +47,8 @@ class BillUpdateService protected User $user; /** - * @param Bill $bill - * @param array $data + * @param Bill $bill + * @param array $data * * @return Bill * @throws FireflyException @@ -141,19 +141,8 @@ class BillUpdateService } /** - * @param Rule $rule - * @param string $key - * - * @return RuleTrigger|null - */ - private function getRuleTrigger(Rule $rule, string $key): ?RuleTrigger - { - return $rule->ruleTriggers()->where('trigger_type', $key)->first(); - } - - /** - * @param Bill $bill - * @param array $data + * @param Bill $bill + * @param array $data * * @return Bill */ @@ -196,9 +185,32 @@ class BillUpdateService } /** - * @param Bill $bill - * @param array $oldData - * @param array $newData + * @param Bill $bill + * @param int $oldOrder + * @param int $newOrder + */ + private function updateOrder(Bill $bill, int $oldOrder, int $newOrder): void + { + if ($newOrder > $oldOrder) { + $this->user->bills()->where('order', '<=', $newOrder)->where('order', '>', $oldOrder) + ->where('bills.id', '!=', $bill->id) + ->decrement('bills.order'); + $bill->order = $newOrder; + $bill->save(); + } + if ($newOrder < $oldOrder) { + $this->user->bills()->where('order', '>=', $newOrder)->where('order', '<', $oldOrder) + ->where('bills.id', '!=', $bill->id) + ->increment('bills.order'); + $bill->order = $newOrder; + $bill->save(); + } + } + + /** + * @param Bill $bill + * @param array $oldData + * @param array $newData */ private function updateBillTriggers(Bill $bill, array $oldData, array $newData): void { @@ -232,33 +244,10 @@ class BillUpdateService } /** - * @param Bill $bill - * @param int $oldOrder - * @param int $newOrder - */ - private function updateOrder(Bill $bill, int $oldOrder, int $newOrder): void - { - if ($newOrder > $oldOrder) { - $this->user->bills()->where('order', '<=', $newOrder)->where('order', '>', $oldOrder) - ->where('bills.id', '!=', $bill->id) - ->decrement('bills.order'); - $bill->order = $newOrder; - $bill->save(); - } - if ($newOrder < $oldOrder) { - $this->user->bills()->where('order', '>=', $newOrder)->where('order', '<', $oldOrder) - ->where('bills.id', '!=', $bill->id) - ->increment('bills.order'); - $bill->order = $newOrder; - $bill->save(); - } - } - - /** - * @param Collection $rules - * @param string $key - * @param string $oldValue - * @param string $newValue + * @param Collection $rules + * @param string $key + * @param string $oldValue + * @param string $newValue */ private function updateRules(Collection $rules, string $key, string $oldValue, string $newValue): void { @@ -279,4 +268,15 @@ class BillUpdateService } } } + + /** + * @param Rule $rule + * @param string $key + * + * @return RuleTrigger|null + */ + private function getRuleTrigger(Rule $rule, string $key): ?RuleTrigger + { + return $rule->ruleTriggers()->where('trigger_type', $key)->first(); + } } diff --git a/app/Services/Internal/Update/CategoryUpdateService.php b/app/Services/Internal/Update/CategoryUpdateService.php index 63c14e3b73..0d2cdba3f7 100644 --- a/app/Services/Internal/Update/CategoryUpdateService.php +++ b/app/Services/Internal/Update/CategoryUpdateService.php @@ -51,7 +51,7 @@ class CategoryUpdateService } /** - * @param mixed $user + * @param mixed $user */ public function setUser($user): void { @@ -59,8 +59,8 @@ class CategoryUpdateService } /** - * @param Category $category - * @param array $data + * @param Category $category + * @param array $data * * @return Category * @throws Exception @@ -83,8 +83,64 @@ class CategoryUpdateService } /** - * @param Category $category - * @param array $data + * @param string $oldName + * @param string $newName + */ + private function updateRuleTriggers(string $oldName, string $newName): void + { + $types = ['category_is',]; + $triggers = RuleTrigger::leftJoin('rules', 'rules.id', '=', 'rule_triggers.rule_id') + ->where('rules.user_id', $this->user->id) + ->whereIn('rule_triggers.trigger_type', $types) + ->where('rule_triggers.trigger_value', $oldName) + ->get(['rule_triggers.*']); + Log::debug(sprintf('Found %d triggers to update.', $triggers->count())); + /** @var RuleTrigger $trigger */ + foreach ($triggers as $trigger) { + $trigger->trigger_value = $newName; + $trigger->save(); + Log::debug(sprintf('Updated trigger %d: %s', $trigger->id, $trigger->trigger_value)); + } + } + + /** + * @param string $oldName + * @param string $newName + */ + private function updateRuleActions(string $oldName, string $newName): void + { + $types = ['set_category',]; + $actions = RuleAction::leftJoin('rules', 'rules.id', '=', 'rule_actions.rule_id') + ->where('rules.user_id', $this->user->id) + ->whereIn('rule_actions.action_type', $types) + ->where('rule_actions.action_value', $oldName) + ->get(['rule_actions.*']); + Log::debug(sprintf('Found %d actions to update.', $actions->count())); + /** @var RuleAction $action */ + foreach ($actions as $action) { + $action->action_value = $newName; + $action->save(); + Log::debug(sprintf('Updated action %d: %s', $action->id, $action->action_value)); + } + } + + /** + * @param string $oldName + * @param string $newName + */ + private function updateRecurrences(string $oldName, string $newName): void + { + RecurrenceTransactionMeta::leftJoin('recurrences_transactions', 'rt_meta.rt_id', '=', 'recurrences_transactions.id') + ->leftJoin('recurrences', 'recurrences.id', '=', 'recurrences_transactions.recurrence_id') + ->where('recurrences.user_id', $this->user->id) + ->where('rt_meta.name', 'category_name') + ->where('rt_meta.value', $oldName) + ->update(['rt_meta.value' => $newName]); + } + + /** + * @param Category $category + * @param array $data * * @throws Exception */ @@ -110,60 +166,4 @@ class CategoryUpdateService $dbNote->text = trim($note); $dbNote->save(); } - - /** - * @param string $oldName - * @param string $newName - */ - private function updateRecurrences(string $oldName, string $newName): void - { - RecurrenceTransactionMeta::leftJoin('recurrences_transactions', 'rt_meta.rt_id', '=', 'recurrences_transactions.id') - ->leftJoin('recurrences', 'recurrences.id', '=', 'recurrences_transactions.recurrence_id') - ->where('recurrences.user_id', $this->user->id) - ->where('rt_meta.name', 'category_name') - ->where('rt_meta.value', $oldName) - ->update(['rt_meta.value' => $newName]); - } - - /** - * @param string $oldName - * @param string $newName - */ - private function updateRuleActions(string $oldName, string $newName): void - { - $types = ['set_category',]; - $actions = RuleAction::leftJoin('rules', 'rules.id', '=', 'rule_actions.rule_id') - ->where('rules.user_id', $this->user->id) - ->whereIn('rule_actions.action_type', $types) - ->where('rule_actions.action_value', $oldName) - ->get(['rule_actions.*']); - Log::debug(sprintf('Found %d actions to update.', $actions->count())); - /** @var RuleAction $action */ - foreach ($actions as $action) { - $action->action_value = $newName; - $action->save(); - Log::debug(sprintf('Updated action %d: %s', $action->id, $action->action_value)); - } - } - - /** - * @param string $oldName - * @param string $newName - */ - private function updateRuleTriggers(string $oldName, string $newName): void - { - $types = ['category_is',]; - $triggers = RuleTrigger::leftJoin('rules', 'rules.id', '=', 'rule_triggers.rule_id') - ->where('rules.user_id', $this->user->id) - ->whereIn('rule_triggers.trigger_type', $types) - ->where('rule_triggers.trigger_value', $oldName) - ->get(['rule_triggers.*']); - Log::debug(sprintf('Found %d triggers to update.', $triggers->count())); - /** @var RuleTrigger $trigger */ - foreach ($triggers as $trigger) { - $trigger->trigger_value = $newName; - $trigger->save(); - Log::debug(sprintf('Updated trigger %d: %s', $trigger->id, $trigger->trigger_value)); - } - } } diff --git a/app/Services/Internal/Update/CurrencyUpdateService.php b/app/Services/Internal/Update/CurrencyUpdateService.php index ab6606141c..c01444e4e8 100644 --- a/app/Services/Internal/Update/CurrencyUpdateService.php +++ b/app/Services/Internal/Update/CurrencyUpdateService.php @@ -33,8 +33,8 @@ use FireflyIII\Models\TransactionCurrency; class CurrencyUpdateService { /** - * @param TransactionCurrency $currency - * @param array $data + * @param TransactionCurrency $currency + * @param array $data * * @return TransactionCurrency */ diff --git a/app/Services/Internal/Update/GroupCloneService.php b/app/Services/Internal/Update/GroupCloneService.php index 1696ef8fbd..21a0e3bbc4 100644 --- a/app/Services/Internal/Update/GroupCloneService.php +++ b/app/Services/Internal/Update/GroupCloneService.php @@ -40,7 +40,7 @@ use FireflyIII\Models\TransactionJournalMeta; class GroupCloneService { /** - * @param TransactionGroup $group + * @param TransactionGroup $group * * @return TransactionGroup */ @@ -56,9 +56,9 @@ class GroupCloneService } /** - * @param TransactionJournal $journal - * @param TransactionGroup $newGroup - * @param int $originalGroup + * @param TransactionJournal $journal + * @param TransactionGroup $newGroup + * @param int $originalGroup */ private function cloneJournal(TransactionJournal $journal, TransactionGroup $newGroup, int $originalGroup): void { @@ -115,22 +115,21 @@ class GroupCloneService } /** - * @param TransactionJournalMeta $meta - * @param TransactionJournal $newJournal + * @param Transaction $transaction + * @param TransactionJournal $newJournal */ - private function cloneMeta(TransactionJournalMeta $meta, TransactionJournal $newJournal): void + private function cloneTransaction(Transaction $transaction, TransactionJournal $newJournal): void { - $newMeta = $meta->replicate(); - $newMeta->transaction_journal_id = $newJournal->id; - if ('recurrence_id' !== $newMeta->name) { - $newMeta->save(); - } + $newTransaction = $transaction->replicate(); + $newTransaction->transaction_journal_id = $newJournal->id; + $newTransaction->reconciled = false; + $newTransaction->save(); } /** - * @param Note $note - * @param TransactionJournal $newJournal - * @param int $oldGroupId + * @param Note $note + * @param TransactionJournal $newJournal + * @param int $oldGroupId */ private function cloneNote(Note $note, TransactionJournal $newJournal, int $oldGroupId): void { @@ -144,14 +143,15 @@ class GroupCloneService } /** - * @param Transaction $transaction - * @param TransactionJournal $newJournal + * @param TransactionJournalMeta $meta + * @param TransactionJournal $newJournal */ - private function cloneTransaction(Transaction $transaction, TransactionJournal $newJournal): void + private function cloneMeta(TransactionJournalMeta $meta, TransactionJournal $newJournal): void { - $newTransaction = $transaction->replicate(); - $newTransaction->transaction_journal_id = $newJournal->id; - $newTransaction->reconciled = false; - $newTransaction->save(); + $newMeta = $meta->replicate(); + $newMeta->transaction_journal_id = $newJournal->id; + if ('recurrence_id' !== $newMeta->name) { + $newMeta->save(); + } } } diff --git a/app/Services/Internal/Update/GroupUpdateService.php b/app/Services/Internal/Update/GroupUpdateService.php index acbcba9d09..040138a74a 100644 --- a/app/Services/Internal/Update/GroupUpdateService.php +++ b/app/Services/Internal/Update/GroupUpdateService.php @@ -124,49 +124,6 @@ class GroupUpdateService return $transactionGroup; } - /** - * @param TransactionGroup $transactionGroup - * @param array $data - * - * @return TransactionJournal|null - * - * @throws DuplicateTransactionException - * @throws FireflyException - * @throws JsonException - */ - private function createTransactionJournal(TransactionGroup $transactionGroup, array $data): ?TransactionJournal - { - $submission = [ - 'transactions' => [ - $data, - ], - ]; - /** @var TransactionJournalFactory $factory */ - $factory = app(TransactionJournalFactory::class); - $factory->setUser($transactionGroup->user); - try { - $collection = $factory->create($submission); - } catch (FireflyException $e) { - Log::error($e->getMessage()); - Log::error($e->getTraceAsString()); - throw new FireflyException( - sprintf('Could not create new transaction journal: %s', $e->getMessage()), - 0, - $e - ); - } - $collection->each( - function (TransactionJournal $journal) use ($transactionGroup) { - $transactionGroup->transactionJournals()->save($journal); - } - ); - if (0 === $collection->count()) { - return null; - } - - return $collection->first(); - } - /** * Update single journal. * @@ -252,4 +209,47 @@ class GroupUpdateService return $updated; } + + /** + * @param TransactionGroup $transactionGroup + * @param array $data + * + * @return TransactionJournal|null + * + * @throws DuplicateTransactionException + * @throws FireflyException + * @throws JsonException + */ + private function createTransactionJournal(TransactionGroup $transactionGroup, array $data): ?TransactionJournal + { + $submission = [ + 'transactions' => [ + $data, + ], + ]; + /** @var TransactionJournalFactory $factory */ + $factory = app(TransactionJournalFactory::class); + $factory->setUser($transactionGroup->user); + try { + $collection = $factory->create($submission); + } catch (FireflyException $e) { + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); + throw new FireflyException( + sprintf('Could not create new transaction journal: %s', $e->getMessage()), + 0, + $e + ); + } + $collection->each( + function (TransactionJournal $journal) use ($transactionGroup) { + $transactionGroup->transactionJournals()->save($journal); + } + ); + if (0 === $collection->count()) { + return null; + } + + return $collection->first(); + } } diff --git a/app/Services/Internal/Update/JournalUpdateService.php b/app/Services/Internal/Update/JournalUpdateService.php index 90c37cf052..14a17caad4 100644 --- a/app/Services/Internal/Update/JournalUpdateService.php +++ b/app/Services/Internal/Update/JournalUpdateService.php @@ -183,49 +183,78 @@ class JournalUpdateService } /** - * Get destination transaction. - * - * @return Transaction + * @return bool */ - private function getDestinationTransaction(): Transaction + private function removeReconciliation(): bool { - if (null === $this->destinationTransaction) { - $this->destinationTransaction = $this->transactionJournal->transactions()->where('amount', '>', 0)->first(); + if (count($this->data) > 1) { + return true; + } + if (1 === count($this->data) && true === array_key_exists('transaction_journal_id', $this->data)) { + return true; } - return $this->destinationTransaction; + return false; } /** - * This method returns the current or expected type of the journal (in case of a change) based on the data in the - * array. - * - * If the array contains key 'type' and the value is correct, this is returned. Otherwise, the original type is - * returned. - * - * @return string + * @return bool */ - private function getExpectedType(): string + private function hasValidAccounts(): bool { - Log::debug('Now in getExpectedType()'); - if ($this->hasFields(['type'])) { - return ucfirst('opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type']); - } - - return $this->transactionJournal->transactionType->type; + return $this->hasValidSourceAccount() && $this->hasValidDestinationAccount(); } /** - * @return Account + * @return bool */ - private function getOriginalDestinationAccount(): Account + private function hasValidSourceAccount(): bool { - if (null === $this->destinationAccount) { - $destination = $this->getDestinationTransaction(); - $this->destinationAccount = $destination->account; + Log::debug('Now in hasValidSourceAccount().'); + $sourceId = $this->data['source_id'] ?? null; + $sourceName = $this->data['source_name'] ?? null; + + if (!$this->hasFields(['source_id', 'source_name'])) { + $origSourceAccount = $this->getOriginalSourceAccount(); + $sourceId = $origSourceAccount->id; + $sourceName = $origSourceAccount->name; } - return $this->destinationAccount; + // make new account validator. + $expectedType = $this->getExpectedType(); + Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType)); + + // make a new validator. + /** @var AccountValidator $validator */ + $validator = app(AccountValidator::class); + $validator->setTransactionType($expectedType); + $validator->setUser($this->transactionJournal->user); + + $result = $validator->validateSource(['id' => $sourceId]); + Log::debug( + sprintf('hasValidSourceAccount(%d, "%s") will return %s', $sourceId, $sourceName, var_export($result, true)) + ); + + // TODO typeoverrule the account validator may have a different opinion on the transaction type. + + // validate submitted info: + return $result; + } + + /** + * @param array $fields + * + * @return bool + */ + private function hasFields(array $fields): bool + { + foreach ($fields as $field) { + if (array_key_exists($field, $this->data)) { + return true; + } + } + + return false; } /** @@ -259,96 +288,22 @@ class JournalUpdateService } /** - * Does a validation and returns the destination account. This method will break if the dest isn't really valid. + * This method returns the current or expected type of the journal (in case of a change) based on the data in the + * array. * - * @return Account - */ - private function getValidDestinationAccount(): Account - { - Log::debug('Now in getValidDestinationAccount().'); - - if (!$this->hasFields(['destination_id', 'destination_name'])) { - return $this->getOriginalDestinationAccount(); - } - - $destInfo = [ - 'id' => (int)($this->data['destination_id'] ?? null), - 'name' => $this->data['destination_name'] ?? null, - 'iban' => $this->data['destination_iban'] ?? null, - 'number' => $this->data['destination_number'] ?? null, - 'bic' => $this->data['destination_bic'] ?? null, - ]; - - // make new account validator. - $expectedType = $this->getExpectedType(); - Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType)); - try { - $result = $this->getAccount($expectedType, 'destination', $destInfo); - } catch (FireflyException $e) { - Log::error(sprintf('getValidDestinationAccount() threw unexpected error: %s', $e->getMessage())); - $result = $this->getOriginalDestinationAccount(); - } - - return $result; - } - - /** - * Does a validation and returns the source account. This method will break if the source isn't really valid. + * If the array contains key 'type' and the value is correct, this is returned. Otherwise, the original type is + * returned. * - * @return Account + * @return string */ - private function getValidSourceAccount(): Account + private function getExpectedType(): string { - Log::debug('Now in getValidSourceAccount().'); - - if (!$this->hasFields(['source_id', 'source_name'])) { - return $this->getOriginalSourceAccount(); + Log::debug('Now in getExpectedType()'); + if ($this->hasFields(['type'])) { + return ucfirst('opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type']); } - $sourceInfo = [ - 'id' => (int)($this->data['source_id'] ?? null), - 'name' => $this->data['source_name'] ?? null, - 'iban' => $this->data['source_iban'] ?? null, - 'number' => $this->data['source_number'] ?? null, - 'bic' => $this->data['source_bic'] ?? null, - ]; - - $expectedType = $this->getExpectedType(); - try { - $result = $this->getAccount($expectedType, 'source', $sourceInfo); - } catch (FireflyException $e) { - Log::error(sprintf('Cant get the valid source account: %s', $e->getMessage())); - - $result = $this->getOriginalSourceAccount(); - } - - Log::debug(sprintf('getValidSourceAccount() will return #%d ("%s")', $result->id, $result->name)); - - return $result; - } - - /** - * @param array $fields - * - * @return bool - */ - private function hasFields(array $fields): bool - { - foreach ($fields as $field) { - if (array_key_exists($field, $this->data)) { - return true; - } - } - - return false; - } - - /** - * @return bool - */ - private function hasValidAccounts(): bool - { - return $this->hasValidSourceAccount() && $this->hasValidDestinationAccount(); + return $this->transactionJournal->transactionType->type; } /** @@ -394,54 +349,65 @@ class JournalUpdateService } /** - * @return bool + * @return Account */ - private function hasValidSourceAccount(): bool + private function getOriginalDestinationAccount(): Account { - Log::debug('Now in hasValidSourceAccount().'); - $sourceId = $this->data['source_id'] ?? null; - $sourceName = $this->data['source_name'] ?? null; - - if (!$this->hasFields(['source_id', 'source_name'])) { - $origSourceAccount = $this->getOriginalSourceAccount(); - $sourceId = $origSourceAccount->id; - $sourceName = $origSourceAccount->name; + if (null === $this->destinationAccount) { + $destination = $this->getDestinationTransaction(); + $this->destinationAccount = $destination->account; } - // make new account validator. - $expectedType = $this->getExpectedType(); - Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType)); - - // make a new validator. - /** @var AccountValidator $validator */ - $validator = app(AccountValidator::class); - $validator->setTransactionType($expectedType); - $validator->setUser($this->transactionJournal->user); - - $result = $validator->validateSource(['id' => $sourceId]); - Log::debug( - sprintf('hasValidSourceAccount(%d, "%s") will return %s', $sourceId, $sourceName, var_export($result, true)) - ); - - // TODO typeoverrule the account validator may have a different opinion on the transaction type. - - // validate submitted info: - return $result; + return $this->destinationAccount; } /** - * @return bool + * Get destination transaction. + * + * @return Transaction */ - private function removeReconciliation(): bool + private function getDestinationTransaction(): Transaction { - if (count($this->data) > 1) { - return true; - } - if (1 === count($this->data) && true === array_key_exists('transaction_journal_id', $this->data)) { - return true; + if (null === $this->destinationTransaction) { + $this->destinationTransaction = $this->transactionJournal->transactions()->where('amount', '>', 0)->first(); } - return false; + return $this->destinationTransaction; + } + + /** + * Does a validation and returns the source account. This method will break if the source isn't really valid. + * + * @return Account + */ + private function getValidSourceAccount(): Account + { + Log::debug('Now in getValidSourceAccount().'); + + if (!$this->hasFields(['source_id', 'source_name'])) { + return $this->getOriginalSourceAccount(); + } + + $sourceInfo = [ + 'id' => (int)($this->data['source_id'] ?? null), + 'name' => $this->data['source_name'] ?? null, + 'iban' => $this->data['source_iban'] ?? null, + 'number' => $this->data['source_number'] ?? null, + 'bic' => $this->data['source_bic'] ?? null, + ]; + + $expectedType = $this->getExpectedType(); + try { + $result = $this->getAccount($expectedType, 'source', $sourceInfo); + } catch (FireflyException $e) { + Log::error(sprintf('Cant get the valid source account: %s', $e->getMessage())); + + $result = $this->getOriginalSourceAccount(); + } + + Log::debug(sprintf('getValidSourceAccount() will return #%d ("%s")', $result->id, $result->name)); + + return $result; } /** @@ -475,34 +441,70 @@ class JournalUpdateService } /** + * Does a validation and returns the destination account. This method will break if the dest isn't really valid. * + * @return Account */ - private function updateAmount(): void + private function getValidDestinationAccount(): Account { - Log::debug(sprintf('Now in %s', __METHOD__)); - if (!$this->hasFields(['amount'])) { - return; + Log::debug('Now in getValidDestinationAccount().'); + + if (!$this->hasFields(['destination_id', 'destination_name'])) { + return $this->getOriginalDestinationAccount(); } - $value = $this->data['amount'] ?? ''; - Log::debug(sprintf('Amount is now "%s"', $value)); + $destInfo = [ + 'id' => (int)($this->data['destination_id'] ?? null), + 'name' => $this->data['destination_name'] ?? null, + 'iban' => $this->data['destination_iban'] ?? null, + 'number' => $this->data['destination_number'] ?? null, + 'bic' => $this->data['destination_bic'] ?? null, + ]; + + // make new account validator. + $expectedType = $this->getExpectedType(); + Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType)); try { - $amount = $this->getAmount($value); + $result = $this->getAccount($expectedType, 'destination', $destInfo); } catch (FireflyException $e) { - Log::debug(sprintf('getAmount("%s") returns error: %s', $value, $e->getMessage())); + Log::error(sprintf('getValidDestinationAccount() threw unexpected error: %s', $e->getMessage())); + $result = $this->getOriginalDestinationAccount(); + } + + return $result; + } + + /** + * Updates journal transaction type. + */ + private function updateType(): void + { + Log::debug('Now in updateType()'); + if ($this->hasFields(['type'])) { + $type = 'opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type']; + Log::debug( + sprintf( + 'Trying to change journal #%d from a %s to a %s.', + $this->transactionJournal->id, + $this->transactionJournal->transactionType->type, + $type + ) + ); + + /** @var TransactionTypeFactory $typeFactory */ + $typeFactory = app(TransactionTypeFactory::class); + $result = $typeFactory->find($this->data['type']); + if (null !== $result) { + Log::debug('Changed transaction type!'); + $this->transactionJournal->transaction_type_id = $result->id; + $this->transactionJournal->save(); + + return; + } return; } - $origSourceTransaction = $this->getSourceTransaction(); - $origSourceTransaction->amount = app('steam')->negative($amount); - $origSourceTransaction->save(); - $destTransaction = $this->getDestinationTransaction(); - $destTransaction->amount = app('steam')->positive($amount); - $destTransaction->save(); - // refresh transactions. - $this->sourceTransaction->refresh(); - $this->destinationTransaction->refresh(); - Log::debug(sprintf('Updated amount to "%s"', $amount)); + Log::debug('No type field present.'); } /** @@ -525,67 +527,6 @@ class JournalUpdateService } } - /** - * - */ - private function updateBudget(): void - { - // update budget - if ($this->hasFields(['budget_id', 'budget_name'])) { - Log::debug('Will update budget.'); - $this->storeBudget($this->transactionJournal, new NullArrayObject($this->data)); - } - // is transfer? remove budget - if (TransactionType::TRANSFER === $this->transactionJournal->transactionType->type) { - $this->transactionJournal->budgets()->sync([]); - } - } - - /** - * - */ - private function updateCategory(): void - { - // update category - if ($this->hasFields(['category_id', 'category_name'])) { - Log::debug('Will update category.'); - - $this->storeCategory($this->transactionJournal, new NullArrayObject($this->data)); - } - } - - /** - * - */ - private function updateCurrency(): void - { - // update transactions. - if (!$this->hasFields(['currency_id', 'currency_code'])) { - return; - } - $currencyId = $this->data['currency_id'] ?? null; - $currencyCode = $this->data['currency_code'] ?? null; - $currency = $this->currencyRepository->findCurrency($currencyId, $currencyCode); - if (null !== $currency) { - // update currency everywhere. - $this->transactionJournal->transaction_currency_id = $currency->id; - $this->transactionJournal->save(); - - $source = $this->getSourceTransaction(); - $source->transaction_currency_id = $currency->id; - $source->save(); - - $dest = $this->getDestinationTransaction(); - $dest->transaction_currency_id = $currency->id; - $dest->save(); - - // refresh transactions. - $this->sourceTransaction->refresh(); - $this->destinationTransaction->refresh(); - Log::debug(sprintf('Updated currency to #%d (%s)', $currency->id, $currency->code)); - } - } - /** * Update journal generic field. Cannot be set to NULL. * @@ -622,6 +563,201 @@ class JournalUpdateService } } + /** + * + */ + private function updateCategory(): void + { + // update category + if ($this->hasFields(['category_id', 'category_name'])) { + Log::debug('Will update category.'); + + $this->storeCategory($this->transactionJournal, new NullArrayObject($this->data)); + } + } + + /** + * + */ + private function updateBudget(): void + { + // update budget + if ($this->hasFields(['budget_id', 'budget_name'])) { + Log::debug('Will update budget.'); + $this->storeBudget($this->transactionJournal, new NullArrayObject($this->data)); + } + // is transfer? remove budget + if (TransactionType::TRANSFER === $this->transactionJournal->transactionType->type) { + $this->transactionJournal->budgets()->sync([]); + } + } + + /** + * + */ + private function updateTags(): void + { + if ($this->hasFields(['tags'])) { + Log::debug('Will update tags.'); + $tags = $this->data['tags'] ?? null; + $this->storeTags($this->transactionJournal, $tags); + } + } + + /** + * + */ + private function updateReconciled(): void + { + if (array_key_exists('reconciled', $this->data) && is_bool($this->data['reconciled'])) { + $this->transactionJournal->transactions()->update(['reconciled' => $this->data['reconciled']]); + } + } + + /** + * + */ + private function updateNotes(): void + { + // update notes. + if ($this->hasFields(['notes'])) { + $notes = '' === (string)$this->data['notes'] ? null : $this->data['notes']; + $this->storeNotes($this->transactionJournal, $notes); + } + } + + /** + * + */ + private function updateMeta(): void + { + // update meta fields. + // first string + if ($this->hasFields($this->metaString)) { + Log::debug('Meta string fields are present.'); + $this->updateMetaFields(); + } + + // then date fields. + if ($this->hasFields($this->metaDate)) { + Log::debug('Meta date fields are present.'); + $this->updateMetaDateFields(); + } + } + + /** + * + */ + private function updateMetaFields(): void + { + /** @var TransactionJournalMetaFactory $factory */ + $factory = app(TransactionJournalMetaFactory::class); + + foreach ($this->metaString as $field) { + if ($this->hasFields([$field])) { + $value = '' === $this->data[$field] ? null : $this->data[$field]; + Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value)); + $set = [ + 'journal' => $this->transactionJournal, + 'name' => $field, + 'data' => $value, + ]; + $factory->updateOrCreate($set); + } + } + } + + /** + * + */ + private function updateMetaDateFields(): void + { + /** @var TransactionJournalMetaFactory $factory */ + $factory = app(TransactionJournalMetaFactory::class); + + foreach ($this->metaDate as $field) { + if ($this->hasFields([$field])) { + try { + $value = '' === (string)$this->data[$field] ? null : new Carbon($this->data[$field]); + } catch (InvalidDateException $e) { + Log::debug(sprintf('%s is not a valid date value: %s', $this->data[$field], $e->getMessage())); + + return; + } + Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value)); + $set = [ + 'journal' => $this->transactionJournal, + 'name' => $field, + 'data' => $value, + ]; + $factory->updateOrCreate($set); + } + } + } + + /** + * + */ + private function updateCurrency(): void + { + // update transactions. + if (!$this->hasFields(['currency_id', 'currency_code'])) { + return; + } + $currencyId = $this->data['currency_id'] ?? null; + $currencyCode = $this->data['currency_code'] ?? null; + $currency = $this->currencyRepository->findCurrency($currencyId, $currencyCode); + if (null !== $currency) { + // update currency everywhere. + $this->transactionJournal->transaction_currency_id = $currency->id; + $this->transactionJournal->save(); + + $source = $this->getSourceTransaction(); + $source->transaction_currency_id = $currency->id; + $source->save(); + + $dest = $this->getDestinationTransaction(); + $dest->transaction_currency_id = $currency->id; + $dest->save(); + + // refresh transactions. + $this->sourceTransaction->refresh(); + $this->destinationTransaction->refresh(); + Log::debug(sprintf('Updated currency to #%d (%s)', $currency->id, $currency->code)); + } + } + + /** + * + */ + private function updateAmount(): void + { + Log::debug(sprintf('Now in %s', __METHOD__)); + if (!$this->hasFields(['amount'])) { + return; + } + + $value = $this->data['amount'] ?? ''; + Log::debug(sprintf('Amount is now "%s"', $value)); + try { + $amount = $this->getAmount($value); + } catch (FireflyException $e) { + Log::debug(sprintf('getAmount("%s") returns error: %s', $value, $e->getMessage())); + + return; + } + $origSourceTransaction = $this->getSourceTransaction(); + $origSourceTransaction->amount = app('steam')->negative($amount); + $origSourceTransaction->save(); + $destTransaction = $this->getDestinationTransaction(); + $destTransaction->amount = app('steam')->positive($amount); + $destTransaction->save(); + // refresh transactions. + $this->sourceTransaction->refresh(); + $this->destinationTransaction->refresh(); + Log::debug(sprintf('Updated amount to "%s"', $amount)); + } + /** * */ @@ -691,140 +827,4 @@ class JournalUpdateService $this->sourceTransaction->refresh(); $this->destinationTransaction->refresh(); } - - /** - * - */ - private function updateMeta(): void - { - // update meta fields. - // first string - if ($this->hasFields($this->metaString)) { - Log::debug('Meta string fields are present.'); - $this->updateMetaFields(); - } - - // then date fields. - if ($this->hasFields($this->metaDate)) { - Log::debug('Meta date fields are present.'); - $this->updateMetaDateFields(); - } - } - - /** - * - */ - private function updateMetaDateFields(): void - { - /** @var TransactionJournalMetaFactory $factory */ - $factory = app(TransactionJournalMetaFactory::class); - - foreach ($this->metaDate as $field) { - if ($this->hasFields([$field])) { - try { - $value = '' === (string)$this->data[$field] ? null : new Carbon($this->data[$field]); - } catch (InvalidDateException $e) { - Log::debug(sprintf('%s is not a valid date value: %s', $this->data[$field], $e->getMessage())); - - return; - } - Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value)); - $set = [ - 'journal' => $this->transactionJournal, - 'name' => $field, - 'data' => $value, - ]; - $factory->updateOrCreate($set); - } - } - } - - /** - * - */ - private function updateMetaFields(): void - { - /** @var TransactionJournalMetaFactory $factory */ - $factory = app(TransactionJournalMetaFactory::class); - - foreach ($this->metaString as $field) { - if ($this->hasFields([$field])) { - $value = '' === $this->data[$field] ? null : $this->data[$field]; - Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value)); - $set = [ - 'journal' => $this->transactionJournal, - 'name' => $field, - 'data' => $value, - ]; - $factory->updateOrCreate($set); - } - } - } - - /** - * - */ - private function updateNotes(): void - { - // update notes. - if ($this->hasFields(['notes'])) { - $notes = '' === (string)$this->data['notes'] ? null : $this->data['notes']; - $this->storeNotes($this->transactionJournal, $notes); - } - } - - /** - * - */ - private function updateReconciled(): void - { - if (array_key_exists('reconciled', $this->data) && is_bool($this->data['reconciled'])) { - $this->transactionJournal->transactions()->update(['reconciled' => $this->data['reconciled']]); - } - } - - /** - * - */ - private function updateTags(): void - { - if ($this->hasFields(['tags'])) { - Log::debug('Will update tags.'); - $tags = $this->data['tags'] ?? null; - $this->storeTags($this->transactionJournal, $tags); - } - } - - /** - * Updates journal transaction type. - */ - private function updateType(): void - { - Log::debug('Now in updateType()'); - if ($this->hasFields(['type'])) { - $type = 'opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type']; - Log::debug( - sprintf( - 'Trying to change journal #%d from a %s to a %s.', - $this->transactionJournal->id, - $this->transactionJournal->transactionType->type, - $type - ) - ); - - /** @var TransactionTypeFactory $typeFactory */ - $typeFactory = app(TransactionTypeFactory::class); - $result = $typeFactory->find($this->data['type']); - if (null !== $result) { - Log::debug('Changed transaction type!'); - $this->transactionJournal->transaction_type_id = $result->id; - $this->transactionJournal->save(); - - return; - } - - return; - } - Log::debug('No type field present.'); - } } diff --git a/app/Services/Internal/Update/RecurrenceUpdateService.php b/app/Services/Internal/Update/RecurrenceUpdateService.php index 9f85b38504..929cca6dc5 100644 --- a/app/Services/Internal/Update/RecurrenceUpdateService.php +++ b/app/Services/Internal/Update/RecurrenceUpdateService.php @@ -33,7 +33,6 @@ use FireflyIII\Services\Internal\Support\RecurringTransactionTrait; use FireflyIII\Services\Internal\Support\TransactionTypeTrait; use FireflyIII\User; use Illuminate\Support\Facades\Log; -use JsonException; /** * Class RecurrenceUpdateService @@ -52,8 +51,8 @@ class RecurrenceUpdateService * * TODO if the user updates the type, the accounts must be validated again. * - * @param Recurrence $recurrence - * @param array $data + * @param Recurrence $recurrence + * @param array $data * * @return Recurrence * @throws FireflyException @@ -113,19 +112,72 @@ class RecurrenceUpdateService } /** - * @param Recurrence $recurrence - * @param int $transactionId - * @return void + * @param Recurrence $recurrence + * @param string $text */ - private function deleteTransaction(Recurrence $recurrence, int $transactionId): void + private function setNoteText(Recurrence $recurrence, string $text): void { - Log::debug(sprintf('Will delete transaction #%d in recurrence #%d.', $transactionId, $recurrence->id)); - $recurrence->recurrenceTransactions()->where('id', $transactionId)->delete(); + $dbNote = $recurrence->notes()->first(); + if ('' !== $text) { + if (null === $dbNote) { + $dbNote = new Note(); + $dbNote->noteable()->associate($recurrence); + } + $dbNote->text = trim($text); + $dbNote->save(); + + return; + } + $dbNote?->delete(); } /** - * @param Recurrence $recurrence - * @param array $data + * + * @param Recurrence $recurrence + * @param array $repetitions + * + * @throws FireflyException + */ + private function updateRepetitions(Recurrence $recurrence, array $repetitions): void + { + $originalCount = $recurrence->recurrenceRepetitions()->count(); + if (0 === count($repetitions)) { + // won't drop repetition, rather avoid. + return; + } + // user added or removed repetitions, delete all and recreate: + if ($originalCount !== count($repetitions)) { + Log::debug('Delete existing repetitions and create new ones.'); + $this->deleteRepetitions($recurrence); + $this->createRepetitions($recurrence, $repetitions); + + return; + } + // loop all and try to match them: + Log::debug('Loop and find'); + foreach ($repetitions as $current) { + $match = $this->matchRepetition($recurrence, $current); + if (null === $match) { + throw new FireflyException('Cannot match recurring repetition to existing repetition. Not sure what to do. Break.'); + } + $fields = [ + 'type' => 'repetition_type', + 'moment' => 'repetition_moment', + 'skip' => 'repetition_skip', + 'weekend' => 'weekend', + ]; + foreach ($fields as $field => $column) { + if (array_key_exists($field, $current)) { + $match->$column = $current[$field]; + $match->save(); + } + } + } + } + + /** + * @param Recurrence $recurrence + * @param array $data * * @return RecurrenceRepetition|null */ @@ -156,28 +208,69 @@ class RecurrenceUpdateService } /** - * @param Recurrence $recurrence - * @param string $text + * TODO this method is very complex. + * + * @param Recurrence $recurrence + * @param array $transactions */ - private function setNoteText(Recurrence $recurrence, string $text): void + private function updateTransactions(Recurrence $recurrence, array $transactions): void { - $dbNote = $recurrence->notes()->first(); - if ('' !== $text) { - if (null === $dbNote) { - $dbNote = new Note(); - $dbNote->noteable()->associate($recurrence); - } - $dbNote->text = trim($text); - $dbNote->save(); - + Log::debug('Now in updateTransactions()'); + $originalCount = $recurrence->recurrenceTransactions()->count(); + Log::debug(sprintf('Original count is %d', $originalCount)); + if (0 === count($transactions)) { + // won't drop transactions, rather avoid. + Log::warning('No transactions to update, too scared to continue!'); return; } - $dbNote?->delete(); + $combinations = []; + $originalTransactions = $recurrence->recurrenceTransactions()->get()->toArray(); + /** + * First, make sure to loop all existing transactions and match them to a counterpart in the submitted transactions array. + */ + foreach ($originalTransactions as $i => $originalTransaction) { + foreach ($transactions as $ii => $submittedTransaction) { + if (array_key_exists('id', $submittedTransaction) && (int)$originalTransaction['id'] === (int)$submittedTransaction['id']) { + Log::debug(sprintf('Match original transaction #%d with an entry in the submitted array.', $originalTransaction['id'])); + $combinations[] = [ + 'original' => $originalTransaction, + 'submitted' => $submittedTransaction, + ]; + unset($originalTransactions[$i]); + unset($transactions[$ii]); + } + } + } + /** + * If one left of both we can match those as well and presto. + */ + if (1 === count($originalTransactions) && 1 === count($transactions)) { + $first = array_shift($originalTransactions); + Log::debug(sprintf('One left of each, link them (ID is #%d)', $first['id'])); + $combinations[] = [ + 'original' => $first, + 'submitted' => array_shift($transactions), + ]; + unset($first); + } + // if they are both empty, we can safely loop all combinations and update them. + if (0 === count($originalTransactions) && 0 === count($transactions)) { + foreach ($combinations as $combination) { + $this->updateCombination($recurrence, $combination); + } + } + // anything left in the original transactions array can be deleted. + foreach ($originalTransactions as $original) { + Log::debug(sprintf('Original transaction #%d is unmatched, delete it!', $original['id'])); + $this->deleteTransaction($recurrence, (int)$original['id']); + } + // anything left is new. + $this->createTransactions($recurrence, $transactions); } /** - * @param Recurrence $recurrence - * @param array $combination + * @param Recurrence $recurrence + * @param array $combination * @return void */ private function updateCombination(Recurrence $recurrence, array $combination): void @@ -257,107 +350,13 @@ class RecurrenceUpdateService } /** - * - * @param Recurrence $recurrence - * @param array $repetitions - * - * @throws FireflyException + * @param Recurrence $recurrence + * @param int $transactionId + * @return void */ - private function updateRepetitions(Recurrence $recurrence, array $repetitions): void + private function deleteTransaction(Recurrence $recurrence, int $transactionId): void { - $originalCount = $recurrence->recurrenceRepetitions()->count(); - if (0 === count($repetitions)) { - // won't drop repetition, rather avoid. - return; - } - // user added or removed repetitions, delete all and recreate: - if ($originalCount !== count($repetitions)) { - Log::debug('Delete existing repetitions and create new ones.'); - $this->deleteRepetitions($recurrence); - $this->createRepetitions($recurrence, $repetitions); - - return; - } - // loop all and try to match them: - Log::debug('Loop and find'); - foreach ($repetitions as $current) { - $match = $this->matchRepetition($recurrence, $current); - if (null === $match) { - throw new FireflyException('Cannot match recurring repetition to existing repetition. Not sure what to do. Break.'); - } - $fields = [ - 'type' => 'repetition_type', - 'moment' => 'repetition_moment', - 'skip' => 'repetition_skip', - 'weekend' => 'weekend', - ]; - foreach ($fields as $field => $column) { - if (array_key_exists($field, $current)) { - $match->$column = $current[$field]; - $match->save(); - } - } - } - } - - /** - * TODO this method is very complex. - * - * @param Recurrence $recurrence - * @param array $transactions - */ - private function updateTransactions(Recurrence $recurrence, array $transactions): void - { - Log::debug('Now in updateTransactions()'); - $originalCount = $recurrence->recurrenceTransactions()->count(); - Log::debug(sprintf('Original count is %d', $originalCount)); - if (0 === count($transactions)) { - // won't drop transactions, rather avoid. - Log::warning('No transactions to update, too scared to continue!'); - return; - } - $combinations = []; - $originalTransactions = $recurrence->recurrenceTransactions()->get()->toArray(); - /** - * First, make sure to loop all existing transactions and match them to a counterpart in the submitted transactions array. - */ - foreach ($originalTransactions as $i => $originalTransaction) { - foreach ($transactions as $ii => $submittedTransaction) { - if (array_key_exists('id', $submittedTransaction) && (int)$originalTransaction['id'] === (int)$submittedTransaction['id']) { - Log::debug(sprintf('Match original transaction #%d with an entry in the submitted array.', $originalTransaction['id'])); - $combinations[] = [ - 'original' => $originalTransaction, - 'submitted' => $submittedTransaction, - ]; - unset($originalTransactions[$i]); - unset($transactions[$ii]); - } - } - } - /** - * If one left of both we can match those as well and presto. - */ - if (1 === count($originalTransactions) && 1 === count($transactions)) { - $first = array_shift($originalTransactions); - Log::debug(sprintf('One left of each, link them (ID is #%d)', $first['id'])); - $combinations[] = [ - 'original' => $first, - 'submitted' => array_shift($transactions), - ]; - unset($first); - } - // if they are both empty, we can safely loop all combinations and update them. - if (0 === count($originalTransactions) && 0 === count($transactions)) { - foreach ($combinations as $combination) { - $this->updateCombination($recurrence, $combination); - } - } - // anything left in the original transactions array can be deleted. - foreach ($originalTransactions as $original) { - Log::debug(sprintf('Original transaction #%d is unmatched, delete it!', $original['id'])); - $this->deleteTransaction($recurrence, (int)$original['id']); - } - // anything left is new. - $this->createTransactions($recurrence, $transactions); + Log::debug(sprintf('Will delete transaction #%d in recurrence #%d.', $transactionId, $recurrence->id)); + $recurrence->recurrenceTransactions()->where('id', $transactionId)->delete(); } } diff --git a/app/Services/Password/PwndVerifierV2.php b/app/Services/Password/PwndVerifierV2.php index 492519d753..76d7bf1a2f 100644 --- a/app/Services/Password/PwndVerifierV2.php +++ b/app/Services/Password/PwndVerifierV2.php @@ -38,7 +38,7 @@ class PwndVerifierV2 implements Verifier /** * Verify the given password against (some) service. * - * @param string $password + * @param string $password * * @return bool */ @@ -63,7 +63,7 @@ class PwndVerifierV2 implements Verifier try { $client = new Client(); $res = $client->request('GET', $url, $opt); - } catch (GuzzleException|RequestException $e) { + } catch (GuzzleException | RequestException $e) { Log::error(sprintf('Could not verify password security: %s', $e->getMessage())); return true; diff --git a/app/Services/Password/Verifier.php b/app/Services/Password/Verifier.php index ac688d7d6d..372771e484 100644 --- a/app/Services/Password/Verifier.php +++ b/app/Services/Password/Verifier.php @@ -31,7 +31,7 @@ interface Verifier /** * Verify the given password against (some) service. * - * @param string $password + * @param string $password * * @return bool */ diff --git a/app/Services/Webhook/StandardWebhookSender.php b/app/Services/Webhook/StandardWebhookSender.php index c4d44fcd44..9fbc430141 100644 --- a/app/Services/Webhook/StandardWebhookSender.php +++ b/app/Services/Webhook/StandardWebhookSender.php @@ -110,7 +110,7 @@ class StandardWebhookSender implements WebhookSenderInterface $client = new Client(); try { $res = $client->request('POST', $this->message->webhook->url, $options); - } catch (RequestException|ConnectException $e) { + } catch (RequestException | ConnectException $e) { Log::error($e->getMessage()); Log::error($e->getTraceAsString()); diff --git a/app/Services/Webhook/WebhookSenderInterface.php b/app/Services/Webhook/WebhookSenderInterface.php index e60aaf1fca..6b827fa9d0 100644 --- a/app/Services/Webhook/WebhookSenderInterface.php +++ b/app/Services/Webhook/WebhookSenderInterface.php @@ -41,7 +41,7 @@ interface WebhookSenderInterface public function send(): void; /** - * @param WebhookMessage $message + * @param WebhookMessage $message */ public function setMessage(WebhookMessage $message): void; } diff --git a/app/Support/Amount.php b/app/Support/Amount.php index f52dbda434..fdad00c33d 100644 --- a/app/Support/Amount.php +++ b/app/Support/Amount.php @@ -40,87 +40,13 @@ use Psr\Container\NotFoundExceptionInterface; */ class Amount { - /** - * bool $sepBySpace is $localeconv['n_sep_by_space'] - * int $signPosn = $localeconv['n_sign_posn'] - * string $sign = $localeconv['negative_sign'] - * bool $csPrecedes = $localeconv['n_cs_precedes']. - * - * @param bool $sepBySpace - * @param int $signPosn - * @param string $sign - * @param bool $csPrecedes - * - * @return string - * - */ - public static function getAmountJsConfig(bool $sepBySpace, int $signPosn, string $sign, bool $csPrecedes): string - { - // negative first: - $space = ' '; - - // require space between symbol and amount? - if (false === $sepBySpace) { - $space = ''; // no - } - - // there are five possible positions for the "+" or "-" sign (if it is even used) - // pos_a and pos_e could be the ( and ) symbol. - $posA = ''; // before everything - $posB = ''; // before currency symbol - $posC = ''; // after currency symbol - $posD = ''; // before amount - $posE = ''; // after everything - - // format would be (currency before amount) - // AB%sC_D%vE - // or: - // AD%v_B%sCE (amount before currency) - // the _ is the optional space - - // switch on how to display amount: - switch ($signPosn) { - default: - case 0: - // ( and ) around the whole thing - $posA = '('; - $posE = ')'; - break; - case 1: - // The sign string precedes the quantity and currency_symbol - $posA = $sign; - break; - case 2: - // The sign string succeeds the quantity and currency_symbol - $posE = $sign; - break; - case 3: - // The sign string immediately precedes the currency_symbol - $posB = $sign; - break; - case 4: - // The sign string immediately succeeds the currency_symbol - $posC = $sign; - } - - // default is amount before currency - $format = $posA.$posD.'%v'.$space.$posB.'%s'.$posC.$posE; - - if ($csPrecedes) { - // alternative is currency before amount - $format = $posA.$posB.'%s'.$posC.$space.$posD.'%v'.$posE; - } - - return $format; - } - /** * This method will properly format the given number, in color or "black and white", * as a currency, given two things: the currency required and the current locale. * - * @param TransactionCurrency $format - * @param string $amount - * @param bool $coloured + * @param TransactionCurrency $format + * @param string $amount + * @param bool $coloured * * @return string * @throws FireflyException @@ -134,10 +60,10 @@ class Amount * This method will properly format the given number, in color or "black and white", * as a currency, given two things: the currency required and the current locale. * - * @param string $symbol - * @param int $decimalPlaces - * @param string $amount - * @param bool $coloured + * @param string $symbol + * @param int $decimalPlaces + * @param string $amount + * @param bool $coloured * * @return string * @@ -224,7 +150,7 @@ class Amount } /** - * @param User $user + * @param User $user * * @return TransactionCurrency * @throws FireflyException @@ -255,6 +181,22 @@ class Amount return $currency; } + /** + * @param string $value + * + * @return string + */ + private function tryDecrypt(string $value): string + { + try { + $value = Crypt::decrypt($value); // verified + } catch (DecryptException $e) { + // @ignoreException + } + + return $value; + } + /** * This method returns the correct format rules required by accounting.js, * the library used to format amounts in charts. @@ -281,26 +223,6 @@ class Amount ]; } - /** - * @return TransactionCurrency - */ - public function getSystemCurrency(): TransactionCurrency - { - return TransactionCurrency::where('code', 'EUR')->first(); - } - - /** - * @param array $info - * @param string $field - * - * @return bool - */ - private function getLocaleField(array $info, string $field): bool - { - return (is_bool($info[$field]) && true === $info[$field]) - || (is_int($info[$field]) && 1 === $info[$field]); - } - /** * @return array * @throws FireflyException @@ -330,18 +252,96 @@ class Amount } /** - * @param string $value + * @param array $info + * @param string $field + * + * @return bool + */ + private function getLocaleField(array $info, string $field): bool + { + return (is_bool($info[$field]) && true === $info[$field]) + || (is_int($info[$field]) && 1 === $info[$field]); + } + + /** + * bool $sepBySpace is $localeconv['n_sep_by_space'] + * int $signPosn = $localeconv['n_sign_posn'] + * string $sign = $localeconv['negative_sign'] + * bool $csPrecedes = $localeconv['n_cs_precedes']. + * + * @param bool $sepBySpace + * @param int $signPosn + * @param string $sign + * @param bool $csPrecedes * * @return string + * */ - private function tryDecrypt(string $value): string + public static function getAmountJsConfig(bool $sepBySpace, int $signPosn, string $sign, bool $csPrecedes): string { - try { - $value = Crypt::decrypt($value); // verified - } catch (DecryptException $e) { - // @ignoreException + // negative first: + $space = ' '; + + // require space between symbol and amount? + if (false === $sepBySpace) { + $space = ''; // no } - return $value; + // there are five possible positions for the "+" or "-" sign (if it is even used) + // pos_a and pos_e could be the ( and ) symbol. + $posA = ''; // before everything + $posB = ''; // before currency symbol + $posC = ''; // after currency symbol + $posD = ''; // before amount + $posE = ''; // after everything + + // format would be (currency before amount) + // AB%sC_D%vE + // or: + // AD%v_B%sCE (amount before currency) + // the _ is the optional space + + // switch on how to display amount: + switch ($signPosn) { + default: + case 0: + // ( and ) around the whole thing + $posA = '('; + $posE = ')'; + break; + case 1: + // The sign string precedes the quantity and currency_symbol + $posA = $sign; + break; + case 2: + // The sign string succeeds the quantity and currency_symbol + $posE = $sign; + break; + case 3: + // The sign string immediately precedes the currency_symbol + $posB = $sign; + break; + case 4: + // The sign string immediately succeeds the currency_symbol + $posC = $sign; + } + + // default is amount before currency + $format = $posA . $posD . '%v' . $space . $posB . '%s' . $posC . $posE; + + if ($csPrecedes) { + // alternative is currency before amount + $format = $posA . $posB . '%s' . $posC . $space . $posD . '%v' . $posE; + } + + return $format; + } + + /** + * @return TransactionCurrency + */ + public function getSystemCurrency(): TransactionCurrency + { + return TransactionCurrency::where('code', 'EUR')->first(); } } diff --git a/app/Support/Authentication/RemoteUserGuard.php b/app/Support/Authentication/RemoteUserGuard.php index fced675818..0dc7485644 100644 --- a/app/Support/Authentication/RemoteUserGuard.php +++ b/app/Support/Authentication/RemoteUserGuard.php @@ -47,8 +47,8 @@ class RemoteUserGuard implements Guard /** * Create a new authentication guard. * - * @param UserProvider $provider - * @param Application $app + * @param UserProvider $provider + * @param Application $app * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ @@ -112,6 +112,15 @@ class RemoteUserGuard implements Guard $this->user = $retrievedUser; } + /** + * @inheritDoc + */ + public function guest(): bool + { + Log::debug(sprintf('Now at %s', __METHOD__)); + return !$this->check(); + } + /** * @inheritDoc */ @@ -124,10 +133,16 @@ class RemoteUserGuard implements Guard /** * @inheritDoc */ - public function guest(): bool + public function user(): ?User { Log::debug(sprintf('Now at %s', __METHOD__)); - return !$this->check(); + $user = $this->user; + if (null === $user) { + Log::debug('User is NULL'); + return null; + } + + return $user; } /** @@ -157,21 +172,6 @@ class RemoteUserGuard implements Guard $this->user = $user; } - /** - * @inheritDoc - */ - public function user(): ?User - { - Log::debug(sprintf('Now at %s', __METHOD__)); - $user = $this->user; - if (null === $user) { - Log::debug('User is NULL'); - return null; - } - - return $user; - } - /** * @inheritDoc */ diff --git a/app/Support/Binder/AccountList.php b/app/Support/Binder/AccountList.php index 828b72aa51..728f77f402 100644 --- a/app/Support/Binder/AccountList.php +++ b/app/Support/Binder/AccountList.php @@ -35,8 +35,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class AccountList implements BinderInterface { /** - * @param string $value - * @param Route $route + * @param string $value + * @param Route $route * * @return Collection * @throws NotFoundHttpException diff --git a/app/Support/Binder/BinderInterface.php b/app/Support/Binder/BinderInterface.php index e0b42449d1..7a9c489268 100644 --- a/app/Support/Binder/BinderInterface.php +++ b/app/Support/Binder/BinderInterface.php @@ -31,8 +31,8 @@ use Illuminate\Routing\Route; interface BinderInterface { /** - * @param string $value - * @param Route $route + * @param string $value + * @param Route $route * * @return mixed */ diff --git a/app/Support/Binder/BudgetList.php b/app/Support/Binder/BudgetList.php index 5b17ac7ddf..8545171385 100644 --- a/app/Support/Binder/BudgetList.php +++ b/app/Support/Binder/BudgetList.php @@ -34,8 +34,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class BudgetList implements BinderInterface { /** - * @param string $value - * @param Route $route + * @param string $value + * @param Route $route * * @return Collection * @throws NotFoundHttpException diff --git a/app/Support/Binder/CLIToken.php b/app/Support/Binder/CLIToken.php index cffa4e4ffd..207224fb3c 100644 --- a/app/Support/Binder/CLIToken.php +++ b/app/Support/Binder/CLIToken.php @@ -35,8 +35,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class CLIToken implements BinderInterface { /** - * @param string $value - * @param Route $route + * @param string $value + * @param Route $route * * @return mixed * @throws FireflyException diff --git a/app/Support/Binder/CategoryList.php b/app/Support/Binder/CategoryList.php index e37c23b8a0..f140cc7607 100644 --- a/app/Support/Binder/CategoryList.php +++ b/app/Support/Binder/CategoryList.php @@ -34,8 +34,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class CategoryList implements BinderInterface { /** - * @param string $value - * @param Route $route + * @param string $value + * @param Route $route * * @return Collection * @throws NotFoundHttpException diff --git a/app/Support/Binder/CurrencyCode.php b/app/Support/Binder/CurrencyCode.php index 7afbfc238b..2f8c141fa9 100644 --- a/app/Support/Binder/CurrencyCode.php +++ b/app/Support/Binder/CurrencyCode.php @@ -33,8 +33,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class CurrencyCode implements BinderInterface { /** - * @param string $value - * @param Route $route + * @param string $value + * @param Route $route * * @return TransactionCurrency * @throws NotFoundHttpException diff --git a/app/Support/Binder/Date.php b/app/Support/Binder/Date.php index 367b4406bc..8ba226fbb5 100644 --- a/app/Support/Binder/Date.php +++ b/app/Support/Binder/Date.php @@ -36,8 +36,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class Date implements BinderInterface { /** - * @param string $value - * @param Route $route + * @param string $value + * @param Route $route * * @return Carbon * @throws NotFoundHttpException diff --git a/app/Support/Binder/DynamicConfigKey.php b/app/Support/Binder/DynamicConfigKey.php index 03d5c58133..e3fb1c608d 100644 --- a/app/Support/Binder/DynamicConfigKey.php +++ b/app/Support/Binder/DynamicConfigKey.php @@ -40,8 +40,8 @@ class DynamicConfigKey ]; /** - * @param string $value - * @param Route $route + * @param string $value + * @param Route $route * * @return string * @throws NotFoundHttpException diff --git a/app/Support/Binder/EitherConfigKey.php b/app/Support/Binder/EitherConfigKey.php index a1638f7dfe..f41db15cbf 100644 --- a/app/Support/Binder/EitherConfigKey.php +++ b/app/Support/Binder/EitherConfigKey.php @@ -57,8 +57,8 @@ class EitherConfigKey ]; /** - * @param string $value - * @param Route $route + * @param string $value + * @param Route $route * * @return string * @throws NotFoundHttpException diff --git a/app/Support/Binder/JournalList.php b/app/Support/Binder/JournalList.php index 4efbbf2c09..a65f91df28 100644 --- a/app/Support/Binder/JournalList.php +++ b/app/Support/Binder/JournalList.php @@ -34,8 +34,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class JournalList implements BinderInterface { /** - * @param string $value - * @param Route $route + * @param string $value + * @param Route $route * * @return array * @@ -63,7 +63,7 @@ class JournalList implements BinderInterface } /** - * @param string $value + * @param string $value * * @return array */ diff --git a/app/Support/Binder/TagList.php b/app/Support/Binder/TagList.php index efd0adad48..4d1e92904e 100644 --- a/app/Support/Binder/TagList.php +++ b/app/Support/Binder/TagList.php @@ -36,8 +36,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class TagList implements BinderInterface { /** - * @param string $value - * @param Route $route + * @param string $value + * @param Route $route * * @return Collection * @throws NotFoundHttpException diff --git a/app/Support/Binder/TagOrId.php b/app/Support/Binder/TagOrId.php index 4cb54de2ad..8c79ec13a2 100644 --- a/app/Support/Binder/TagOrId.php +++ b/app/Support/Binder/TagOrId.php @@ -35,8 +35,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class TagOrId implements BinderInterface { /** - * @param string $value - * @param Route $route + * @param string $value + * @param Route $route * * @return Tag */ diff --git a/app/Support/CacheProperties.php b/app/Support/CacheProperties.php index 81e2721f3a..8156dc691a 100644 --- a/app/Support/CacheProperties.php +++ b/app/Support/CacheProperties.php @@ -50,7 +50,7 @@ class CacheProperties } /** - * @param mixed $property + * @param mixed $property */ public function addProperty($property): void { @@ -86,14 +86,6 @@ class CacheProperties return Cache::has($this->hash); } - /** - * @param mixed $data - */ - public function store($data): void - { - Cache::forever($this->hash, $data); - } - /** */ private function hash(): void @@ -109,4 +101,12 @@ class CacheProperties } $this->hash = substr(hash('sha256', $content), 0, 16); } + + /** + * @param mixed $data + */ + public function store($data): void + { + Cache::forever($this->hash, $data); + } } diff --git a/app/Support/Chart/Budget/FrontpageChartGenerator.php b/app/Support/Chart/Budget/FrontpageChartGenerator.php index 4f6ad56908..086092da0d 100644 --- a/app/Support/Chart/Budget/FrontpageChartGenerator.php +++ b/app/Support/Chart/Budget/FrontpageChartGenerator.php @@ -79,61 +79,34 @@ class FrontpageChartGenerator } /** - * @param Carbon $end - */ - public function setEnd(Carbon $end): void - { - $this->end = $end; - } - - /** - * @param Carbon $start - */ - public function setStart(Carbon $start): void - { - $this->start = $start; - } - - /** - * A basic setter for the user. Also updates the repositories with the right user. + * For each budget, gets all budget limits for the current time range. + * When no limits are present, the time range is used to collect information on money spent. + * If limits are present, each limit is processed individually. * - * @param User $user - */ - public function setUser(User $user): void - { - $this->budgetRepository->setUser($user); - $this->blRepository->setUser($user); - $this->opsRepository->setUser($user); - - $locale = app('steam')->getLocale(); - $this->monthAndDayFormat = (string)trans('config.month_and_day_js', [], $locale); - } - - /** - * If a budget has budget limit, each limit is processed individually. - * - * @param array $data - * @param Budget $budget - * @param Collection $limits + * @param array $data + * @param Budget $budget * * @return array */ - private function budgetLimits(array $data, Budget $budget, Collection $limits): array + private function processBudget(array $data, Budget $budget): array { - /** @var BudgetLimit $limit */ - foreach ($limits as $limit) { - $data = $this->processLimit($data, $budget, $limit); + // get all limits: + $limits = $this->blRepository->getBudgetLimits($budget, $this->start, $this->end); + + // if no limits + if (0 === $limits->count()) { + return $this->noBudgetLimits($data, $budget); } - return $data; + return $this->budgetLimits($data, $budget, $limits); } /** * When no limits are present, the expenses of the whole period are collected and grouped. * This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty. * - * @param array $data - * @param Budget $budget + * @param array $data + * @param Budget $budget * * @return array */ @@ -152,34 +125,31 @@ class FrontpageChartGenerator } /** - * For each budget, gets all budget limits for the current time range. - * When no limits are present, the time range is used to collect information on money spent. - * If limits are present, each limit is processed individually. + * If a budget has budget limit, each limit is processed individually. * - * @param array $data - * @param Budget $budget + * @param array $data + * @param Budget $budget + * @param Collection $limits * * @return array */ - private function processBudget(array $data, Budget $budget): array + private function budgetLimits(array $data, Budget $budget, Collection $limits): array { - // get all limits: - $limits = $this->blRepository->getBudgetLimits($budget, $this->start, $this->end); - - // if no limits - if (0 === $limits->count()) { - return $this->noBudgetLimits($data, $budget); + /** @var BudgetLimit $limit */ + foreach ($limits as $limit) { + $data = $this->processLimit($data, $budget, $limit); } - return $this->budgetLimits($data, $budget, $limits); + return $data; } /** - * For each limit, the expenses from the time range of the limit are collected. Each row from the result is processed individually. + * For each limit, the expenses from the time range of the limit are collected. Each row from the result is + * processed individually. * - * @param array $data - * @param Budget $budget - * @param BudgetLimit $limit + * @param array $data + * @param Budget $budget + * @param BudgetLimit $limit * * @return array */ @@ -200,13 +170,13 @@ class FrontpageChartGenerator /** * Each row of expenses from a budget limit is in another currency (note $entry['currency_name']). * - * Each one is added to the $data array. If the limit's date range is different from the global $start and $end dates, - * for example when a limit only partially falls into this month, the title is expanded to clarify. + * Each one is added to the $data array. If the limit's date range is different from the global $start and $end + * dates, for example when a limit only partially falls into this month, the title is expanded to clarify. * - * @param array $data - * @param Budget $budget - * @param BudgetLimit $limit - * @param array $entry + * @param array $data + * @param Budget $budget + * @param BudgetLimit $limit + * @param array $entry * * @return array */ @@ -230,4 +200,35 @@ class FrontpageChartGenerator return $data; } + + /** + * @param Carbon $end + */ + public function setEnd(Carbon $end): void + { + $this->end = $end; + } + + /** + * @param Carbon $start + */ + public function setStart(Carbon $start): void + { + $this->start = $start; + } + + /** + * A basic setter for the user. Also updates the repositories with the right user. + * + * @param User $user + */ + public function setUser(User $user): void + { + $this->budgetRepository->setUser($user); + $this->blRepository->setUser($user); + $this->opsRepository->setUser($user); + + $locale = app('steam')->getLocale(); + $this->monthAndDayFormat = (string)trans('config.month_and_day_js', [], $locale); + } } diff --git a/app/Support/Chart/Category/FrontpageChartGenerator.php b/app/Support/Chart/Category/FrontpageChartGenerator.php index 824e848e9e..c708797692 100644 --- a/app/Support/Chart/Category/FrontpageChartGenerator.php +++ b/app/Support/Chart/Category/FrontpageChartGenerator.php @@ -52,8 +52,8 @@ class FrontpageChartGenerator /** * FrontpageChartGenerator constructor. * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end */ public function __construct(Carbon $start, Carbon $end) { @@ -99,24 +99,8 @@ class FrontpageChartGenerator } /** - * @param array $currency - */ - private function addCurrency(array $currency): void - { - $currencyId = (int)$currency['currency_id']; - - $this->currencies[$currencyId] = $this->currencies[$currencyId] ?? [ - 'currency_id' => $currencyId, - 'currency_name' => $currency['currency_name'], - 'currency_symbol' => $currency['currency_symbol'], - 'currency_code' => $currency['currency_code'], - 'currency_decimal_places' => $currency['currency_decimal_places'], - ]; - } - - /** - * @param Category $category - * @param Collection $accounts + * @param Category $category + * @param Collection $accounts * * @return array */ @@ -138,7 +122,23 @@ class FrontpageChartGenerator } /** - * @param Collection $accounts + * @param array $currency + */ + private function addCurrency(array $currency): void + { + $currencyId = (int)$currency['currency_id']; + + $this->currencies[$currencyId] = $this->currencies[$currencyId] ?? [ + 'currency_id' => $currencyId, + 'currency_name' => $currency['currency_name'], + 'currency_symbol' => $currency['currency_symbol'], + 'currency_code' => $currency['currency_code'], + 'currency_decimal_places' => $currency['currency_decimal_places'], + ]; + } + + /** + * @param Collection $accounts * * @return array */ @@ -160,7 +160,7 @@ class FrontpageChartGenerator } /** - * @param array $data + * @param array $data * * @return array */ @@ -185,8 +185,8 @@ class FrontpageChartGenerator } /** - * @param array $currencyData - * @param array $monetaryData + * @param array $currencyData + * @param array $monetaryData * * @return array */ diff --git a/app/Support/Chart/Category/WholePeriodChartGenerator.php b/app/Support/Chart/Category/WholePeriodChartGenerator.php index 4b4e500b52..808750a97a 100644 --- a/app/Support/Chart/Category/WholePeriodChartGenerator.php +++ b/app/Support/Chart/Category/WholePeriodChartGenerator.php @@ -36,9 +36,9 @@ use Illuminate\Support\Collection; class WholePeriodChartGenerator { /** - * @param Category $category - * @param Carbon $start - * @param Carbon $end + * @param Category $category + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -117,8 +117,8 @@ class WholePeriodChartGenerator /** * TODO this method is duplicated * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return string */ @@ -143,7 +143,7 @@ class WholePeriodChartGenerator * Loop array of spent/earned info, and extract which currencies are present. * Key is the currency ID. * - * @param array $array + * @param array $array * * @return array */ diff --git a/app/Support/ChartColour.php b/app/Support/ChartColour.php index ed59ce82bc..54d64c32ea 100644 --- a/app/Support/ChartColour.php +++ b/app/Support/ChartColour.php @@ -55,7 +55,7 @@ class ChartColour ]; /** - * @param int $index + * @param int $index * * @return string */ diff --git a/app/Support/Cronjobs/AbstractCronjob.php b/app/Support/Cronjobs/AbstractCronjob.php index e66bbe006f..581051e3db 100644 --- a/app/Support/Cronjobs/AbstractCronjob.php +++ b/app/Support/Cronjobs/AbstractCronjob.php @@ -59,7 +59,7 @@ abstract class AbstractCronjob abstract public function fire(): void; /** - * @param Carbon $date + * @param Carbon $date */ final public function setDate(Carbon $date): void { @@ -68,7 +68,7 @@ abstract class AbstractCronjob } /** - * @param bool $force + * @param bool $force */ final public function setForce(bool $force): void { diff --git a/app/Support/ExpandedForm.php b/app/Support/ExpandedForm.php index 627da132e9..fc78951bea 100644 --- a/app/Support/ExpandedForm.php +++ b/app/Support/ExpandedForm.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace FireflyIII\Support; -use Amount as Amt; use Eloquent; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Support\Form\FormSupport; @@ -42,9 +41,9 @@ class ExpandedForm use FormSupport; /** - * @param string $name - * @param mixed $value - * @param array|null $options + * @param string $name + * @param mixed $value + * @param array|null $options * * @return string * @throws FireflyException @@ -75,10 +74,10 @@ class ExpandedForm } /** - * @param string $name - * @param int|null $value - * @param mixed $checked - * @param array|null $options + * @param string $name + * @param int|null $value + * @param mixed $checked + * @param array|null $options * * @return string * @throws FireflyException @@ -112,9 +111,9 @@ class ExpandedForm } /** - * @param string $name - * @param mixed $value - * @param array|null $options + * @param string $name + * @param mixed $value + * @param array|null $options * * @return string * @throws FireflyException @@ -138,8 +137,8 @@ class ExpandedForm } /** - * @param string $name - * @param array|null $options + * @param string $name + * @param array|null $options * * @return string * @throws FireflyException @@ -162,9 +161,9 @@ class ExpandedForm } /** - * @param string $name - * @param mixed $value - * @param array|null $options + * @param string $name + * @param mixed $value + * @param array|null $options * * @return string * @throws FireflyException @@ -189,9 +188,9 @@ class ExpandedForm } /** - * @param string $name - * @param mixed $value - * @param array|null $options + * @param string $name + * @param mixed $value + * @param array|null $options * * @return string * @throws FireflyException @@ -215,7 +214,7 @@ class ExpandedForm } /** - * @param Collection $set + * @param Collection $set * * @return array * @@ -244,8 +243,8 @@ class ExpandedForm /** - * @param null $value - * @param array|null $options + * @param null $value + * @param array|null $options * * @return string * @throws FireflyException @@ -275,8 +274,8 @@ class ExpandedForm } /** - * @param string $type - * @param string $name + * @param string $type + * @param string $name * * @return string * @throws FireflyException @@ -295,8 +294,8 @@ class ExpandedForm } /** - * @param string $name - * @param array|null $options + * @param string $name + * @param array|null $options * * @return string * @throws FireflyException @@ -320,9 +319,9 @@ class ExpandedForm /** * Function to render a percentage. * - * @param string $name - * @param mixed $value - * @param array|null $options + * @param string $name + * @param mixed $value + * @param array|null $options * * @return string * @throws FireflyException @@ -347,9 +346,9 @@ class ExpandedForm } /** - * @param string $name - * @param mixed $value - * @param array|null $options + * @param string $name + * @param mixed $value + * @param array|null $options * * @return string * @throws FireflyException @@ -371,9 +370,9 @@ class ExpandedForm } /** - * @param string $name - * @param mixed $value - * @param array|null $options + * @param string $name + * @param mixed $value + * @param array|null $options * * @return string * @throws FireflyException @@ -396,9 +395,9 @@ class ExpandedForm } /** - * @param string $name - * @param mixed $value - * @param array|null $options + * @param string $name + * @param mixed $value + * @param array|null $options * * @return string * @throws FireflyException diff --git a/app/Support/Export/ExportDataGenerator.php b/app/Support/Export/ExportDataGenerator.php index 0c5298a842..e9ab02ec68 100644 --- a/app/Support/Export/ExportDataGenerator.php +++ b/app/Support/Export/ExportDataGenerator.php @@ -140,126 +140,6 @@ class ExportDataGenerator return $return; } - /** - * @inheritDoc - */ - public function get(string $key, mixed $default = null): mixed - { - return null; - } - - /** - * @inheritDoc - */ - public function has(mixed $key): mixed - { - return null; - } - - /** - * @param Collection $accounts - */ - public function setAccounts(Collection $accounts): void - { - $this->accounts = $accounts; - } - - /** - * @param Carbon $end - */ - public function setEnd(Carbon $end): void - { - $this->end = $end; - } - - /** - * @param bool $exportAccounts - */ - public function setExportAccounts(bool $exportAccounts): void - { - $this->exportAccounts = $exportAccounts; - } - - /** - * @param bool $exportBills - */ - public function setExportBills(bool $exportBills): void - { - $this->exportBills = $exportBills; - } - - /** - * @param bool $exportBudgets - */ - public function setExportBudgets(bool $exportBudgets): void - { - $this->exportBudgets = $exportBudgets; - } - - /** - * @param bool $exportCategories - */ - public function setExportCategories(bool $exportCategories): void - { - $this->exportCategories = $exportCategories; - } - - /** - * @param bool $exportPiggies - */ - public function setExportPiggies(bool $exportPiggies): void - { - $this->exportPiggies = $exportPiggies; - } - - /** - * @param bool $exportRecurring - */ - public function setExportRecurring(bool $exportRecurring): void - { - $this->exportRecurring = $exportRecurring; - } - - /** - * @param bool $exportRules - */ - public function setExportRules(bool $exportRules): void - { - $this->exportRules = $exportRules; - } - - /** - * @param bool $exportTags - */ - public function setExportTags(bool $exportTags): void - { - $this->exportTags = $exportTags; - } - - /** - * @param bool $exportTransactions - */ - public function setExportTransactions(bool $exportTransactions): void - { - $this->exportTransactions = $exportTransactions; - } - - /** - * @param Carbon $start - */ - public function setStart(Carbon $start): void - { - $this->start = $start; - } - - /** - * @param User $user - */ - public function setUser(User $user): void - { - $this->user = $user; - } - /** * @return string * @throws FireflyException @@ -337,6 +217,14 @@ class ExportDataGenerator return $string; } + /** + * @param User $user + */ + public function setUser(User $user): void + { + $this->user = $user; + } + /** * @return string * @throws FireflyException @@ -940,6 +828,14 @@ class ExportDataGenerator return $string; } + /** + * @inheritDoc + */ + public function get(string $key, mixed $default = null): mixed + { + return null; + } + /** * @return string * @throws FireflyException @@ -1084,7 +980,15 @@ class ExportDataGenerator } /** - * @param array $tags + * @param Collection $accounts + */ + public function setAccounts(Collection $accounts): void + { + $this->accounts = $accounts; + } + + /** + * @param array $tags * * @return string */ @@ -1100,4 +1004,100 @@ class ExportDataGenerator return implode(',', $smol); } + + /** + * @inheritDoc + */ + public function has(mixed $key): mixed + { + return null; + } + + /** + * @param Carbon $end + */ + public function setEnd(Carbon $end): void + { + $this->end = $end; + } + + /** + * @param bool $exportAccounts + */ + public function setExportAccounts(bool $exportAccounts): void + { + $this->exportAccounts = $exportAccounts; + } + + /** + * @param bool $exportBills + */ + public function setExportBills(bool $exportBills): void + { + $this->exportBills = $exportBills; + } + + /** + * @param bool $exportBudgets + */ + public function setExportBudgets(bool $exportBudgets): void + { + $this->exportBudgets = $exportBudgets; + } + + /** + * @param bool $exportCategories + */ + public function setExportCategories(bool $exportCategories): void + { + $this->exportCategories = $exportCategories; + } + + /** + * @param bool $exportPiggies + */ + public function setExportPiggies(bool $exportPiggies): void + { + $this->exportPiggies = $exportPiggies; + } + + /** + * @param bool $exportRecurring + */ + public function setExportRecurring(bool $exportRecurring): void + { + $this->exportRecurring = $exportRecurring; + } + + /** + * @param bool $exportRules + */ + public function setExportRules(bool $exportRules): void + { + $this->exportRules = $exportRules; + } + + /** + * @param bool $exportTags + */ + public function setExportTags(bool $exportTags): void + { + $this->exportTags = $exportTags; + } + + /** + * @param bool $exportTransactions + */ + public function setExportTransactions(bool $exportTransactions): void + { + $this->exportTransactions = $exportTransactions; + } + + /** + * @param Carbon $start + */ + public function setStart(Carbon $start): void + { + $this->start = $start; + } } diff --git a/app/Support/FireflyConfig.php b/app/Support/FireflyConfig.php index c65a44c942..86dcd29dbf 100644 --- a/app/Support/FireflyConfig.php +++ b/app/Support/FireflyConfig.php @@ -38,11 +38,11 @@ use Illuminate\Support\Facades\Log; class FireflyConfig { /** - * @param string $name + * @param string $name */ public function delete(string $name): void { - $fullName = 'ff-config-'.$name; + $fullName = 'ff-config-' . $name; if (Cache::has($fullName)) { Cache::forget($fullName); } @@ -50,15 +50,25 @@ class FireflyConfig } /** - * @param string $name - * @param bool|string|int|null $default + * @param string $name + * + * @return bool + */ + public function has(string $name): bool + { + return Configuration::where('name', $name)->count() === 1; + } + + /** + * @param string $name + * @param bool|string|int|null $default * * @return Configuration|null * @throws FireflyException */ public function get(string $name, $default = null): ?Configuration { - $fullName = 'ff-config-'.$name; + $fullName = 'ff-config-' . $name; if (Cache::has($fullName)) { return Cache::get($fullName); } @@ -66,7 +76,7 @@ class FireflyConfig try { /** @var Configuration|null $config */ $config = Configuration::where('name', $name)->first(['id', 'name', 'data']); - } catch (QueryException|Exception $e) { + } catch (QueryException | Exception $e) { throw new FireflyException(sprintf('Could not poll the database: %s', $e->getMessage()), 0, $e); } @@ -84,49 +94,8 @@ class FireflyConfig } /** - * @param string $name - * @param mixed $default - * - * @return Configuration|null - */ - public function getFresh(string $name, $default = null): ?Configuration - { - $config = Configuration::where('name', $name)->first(['id', 'name', 'data']); - if ($config) { - return $config; - } - // no preference found and default is null: - if (null === $default) { - return null; - } - - return $this->set($name, $default); - } - - /** - * @param string $name - * - * @return bool - */ - public function has(string $name): bool - { - return Configuration::where('name', $name)->count() === 1; - } - - /** - * @param string $name - * @param mixed $value - * - * @return Configuration - */ - public function put(string $name, $value): Configuration - { - return $this->set($name, $value); - } - - /** - * @param string $name - * @param mixed $value + * @param string $name + * @param mixed $value * * @return Configuration */ @@ -148,14 +117,45 @@ class FireflyConfig $item->name = $name; $item->data = $value; $item->save(); - Cache::forget('ff-config-'.$name); + Cache::forget('ff-config-' . $name); return $item; } $config->data = $value; $config->save(); - Cache::forget('ff-config-'.$name); + Cache::forget('ff-config-' . $name); return $config; } + + /** + * @param string $name + * @param mixed $default + * + * @return Configuration|null + */ + public function getFresh(string $name, $default = null): ?Configuration + { + $config = Configuration::where('name', $name)->first(['id', 'name', 'data']); + if ($config) { + return $config; + } + // no preference found and default is null: + if (null === $default) { + return null; + } + + return $this->set($name, $default); + } + + /** + * @param string $name + * @param mixed $value + * + * @return Configuration + */ + public function put(string $name, $value): Configuration + { + return $this->set($name, $value); + } } diff --git a/app/Support/Form/AccountForm.php b/app/Support/Form/AccountForm.php index fc0f25c3b3..22e538c178 100644 --- a/app/Support/Form/AccountForm.php +++ b/app/Support/Form/AccountForm.php @@ -45,9 +45,9 @@ class AccountForm /** * Grouped dropdown list of all accounts that are valid as the destination of a withdrawal. * - * @param string $name - * @param mixed $value - * @param array|null $options + * @param string $name + * @param mixed $value + * @param array|null $options * * @return string */ @@ -64,97 +64,8 @@ class AccountForm } /** - * Grouped dropdown list of all accounts that are valid as the destination of a withdrawal. - * - * @param string $name - * @param mixed $value - * @param array|null $options - * - * @return string - */ - public function activeWithdrawalDestinations(string $name, mixed $value = null, array $options = null): string - { - $types = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN, AccountType::EXPENSE,]; - $repository = $this->getAccountRepository(); - $grouped = $this->getAccountsGrouped($types, $repository); - - $cash = $repository->getCashAccount(); - $key = (string)trans('firefly.cash_account_type'); - $grouped[$key][$cash->id] = sprintf('(%s)', (string)trans('firefly.cash')); - - return $this->select($name, $grouped, $value, $options); - } - - /** - * Check list of asset accounts. - * - * @param string $name - * @param array|null $options - * - * @return string - * @throws FireflyException - */ - public function assetAccountCheckList(string $name, array $options = null): string - { - $options = $options ?? []; - $label = $this->label($name, $options); - $options = $this->expandOptionArray($name, $label, $options); - $classes = $this->getHolderClasses($name); - $selected = request()->old($name) ?? []; - - // get all asset accounts: - $types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT]; - $grouped = $this->getAccountsGrouped($types); - - unset($options['class']); - try { - $html = view('form.assetAccountCheckList', compact('classes', 'selected', 'name', 'label', 'options', 'grouped'))->render(); - } catch (Throwable $e) { - Log::debug(sprintf('Could not render assetAccountCheckList(): %s', $e->getMessage())); - $html = 'Could not render assetAccountCheckList.'; - throw new FireflyException($html, 0, $e); - } - - return $html; - } - - /** - * Basic list of asset accounts. - * - * @param string $name - * @param mixed $value - * @param array|null $options - * - * @return string - */ - public function assetAccountList(string $name, $value = null, array $options = null): string - { - $types = [AccountType::ASSET, AccountType::DEFAULT]; - $grouped = $this->getAccountsGrouped($types); - - return $this->select($name, $grouped, $value, $options); - } - - /** - * Same list but all liabilities as well. - * - * @param string $name - * @param mixed $value - * @param array|null $options - * - * @return string - */ - public function longAccountList(string $name, $value = null, array $options = null): string - { - $types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN,]; - $grouped = $this->getAccountsGrouped($types); - - return $this->select($name, $grouped, $value, $options); - } - - /** - * @param array $types - * @param AccountRepositoryInterface|null $repository + * @param array $types + * @param AccountRepositoryInterface|null $repository * @return array */ private function getAccountsGrouped(array $types, AccountRepositoryInterface $repository = null): array @@ -187,4 +98,93 @@ class AccountForm return $grouped; } + + /** + * Grouped dropdown list of all accounts that are valid as the destination of a withdrawal. + * + * @param string $name + * @param mixed $value + * @param array|null $options + * + * @return string + */ + public function activeWithdrawalDestinations(string $name, mixed $value = null, array $options = null): string + { + $types = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN, AccountType::EXPENSE,]; + $repository = $this->getAccountRepository(); + $grouped = $this->getAccountsGrouped($types, $repository); + + $cash = $repository->getCashAccount(); + $key = (string)trans('firefly.cash_account_type'); + $grouped[$key][$cash->id] = sprintf('(%s)', (string)trans('firefly.cash')); + + return $this->select($name, $grouped, $value, $options); + } + + /** + * Check list of asset accounts. + * + * @param string $name + * @param array|null $options + * + * @return string + * @throws FireflyException + */ + public function assetAccountCheckList(string $name, array $options = null): string + { + $options = $options ?? []; + $label = $this->label($name, $options); + $options = $this->expandOptionArray($name, $label, $options); + $classes = $this->getHolderClasses($name); + $selected = request()->old($name) ?? []; + + // get all asset accounts: + $types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT]; + $grouped = $this->getAccountsGrouped($types); + + unset($options['class']); + try { + $html = view('form.assetAccountCheckList', compact('classes', 'selected', 'name', 'label', 'options', 'grouped'))->render(); + } catch (Throwable $e) { + Log::debug(sprintf('Could not render assetAccountCheckList(): %s', $e->getMessage())); + $html = 'Could not render assetAccountCheckList.'; + throw new FireflyException($html, 0, $e); + } + + return $html; + } + + /** + * Basic list of asset accounts. + * + * @param string $name + * @param mixed $value + * @param array|null $options + * + * @return string + */ + public function assetAccountList(string $name, $value = null, array $options = null): string + { + $types = [AccountType::ASSET, AccountType::DEFAULT]; + $grouped = $this->getAccountsGrouped($types); + + return $this->select($name, $grouped, $value, $options); + } + + /** + * Same list but all liabilities as well. + * + * @param string $name + * @param mixed $value + * @param array|null $options + * + * @return string + */ + public function longAccountList(string $name, $value = null, array $options = null): string + { + $types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN,]; + $grouped = $this->getAccountsGrouped($types); + + return $this->select($name, $grouped, $value, $options); + } } diff --git a/app/Support/Form/CurrencyForm.php b/app/Support/Form/CurrencyForm.php index 636f235579..ea44ade235 100644 --- a/app/Support/Form/CurrencyForm.php +++ b/app/Support/Form/CurrencyForm.php @@ -41,9 +41,9 @@ class CurrencyForm use FormSupport; /** - * @param string $name - * @param mixed $value - * @param array|null $options + * @param string $name + * @param mixed $value + * @param array|null $options * * @return string * @throws FireflyException @@ -54,134 +54,10 @@ class CurrencyForm } /** - * TODO describe and cleanup. - * - * @param string $name - * @param mixed $value - * @param array|null $options - * - * @return string - * @throws FireflyException - */ - public function balanceAll(string $name, $value = null, array $options = null): string - { - return $this->allCurrencyField($name, 'balance', $value, $options); - } - - /** - * TODO cleanup and describe - * - * @param string $name - * @param mixed $value - * @param array|null $options - * - * @return string - */ - public function currencyList(string $name, $value = null, array $options = null): string - { - /** @var CurrencyRepositoryInterface $currencyRepos */ - $currencyRepos = app(CurrencyRepositoryInterface::class); - - // get all currencies: - $list = $currencyRepos->get(); - $array = []; - /** @var TransactionCurrency $currency */ - foreach ($list as $currency) { - $array[$currency->id] = $currency->name.' ('.$currency->symbol.')'; - } - - return $this->select($name, $array, $value, $options); - } - - /** - * TODO cleanup and describe - * - * @param string $name - * @param mixed $value - * @param array|null $options - * - * @return string - */ - public function currencyListEmpty(string $name, $value = null, array $options = null): string - { - /** @var CurrencyRepositoryInterface $currencyRepos */ - $currencyRepos = app(CurrencyRepositoryInterface::class); - - // get all currencies: - $list = $currencyRepos->get(); - $array = [ - 0 => (string)trans('firefly.no_currency'), - ]; - /** @var TransactionCurrency $currency */ - foreach ($list as $currency) { - $array[$currency->id] = $currency->name.' ('.$currency->symbol.')'; - } - - return $this->select($name, $array, $value, $options); - } - - /** - * TODO describe and cleanup - * - * @param string $name - * @param string $view - * @param mixed $value - * @param array|null $options - * - * @return string - * @throws FireflyException - */ - protected function allCurrencyField(string $name, string $view, $value = null, array $options = null): string - { - $label = $this->label($name, $options); - $options = $this->expandOptionArray($name, $label, $options); - $classes = $this->getHolderClasses($name); - $value = $this->fillFieldValue($name, $value); - $options['step'] = 'any'; - $defaultCurrency = $options['currency'] ?? Amt::getDefaultCurrency(); - /** @var Collection $currencies */ - $currencies = app('amount')->getAllCurrencies(); - unset($options['currency'], $options['placeholder']); - - // perhaps the currency has been sent to us in the field $amount_currency_id_$name (amount_currency_id_amount) - $preFilled = session('preFilled'); - if (!is_array($preFilled)) { - $preFilled = []; - } - $key = 'amount_currency_id_'.$name; - $sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $defaultCurrency->id; - - Log::debug(sprintf('Sent currency ID is %d', $sentCurrencyId)); - - // find this currency in set of currencies: - foreach ($currencies as $currency) { - if ($currency->id === $sentCurrencyId) { - $defaultCurrency = $currency; - Log::debug(sprintf('default currency is now %s', $defaultCurrency->code)); - break; - } - } - - // make sure value is formatted nicely: - if (null !== $value && '' !== $value) { - $value = app('steam')->bcround($value, $defaultCurrency->decimal_places); - } - try { - $html = view('form.'.$view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render(); - } catch (Throwable $e) { - Log::debug(sprintf('Could not render currencyField(): %s', $e->getMessage())); - $html = 'Could not render currencyField.'; - throw new FireflyException($html, 0, $e); - } - - return $html; - } - - /** - * @param string $name - * @param string $view - * @param mixed $value - * @param array|null $options + * @param string $name + * @param string $view + * @param mixed $value + * @param array|null $options * * @return string * @throws FireflyException @@ -203,7 +79,7 @@ class CurrencyForm if (!is_array($preFilled)) { $preFilled = []; } - $key = 'amount_currency_id_'.$name; + $key = 'amount_currency_id_' . $name; $sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $defaultCurrency->id; Log::debug(sprintf('Sent currency ID is %d', $sentCurrencyId)); @@ -222,7 +98,7 @@ class CurrencyForm $value = app('steam')->bcround($value, $defaultCurrency->decimal_places); } try { - $html = view('form.'.$view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render(); + $html = view('form.' . $view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render(); } catch (Throwable $e) { Log::debug(sprintf('Could not render currencyField(): %s', $e->getMessage())); $html = 'Could not render currencyField.'; @@ -231,4 +107,128 @@ class CurrencyForm return $html; } + + /** + * TODO describe and cleanup. + * + * @param string $name + * @param mixed $value + * @param array|null $options + * + * @return string + * @throws FireflyException + */ + public function balanceAll(string $name, $value = null, array $options = null): string + { + return $this->allCurrencyField($name, 'balance', $value, $options); + } + + /** + * TODO describe and cleanup + * + * @param string $name + * @param string $view + * @param mixed $value + * @param array|null $options + * + * @return string + * @throws FireflyException + */ + protected function allCurrencyField(string $name, string $view, $value = null, array $options = null): string + { + $label = $this->label($name, $options); + $options = $this->expandOptionArray($name, $label, $options); + $classes = $this->getHolderClasses($name); + $value = $this->fillFieldValue($name, $value); + $options['step'] = 'any'; + $defaultCurrency = $options['currency'] ?? Amt::getDefaultCurrency(); + /** @var Collection $currencies */ + $currencies = app('amount')->getAllCurrencies(); + unset($options['currency'], $options['placeholder']); + + // perhaps the currency has been sent to us in the field $amount_currency_id_$name (amount_currency_id_amount) + $preFilled = session('preFilled'); + if (!is_array($preFilled)) { + $preFilled = []; + } + $key = 'amount_currency_id_' . $name; + $sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $defaultCurrency->id; + + Log::debug(sprintf('Sent currency ID is %d', $sentCurrencyId)); + + // find this currency in set of currencies: + foreach ($currencies as $currency) { + if ($currency->id === $sentCurrencyId) { + $defaultCurrency = $currency; + Log::debug(sprintf('default currency is now %s', $defaultCurrency->code)); + break; + } + } + + // make sure value is formatted nicely: + if (null !== $value && '' !== $value) { + $value = app('steam')->bcround($value, $defaultCurrency->decimal_places); + } + try { + $html = view('form.' . $view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render(); + } catch (Throwable $e) { + Log::debug(sprintf('Could not render currencyField(): %s', $e->getMessage())); + $html = 'Could not render currencyField.'; + throw new FireflyException($html, 0, $e); + } + + return $html; + } + + /** + * TODO cleanup and describe + * + * @param string $name + * @param mixed $value + * @param array|null $options + * + * @return string + */ + public function currencyList(string $name, $value = null, array $options = null): string + { + /** @var CurrencyRepositoryInterface $currencyRepos */ + $currencyRepos = app(CurrencyRepositoryInterface::class); + + // get all currencies: + $list = $currencyRepos->get(); + $array = []; + /** @var TransactionCurrency $currency */ + foreach ($list as $currency) { + $array[$currency->id] = $currency->name . ' (' . $currency->symbol . ')'; + } + + return $this->select($name, $array, $value, $options); + } + + /** + * TODO cleanup and describe + * + * @param string $name + * @param mixed $value + * @param array|null $options + * + * @return string + */ + public function currencyListEmpty(string $name, $value = null, array $options = null): string + { + /** @var CurrencyRepositoryInterface $currencyRepos */ + $currencyRepos = app(CurrencyRepositoryInterface::class); + + // get all currencies: + $list = $currencyRepos->get(); + $array = [ + 0 => (string)trans('firefly.no_currency'), + ]; + /** @var TransactionCurrency $currency */ + foreach ($list as $currency) { + $array[$currency->id] = $currency->name . ' (' . $currency->symbol . ')'; + } + + return $this->select($name, $array, $value, $options); + } } diff --git a/app/Support/Form/FormSupport.php b/app/Support/Form/FormSupport.php index d8c7da9880..ebb78e43aa 100644 --- a/app/Support/Form/FormSupport.php +++ b/app/Support/Form/FormSupport.php @@ -36,10 +36,10 @@ use Throwable; trait FormSupport { /** - * @param string $name - * @param array|null $list - * @param mixed $selected - * @param array|null $options + * @param string $name + * @param array|null $list + * @param mixed $selected + * @param array|null $options * * @return string */ @@ -62,9 +62,26 @@ trait FormSupport } /** - * @param string $name - * @param mixed $label - * @param array|null $options + * @param string $name + * @param array|null $options + * + * @return string + */ + protected function label(string $name, array $options = null): string + { + $options = $options ?? []; + if (array_key_exists('label', $options)) { + return $options['label']; + } + $name = str_replace('[]', '', $name); + + return (string)trans('form.' . $name); + } + + /** + * @param string $name + * @param mixed $label + * @param array|null $options * * @return array */ @@ -73,7 +90,7 @@ trait FormSupport $options = $options ?? []; $name = str_replace('[]', '', $name); $options['class'] = 'form-control'; - $options['id'] = 'ffInput_'.$name; + $options['id'] = 'ffInput_' . $name; $options['autocomplete'] = 'off'; $options['placeholder'] = ucfirst($label); @@ -81,8 +98,27 @@ trait FormSupport } /** - * @param string $name - * @param mixed|null $value + * @param string $name + * + * @return string + */ + protected function getHolderClasses(string $name): string + { + // Get errors from session: + /** @var MessageBag $errors */ + $errors = session('errors'); + $classes = 'form-group'; + + if (null !== $errors && $errors->has($name)) { + $classes = 'form-group has-error has-feedback'; + } + + return $classes; + } + + /** + * @param string $name + * @param mixed|null $value * * @return mixed */ @@ -127,40 +163,4 @@ trait FormSupport return $date; } - - /** - * @param string $name - * - * @return string - */ - protected function getHolderClasses(string $name): string - { - // Get errors from session: - /** @var MessageBag $errors */ - $errors = session('errors'); - $classes = 'form-group'; - - if (null !== $errors && $errors->has($name)) { - $classes = 'form-group has-error has-feedback'; - } - - return $classes; - } - - /** - * @param string $name - * @param array|null $options - * - * @return string - */ - protected function label(string $name, array $options = null): string - { - $options = $options ?? []; - if (array_key_exists('label', $options)) { - return $options['label']; - } - $name = str_replace('[]', '', $name); - - return (string)trans('form.'.$name); - } } diff --git a/app/Support/Form/PiggyBankForm.php b/app/Support/Form/PiggyBankForm.php index c9391d375a..2f7e865483 100644 --- a/app/Support/Form/PiggyBankForm.php +++ b/app/Support/Form/PiggyBankForm.php @@ -38,9 +38,9 @@ class PiggyBankForm /** * TODO cleanup and describe * - * @param string $name - * @param mixed $value - * @param array|null $options + * @param string $name + * @param mixed $value + * @param array|null $options * * @return string */ diff --git a/app/Support/Form/RuleForm.php b/app/Support/Form/RuleForm.php index e985fd6576..eec7f7e3f7 100644 --- a/app/Support/Form/RuleForm.php +++ b/app/Support/Form/RuleForm.php @@ -37,8 +37,8 @@ class RuleForm use FormSupport; /** - * @param string $name - * @param mixed $value + * @param string $name + * @param mixed $value * @param array|null $options * * @return string @@ -60,8 +60,8 @@ class RuleForm } /** - * @param string $name - * @param null $value + * @param string $name + * @param null $value * @param array|null $options * * @return HtmlString diff --git a/app/Support/Http/Api/AccountFilter.php b/app/Support/Http/Api/AccountFilter.php index 14d6ac3da2..5aeeec5cd1 100644 --- a/app/Support/Http/Api/AccountFilter.php +++ b/app/Support/Http/Api/AccountFilter.php @@ -35,7 +35,7 @@ trait AccountFilter /** * All the available types. * - * @param string $type + * @param string $type * * @return array */ diff --git a/app/Support/Http/Api/ApiSupport.php b/app/Support/Http/Api/ApiSupport.php index 86ce524680..04a6037de2 100644 --- a/app/Support/Http/Api/ApiSupport.php +++ b/app/Support/Http/Api/ApiSupport.php @@ -36,7 +36,7 @@ trait ApiSupport /** * Small helper function for the revenue and expense account charts. * - * @param array $names + * @param array $names * * @return array */ @@ -53,7 +53,7 @@ trait ApiSupport /** * Small helper function for the revenue and expense account charts. * - * @param Collection $accounts + * @param Collection $accounts * * @return array */ diff --git a/app/Support/Http/Api/ConvertsExchangeRates.php b/app/Support/Http/Api/ConvertsExchangeRates.php index 0447677055..74bf39a2d1 100644 --- a/app/Support/Http/Api/ConvertsExchangeRates.php +++ b/app/Support/Http/Api/ConvertsExchangeRates.php @@ -38,7 +38,7 @@ trait ConvertsExchangeRates private ?bool $enabled = null; /** - * @param array $set + * @param array $set * @return array */ public function cerChartSet(array $set): array @@ -74,10 +74,135 @@ trait ConvertsExchangeRates return $set; } + /** + * @return void + */ + private function getPreference(): void + { + $this->enabled = true; + } + + /** + * @param int $currencyId + * @return TransactionCurrency + */ + private function getCurrency(int $currencyId): TransactionCurrency + { + $result = TransactionCurrency::find($currencyId); + if (null === $result) { + return app('amount')->getDefaultCurrency(); + } + return $result; + } + + /** + * @param TransactionCurrency $from + * @param TransactionCurrency $to + * @param Carbon $date + * @return string + */ + private function getRate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): string + { + Log::debug(sprintf('getRate(%s, %s, "%s")', $from->code, $to->code, $date->format('Y-m-d'))); + /** @var CurrencyExchangeRate $result */ + $result = auth()->user() + ->currencyExchangeRates() + ->where('from_currency_id', $from->id) + ->where('to_currency_id', $to->id) + ->where('date', '<=', $date->format('Y-m-d')) + ->orderBy('date', 'DESC') + ->first(); + if (null !== $result) { + $rate = (string)$result->rate; + Log::debug(sprintf('Rate is %s', $rate)); + return $rate; + } + // no result. perhaps the other way around? + /** @var CurrencyExchangeRate $result */ + $result = auth()->user() + ->currencyExchangeRates() + ->where('from_currency_id', $to->id) + ->where('to_currency_id', $from->id) + ->where('date', '<=', $date->format('Y-m-d')) + ->orderBy('date', 'DESC') + ->first(); + if (null !== $result) { + $rate = bcdiv('1', (string)$result->rate); + Log::debug(sprintf('Reversed rate is %s', $rate)); + return $rate; + } + // try euro rates + $result1 = $this->getEuroRate($from, $date); + if ('0' === $result1) { + Log::debug(sprintf('No exchange rate between EUR and %s', $from->code)); + return '0'; + } + $result2 = $this->getEuroRate($to, $date); + if ('0' === $result2) { + Log::debug(sprintf('No exchange rate between EUR and %s', $to->code)); + return '0'; + } + // still need to inverse rate 2: + $result2 = bcdiv('1', $result2); + $rate = bcmul($result1, $result2); + Log::debug(sprintf('Rate %s to EUR is %s', $from->code, $result1)); + Log::debug(sprintf('Rate EUR to %s is %s', $to->code, $result2)); + Log::debug(sprintf('Rate for %s to %s is %s', $from->code, $to->code, $rate)); + return $rate; + } + + /** + * @param TransactionCurrency $currency + * @param Carbon $date + * @return string + */ + private function getEuroRate(TransactionCurrency $currency, Carbon $date): string + { + Log::debug(sprintf('Find rate for %s to Euro', $currency->code)); + $euro = TransactionCurrency::whereCode('EUR')->first(); + if (null === $euro) { + app('log')->warning('Cannot do indirect conversion without EUR.'); + return '0'; + } + + // try one way: + /** @var CurrencyExchangeRate $result */ + $result = auth()->user() + ->currencyExchangeRates() + ->where('from_currency_id', $currency->id) + ->where('to_currency_id', $euro->id) + ->where('date', '<=', $date->format('Y-m-d')) + ->orderBy('date', 'DESC') + ->first(); + if (null !== $result) { + $rate = (string)$result->rate; + Log::debug(sprintf('Rate for %s to EUR is %s.', $currency->code, $rate)); + return $rate; + } + // try the other way around and inverse it. + /** @var CurrencyExchangeRate $result */ + $result = auth()->user() + ->currencyExchangeRates() + ->where('from_currency_id', $euro->id) + ->where('to_currency_id', $currency->id) + ->where('date', '<=', $date->format('Y-m-d')) + ->orderBy('date', 'DESC') + ->first(); + if (null !== $result) { + $rate = bcdiv('1', (string)$result->rate); + Log::debug(sprintf('Inverted rate for %s to EUR is %s.', $currency->code, $rate)); + return $rate; + } + + Log::debug(sprintf('No rate for %s to EUR.', $currency->code)); + return '0'; + } + /** * For a sum of entries, get the exchange rate to the native currency of * the user. - * @param array $entries + * + * @param array $entries * @return array */ public function cerSum(array $entries): array @@ -136,128 +261,4 @@ trait ConvertsExchangeRates return bcmul($amount, $rate); } - - /** - * @param int $currencyId - * @return TransactionCurrency - */ - private function getCurrency(int $currencyId): TransactionCurrency - { - $result = TransactionCurrency::find($currencyId); - if (null === $result) { - return app('amount')->getDefaultCurrency(); - } - return $result; - } - - /** - * @param TransactionCurrency $currency - * @param Carbon $date - * @return string - */ - private function getEuroRate(TransactionCurrency $currency, Carbon $date): string - { - Log::debug(sprintf('Find rate for %s to Euro', $currency->code)); - $euro = TransactionCurrency::whereCode('EUR')->first(); - if (null === $euro) { - app('log')->warning('Cannot do indirect conversion without EUR.'); - return '0'; - } - - // try one way: - /** @var CurrencyExchangeRate $result */ - $result = auth()->user() - ->currencyExchangeRates() - ->where('from_currency_id', $currency->id) - ->where('to_currency_id', $euro->id) - ->where('date', '<=', $date->format('Y-m-d')) - ->orderBy('date', 'DESC') - ->first(); - if (null !== $result) { - $rate = (string)$result->rate; - Log::debug(sprintf('Rate for %s to EUR is %s.', $currency->code, $rate)); - return $rate; - } - // try the other way around and inverse it. - /** @var CurrencyExchangeRate $result */ - $result = auth()->user() - ->currencyExchangeRates() - ->where('from_currency_id', $euro->id) - ->where('to_currency_id', $currency->id) - ->where('date', '<=', $date->format('Y-m-d')) - ->orderBy('date', 'DESC') - ->first(); - if (null !== $result) { - $rate = bcdiv('1', (string)$result->rate); - Log::debug(sprintf('Inverted rate for %s to EUR is %s.', $currency->code, $rate)); - return $rate; - } - - Log::debug(sprintf('No rate for %s to EUR.', $currency->code)); - return '0'; - } - - /** - * @return void - */ - private function getPreference(): void - { - $this->enabled = true; - } - - /** - * @param TransactionCurrency $from - * @param TransactionCurrency $to - * @param Carbon $date - * @return string - */ - private function getRate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): string - { - Log::debug(sprintf('getRate(%s, %s, "%s")', $from->code, $to->code, $date->format('Y-m-d'))); - /** @var CurrencyExchangeRate $result */ - $result = auth()->user() - ->currencyExchangeRates() - ->where('from_currency_id', $from->id) - ->where('to_currency_id', $to->id) - ->where('date', '<=', $date->format('Y-m-d')) - ->orderBy('date', 'DESC') - ->first(); - if (null !== $result) { - $rate = (string)$result->rate; - Log::debug(sprintf('Rate is %s', $rate)); - return $rate; - } - // no result. perhaps the other way around? - /** @var CurrencyExchangeRate $result */ - $result = auth()->user() - ->currencyExchangeRates() - ->where('from_currency_id', $to->id) - ->where('to_currency_id', $from->id) - ->where('date', '<=', $date->format('Y-m-d')) - ->orderBy('date', 'DESC') - ->first(); - if (null !== $result) { - $rate = bcdiv('1', (string)$result->rate); - Log::debug(sprintf('Reversed rate is %s', $rate)); - return $rate; - } - // try euro rates - $result1 = $this->getEuroRate($from, $date); - if ('0' === $result1) { - Log::debug(sprintf('No exchange rate between EUR and %s', $from->code)); - return '0'; - } - $result2 = $this->getEuroRate($to, $date); - if ('0' === $result2) { - Log::debug(sprintf('No exchange rate between EUR and %s', $to->code)); - return '0'; - } - // still need to inverse rate 2: - $result2 = bcdiv('1', $result2); - $rate = bcmul($result1, $result2); - Log::debug(sprintf('Rate %s to EUR is %s', $from->code, $result1)); - Log::debug(sprintf('Rate EUR to %s is %s', $to->code, $result2)); - Log::debug(sprintf('Rate for %s to %s is %s', $from->code, $to->code, $rate)); - return $rate; - } } diff --git a/app/Support/Http/Api/TransactionFilter.php b/app/Support/Http/Api/TransactionFilter.php index ce91b6dedf..06972ea929 100644 --- a/app/Support/Http/Api/TransactionFilter.php +++ b/app/Support/Http/Api/TransactionFilter.php @@ -35,7 +35,7 @@ trait TransactionFilter /** * All the types you can request. * - * @param string $type + * @param string $type * * @return array */ diff --git a/app/Support/Http/Controllers/AugumentData.php b/app/Support/Http/Controllers/AugumentData.php index 1db9fb5f8f..c21eb7b3b5 100644 --- a/app/Support/Http/Controllers/AugumentData.php +++ b/app/Support/Http/Controllers/AugumentData.php @@ -47,7 +47,7 @@ trait AugumentData /** * Searches for the opposing account. * - * @param Collection $accounts + * @param Collection $accounts * * @return array */ @@ -74,7 +74,7 @@ trait AugumentData /** * Small helper function for the revenue and expense account charts. * - * @param array $names + * @param array $names * * @return array */ @@ -91,7 +91,7 @@ trait AugumentData /** * Small helper function for the revenue and expense account charts. * - * @param Collection $accounts + * @param Collection $accounts * * @return array */ @@ -109,7 +109,7 @@ trait AugumentData /** * Get the account names belonging to a bunch of account ID's. * - * @param array $accountIds + * @param array $accountIds * * @return array */ @@ -135,7 +135,7 @@ trait AugumentData /** * Get the budget names from a set of budget ID's. * - * @param array $budgetIds + * @param array $budgetIds * * @return array */ @@ -159,7 +159,7 @@ trait AugumentData /** * Get the category names from a set of category ID's. Small helper function for some of the charts. * - * @param array $categoryIds + * @param array $categoryIds * * @return array */ @@ -185,9 +185,9 @@ trait AugumentData /** * Gets all budget limits for a budget. * - * @param Budget $budget - * @param Carbon $start - * @param Carbon $end + * @param Budget $budget + * @param Carbon $start + * @param Carbon $end * * @return Collection */ @@ -233,7 +233,7 @@ trait AugumentData /** * Group set of transactions by name of opposing account. * - * @param array $array + * @param array $array * * @return array */ @@ -261,10 +261,10 @@ trait AugumentData /** * Spent in a period. * - * @param Collection $assets - * @param Collection $opposing - * @param Carbon $start - * @param Carbon $end + * @param Collection $assets + * @param Collection $opposing + * @param Carbon $start + * @param Carbon $end * * @return array */ diff --git a/app/Support/Http/Controllers/BasicDataSupport.php b/app/Support/Http/Controllers/BasicDataSupport.php index d0bc600038..360634330b 100644 --- a/app/Support/Http/Controllers/BasicDataSupport.php +++ b/app/Support/Http/Controllers/BasicDataSupport.php @@ -34,8 +34,8 @@ trait BasicDataSupport /** * Find the ID in a given array. Return '0' if not there (amount). * - * @param array $array - * @param int $entryId + * @param array $array + * @param int $entryId * * @return null|mixed */ @@ -47,8 +47,8 @@ trait BasicDataSupport /** * Find the ID in a given array. Return null if not there (amount). * - * @param array $array - * @param int $entryId + * @param array $array + * @param int $entryId * * @return null|Carbon */ diff --git a/app/Support/Http/Controllers/ChartGeneration.php b/app/Support/Http/Controllers/ChartGeneration.php index 456a28fad8..5b2cd7c6e6 100644 --- a/app/Support/Http/Controllers/ChartGeneration.php +++ b/app/Support/Http/Controllers/ChartGeneration.php @@ -42,9 +42,9 @@ trait ChartGeneration /** * Shows an overview of the account balances for a set of accounts. * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end * * @return array * @throws FireflyException diff --git a/app/Support/Http/Controllers/CreateStuff.php b/app/Support/Http/Controllers/CreateStuff.php index 9a8e8273ab..a856a2ea64 100644 --- a/app/Support/Http/Controllers/CreateStuff.php +++ b/app/Support/Http/Controllers/CreateStuff.php @@ -41,8 +41,8 @@ trait CreateStuff /** * Creates an asset account. * - * @param NewUserFormRequest $request - * @param TransactionCurrency $currency + * @param NewUserFormRequest $request + * @param TransactionCurrency $currency * * @return bool */ @@ -71,8 +71,8 @@ trait CreateStuff /** * Creates a cash wallet. * - * @param TransactionCurrency $currency - * @param string $language + * @param TransactionCurrency $currency + * @param string $language * * @return bool */ @@ -123,9 +123,9 @@ trait CreateStuff /** * Create a savings account. * - * @param NewUserFormRequest $request - * @param TransactionCurrency $currency - * @param string $language + * @param NewUserFormRequest $request + * @param TransactionCurrency $currency + * @param string $language * * @return bool */ @@ -153,7 +153,7 @@ trait CreateStuff /** * Create a new user instance after a valid registration. * - * @param array $data + * @param array $data * * @return User */ diff --git a/app/Support/Http/Controllers/CronRunner.php b/app/Support/Http/Controllers/CronRunner.php index 697d300bbb..dc0b337bd1 100644 --- a/app/Support/Http/Controllers/CronRunner.php +++ b/app/Support/Http/Controllers/CronRunner.php @@ -38,8 +38,8 @@ use Psr\Container\NotFoundExceptionInterface; trait CronRunner { /** - * @param bool $force - * @param Carbon $date + * @param bool $force + * @param Carbon $date * * @return array * @throws ContainerExceptionInterface @@ -71,8 +71,8 @@ trait CronRunner } /** - * @param bool $force - * @param Carbon $date + * @param bool $force + * @param Carbon $date * * @return array */ @@ -102,8 +102,8 @@ trait CronRunner } /** - * @param bool $force - * @param Carbon $date + * @param bool $force + * @param Carbon $date * * @return array */ @@ -133,8 +133,8 @@ trait CronRunner } /** - * @param bool $force - * @param Carbon $date + * @param bool $force + * @param Carbon $date * * @return array * @throws ContainerExceptionInterface diff --git a/app/Support/Http/Controllers/DateCalculation.php b/app/Support/Http/Controllers/DateCalculation.php index 3238119c13..ae01a4135e 100644 --- a/app/Support/Http/Controllers/DateCalculation.php +++ b/app/Support/Http/Controllers/DateCalculation.php @@ -35,10 +35,11 @@ trait DateCalculation * Calculate the number of days passed left until end date, as seen from start date. * If today is between start and end, today will be used instead of end. * - * If both are in the past OR both are in the future, simply return the number of days in the period with a minimum of 1 + * If both are in the past OR both are in the future, simply return the number of days in the period with a minimum + * of 1 * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return int */ @@ -59,8 +60,8 @@ trait DateCalculation * * If both are in the past OR both are in the future, simply return the period between them with a minimum of 1 * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return int */ @@ -77,8 +78,8 @@ trait DateCalculation } /** - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return string */ @@ -103,8 +104,8 @@ trait DateCalculation * Get a list of the periods that will occur after this date. For example, * March 2018, April 2018, etc. * - * @param Carbon $date - * @param string $range + * @param Carbon $date + * @param string $range * * @return array */ @@ -139,8 +140,8 @@ trait DateCalculation * Get a list of the periods that occurred before the start date. For example, * March 2018, February 2018, etc. * - * @param Carbon $date - * @param string $range + * @param Carbon $date + * @param string $range * * @return array */ diff --git a/app/Support/Http/Controllers/GetConfigurationData.php b/app/Support/Http/Controllers/GetConfigurationData.php index 315262c88d..0cfe7b8019 100644 --- a/app/Support/Http/Controllers/GetConfigurationData.php +++ b/app/Support/Http/Controllers/GetConfigurationData.php @@ -38,7 +38,7 @@ trait GetConfigurationData /** * Some common combinations. * - * @param int $value + * @param int $value * * @return string */ @@ -60,7 +60,7 @@ trait GetConfigurationData /** * Get the basic steps from config. * - * @param string $route + * @param string $route * * @return array */ @@ -74,7 +74,7 @@ trait GetConfigurationData $currentStep = $options; // get the text: - $currentStep['intro'] = (string)trans('intro.'.$route.'_'.$key); + $currentStep['intro'] = (string)trans('intro.' . $route . '_' . $key); // save in array: $steps[] = $currentStep; @@ -183,8 +183,8 @@ trait GetConfigurationData /** * Get specific info for special routes. * - * @param string $route - * @param string $specificPage + * @param string $route + * @param string $specificPage * * @return array * @@ -197,13 +197,13 @@ trait GetConfigurationData // user is on page with specific instructions: if ('' !== $specificPage) { $routeKey = str_replace('.', '_', $route); - $elements = config(sprintf('intro.%s', $routeKey.'_'.$specificPage)); + $elements = config(sprintf('intro.%s', $routeKey . '_' . $specificPage)); if (is_array($elements) && count($elements) > 0) { foreach ($elements as $key => $options) { $currentStep = $options; // get the text: - $currentStep['intro'] = (string)trans('intro.'.$route.'_'.$specificPage.'_'.$key); + $currentStep['intro'] = (string)trans('intro.' . $route . '_' . $specificPage . '_' . $key); // save in array: $steps[] = $currentStep; diff --git a/app/Support/Http/Controllers/ModelInformation.php b/app/Support/Http/Controllers/ModelInformation.php index 15242561f2..7d3d42e7ce 100644 --- a/app/Support/Http/Controllers/ModelInformation.php +++ b/app/Support/Http/Controllers/ModelInformation.php @@ -42,7 +42,7 @@ trait ModelInformation /** * Get actions based on a bill. * - * @param Bill $bill + * @param Bill $bill * * @return array * @throws FireflyException @@ -109,7 +109,7 @@ trait ModelInformation /** * Create fake triggers to match the bill's properties * - * @param Bill $bill + * @param Bill $bill * * @return array * @throws FireflyException @@ -161,7 +161,7 @@ trait ModelInformation } /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return array * @throws FireflyException diff --git a/app/Support/Http/Controllers/PeriodOverview.php b/app/Support/Http/Controllers/PeriodOverview.php index 9f398262a5..8bdacc157d 100644 --- a/app/Support/Http/Controllers/PeriodOverview.php +++ b/app/Support/Http/Controllers/PeriodOverview.php @@ -74,9 +74,9 @@ trait PeriodOverview * and for each period, the amount of money spent and earned. This is a complex operation which is cached for * performance reasons. * - * @param Account $account - * @param Carbon $start - * @param Carbon $end + * @param Account $account + * @param Carbon $start + * @param Carbon $end * * @return array * @throws FireflyException @@ -150,12 +150,122 @@ trait PeriodOverview return $entries; } + /** + * Filter a list of journals by a set of dates, and then group them by currency. + * + * @param array $array + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + private function filterJournalsByDate(array $array, Carbon $start, Carbon $end): array + { + $result = []; + /** @var array $journal */ + foreach ($array as $journal) { + if ($journal['date'] <= $end && $journal['date'] >= $start) { + $result[] = $journal; + } + } + + return $result; + } + + /** + * Return only transactions where $account is the source. + * + * @param Account $account + * @param array $journals + * + * @return array + */ + private function filterTransferredAway(Account $account, array $journals): array + { + $return = []; + /** @var array $journal */ + foreach ($journals as $journal) { + if ($account->id === (int)$journal['source_account_id']) { + $return[] = $journal; + } + } + + return $return; + } + + /** + * Return only transactions where $account is the source. + * + * @param Account $account + * @param array $journals + * + * @return array + */ + private function filterTransferredIn(Account $account, array $journals): array + { + $return = []; + /** @var array $journal */ + foreach ($journals as $journal) { + if ($account->id === (int)$journal['destination_account_id']) { + $return[] = $journal; + } + } + + return $return; + } + + /** + * @param array $journals + * + * @return array + */ + private function groupByCurrency(array $journals): array + { + $return = []; + /** @var array $journal */ + foreach ($journals as $journal) { + $currencyId = (int)$journal['currency_id']; + $foreignCurrencyId = $journal['foreign_currency_id']; + if (!array_key_exists($currencyId, $return)) { + $return[$currencyId] = [ + 'amount' => '0', + 'count' => 0, + 'currency_id' => $currencyId, + 'currency_name' => $journal['currency_name'], + 'currency_code' => $journal['currency_code'], + 'currency_symbol' => $journal['currency_symbol'], + 'currency_decimal_places' => $journal['currency_decimal_places'], + ]; + } + $return[$currencyId]['amount'] = bcadd($return[$currencyId]['amount'], $journal['amount'] ?? '0'); + $return[$currencyId]['count']++; + + if (null !== $foreignCurrencyId && null !== $journal['foreign_amount']) { + if (!array_key_exists($foreignCurrencyId, $return)) { + $return[$foreignCurrencyId] = [ + 'amount' => '0', + 'count' => 0, + 'currency_id' => (int)$foreignCurrencyId, + 'currency_name' => $journal['foreign_currency_name'], + 'currency_code' => $journal['foreign_currency_code'], + 'currency_symbol' => $journal['foreign_currency_symbol'], + 'currency_decimal_places' => $journal['foreign_currency_decimal_places'], + ]; + } + $return[$foreignCurrencyId]['count']++; + $return[$foreignCurrencyId]['amount'] = bcadd($return[$foreignCurrencyId]['amount'], $journal['foreign_amount']); + } + } + + return $return; + } + /** * Overview for single category. Has been refactored recently. * - * @param Category $category - * @param Carbon $start - * @param Carbon $end + * @param Category $category + * @param Carbon $start + * @param Carbon $end * * @return array * @throws FireflyException @@ -234,8 +344,8 @@ trait PeriodOverview * * This method has been refactored recently. * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return array * @throws FireflyException @@ -290,7 +400,7 @@ trait PeriodOverview * * Show period overview for no category view. * - * @param Carbon $theDate + * @param Carbon $theDate * * @return array * @throws FireflyException @@ -360,9 +470,9 @@ trait PeriodOverview /** * This shows a period overview for a tag. It goes back in time and lists all relevant transactions and sums. * - * @param Tag $tag - * @param Carbon $start - * @param Carbon $end + * @param Tag $tag + * @param Carbon $start + * @param Carbon $end * * @return array * @throws FireflyException @@ -435,9 +545,9 @@ trait PeriodOverview } /** - * @param string $transactionType - * @param Carbon $start - * @param Carbon $end + * @param string $transactionType + * @param Carbon $start + * @param Carbon $end * * @return array * @throws FireflyException @@ -498,114 +608,4 @@ trait PeriodOverview return $entries; } - - /** - * Filter a list of journals by a set of dates, and then group them by currency. - * - * @param array $array - * @param Carbon $start - * @param Carbon $end - * - * @return array - */ - private function filterJournalsByDate(array $array, Carbon $start, Carbon $end): array - { - $result = []; - /** @var array $journal */ - foreach ($array as $journal) { - if ($journal['date'] <= $end && $journal['date'] >= $start) { - $result[] = $journal; - } - } - - return $result; - } - - /** - * Return only transactions where $account is the source. - * - * @param Account $account - * @param array $journals - * - * @return array - */ - private function filterTransferredAway(Account $account, array $journals): array - { - $return = []; - /** @var array $journal */ - foreach ($journals as $journal) { - if ($account->id === (int)$journal['source_account_id']) { - $return[] = $journal; - } - } - - return $return; - } - - /** - * Return only transactions where $account is the source. - * - * @param Account $account - * @param array $journals - * - * @return array - */ - private function filterTransferredIn(Account $account, array $journals): array - { - $return = []; - /** @var array $journal */ - foreach ($journals as $journal) { - if ($account->id === (int)$journal['destination_account_id']) { - $return[] = $journal; - } - } - - return $return; - } - - /** - * @param array $journals - * - * @return array - */ - private function groupByCurrency(array $journals): array - { - $return = []; - /** @var array $journal */ - foreach ($journals as $journal) { - $currencyId = (int)$journal['currency_id']; - $foreignCurrencyId = $journal['foreign_currency_id']; - if (!array_key_exists($currencyId, $return)) { - $return[$currencyId] = [ - 'amount' => '0', - 'count' => 0, - 'currency_id' => $currencyId, - 'currency_name' => $journal['currency_name'], - 'currency_code' => $journal['currency_code'], - 'currency_symbol' => $journal['currency_symbol'], - 'currency_decimal_places' => $journal['currency_decimal_places'], - ]; - } - $return[$currencyId]['amount'] = bcadd($return[$currencyId]['amount'], $journal['amount'] ?? '0'); - $return[$currencyId]['count']++; - - if (null !== $foreignCurrencyId && null !== $journal['foreign_amount']) { - if (!array_key_exists($foreignCurrencyId, $return)) { - $return[$foreignCurrencyId] = [ - 'amount' => '0', - 'count' => 0, - 'currency_id' => (int)$foreignCurrencyId, - 'currency_name' => $journal['foreign_currency_name'], - 'currency_code' => $journal['foreign_currency_code'], - 'currency_symbol' => $journal['foreign_currency_symbol'], - 'currency_decimal_places' => $journal['foreign_currency_decimal_places'], - ]; - } - $return[$foreignCurrencyId]['count']++; - $return[$foreignCurrencyId]['amount'] = bcadd($return[$foreignCurrencyId]['amount'], $journal['foreign_amount']); - } - } - - return $return; - } } diff --git a/app/Support/Http/Controllers/RenderPartialViews.php b/app/Support/Http/Controllers/RenderPartialViews.php index 84dfd9546a..7d22120392 100644 --- a/app/Support/Http/Controllers/RenderPartialViews.php +++ b/app/Support/Http/Controllers/RenderPartialViews.php @@ -48,7 +48,7 @@ trait RenderPartialViews /** * View for transactions in a budget for an account. * - * @param array $attributes + * @param array $attributes * * @return string * @throws FireflyException @@ -104,7 +104,7 @@ trait RenderPartialViews /** * View for spent in a single budget. * - * @param array $attributes + * @param array $attributes * * @return string * @throws FireflyException @@ -137,7 +137,7 @@ trait RenderPartialViews /** * View for transactions in a category. * - * @param array $attributes + * @param array $attributes * * @return string * @throws FireflyException @@ -232,7 +232,7 @@ trait RenderPartialViews /** * Returns all the expenses that went to the given expense account. * - * @param array $attributes + * @param array $attributes * * @return string * @throws FireflyException @@ -267,7 +267,7 @@ trait RenderPartialViews /** * Get current (from system) rule actions. * - * @param Rule $rule + * @param Rule $rule * * @return array * @throws FireflyException @@ -306,7 +306,7 @@ trait RenderPartialViews /** * Get current (from DB) rule triggers. * - * @param Rule $rule + * @param Rule $rule * * @return array * @throws FireflyException @@ -362,7 +362,7 @@ trait RenderPartialViews /** * Returns all the incomes that went to the given asset account. * - * @param array $attributes + * @param array $attributes * * @return string * @throws FireflyException diff --git a/app/Support/Http/Controllers/RequestInformation.php b/app/Support/Http/Controllers/RequestInformation.php index a845d53dfc..28780e340f 100644 --- a/app/Support/Http/Controllers/RequestInformation.php +++ b/app/Support/Http/Controllers/RequestInformation.php @@ -59,28 +59,10 @@ trait RequestInformation return $parts['host']; } - /** - * @return string - */ - final protected function getPageName(): string // get request info - { - return str_replace('.', '_', RouteFacade::currentRouteName()); - } - - /** - * Get the specific name of a page for intro. - * - * @return string - */ - final protected function getSpecificPageName(): string // get request info - { - return null === RouteFacade::current()->parameter('objectType') ? '' : '_'.RouteFacade::current()->parameter('objectType'); - } - /** * Get a list of triggers. * - * @param TestRuleFormRequest $request + * @param TestRuleFormRequest $request * * @return array */ @@ -133,10 +115,28 @@ trait RequestInformation return $shownDemo; } + /** + * @return string + */ + final protected function getPageName(): string // get request info + { + return str_replace('.', '_', RouteFacade::currentRouteName()); + } + + /** + * Get the specific name of a page for intro. + * + * @return string + */ + final protected function getSpecificPageName(): string // get request info + { + return null === RouteFacade::current()->parameter('objectType') ? '' : '_' . RouteFacade::current()->parameter('objectType'); + } + /** * Check if date is outside session range. * - * @param Carbon $date + * @param Carbon $date * * @return bool * @@ -162,7 +162,7 @@ trait RequestInformation /** * Parses attributes from URL * - * @param array $attributes + * @param array $attributes * * @return array */ @@ -192,9 +192,9 @@ trait RequestInformation /** * Validate users new password. * - * @param User $user - * @param string $current - * @param string $new + * @param User $user + * @param string $current + * @param string $new * * @return bool * @@ -216,7 +216,7 @@ trait RequestInformation /** * Get a validator for an incoming registration request. * - * @param array $data + * @param array $data * * @return ValidatorContract */ diff --git a/app/Support/Http/Controllers/RuleManagement.php b/app/Support/Http/Controllers/RuleManagement.php index f3068e7b0c..fed876ed27 100644 --- a/app/Support/Http/Controllers/RuleManagement.php +++ b/app/Support/Http/Controllers/RuleManagement.php @@ -37,7 +37,7 @@ use Throwable; trait RuleManagement { /** - * @param Request $request + * @param Request $request * * @return array * @throws FireflyException @@ -72,7 +72,7 @@ trait RuleManagement } /** - * @param Request $request + * @param Request $request * * @return array * @throws FireflyException @@ -119,7 +119,7 @@ trait RuleManagement } /** - * @param array $submittedOperators + * @param array $submittedOperators * * @return array * @throws FireflyException diff --git a/app/Support/Http/Controllers/TransactionCalculation.php b/app/Support/Http/Controllers/TransactionCalculation.php index 5d8ac77d9d..c17c26a7a5 100644 --- a/app/Support/Http/Controllers/TransactionCalculation.php +++ b/app/Support/Http/Controllers/TransactionCalculation.php @@ -37,10 +37,10 @@ trait TransactionCalculation /** * Get all expenses for a set of accounts. * - * @param Collection $accounts - * @param Collection $opposing - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $opposing + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -61,10 +61,10 @@ trait TransactionCalculation /** * Get all expenses by tags. * - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return array * @@ -83,10 +83,10 @@ trait TransactionCalculation /** * Helper function that collects expenses for the given budgets. * - * @param Collection $accounts - * @param Collection $budgets - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $budgets + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -103,10 +103,10 @@ trait TransactionCalculation /** * Get all expenses in a period for categories. * - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -127,10 +127,10 @@ trait TransactionCalculation /** * Get all income for a period and a bunch of categories. * - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -147,10 +147,10 @@ trait TransactionCalculation /** * Get the income for a set of accounts. * - * @param Collection $accounts - * @param Collection $opposing - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $opposing + * @param Carbon $start + * @param Carbon $end * * @return array */ @@ -167,10 +167,10 @@ trait TransactionCalculation /** * Get all income by tag. * - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end * * @return array */ diff --git a/app/Support/Http/Controllers/UserNavigation.php b/app/Support/Http/Controllers/UserNavigation.php index 3ccdfc1d4c..6fffe00a08 100644 --- a/app/Support/Http/Controllers/UserNavigation.php +++ b/app/Support/Http/Controllers/UserNavigation.php @@ -42,11 +42,12 @@ trait UserNavigation /** * Functionality:. * - * - If the $identifier contains the word "delete" then a remembered url with the text "/show/" in it will not be returned but instead the index (/) - * will be returned. - * - If the remembered url contains "jscript/" the remembered url will not be returned but instead the index (/) will be returned. + * - If the $identifier contains the word "delete" then a remembered url with the text "/show/" in it will not be + * returned but instead the index (/) will be returned. + * - If the remembered url contains "jscript/" the remembered url will not be returned but instead the index (/) + * will be returned. * - * @param string $identifier + * @param string $identifier * * @return string */ @@ -62,7 +63,7 @@ trait UserNavigation /** * Will return false if you cant edit this account type. * - * @param Account $account + * @param Account $account * * @return bool */ @@ -75,7 +76,7 @@ trait UserNavigation } /** - * @param TransactionGroup $group + * @param TransactionGroup $group * * @return bool */ @@ -93,7 +94,7 @@ trait UserNavigation } /** - * @param Account $account + * @param Account $account * * @return RedirectResponse|Redirector */ @@ -128,7 +129,7 @@ trait UserNavigation } /** - * @param TransactionGroup $group + * @param TransactionGroup $group * * @return RedirectResponse|Redirector */ @@ -156,7 +157,7 @@ trait UserNavigation } /** - * @param string $identifier + * @param string $identifier * * @return string|null */ diff --git a/app/Support/Logging/AuditLogger.php b/app/Support/Logging/AuditLogger.php index 3e19e38f20..eeac766f53 100644 --- a/app/Support/Logging/AuditLogger.php +++ b/app/Support/Logging/AuditLogger.php @@ -38,7 +38,7 @@ class AuditLogger /** * Customize the given logger instance. * - * @param Logger $logger + * @param Logger $logger * * @return void */ diff --git a/app/Support/Logging/AuditProcessor.php b/app/Support/Logging/AuditProcessor.php index 12ef8f7c2d..8e64183298 100644 --- a/app/Support/Logging/AuditProcessor.php +++ b/app/Support/Logging/AuditProcessor.php @@ -34,7 +34,7 @@ use Monolog\LogRecord; class AuditProcessor { /** - * @param LogRecord $record + * @param LogRecord $record * * @return LogRecord */ diff --git a/app/Support/Navigation.php b/app/Support/Navigation.php index c8477cdb6f..7d5f90b23b 100644 --- a/app/Support/Navigation.php +++ b/app/Support/Navigation.php @@ -36,9 +36,9 @@ use Psr\Container\NotFoundExceptionInterface; class Navigation { /** - * @param Carbon $theDate - * @param string $repeatFreq - * @param int $skip + * @param Carbon $theDate + * @param string $repeatFreq + * @param int $skip * * @return Carbon */ @@ -113,9 +113,9 @@ class Navigation } /** - * @param Carbon $start - * @param Carbon $end - * @param string $range + * @param Carbon $start + * @param Carbon $end + * @param string $range * * @return array * @@ -174,8 +174,73 @@ class Navigation } /** - * @param Carbon $end - * @param string $repeatFreq + * @param Carbon $theDate + * @param string $repeatFreq + * + * @return Carbon + */ + public function startOfPeriod(Carbon $theDate, string $repeatFreq): Carbon + { + $date = clone $theDate; + + $functionMap = [ + '1D' => 'startOfDay', + 'daily' => 'startOfDay', + '1W' => 'startOfWeek', + 'week' => 'startOfWeek', + 'weekly' => 'startOfWeek', + 'month' => 'startOfMonth', + '1M' => 'startOfMonth', + 'monthly' => 'startOfMonth', + '3M' => 'firstOfQuarter', + 'quarter' => 'firstOfQuarter', + 'quarterly' => 'firstOfQuarter', + 'year' => 'startOfYear', + 'yearly' => 'startOfYear', + '1Y' => 'startOfYear', + ]; + if (array_key_exists($repeatFreq, $functionMap)) { + $function = $functionMap[$repeatFreq]; + $date->$function(); + + return $date; + } + if ('half-year' === $repeatFreq || '6M' === $repeatFreq) { + $month = $date->month; + $date->startOfYear(); + if ($month >= 7) { + $date->addMonths(6); + } + + return $date; + } + + $result = match ($repeatFreq) { + 'last7' => $date->subDays(7)->startOfDay(), + 'last30' => $date->subDays(30)->startOfDay(), + 'last90' => $date->subDays(90)->startOfDay(), + 'last365' => $date->subDays(365)->startOfDay(), + 'MTD' => $date->startOfMonth()->startOfDay(), + 'QTD' => $date->firstOfQuarter()->startOfDay(), + 'YTD' => $date->startOfYear()->startOfDay(), + default => null, + }; + if (null !== $result) { + return $result; + } + + + if ('custom' === $repeatFreq) { + return $date; // the date is already at the start. + } + Log::error(sprintf('Cannot do startOfPeriod for $repeat_freq "%s"', $repeatFreq)); + + return $theDate; + } + + /** + * @param Carbon $end + * @param string $repeatFreq * * @return Carbon */ @@ -269,9 +334,9 @@ class Navigation } /** - * @param Carbon $theCurrentEnd - * @param string $repeatFreq - * @param Carbon|null $maxDate + * @param Carbon $theCurrentEnd + * @param string $repeatFreq + * @param Carbon|null $maxDate * * @return Carbon */ @@ -311,7 +376,8 @@ class Navigation /** * Returns the user's view range and if necessary, corrects the dynamic view * range to a normal range. - * @param bool $correct + * + * @param bool $correct * @return string * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface @@ -340,8 +406,8 @@ class Navigation } /** - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return array * @throws FireflyException @@ -377,8 +443,31 @@ class Navigation } /** - * @param Carbon $theDate - * @param string $repeatFrequency + * If the date difference between start and end is less than a month, method returns "Y-m-d". If the difference is + * less than a year, method returns "Y-m". If the date difference is larger, method returns "Y". + * + * @param Carbon $start + * @param Carbon $end + * + * @return string + */ + public function preferredCarbonFormat(Carbon $start, Carbon $end): string + { + $format = 'Y-m-d'; + if ($start->diffInMonths($end) > 1) { + $format = 'Y-m'; + } + + if ($start->diffInMonths($end) > 12) { + $format = 'Y'; + } + + return $format; + } + + /** + * @param Carbon $theDate + * @param string $repeatFrequency * * @return string */ @@ -417,34 +506,12 @@ class Navigation } /** - * If the date difference between start and end is less than a month, method returns "Y-m-d". If the difference is less than a year, - * method returns "Y-m". If the date difference is larger, method returns "Y". + * If the date difference between start and end is less than a month, method returns trans(config.month_and_day). + * If the difference is less than a year, method returns "config.month". If the date difference is larger, method + * returns "config.year". * - * @param Carbon $start - * @param Carbon $end - * - * @return string - */ - public function preferredCarbonFormat(Carbon $start, Carbon $end): string - { - $format = 'Y-m-d'; - if ($start->diffInMonths($end) > 1) { - $format = 'Y-m'; - } - - if ($start->diffInMonths($end) > 12) { - $format = 'Y'; - } - - return $format; - } - - /** - * If the date difference between start and end is less than a month, method returns trans(config.month_and_day). If the difference is less than a year, - * method returns "config.month". If the date difference is larger, method returns "config.year". - * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return string */ @@ -464,11 +531,11 @@ class Navigation } /** - * If the date difference between start and end is less than a month, method returns "endOfDay". If the difference is less than a year, - * method returns "endOfMonth". If the date difference is larger, method returns "endOfYear". + * If the date difference between start and end is less than a month, method returns "endOfDay". If the difference + * is less than a year, method returns "endOfMonth". If the date difference is larger, method returns "endOfYear". * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return string */ @@ -487,11 +554,11 @@ class Navigation } /** - * If the date difference between start and end is less than a month, method returns "1D". If the difference is less than a year, - * method returns "1M". If the date difference is larger, method returns "1Y". + * If the date difference between start and end is less than a month, method returns "1D". If the difference is + * less than a year, method returns "1M". If the date difference is larger, method returns "1Y". * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return string */ @@ -510,11 +577,11 @@ class Navigation } /** - * If the date difference between start and end is less than a month, method returns "%Y-%m-%d". If the difference is less than a year, - * method returns "%Y-%m". If the date difference is larger, method returns "%Y". + * If the date difference between start and end is less than a month, method returns "%Y-%m-%d". If the difference + * is less than a year, method returns "%Y-%m". If the date difference is larger, method returns "%Y". * - * @param Carbon $start - * @param Carbon $end + * @param Carbon $start + * @param Carbon $end * * @return string */ @@ -533,74 +600,9 @@ class Navigation } /** - * @param Carbon $theDate - * @param string $repeatFreq - * - * @return Carbon - */ - public function startOfPeriod(Carbon $theDate, string $repeatFreq): Carbon - { - $date = clone $theDate; - - $functionMap = [ - '1D' => 'startOfDay', - 'daily' => 'startOfDay', - '1W' => 'startOfWeek', - 'week' => 'startOfWeek', - 'weekly' => 'startOfWeek', - 'month' => 'startOfMonth', - '1M' => 'startOfMonth', - 'monthly' => 'startOfMonth', - '3M' => 'firstOfQuarter', - 'quarter' => 'firstOfQuarter', - 'quarterly' => 'firstOfQuarter', - 'year' => 'startOfYear', - 'yearly' => 'startOfYear', - '1Y' => 'startOfYear', - ]; - if (array_key_exists($repeatFreq, $functionMap)) { - $function = $functionMap[$repeatFreq]; - $date->$function(); - - return $date; - } - if ('half-year' === $repeatFreq || '6M' === $repeatFreq) { - $month = $date->month; - $date->startOfYear(); - if ($month >= 7) { - $date->addMonths(6); - } - - return $date; - } - - $result = match ($repeatFreq) { - 'last7' => $date->subDays(7)->startOfDay(), - 'last30' => $date->subDays(30)->startOfDay(), - 'last90' => $date->subDays(90)->startOfDay(), - 'last365' => $date->subDays(365)->startOfDay(), - 'MTD' => $date->startOfMonth()->startOfDay(), - 'QTD' => $date->firstOfQuarter()->startOfDay(), - 'YTD' => $date->startOfYear()->startOfDay(), - default => null, - }; - if (null !== $result) { - return $result; - } - - - if ('custom' === $repeatFreq) { - return $date; // the date is already at the start. - } - Log::error(sprintf('Cannot do startOfPeriod for $repeat_freq "%s"', $repeatFreq)); - - return $theDate; - } - - /** - * @param Carbon $theDate - * @param string $repeatFreq - * @param int|null $subtract + * @param Carbon $theDate + * @param string $repeatFreq + * @param int|null $subtract * * @return Carbon * @@ -687,8 +689,8 @@ class Navigation } /** - * @param string $range - * @param Carbon $start + * @param string $range + * @param Carbon $start * * @return Carbon * @@ -750,8 +752,8 @@ class Navigation } /** - * @param string $range - * @param Carbon $start + * @param string $range + * @param Carbon $start * * @return Carbon * diff --git a/app/Support/NullArrayObject.php b/app/Support/NullArrayObject.php index 0c18f43e47..035488f626 100644 --- a/app/Support/NullArrayObject.php +++ b/app/Support/NullArrayObject.php @@ -37,8 +37,8 @@ class NullArrayObject extends ArrayObject /** * NullArrayObject constructor. * - * @param array $array - * @param null $default + * @param array $array + * @param null $default */ /* @phpstan-ignore-next-line */ public function __construct(array $array, $default = null) @@ -48,7 +48,7 @@ class NullArrayObject extends ArrayObject } /** - * @param mixed $key + * @param mixed $key * * @return mixed */ diff --git a/app/Support/ParseDateString.php b/app/Support/ParseDateString.php index ed108d802c..e75676575b 100644 --- a/app/Support/ParseDateString.php +++ b/app/Support/ParseDateString.php @@ -49,7 +49,7 @@ class ParseDateString ]; /** - * @param string $date + * @param string $date * * @return bool */ @@ -73,7 +73,7 @@ class ParseDateString } /** - * @param string $date + * @param string $date * * @return Carbon * @throws FireflyException @@ -122,184 +122,7 @@ class ParseDateString } /** - * @param string $date - * - * @return array - */ - public function parseRange(string $date): array - { - // several types of range can be submitted - $result = [ - 'exact' => new Carbon('1984-09-17'), - ]; - switch (true) { - default: - break; - case $this->isDayRange($date): - $result = $this->parseDayRange($date); - break; - case $this->isMonthRange($date): - $result = $this->parseMonthRange($date); - break; - case $this->isYearRange($date): - $result = $this->parseYearRange($date); - break; - case $this->isMonthDayRange($date): - $result = $this->parseMonthDayRange($date); - break; - case $this->isDayYearRange($date): - $result = $this->parseDayYearRange($date); - break; - case $this->isMonthYearRange($date): - $result = $this->parseMonthYearRange($date); - break; - } - - return $result; - } - - /** - * @param string $date - * - * @return bool - */ - protected function isDayRange(string $date): bool - { - // if regex for xxxx-xx-DD: - $pattern = '/^xxxx-xx-(0[1-9]|[12]\d|3[01])$/'; - if (preg_match($pattern, $date)) { - Log::debug(sprintf('"%s" is a day range.', $date)); - - return true; - } - Log::debug(sprintf('"%s" is not a day range.', $date)); - - return false; - } - - /** - * @param string $date - * - * @return bool - */ - protected function isDayYearRange(string $date): bool - { - // if regex for YYYY-xx-DD: - $pattern = '/^(19|20)\d\d-xx-(0[1-9]|[12]\d|3[01])$/'; - if (preg_match($pattern, $date)) { - Log::debug(sprintf('"%s" is a day/year range.', $date)); - - return true; - } - Log::debug(sprintf('"%s" is not a day/year range.', $date)); - - return false; - } - - /** - * @param string $date - * - * @return bool - */ - protected function isMonthDayRange(string $date): bool - { - // if regex for xxxx-MM-DD: - $pattern = '/^xxxx-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$/'; - if (preg_match($pattern, $date)) { - Log::debug(sprintf('"%s" is a month/day range.', $date)); - - return true; - } - Log::debug(sprintf('"%s" is not a month/day range.', $date)); - - return false; - } - - /** - * @param string $date - * - * @return bool - */ - protected function isMonthRange(string $date): bool - { - // if regex for xxxx-MM-xx: - $pattern = '/^xxxx-(0[1-9]|1[012])-xx$/'; - if (preg_match($pattern, $date)) { - Log::debug(sprintf('"%s" is a month range.', $date)); - - return true; - } - Log::debug(sprintf('"%s" is not a month range.', $date)); - - return false; - } - - /** - * @param string $date - * - * @return bool - */ - protected function isMonthYearRange(string $date): bool - { - // if regex for YYYY-MM-xx: - $pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-xx$/'; - if (preg_match($pattern, $date)) { - Log::debug(sprintf('"%s" is a month/year range.', $date)); - - return true; - } - Log::debug(sprintf('"%s" is not a month/year range.', $date)); - - return false; - } - - /** - * @param string $date - * - * @return bool - */ - protected function isYearRange(string $date): bool - { - // if regex for YYYY-xx-xx: - $pattern = '/^(19|20)\d\d-xx-xx$/'; - if (preg_match($pattern, $date)) { - Log::debug(sprintf('"%s" is a year range.', $date)); - - return true; - } - Log::debug(sprintf('"%s" is not a year range.', $date)); - - return false; - } - - /** - * format of string is xxxx-xx-DD - * - * @param string $date - * - * @return array - */ - protected function parseDayRange(string $date): array - { - $parts = explode('-', $date); - - return [ - 'day' => $parts[2], - ]; - } - - /** - * @param string $date - * - * @return Carbon - */ - protected function parseDefaultDate(string $date): Carbon - { - return Carbon::createFromFormat('Y-m-d', $date); - } - - /** - * @param string $keyword + * @param string $keyword * * @return Carbon */ @@ -323,42 +146,17 @@ class ParseDateString } /** - * format of string is xxxx-MM-xx + * @param string $date * - * @param string $date - * - * @return array + * @return Carbon */ - protected function parseMonthRange(string $date): array + protected function parseDefaultDate(string $date): Carbon { - Log::debug(sprintf('parseMonthRange: Parsed "%s".', $date)); - $parts = explode('-', $date); - - return [ - 'month' => $parts[1], - ]; + return Carbon::createFromFormat('Y-m-d', $date); } /** - * format of string is YYYY-MM-xx - * - * @param string $date - * - * @return array - */ - protected function parseMonthYearRange(string $date): array - { - Log::debug(sprintf('parseMonthYearRange: Parsed "%s".', $date)); - $parts = explode('-', $date); - - return [ - 'year' => $parts[0], - 'month' => $parts[1], - ]; - } - - /** - * @param string $date + * @param string $date * * @return Carbon */ @@ -411,10 +209,137 @@ class ParseDateString return $today; } + /** + * @param string $date + * + * @return array + */ + public function parseRange(string $date): array + { + // several types of range can be submitted + $result = [ + 'exact' => new Carbon('1984-09-17'), + ]; + switch (true) { + default: + break; + case $this->isDayRange($date): + $result = $this->parseDayRange($date); + break; + case $this->isMonthRange($date): + $result = $this->parseMonthRange($date); + break; + case $this->isYearRange($date): + $result = $this->parseYearRange($date); + break; + case $this->isMonthDayRange($date): + $result = $this->parseMonthDayRange($date); + break; + case $this->isDayYearRange($date): + $result = $this->parseDayYearRange($date); + break; + case $this->isMonthYearRange($date): + $result = $this->parseMonthYearRange($date); + break; + } + + return $result; + } + + /** + * @param string $date + * + * @return bool + */ + protected function isDayRange(string $date): bool + { + // if regex for xxxx-xx-DD: + $pattern = '/^xxxx-xx-(0[1-9]|[12]\d|3[01])$/'; + if (preg_match($pattern, $date)) { + Log::debug(sprintf('"%s" is a day range.', $date)); + + return true; + } + Log::debug(sprintf('"%s" is not a day range.', $date)); + + return false; + } + + /** + * format of string is xxxx-xx-DD + * + * @param string $date + * + * @return array + */ + protected function parseDayRange(string $date): array + { + $parts = explode('-', $date); + + return [ + 'day' => $parts[2], + ]; + } + + /** + * @param string $date + * + * @return bool + */ + protected function isMonthRange(string $date): bool + { + // if regex for xxxx-MM-xx: + $pattern = '/^xxxx-(0[1-9]|1[012])-xx$/'; + if (preg_match($pattern, $date)) { + Log::debug(sprintf('"%s" is a month range.', $date)); + + return true; + } + Log::debug(sprintf('"%s" is not a month range.', $date)); + + return false; + } + + /** + * format of string is xxxx-MM-xx + * + * @param string $date + * + * @return array + */ + protected function parseMonthRange(string $date): array + { + Log::debug(sprintf('parseMonthRange: Parsed "%s".', $date)); + $parts = explode('-', $date); + + return [ + 'month' => $parts[1], + ]; + } + + /** + * @param string $date + * + * @return bool + */ + protected function isYearRange(string $date): bool + { + // if regex for YYYY-xx-xx: + $pattern = '/^(19|20)\d\d-xx-xx$/'; + if (preg_match($pattern, $date)) { + Log::debug(sprintf('"%s" is a year range.', $date)); + + return true; + } + Log::debug(sprintf('"%s" is not a year range.', $date)); + + return false; + } + /** * format of string is YYYY-xx-xx * - * @param string $date + * @param string $date * * @return array */ @@ -428,10 +353,66 @@ class ParseDateString ]; } + /** + * @param string $date + * + * @return bool + */ + protected function isMonthDayRange(string $date): bool + { + // if regex for xxxx-MM-DD: + $pattern = '/^xxxx-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$/'; + if (preg_match($pattern, $date)) { + Log::debug(sprintf('"%s" is a month/day range.', $date)); + + return true; + } + Log::debug(sprintf('"%s" is not a month/day range.', $date)); + + return false; + } + + /** + * format of string is xxxx-MM-DD + * + * @param string $date + * + * @return array + */ + private function parseMonthDayRange(string $date): array + { + Log::debug(sprintf('parseMonthDayRange: Parsed "%s".', $date)); + $parts = explode('-', $date); + + return [ + 'month' => $parts[1], + 'day' => $parts[2], + ]; + } + + /** + * @param string $date + * + * @return bool + */ + protected function isDayYearRange(string $date): bool + { + // if regex for YYYY-xx-DD: + $pattern = '/^(19|20)\d\d-xx-(0[1-9]|[12]\d|3[01])$/'; + if (preg_match($pattern, $date)) { + Log::debug(sprintf('"%s" is a day/year range.', $date)); + + return true; + } + Log::debug(sprintf('"%s" is not a day/year range.', $date)); + + return false; + } + /** * format of string is YYYY-xx-DD * - * @param string $date + * @param string $date * * @return array */ @@ -447,20 +428,39 @@ class ParseDateString } /** - * format of string is xxxx-MM-DD + * @param string $date * - * @param string $date + * @return bool + */ + protected function isMonthYearRange(string $date): bool + { + // if regex for YYYY-MM-xx: + $pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-xx$/'; + if (preg_match($pattern, $date)) { + Log::debug(sprintf('"%s" is a month/year range.', $date)); + + return true; + } + Log::debug(sprintf('"%s" is not a month/year range.', $date)); + + return false; + } + + /** + * format of string is YYYY-MM-xx + * + * @param string $date * * @return array */ - private function parseMonthDayRange(string $date): array + protected function parseMonthYearRange(string $date): array { - Log::debug(sprintf('parseMonthDayRange: Parsed "%s".', $date)); + Log::debug(sprintf('parseMonthYearRange: Parsed "%s".', $date)); $parts = explode('-', $date); return [ + 'year' => $parts[0], 'month' => $parts[1], - 'day' => $parts[2], ]; } } diff --git a/app/Support/Preferences.php b/app/Support/Preferences.php index 7b15c0a52b..c519a992ee 100644 --- a/app/Support/Preferences.php +++ b/app/Support/Preferences.php @@ -52,57 +52,8 @@ class Preferences } /** - * @param User $user - * @param string $search - * - * @return Collection - */ - public function beginsWith(User $user, string $search): Collection - { - return Preference::where('user_id', $user->id)->where('name', 'LIKE', $search.'%')->get(); - } - - /** - * @param string $name - * - * @return bool - * @throws FireflyException - */ - public function delete(string $name): bool - { - $fullName = sprintf('preference%s%s', auth()->user()->id, $name); - if (Cache::has($fullName)) { - Cache::forget($fullName); - } - Preference::where('user_id', auth()->user()->id)->where('name', $name)->delete(); - - return true; - } - - /** - * @param string $name - * - * @return Collection - */ - public function findByName(string $name): Collection - { - return Preference::where('name', $name)->get(); - } - - /** - * @param User $user - * @param string $name - */ - public function forget(User $user, string $name): void - { - $key = sprintf('preference%s%s', $user->id, $name); - Cache::forget($key); - Cache::put($key, '', 5); - } - - /** - * @param string $name - * @param mixed $default + * @param string $name + * @param mixed $default * * @return Preference|null * @throws FireflyException @@ -122,32 +73,9 @@ class Preferences } /** - * @param User $user - * @param array $list - * - * @return array - */ - public function getArrayForUser(User $user, array $list): array - { - $result = []; - $preferences = Preference::where('user_id', $user->id)->whereIn('name', $list)->get(['id', 'name', 'data']); - /** @var Preference $preference */ - foreach ($preferences as $preference) { - $result[$preference->name] = $preference->data; - } - foreach ($list as $name) { - if (!array_key_exists($name, $result)) { - $result[$name] = null; - } - } - - return $result; - } - - /** - * @param User $user - * @param string $name - * @param null|string|int $default + * @param User $user + * @param string $name + * @param null|string|int $default * * @return Preference|null * @throws FireflyException @@ -173,8 +101,119 @@ class Preferences } /** - * @param string $name - * @param mixed $default + * @param string $name + * + * @return bool + * @throws FireflyException + */ + public function delete(string $name): bool + { + $fullName = sprintf('preference%s%s', auth()->user()->id, $name); + if (Cache::has($fullName)) { + Cache::forget($fullName); + } + Preference::where('user_id', auth()->user()->id)->where('name', $name)->delete(); + + return true; + } + + /** + * @param User $user + * @param string $name + */ + public function forget(User $user, string $name): void + { + $key = sprintf('preference%s%s', $user->id, $name); + Cache::forget($key); + Cache::put($key, '', 5); + } + + /** + * @param User $user + * @param string $name + * @param mixed $value + * + * @return Preference + * @throws FireflyException + */ + public function setForUser(User $user, string $name, $value): Preference + { + $fullName = sprintf('preference%s%s', $user->id, $name); + Cache::forget($fullName); + /** @var Preference|null $pref */ + $pref = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data', 'updated_at', 'created_at']); + + if (null !== $pref && null === $value) { + $pref->delete(); + + return new Preference(); + } + if (null === $value) { + return new Preference(); + } + if (null === $pref) { + $pref = new Preference(); + $pref->user_id = $user->id; + $pref->name = $name; + } + $pref->data = $value; + try { + $pref->save(); + } catch (PDOException $e) { + throw new FireflyException(sprintf('Could not save preference: %s', $e->getMessage()), 0, $e); + } + Cache::forever($fullName, $pref); + + return $pref; + } + + /** + * @param User $user + * @param string $search + * + * @return Collection + */ + public function beginsWith(User $user, string $search): Collection + { + return Preference::where('user_id', $user->id)->where('name', 'LIKE', $search . '%')->get(); + } + + /** + * @param string $name + * + * @return Collection + */ + public function findByName(string $name): Collection + { + return Preference::where('name', $name)->get(); + } + + /** + * @param User $user + * @param array $list + * + * @return array + */ + public function getArrayForUser(User $user, array $list): array + { + $result = []; + $preferences = Preference::where('user_id', $user->id)->whereIn('name', $list)->get(['id', 'name', 'data']); + /** @var Preference $preference */ + foreach ($preferences as $preference) { + $result[$preference->name] = $preference->data; + } + foreach ($list as $name) { + if (!array_key_exists($name, $result)) { + $result[$name] = null; + } + } + + return $result; + } + + /** + * @param string $name + * @param mixed $default * * @return Preference|null * @throws FireflyException @@ -194,9 +233,9 @@ class Preferences } /** - * @param User $user - * @param string $name - * @param null $default + * @param User $user + * @param string $name + * @param null $default * * @return Preference|null * TODO remove me. @@ -236,8 +275,8 @@ class Preferences } /** - * @param string $name - * @param mixed $value + * @param string $name + * @param mixed $value * * @return Preference * @throws FireflyException @@ -256,43 +295,4 @@ class Preferences return $this->setForUser(auth()->user(), $name, $value); } - - /** - * @param User $user - * @param string $name - * @param mixed $value - * - * @return Preference - * @throws FireflyException - */ - public function setForUser(User $user, string $name, $value): Preference - { - $fullName = sprintf('preference%s%s', $user->id, $name); - Cache::forget($fullName); - /** @var Preference|null $pref */ - $pref = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data', 'updated_at', 'created_at']); - - if (null !== $pref && null === $value) { - $pref->delete(); - - return new Preference(); - } - if (null === $value) { - return new Preference(); - } - if (null === $pref) { - $pref = new Preference(); - $pref->user_id = $user->id; - $pref->name = $name; - } - $pref->data = $value; - try { - $pref->save(); - } catch (PDOException $e) { - throw new FireflyException(sprintf('Could not save preference: %s', $e->getMessage()), 0, $e); - } - Cache::forever($fullName, $pref); - - return $pref; - } } diff --git a/app/Support/Report/Budget/BudgetReportGenerator.php b/app/Support/Report/Budget/BudgetReportGenerator.php index 94078cd593..dbdef26c57 100644 --- a/app/Support/Report/Budget/BudgetReportGenerator.php +++ b/app/Support/Report/Budget/BudgetReportGenerator.php @@ -91,6 +91,48 @@ class BudgetReportGenerator } } + /** + * Process each row of expenses collected for the "Account per budget" partial + * + * @param array $expenses + */ + private function processExpenses(array $expenses): void + { + foreach ($expenses['budgets'] as $budget) { + $this->processBudgetExpenses($expenses, $budget); + } + } + + /** + * Process each set of transactions for each row of expenses. + * + * @param array $expenses + * @param array $budget + */ + private function processBudgetExpenses(array $expenses, array $budget): void + { + $budgetId = (int)$budget['id']; + $currencyId = (int)$expenses['currency_id']; + foreach ($budget['transaction_journals'] as $journal) { + $sourceAccountId = $journal['source_account_id']; + + $this->report[$sourceAccountId]['currencies'][$currencyId] + = $this->report[$sourceAccountId]['currencies'][$currencyId] ?? [ + 'currency_id' => $expenses['currency_id'], + 'currency_symbol' => $expenses['currency_symbol'], + 'currency_name' => $expenses['currency_name'], + 'currency_decimal_places' => $expenses['currency_decimal_places'], + 'budgets' => [], + ]; + + $this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId] + = $this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId] ?? '0'; + + $this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId] + = bcadd($this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId], $journal['amount']); + } + } + /** * Generates the data necessary to create the card that displays * the budget overview in the general report. @@ -107,60 +149,6 @@ class BudgetReportGenerator $this->percentageReport(); } - /** - * @return array - */ - public function getReport(): array - { - return $this->report; - } - - /** - * @param Collection $accounts - */ - public function setAccounts(Collection $accounts): void - { - $this->accounts = $accounts; - } - - /** - * @param Collection $budgets - */ - public function setBudgets(Collection $budgets): void - { - $this->budgets = $budgets; - } - - /** - * @param Carbon $end - */ - public function setEnd(Carbon $end): void - { - $this->end = $end; - } - - /** - * @param Carbon $start - */ - public function setStart(Carbon $start): void - { - $this->start = $start; - } - - /** - * @param User $user - * @throws FireflyException - * @throws JsonException - */ - public function setUser(User $user): void - { - $this->repository->setUser($user); - $this->blRepository->setUser($user); - $this->opsRepository->setUser($user); - $this->nbRepository->setUser($user); - $this->currency = app('amount')->getDefaultCurrencyByUser($user); - } - /** * Start the budgets block on the default report by processing every budget. */ @@ -173,6 +161,82 @@ class BudgetReportGenerator } } + /** + * Process expenses etc. for a single budget for the budgets block on the default report. + * + * @param Budget $budget + */ + private function processBudget(Budget $budget): void + { + $budgetId = (int)$budget->id; + $this->report['budgets'][$budgetId] = $this->report['budgets'][$budgetId] ?? [ + 'budget_id' => $budgetId, + 'budget_name' => $budget->name, + 'no_budget' => false, + 'budget_limits' => [], + ]; + + // get all budget limits for budget in period: + $limits = $this->blRepository->getBudgetLimits($budget, $this->start, $this->end); + /** @var BudgetLimit $limit */ + foreach ($limits as $limit) { + $this->processLimit($budget, $limit); + } + } + + /** + * Process a single budget limit for the budgets block on the default report. + * + * @param Budget $budget + * @param BudgetLimit $limit + */ + private function processLimit(Budget $budget, BudgetLimit $limit): void + { + $budgetId = (int)$budget->id; + $limitId = (int)$limit->id; + $limitCurrency = $limit->transactionCurrency ?? $this->currency; + $currencyId = (int)$limitCurrency->id; + $expenses = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, $this->accounts, new Collection([$budget])); + $spent = $expenses[$currencyId]['sum'] ?? '0'; + $left = -1 === bccomp(bcadd($limit->amount, $spent), '0') ? '0' : bcadd($limit->amount, $spent); + $overspent = 1 === bccomp(bcmul($spent, '-1'), $limit->amount) ? bcadd($spent, $limit->amount) : '0'; + + $this->report['budgets'][$budgetId]['budget_limits'][$limitId] = $this->report['budgets'][$budgetId]['budget_limits'][$limitId] ?? [ + 'budget_limit_id' => $limitId, + 'start_date' => $limit->start_date, + 'end_date' => $limit->end_date, + 'budgeted' => $limit->amount, + 'budgeted_pct' => '0', + 'spent' => $spent, + 'spent_pct' => '0', + 'left' => $left, + 'overspent' => $overspent, + 'currency_id' => $currencyId, + 'currency_code' => $limitCurrency->code, + 'currency_name' => $limitCurrency->name, + 'currency_symbol' => $limitCurrency->symbol, + 'currency_decimal_places' => $limitCurrency->decimal_places, + ]; + + // make sum information: + $this->report['sums'][$currencyId] + = $this->report['sums'][$currencyId] ?? [ + 'budgeted' => '0', + 'spent' => '0', + 'left' => '0', + 'overspent' => '0', + 'currency_id' => $currencyId, + 'currency_code' => $limitCurrency->code, + 'currency_name' => $limitCurrency->name, + 'currency_symbol' => $limitCurrency->symbol, + 'currency_decimal_places' => $limitCurrency->decimal_places, + ]; + $this->report['sums'][$currencyId]['budgeted'] = bcadd($this->report['sums'][$currencyId]['budgeted'], $limit->amount); + $this->report['sums'][$currencyId]['spent'] = bcadd($this->report['sums'][$currencyId]['spent'], $spent); + $this->report['sums'][$currencyId]['left'] = bcadd($this->report['sums'][$currencyId]['left'], bcadd($limit->amount, $spent)); + $this->report['sums'][$currencyId]['overspent'] = bcadd($this->report['sums'][$currencyId]['overspent'], $overspent); + } + /** * Calculate the expenses for transactions without a budget. Part of the "budgets" block of the default report. */ @@ -258,120 +322,56 @@ class BudgetReportGenerator } /** - * Process expenses etc. for a single budget for the budgets block on the default report. - * - * @param Budget $budget + * @return array */ - private function processBudget(Budget $budget): void + public function getReport(): array { - $budgetId = (int)$budget->id; - $this->report['budgets'][$budgetId] = $this->report['budgets'][$budgetId] ?? [ - 'budget_id' => $budgetId, - 'budget_name' => $budget->name, - 'no_budget' => false, - 'budget_limits' => [], - ]; - - // get all budget limits for budget in period: - $limits = $this->blRepository->getBudgetLimits($budget, $this->start, $this->end); - /** @var BudgetLimit $limit */ - foreach ($limits as $limit) { - $this->processLimit($budget, $limit); - } + return $this->report; } /** - * Process each set of transactions for each row of expenses. - * - * @param array $expenses - * @param array $budget + * @param Collection $accounts */ - private function processBudgetExpenses(array $expenses, array $budget): void + public function setAccounts(Collection $accounts): void { - $budgetId = (int)$budget['id']; - $currencyId = (int)$expenses['currency_id']; - foreach ($budget['transaction_journals'] as $journal) { - $sourceAccountId = $journal['source_account_id']; - - $this->report[$sourceAccountId]['currencies'][$currencyId] - = $this->report[$sourceAccountId]['currencies'][$currencyId] ?? [ - 'currency_id' => $expenses['currency_id'], - 'currency_symbol' => $expenses['currency_symbol'], - 'currency_name' => $expenses['currency_name'], - 'currency_decimal_places' => $expenses['currency_decimal_places'], - 'budgets' => [], - ]; - - $this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId] - = $this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId] ?? '0'; - - $this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId] - = bcadd($this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId], $journal['amount']); - } + $this->accounts = $accounts; } /** - * Process each row of expenses collected for the "Account per budget" partial - * - * @param array $expenses + * @param Collection $budgets */ - private function processExpenses(array $expenses): void + public function setBudgets(Collection $budgets): void { - foreach ($expenses['budgets'] as $budget) { - $this->processBudgetExpenses($expenses, $budget); - } + $this->budgets = $budgets; } /** - * Process a single budget limit for the budgets block on the default report. - * - * @param Budget $budget - * @param BudgetLimit $limit + * @param Carbon $end */ - private function processLimit(Budget $budget, BudgetLimit $limit): void + public function setEnd(Carbon $end): void { - $budgetId = (int)$budget->id; - $limitId = (int)$limit->id; - $limitCurrency = $limit->transactionCurrency ?? $this->currency; - $currencyId = (int)$limitCurrency->id; - $expenses = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, $this->accounts, new Collection([$budget])); - $spent = $expenses[$currencyId]['sum'] ?? '0'; - $left = -1 === bccomp(bcadd($limit->amount, $spent), '0') ? '0' : bcadd($limit->amount, $spent); - $overspent = 1 === bccomp(bcmul($spent, '-1'), $limit->amount) ? bcadd($spent, $limit->amount) : '0'; + $this->end = $end; + } - $this->report['budgets'][$budgetId]['budget_limits'][$limitId] = $this->report['budgets'][$budgetId]['budget_limits'][$limitId] ?? [ - 'budget_limit_id' => $limitId, - 'start_date' => $limit->start_date, - 'end_date' => $limit->end_date, - 'budgeted' => $limit->amount, - 'budgeted_pct' => '0', - 'spent' => $spent, - 'spent_pct' => '0', - 'left' => $left, - 'overspent' => $overspent, - 'currency_id' => $currencyId, - 'currency_code' => $limitCurrency->code, - 'currency_name' => $limitCurrency->name, - 'currency_symbol' => $limitCurrency->symbol, - 'currency_decimal_places' => $limitCurrency->decimal_places, - ]; + /** + * @param Carbon $start + */ + public function setStart(Carbon $start): void + { + $this->start = $start; + } - // make sum information: - $this->report['sums'][$currencyId] - = $this->report['sums'][$currencyId] ?? [ - 'budgeted' => '0', - 'spent' => '0', - 'left' => '0', - 'overspent' => '0', - 'currency_id' => $currencyId, - 'currency_code' => $limitCurrency->code, - 'currency_name' => $limitCurrency->name, - 'currency_symbol' => $limitCurrency->symbol, - 'currency_decimal_places' => $limitCurrency->decimal_places, - ]; - $this->report['sums'][$currencyId]['budgeted'] = bcadd($this->report['sums'][$currencyId]['budgeted'], $limit->amount); - $this->report['sums'][$currencyId]['spent'] = bcadd($this->report['sums'][$currencyId]['spent'], $spent); - $this->report['sums'][$currencyId]['left'] = bcadd($this->report['sums'][$currencyId]['left'], bcadd($limit->amount, $spent)); - $this->report['sums'][$currencyId]['overspent'] = bcadd($this->report['sums'][$currencyId]['overspent'], $overspent); + /** + * @param User $user + * @throws FireflyException + * @throws JsonException + */ + public function setUser(User $user): void + { + $this->repository->setUser($user); + $this->blRepository->setUser($user); + $this->opsRepository->setUser($user); + $this->nbRepository->setUser($user); + $this->currency = app('amount')->getDefaultCurrencyByUser($user); } } diff --git a/app/Support/Report/Category/CategoryReportGenerator.php b/app/Support/Report/Category/CategoryReportGenerator.php index abbd6df6fa..f8e85f9cb4 100644 --- a/app/Support/Report/Category/CategoryReportGenerator.php +++ b/app/Support/Report/Category/CategoryReportGenerator.php @@ -86,43 +86,52 @@ class CategoryReportGenerator } /** - * @param Collection $accounts + * Process one of the spent arrays from the operations method. + * + * @param array $data */ - public function setAccounts(Collection $accounts): void + private function processOpsArray(array $data): void { - $this->accounts = $accounts; + /** + * @var int $currencyId + * @var array $currencyRow + */ + foreach ($data as $currencyId => $currencyRow) { + $this->processCurrencyArray($currencyId, $currencyRow); + } } /** - * @param Carbon $end + * @param int $currencyId + * @param array $currencyRow */ - public function setEnd(Carbon $end): void + private function processCurrencyArray(int $currencyId, array $currencyRow): void { - $this->end = $end; + $this->report['sums'][$currencyId] = $this->report['sums'][$currencyId] ?? [ + 'spent' => '0', + 'earned' => '0', + 'sum' => '0', + 'currency_id' => $currencyRow['currency_id'], + 'currency_symbol' => $currencyRow['currency_symbol'], + 'currency_name' => $currencyRow['currency_name'], + 'currency_code' => $currencyRow['currency_code'], + 'currency_decimal_places' => $currencyRow['currency_decimal_places'], + ]; + + /** + * @var int $categoryId + * @var array $categoryRow + */ + foreach ($currencyRow['categories'] as $categoryId => $categoryRow) { + $this->processCategoryRow($currencyId, $currencyRow, $categoryId, $categoryRow); + } } /** - * @param Carbon $start - */ - public function setStart(Carbon $start): void - { - $this->start = $start; - } - - /** - * @param User $user - */ - public function setUser(User $user): void - { - $this->noCatRepository->setUser($user); - $this->opsRepository->setUser($user); - } - - /** - * @param int $currencyId - * @param array $currencyRow - * @param int $categoryId - * @param array $categoryRow + * @param int $currencyId + * @param array $currencyRow + * @param int $categoryId + * @param array $categoryRow */ private function processCategoryRow(int $currencyId, array $currencyRow, int $categoryId, array $categoryRow): void { @@ -170,44 +179,35 @@ class CategoryReportGenerator } /** - * @param int $currencyId - * @param array $currencyRow + * @param Collection $accounts */ - private function processCurrencyArray(int $currencyId, array $currencyRow): void + public function setAccounts(Collection $accounts): void { - $this->report['sums'][$currencyId] = $this->report['sums'][$currencyId] ?? [ - 'spent' => '0', - 'earned' => '0', - 'sum' => '0', - 'currency_id' => $currencyRow['currency_id'], - 'currency_symbol' => $currencyRow['currency_symbol'], - 'currency_name' => $currencyRow['currency_name'], - 'currency_code' => $currencyRow['currency_code'], - 'currency_decimal_places' => $currencyRow['currency_decimal_places'], - ]; - - /** - * @var int $categoryId - * @var array $categoryRow - */ - foreach ($currencyRow['categories'] as $categoryId => $categoryRow) { - $this->processCategoryRow($currencyId, $currencyRow, $categoryId, $categoryRow); - } + $this->accounts = $accounts; } /** - * Process one of the spent arrays from the operations method. - * - * @param array $data + * @param Carbon $end */ - private function processOpsArray(array $data): void + public function setEnd(Carbon $end): void { - /** - * @var int $currencyId - * @var array $currencyRow - */ - foreach ($data as $currencyId => $currencyRow) { - $this->processCurrencyArray($currencyId, $currencyRow); - } + $this->end = $end; + } + + /** + * @param Carbon $start + */ + public function setStart(Carbon $start): void + { + $this->start = $start; + } + + /** + * @param User $user + */ + public function setUser(User $user): void + { + $this->noCatRepository->setUser($user); + $this->opsRepository->setUser($user); } } diff --git a/app/Support/Repositories/Administration/AdministrationTrait.php b/app/Support/Repositories/Administration/AdministrationTrait.php index 16060af73d..7121da6a41 100644 --- a/app/Support/Repositories/Administration/AdministrationTrait.php +++ b/app/Support/Repositories/Administration/AdministrationTrait.php @@ -47,7 +47,7 @@ trait AdministrationTrait } /** - * @param int $administrationId + * @param int $administrationId * @throws FireflyException */ public function setAdministrationId(int $administrationId): void @@ -56,13 +56,6 @@ trait AdministrationTrait $this->refreshAdministration(); } - public function setUser(Authenticatable|User|null $user): void - { - if (null !== $user) { - $this->user = $user; - } - } - /** * @return void */ @@ -80,4 +73,11 @@ trait AdministrationTrait } throw new FireflyException(sprintf('Cannot validate administration for user #%d', $this->user->id)); } + + public function setUser(Authenticatable | User | null $user): void + { + if (null !== $user) { + $this->user = $user; + } + } } diff --git a/app/Support/Repositories/Recurring/CalculateRangeOccurrences.php b/app/Support/Repositories/Recurring/CalculateRangeOccurrences.php index cccdb12026..89588bd41b 100644 --- a/app/Support/Repositories/Recurring/CalculateRangeOccurrences.php +++ b/app/Support/Repositories/Recurring/CalculateRangeOccurrences.php @@ -33,11 +33,12 @@ use Illuminate\Support\Facades\Log; trait CalculateRangeOccurrences { /** - * Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every $skipMod-1 occurrences. + * Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every + * $skipMod-1 occurrences. * - * @param Carbon $start - * @param Carbon $end - * @param int $skipMod + * @param Carbon $start + * @param Carbon $end + * @param int $skipMod * * @return array */ @@ -57,12 +58,13 @@ trait CalculateRangeOccurrences } /** - * Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every $skipMod-1 occurrences. + * Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every + * $skipMod-1 occurrences. * - * @param Carbon $start - * @param Carbon $end - * @param int $skipMod - * @param string $moment + * @param Carbon $start + * @param Carbon $end + * @param int $skipMod + * @param string $moment * * @return array * @@ -90,12 +92,13 @@ trait CalculateRangeOccurrences } /** - * Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every $skipMod-1 occurrences. + * Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every + * $skipMod-1 occurrences. * - * @param Carbon $start - * @param Carbon $end - * @param int $skipMod - * @param string $moment + * @param Carbon $start + * @param Carbon $end + * @param int $skipMod + * @param string $moment * * @return array */ @@ -122,12 +125,13 @@ trait CalculateRangeOccurrences } /** - * Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every $skipMod-1 occurrences. + * Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every + * $skipMod-1 occurrences. * - * @param Carbon $start - * @param Carbon $end - * @param int $skipMod - * @param string $moment + * @param Carbon $start + * @param Carbon $end + * @param int $skipMod + * @param string $moment * * @return array * @@ -166,12 +170,13 @@ trait CalculateRangeOccurrences } /** - * Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every $skipMod-1 occurrences. + * Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every + * $skipMod-1 occurrences. * - * @param Carbon $start - * @param Carbon $end - * @param int $skipMod - * @param string $moment + * @param Carbon $start + * @param Carbon $end + * @param int $skipMod + * @param string $moment * * @return array * diff --git a/app/Support/Repositories/Recurring/CalculateXOccurrences.php b/app/Support/Repositories/Recurring/CalculateXOccurrences.php index 59e7ea2861..eae0b5eaa5 100644 --- a/app/Support/Repositories/Recurring/CalculateXOccurrences.php +++ b/app/Support/Repositories/Recurring/CalculateXOccurrences.php @@ -32,12 +32,12 @@ use Carbon\Carbon; trait CalculateXOccurrences { /** - * Calculates the number of daily occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip - * over $skipMod -1 recurrences. + * Calculates the number of daily occurrences for a recurring transaction, starting at the date, until $count is + * reached. It will skip over $skipMod -1 recurrences. * - * @param Carbon $date - * @param int $count - * @param int $skipMod + * @param Carbon $date + * @param int $count + * @param int $skipMod * * @return array */ @@ -60,13 +60,13 @@ trait CalculateXOccurrences } /** - * Calculates the number of monthly occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip - * over $skipMod -1 recurrences. + * Calculates the number of monthly occurrences for a recurring transaction, starting at the date, until $count is + * reached. It will skip over $skipMod -1 recurrences. * - * @param Carbon $date - * @param int $count - * @param int $skipMod - * @param string $moment + * @param Carbon $date + * @param int $count + * @param int $skipMod + * @param string $moment * * @return array */ @@ -97,13 +97,13 @@ trait CalculateXOccurrences } /** - * Calculates the number of NDOM occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip - * over $skipMod -1 recurrences. + * Calculates the number of NDOM occurrences for a recurring transaction, starting at the date, until $count is + * reached. It will skip over $skipMod -1 recurrences. * - * @param Carbon $date - * @param int $count - * @param int $skipMod - * @param string $moment + * @param Carbon $date + * @param int $count + * @param int $skipMod + * @param string $moment * * @return array */ @@ -135,13 +135,13 @@ trait CalculateXOccurrences } /** - * Calculates the number of weekly occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip - * over $skipMod -1 recurrences. + * Calculates the number of weekly occurrences for a recurring transaction, starting at the date, until $count is + * reached. It will skip over $skipMod -1 recurrences. * - * @param Carbon $date - * @param int $count - * @param int $skipMod - * @param string $moment + * @param Carbon $date + * @param int $count + * @param int $skipMod + * @param string $moment * * @return array */ @@ -177,13 +177,13 @@ trait CalculateXOccurrences } /** - * Calculates the number of yearly occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip - * over $skipMod -1 recurrences. + * Calculates the number of yearly occurrences for a recurring transaction, starting at the date, until $count is + * reached. It will skip over $skipMod -1 recurrences. * - * @param Carbon $date - * @param int $count - * @param int $skipMod - * @param string $moment + * @param Carbon $date + * @param int $count + * @param int $skipMod + * @param string $moment * * @return array */ diff --git a/app/Support/Repositories/Recurring/CalculateXOccurrencesSince.php b/app/Support/Repositories/Recurring/CalculateXOccurrencesSince.php index 950c2ec5d2..f4c52b5580 100644 --- a/app/Support/Repositories/Recurring/CalculateXOccurrencesSince.php +++ b/app/Support/Repositories/Recurring/CalculateXOccurrencesSince.php @@ -33,13 +33,13 @@ use Illuminate\Support\Facades\Log; trait CalculateXOccurrencesSince { /** - * Calculates the number of daily occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip - * over $skipMod -1 recurrences. + * Calculates the number of daily occurrences for a recurring transaction, starting at the date, until $count is + * reached. It will skip over $skipMod -1 recurrences. * - * @param Carbon $date - * @param Carbon $afterDate - * @param int $count - * @param int $skipMod + * @param Carbon $date + * @param Carbon $afterDate + * @param int $count + * @param int $skipMod * * @return array */ @@ -63,14 +63,14 @@ trait CalculateXOccurrencesSince } /** - * Calculates the number of monthly occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip - * over $skipMod -1 recurrences. + * Calculates the number of monthly occurrences for a recurring transaction, starting at the date, until $count is + * reached. It will skip over $skipMod -1 recurrences. * - * @param Carbon $date - * @param Carbon $afterDate - * @param int $count - * @param int $skipMod - * @param string $moment + * @param Carbon $date + * @param Carbon $afterDate + * @param int $count + * @param int $skipMod + * @param string $moment * * @return array */ @@ -106,14 +106,14 @@ trait CalculateXOccurrencesSince } /** - * Calculates the number of NDOM occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip - * over $skipMod -1 recurrences. + * Calculates the number of NDOM occurrences for a recurring transaction, starting at the date, until $count is + * reached. It will skip over $skipMod -1 recurrences. * - * @param Carbon $date - * @param Carbon $afterDate - * @param int $count - * @param int $skipMod - * @param string $moment + * @param Carbon $date + * @param Carbon $afterDate + * @param int $count + * @param int $skipMod + * @param string $moment * * @return array */ @@ -146,14 +146,14 @@ trait CalculateXOccurrencesSince } /** - * Calculates the number of weekly occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip - * over $skipMod -1 recurrences. + * Calculates the number of weekly occurrences for a recurring transaction, starting at the date, until $count is + * reached. It will skip over $skipMod -1 recurrences. * - * @param Carbon $date - * @param Carbon $afterDate - * @param int $count - * @param int $skipMod - * @param string $moment + * @param Carbon $date + * @param Carbon $afterDate + * @param int $count + * @param int $skipMod + * @param string $moment * * @return array */ @@ -191,14 +191,14 @@ trait CalculateXOccurrencesSince } /** - * Calculates the number of yearly occurrences for a recurring transaction, starting at the date, until $count is reached. It will skip - * over $skipMod -1 recurrences. + * Calculates the number of yearly occurrences for a recurring transaction, starting at the date, until $count is + * reached. It will skip over $skipMod -1 recurrences. * - * @param Carbon $date - * @param Carbon $afterDate - * @param int $count - * @param int $skipMod - * @param string $moment + * @param Carbon $date + * @param Carbon $afterDate + * @param int $count + * @param int $skipMod + * @param string $moment * * @return array */ diff --git a/app/Support/Repositories/Recurring/FiltersWeekends.php b/app/Support/Repositories/Recurring/FiltersWeekends.php index a86be7a4fc..49a3e3e700 100644 --- a/app/Support/Repositories/Recurring/FiltersWeekends.php +++ b/app/Support/Repositories/Recurring/FiltersWeekends.php @@ -37,8 +37,8 @@ trait FiltersWeekends /** * Filters out all weekend entries, if necessary. * - * @param RecurrenceRepetition $repetition - * @param array $dates + * @param RecurrenceRepetition $repetition + * @param array $dates * * @return array * diff --git a/app/Support/Request/AppendsLocationData.php b/app/Support/Request/AppendsLocationData.php index 373be35b11..5d126ffb17 100644 --- a/app/Support/Request/AppendsLocationData.php +++ b/app/Support/Request/AppendsLocationData.php @@ -30,16 +30,6 @@ use Illuminate\Support\Facades\Log; */ trait AppendsLocationData { - /** - * Abstract method stolen from "InteractsWithInput". - * - * @param null $key - * @param bool $default - * - * @return mixed - */ - abstract public function boolean($key = null, $default = false); - /** * Abstract method. * @@ -49,28 +39,12 @@ trait AppendsLocationData */ abstract public function has($key); - /** - * Abstract method. - * - * @return string - */ - abstract public function method(); - - /** - * Abstract method. - * - * @param mixed ...$patterns - * - * @return mixed - */ - abstract public function routeIs(...$patterns); - /** * Read the submitted Request data and add new or updated Location data to the array. * - * @param array $data + * @param array $data * - * @param string|null $prefix + * @param string|null $prefix * * @return array */ @@ -126,8 +100,8 @@ trait AppendsLocationData } /** - * @param string|null $prefix - * @param string $key + * @param string|null $prefix + * @param string $key * * @return string */ @@ -141,28 +115,7 @@ trait AppendsLocationData } /** - * @param string|null $prefix - * - * @return bool - */ - private function isValidEmptyPUT(?string $prefix): bool - { - $longitudeKey = $this->getLocationKey($prefix, 'longitude'); - $latitudeKey = $this->getLocationKey($prefix, 'latitude'); - $zoomLevelKey = $this->getLocationKey($prefix, 'zoom_level'); - - return ( - null === $this->get($longitudeKey) - && null === $this->get($latitudeKey) - && null === $this->get($zoomLevelKey)) - && ( - 'PUT' === $this->method() - || ('POST' === $this->method() && $this->routeIs('*.update')) - ); - } - - /** - * @param string|null $prefix + * @param string|null $prefix * * @return bool */ @@ -205,7 +158,33 @@ trait AppendsLocationData } /** - * @param string|null $prefix + * Abstract method. + * + * @return string + */ + abstract public function method(); + + /** + * Abstract method. + * + * @param mixed ...$patterns + * + * @return mixed + */ + abstract public function routeIs(...$patterns); + + /** + * Abstract method stolen from "InteractsWithInput". + * + * @param null $key + * @param bool $default + * + * @return mixed + */ + abstract public function boolean($key = null, $default = false); + + /** + * @param string|null $prefix * * @return bool */ @@ -248,4 +227,25 @@ trait AppendsLocationData return false; } + + /** + * @param string|null $prefix + * + * @return bool + */ + private function isValidEmptyPUT(?string $prefix): bool + { + $longitudeKey = $this->getLocationKey($prefix, 'longitude'); + $latitudeKey = $this->getLocationKey($prefix, 'latitude'); + $zoomLevelKey = $this->getLocationKey($prefix, 'zoom_level'); + + return ( + null === $this->get($longitudeKey) + && null === $this->get($latitudeKey) + && null === $this->get($zoomLevelKey)) + && ( + 'PUT' === $this->method() + || ('POST' === $this->method() && $this->routeIs('*.update')) + ); + } } diff --git a/app/Support/Request/ConvertsDataTypes.php b/app/Support/Request/ConvertsDataTypes.php index 3f261c8f89..94a2fd29f0 100644 --- a/app/Support/Request/ConvertsDataTypes.php +++ b/app/Support/Request/ConvertsDataTypes.php @@ -34,8 +34,46 @@ use Illuminate\Support\Facades\Log; trait ConvertsDataTypes { /** - * @param string|null $string - * @param bool $keepNewlines + * Return integer value. + * + * @param string $field + * + * @return int + */ + public function convertInteger(string $field): int + { + return (int)$this->get($field); + } + + /** + * Abstract method that always exists in the Request classes that use this + * trait, OR a stub needs to be added by any other class that uses this train. + * + * @param string $key + * @param mixed|null $default + * @return mixed + */ + abstract public function get(string $key, mixed $default = null): mixed; + + /** + * Return string value. + * + * @param string $field + * + * @return string + */ + public function convertString(string $field): string + { + $entry = $this->get($field); + if (!is_scalar($entry)) { + return ''; + } + return $this->clearString((string)$entry, false); + } + + /** + * @param string|null $string + * @param bool $keepNewlines * * @return string|null */ @@ -114,57 +152,10 @@ trait ConvertsDataTypes return trim($string); } - /** - * Return integer value. - * - * @param string $field - * - * @return int - */ - public function convertInteger(string $field): int - { - return (int)$this->get($field); - } - - /** - * Return string value. - * - * @param string $field - * - * @return string - */ - public function convertString(string $field): string - { - $entry = $this->get($field); - if (!is_scalar($entry)) { - return ''; - } - return $this->clearString((string)$entry, false); - } - - /** - * Abstract method that always exists in the Request classes that use this - * trait, OR a stub needs to be added by any other class that uses this train. - * - * @param string $key - * @param mixed|null $default - * @return mixed - */ - abstract public function get(string $key, mixed $default = null): mixed; - - /** - * Abstract method that always exists in the Request classes that use this - * trait, OR a stub needs to be added by any other class that uses this train. - * - * @param mixed $key - * @return mixed - */ - abstract public function has($key); - /** * Return string value with newlines. * - * @param string $field + * @param string $field * * @return string */ @@ -174,7 +165,7 @@ trait ConvertsDataTypes } /** - * @param mixed $array + * @param mixed $array * * @return array|null */ @@ -194,7 +185,7 @@ trait ConvertsDataTypes } /** - * @param string|null $value + * @param string|null $value * * @return bool */ @@ -260,7 +251,7 @@ trait ConvertsDataTypes /** * Return floating value. * - * @param string $field + * @param string $field * * @return float|null */ @@ -275,7 +266,7 @@ trait ConvertsDataTypes } /** - * @param string|null $string + * @param string|null $string * * @return Carbon|null */ @@ -307,7 +298,7 @@ trait ConvertsDataTypes * Returns all data in the request, or omits the field if not set, * according to the config from the request. This is the way. * - * @param array $fields + * @param array $fields * * @return array */ @@ -324,10 +315,19 @@ trait ConvertsDataTypes return $return; } + /** + * Abstract method that always exists in the Request classes that use this + * trait, OR a stub needs to be added by any other class that uses this train. + * + * @param mixed $key + * @return mixed + */ + abstract public function has($key); + /** * Return date or NULL. * - * @param string $field + * @param string $field * * @return Carbon|null */ @@ -349,7 +349,7 @@ trait ConvertsDataTypes /** * Parse to integer * - * @param string|null $string + * @param string|null $string * * @return int|null */ @@ -368,7 +368,7 @@ trait ConvertsDataTypes /** * Return integer value, or NULL when it's not set. * - * @param string $field + * @param string $field * * @return int|null */ diff --git a/app/Support/Request/GetRecurrenceData.php b/app/Support/Request/GetRecurrenceData.php index 417f927b0e..d26b9e702e 100644 --- a/app/Support/Request/GetRecurrenceData.php +++ b/app/Support/Request/GetRecurrenceData.php @@ -29,7 +29,7 @@ namespace FireflyIII\Support\Request; trait GetRecurrenceData { /** - * @param array $transaction + * @param array $transaction * * @return array */ diff --git a/app/Support/Search/AccountSearch.php b/app/Support/Search/AccountSearch.php index 885ec5887a..2850db13a4 100644 --- a/app/Support/Search/AccountSearch.php +++ b/app/Support/Search/AccountSearch.php @@ -109,7 +109,7 @@ class AccountSearch implements GenericSearchInterface } /** - * @param string $field + * @param string $field */ public function setField(string $field): void { @@ -117,7 +117,7 @@ class AccountSearch implements GenericSearchInterface } /** - * @param string $query + * @param string $query */ public function setQuery(string $query): void { @@ -125,7 +125,7 @@ class AccountSearch implements GenericSearchInterface } /** - * @param array $types + * @param array $types */ public function setTypes(array $types): void { @@ -133,10 +133,10 @@ class AccountSearch implements GenericSearchInterface } /** - * @param User|Authenticatable|null $user + * @param User|Authenticatable|null $user * @return void */ - public function setUser(User|Authenticatable|null $user): void + public function setUser(User | Authenticatable | null $user): void { if (null !== $user) { $this->user = $user; diff --git a/app/Support/Search/OperatorQuerySearch.php b/app/Support/Search/OperatorQuerySearch.php index 7336581724..4d9f692e63 100644 --- a/app/Support/Search/OperatorQuerySearch.php +++ b/app/Support/Search/OperatorQuerySearch.php @@ -104,39 +104,6 @@ class OperatorQuerySearch implements SearchInterface $this->currencyRepository = app(CurrencyRepositoryInterface::class); } - /** - * @param string $operator - * - * @return string - * @throws FireflyException - */ - public static function getRootOperator(string $operator): string - { - $original = $operator; - // if the string starts with "-" (not), we can remove it and recycle - // the configuration from the original operator. - if (str_starts_with($operator, '-')) { - $operator = substr($operator, 1); - } - - $config = config(sprintf('search.operators.%s', $operator)); - if (null === $config) { - throw new FireflyException(sprintf('No configuration for search operator "%s"', $operator)); - } - if (true === $config['alias']) { - $return = $config['alias_for']; - if (str_starts_with($original, '-')) { - $return = sprintf('-%s', $config['alias_for']); - } - Log::debug(sprintf('"%s" is an alias for "%s", so return that instead.', $original, $return)); - - return $return; - } - Log::debug(sprintf('"%s" is not an alias.', $operator)); - - return $original; - } - /** * @return array */ @@ -161,14 +128,6 @@ class OperatorQuerySearch implements SearchInterface return $this->operators; } - /** - * @return array - */ - public function getWords(): array - { - return $this->words; - } - /** * @inheritDoc */ @@ -196,7 +155,7 @@ class OperatorQuerySearch implements SearchInterface $parser = new QueryParser(); try { $query1 = $parser->parse($query); - } catch (TypeError|LogicException $e) { + } catch (TypeError | LogicException $e) { Log::error($e->getMessage()); Log::error(sprintf('Could not parse search: "%s".', $query)); throw new FireflyException(sprintf('Invalid search value "%s". See the logs.', e($query)), 0, $e); @@ -212,98 +171,7 @@ class OperatorQuerySearch implements SearchInterface } /** - * @inheritDoc - */ - public function searchTime(): float - { - return microtime(true) - $this->startTime; - } - - /** - * @inheritDoc - */ - public function searchTransactions(): LengthAwarePaginator - { - if (0 === count($this->getWords()) && 0 === count($this->getOperators())) { - return new LengthAwarePaginator([], 0, 5, 1); - } - - return $this->collector->getPaginatedGroups(); - } - - /** - * @param Carbon $date - */ - public function setDate(Carbon $date): void - { - $this->date = $date; - } - - /** - * @param int $limit - */ - public function setLimit(int $limit): void - { - $this->limit = $limit; - $this->collector->setLimit($this->limit); - } - - /** - * @inheritDoc - */ - public function setPage(int $page): void - { - $this->page = $page; - $this->collector->setPage($this->page); - } - - /** - * @inheritDoc - */ - public function setUser(User $user): void - { - $this->accountRepository->setUser($user); - $this->billRepository->setUser($user); - $this->categoryRepository->setUser($user); - $this->budgetRepository->setUser($user); - $this->tagRepository->setUser($user); - $this->collector = app(GroupCollectorInterface::class); - $this->collector->setUser($user); - $this->collector->withAccountInformation()->withCategoryInformation()->withBudgetInformation(); - - $this->setLimit((int)app('preferences')->getForUser($user, 'listPageSize', 50)->data); - } - - /** - * @param string $value - * - * @return TransactionCurrency|null - */ - private function findCurrency(string $value): ?TransactionCurrency - { - if (str_contains($value, '(') && str_contains($value, ')')) { - // bad method to split and get the currency code: - $parts = explode(' ', $value); - $value = trim($parts[count($parts) - 1], "() \t\n\r\0\x0B"); - } - $result = $this->currencyRepository->findByCodeNull($value); - if (null === $result) { - $result = $this->currencyRepository->findByNameNull($value); - } - - return $result; - } - - /** - * @return Account - */ - private function getCashAccount(): Account - { - return $this->accountRepository->getCashAccount(); - } - - /** - * @param Node $searchNode + * @param Node $searchNode * * @throws FireflyException */ @@ -371,592 +239,6 @@ class OperatorQuerySearch implements SearchInterface } } - /** - * @param string $value - * - * @return array - * @throws FireflyException - */ - private function parseDateRange(string $value): array - { - $parser = new ParseDateString(); - if ($parser->isDateRange($value)) { - return $parser->parseRange($value); - } - $parsedDate = $parser->parseDate($value); - - return [ - 'exact' => $parsedDate, - ]; - } - - /** - * searchDirection: 1 = source (default), 2 = destination, 3 = both - * stringPosition: 1 = start (default), 2 = end, 3 = contains, 4 = is - * - * @param string $value - * @param int $searchDirection - * @param int $stringPosition - * @param bool $prohibited - */ - private function searchAccount(string $value, int $searchDirection, int $stringPosition, bool $prohibited = false): void - { - Log::debug(sprintf('searchAccount("%s", %d, %d)', $value, $stringPosition, $searchDirection)); - - // search direction (default): for source accounts - $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::REVENUE]; - $collectorMethod = 'setSourceAccounts'; - if ($prohibited) { - $collectorMethod = 'excludeSourceAccounts'; - } - - // search direction: for destination accounts - if (2 === $searchDirection) { - // destination can be - $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE]; - $collectorMethod = 'setDestinationAccounts'; - if ($prohibited) { - $collectorMethod = 'excludeDestinationAccounts'; - } - } - // either account could be: - if (3 === $searchDirection) { - $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE, AccountType::REVENUE]; - $collectorMethod = 'setAccounts'; - if ($prohibited) { - $collectorMethod = 'excludeAccounts'; - } - } - // string position (default): starts with: - $stringMethod = 'str_starts_with'; - - // string position: ends with: - if (2 === $stringPosition) { - $stringMethod = 'str_ends_with'; - } - if (3 === $stringPosition) { - $stringMethod = 'str_contains'; - } - if (4 === $stringPosition) { - $stringMethod = 'stringIsEqual'; - } - - // get accounts: - $accounts = $this->accountRepository->searchAccount($value, $searchTypes, 1337); - if (0 === $accounts->count()) { - Log::debug('Found zero accounts, search for non existing account, NO results will be returned.'); - $this->collector->findNothing(); - - return; - } - Log::debug(sprintf('Found %d accounts, will filter.', $accounts->count())); - $filtered = $accounts->filter( - function (Account $account) use ($value, $stringMethod) { - return $stringMethod(strtolower($account->name), strtolower($value)); - } - ); - - if (0 === $filtered->count()) { - Log::debug('Left with zero accounts, so cannot find anything, NO results will be returned.'); - $this->collector->findNothing(); - - return; - } - Log::debug(sprintf('Left with %d, set as %s().', $filtered->count(), $collectorMethod)); - $this->collector->$collectorMethod($filtered); - } - - /** - * searchDirection: 1 = source (default), 2 = destination, 3 = both - * stringPosition: 1 = start (default), 2 = end, 3 = contains, 4 = is - * - * @param string $value - * @param int $searchDirection - * @param int $stringPosition - * @param bool $prohibited - */ - private function searchAccountNr(string $value, int $searchDirection, int $stringPosition, bool $prohibited = false): void - { - Log::debug(sprintf('searchAccountNr(%s, %d, %d)', $value, $searchDirection, $stringPosition)); - - // search direction (default): for source accounts - $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::REVENUE]; - $collectorMethod = 'setSourceAccounts'; - if (true === $prohibited) { - $collectorMethod = 'excludeSourceAccounts'; - } - - // search direction: for destination accounts - if (2 === $searchDirection) { - // destination can be - $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE]; - $collectorMethod = 'setDestinationAccounts'; - if (true === $prohibited) { - $collectorMethod = 'excludeDestinationAccounts'; - } - } - - // either account could be: - if (3 === $searchDirection) { - $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE, AccountType::REVENUE]; - $collectorMethod = 'setAccounts'; - if (true === $prohibited) { - $collectorMethod = 'excludeAccounts'; - } - } - - // string position (default): starts with: - $stringMethod = 'str_starts_with'; - - // string position: ends with: - if (2 === $stringPosition) { - $stringMethod = 'str_ends_with'; - } - if (3 === $stringPosition) { - $stringMethod = 'str_contains'; - } - if (4 === $stringPosition) { - $stringMethod = 'stringIsEqual'; - } - - // search for accounts: - $accounts = $this->accountRepository->searchAccountNr($value, $searchTypes, 1337); - if (0 === $accounts->count()) { - Log::debug('Found zero accounts, search for invalid account.'); - $this->collector->findNothing(); - - return; - } - - // if found, do filter - Log::debug(sprintf('Found %d accounts, will filter.', $accounts->count())); - $filtered = $accounts->filter( - function (Account $account) use ($value, $stringMethod) { - // either IBAN or account number - $ibanMatch = $stringMethod(strtolower((string)$account->iban), strtolower((string)$value)); - $accountNrMatch = false; - /** @var AccountMeta $meta */ - foreach ($account->accountMeta as $meta) { - if ('account_number' === $meta->name && $stringMethod(strtolower($meta->data), strtolower($value))) { - $accountNrMatch = true; - } - } - - return $ibanMatch || $accountNrMatch; - } - ); - - if (0 === $filtered->count()) { - Log::debug('Left with zero, search for invalid account'); - $this->collector->findNothing(); - - return; - } - Log::debug(sprintf('Left with %d, set as %s().', $filtered->count(), $collectorMethod)); - $this->collector->$collectorMethod($filtered); - } - - /** - * - * @throws FireflyException - */ - private function setDateAfterParams(array $range, bool $prohibited = false) - { - /** - * @var string $key - * @var Carbon|string $value - */ - foreach ($range as $key => $value) { - $key = $prohibited ? sprintf('%s_not', $key) : $key; - switch ($key) { - default: - throw new FireflyException(sprintf('Cannot handle key "%s" in setDateAfterParams()', $key)); - case 'exact': - $this->collector->setAfter($value); - $this->operators->push(['type' => 'date_after', 'value' => $value->format('Y-m-d'),]); - break; - case 'year': - Log::debug(sprintf('Set date_is_after YEAR value "%s"', $value)); - $this->collector->yearAfter($value); - $this->operators->push(['type' => 'date_after_year', 'value' => $value,]); - break; - case 'month': - Log::debug(sprintf('Set date_is_after MONTH value "%s"', $value)); - $this->collector->monthAfter($value); - $this->operators->push(['type' => 'date_after_month', 'value' => $value,]); - break; - case 'day': - Log::debug(sprintf('Set date_is_after DAY value "%s"', $value)); - $this->collector->dayAfter($value); - $this->operators->push(['type' => 'date_after_day', 'value' => $value,]); - break; - } - } - } - - /** - * - * @throws FireflyException - */ - private function setDateBeforeParams(array $range, bool $prohibited = false): void - { - /** - * @var string $key - * @var Carbon|string $value - */ - foreach ($range as $key => $value) { - $key = $prohibited ? sprintf('%s_not', $key) : $key; - switch ($key) { - default: - throw new FireflyException(sprintf('Cannot handle key "%s" in setDateBeforeParams()', $key)); - case 'exact': - $this->collector->setBefore($value); - $this->operators->push(['type' => 'date_before', 'value' => $value->format('Y-m-d'),]); - break; - case 'year': - Log::debug(sprintf('Set date_is_before YEAR value "%s"', $value)); - $this->collector->yearBefore($value); - $this->operators->push(['type' => 'date_before_year', 'value' => $value,]); - break; - case 'month': - Log::debug(sprintf('Set date_is_before MONTH value "%s"', $value)); - $this->collector->monthBefore($value); - $this->operators->push(['type' => 'date_before_month', 'value' => $value,]); - break; - case 'day': - Log::debug(sprintf('Set date_is_before DAY value "%s"', $value)); - $this->collector->dayBefore($value); - $this->operators->push(['type' => 'date_before_day', 'value' => $value,]); - break; - } - } - } - - /** - * - * @throws FireflyException - */ - private function setExactDateParams(array $range, bool $prohibited = false): void - { - /** - * @var string $key - * @var Carbon|string $value - */ - foreach ($range as $key => $value) { - $key = $prohibited ? sprintf('%s_not', $key) : $key; - switch ($key) { - default: - throw new FireflyException(sprintf('Cannot handle key "%s" in setExactParameters()', $key)); - case 'exact': - Log::debug(sprintf('Set date_is_exact value "%s"', $value->format('Y-m-d'))); - $this->collector->setRange($value, $value); - $this->operators->push(['type' => 'date_on', 'value' => $value->format('Y-m-d'),]); - break; - case 'exact_not': - $this->collector->excludeRange($value, $value); - $this->operators->push(['type' => 'not_date_on', 'value' => $value->format('Y-m-d'),]); - break; - case 'year': - Log::debug(sprintf('Set date_is_exact YEAR value "%s"', $value)); - $this->collector->yearIs($value); - $this->operators->push(['type' => 'date_on_year', 'value' => $value,]); - break; - case 'year_not': - Log::debug(sprintf('Set date_is_exact_not YEAR value "%s"', $value)); - $this->collector->yearIsNot($value); - $this->operators->push(['type' => 'not_date_on_year', 'value' => $value,]); - break; - case 'month': - Log::debug(sprintf('Set date_is_exact MONTH value "%s"', $value)); - $this->collector->monthIs($value); - $this->operators->push(['type' => 'date_on_month', 'value' => $value,]); - break; - case 'month_not': - Log::debug(sprintf('Set date_is_exact not MONTH value "%s"', $value)); - $this->collector->monthIsNot($value); - $this->operators->push(['type' => 'not_date_on_month', 'value' => $value,]); - break; - case 'day': - Log::debug(sprintf('Set date_is_exact DAY value "%s"', $value)); - $this->collector->dayIs($value); - $this->operators->push(['type' => 'date_on_day', 'value' => $value,]); - break; - case 'day_not': - Log::debug(sprintf('Set not date_is_exact DAY value "%s"', $value)); - $this->collector->dayIsNot($value); - $this->operators->push(['type' => 'not_date_on_day', 'value' => $value,]); - break; - } - } - } - - /** - * @throws FireflyException - */ - private function setExactMetaDateParams(string $field, array $range, bool $prohibited = false): void - { - Log::debug('Now in setExactMetaDateParams()'); - /** - * @var string $key - * @var Carbon|string $value - */ - foreach ($range as $key => $value) { - $key = $prohibited ? sprintf('%s_not', $key) : $key; - switch ($key) { - default: - throw new FireflyException(sprintf('Cannot handle key "%s" in setExactMetaDateParams()', $key)); - case 'exact': - Log::debug(sprintf('Set %s_is_exact value "%s"', $field, $value->format('Y-m-d'))); - $this->collector->setMetaDateRange($value, $value, $field); - $this->operators->push(['type' => sprintf('%s_on', $field), 'value' => $value->format('Y-m-d'),]); - break; - case 'exact_not': - Log::debug(sprintf('Set NOT %s_is_exact value "%s"', $field, $value->format('Y-m-d'))); - $this->collector->excludeMetaDateRange($value, $value, $field); - $this->operators->push(['type' => sprintf('not_%s_on', $field), 'value' => $value->format('Y-m-d'),]); - break; - case 'year': - Log::debug(sprintf('Set %s_is_exact YEAR value "%s"', $field, $value)); - $this->collector->metaYearIs($value, $field); - $this->operators->push(['type' => sprintf('%s_on_year', $field), 'value' => $value,]); - break; - case 'year_not': - Log::debug(sprintf('Set NOT %s_is_exact YEAR value "%s"', $field, $value)); - $this->collector->metaYearIsNot($value, $field); - $this->operators->push(['type' => sprintf('not_%s_on_year', $field), 'value' => $value,]); - break; - case 'month': - Log::debug(sprintf('Set %s_is_exact MONTH value "%s"', $field, $value)); - $this->collector->metaMonthIs($value, $field); - $this->operators->push(['type' => sprintf('%s_on_month', $field), 'value' => $value,]); - break; - case 'month_not': - Log::debug(sprintf('Set NOT %s_is_exact MONTH value "%s"', $field, $value)); - $this->collector->metaMonthIsNot($value, $field); - $this->operators->push(['type' => sprintf('not_%s_on_month', $field), 'value' => $value,]); - break; - case 'day': - Log::debug(sprintf('Set %s_is_exact DAY value "%s"', $field, $value)); - $this->collector->metaDayIs($value, $field); - $this->operators->push(['type' => sprintf('%s_on_day', $field), 'value' => $value,]); - break; - case 'day_not': - Log::debug(sprintf('Set NOT %s_is_exact DAY value "%s"', $field, $value)); - $this->collector->metaDayIsNot($value, $field); - $this->operators->push(['type' => sprintf('not_%s_on_day', $field), 'value' => $value,]); - break; - } - } - } - - /** - * @throws FireflyException - */ - private function setExactObjectDateParams(string $field, array $range, bool $prohibited = false): void - { - /** - * @var string $key - * @var Carbon|string $value - */ - foreach ($range as $key => $value) { - $key = $prohibited ? sprintf('%s_not', $key) : $key; - switch ($key) { - default: - throw new FireflyException(sprintf('Cannot handle key "%s" in setExactObjectDateParams()', $key)); - case 'exact': - Log::debug(sprintf('Set %s_is_exact value "%s"', $field, $value->format('Y-m-d'))); - $this->collector->setObjectRange($value, clone $value, $field); - $this->operators->push(['type' => sprintf('%s_on', $field), 'value' => $value->format('Y-m-d'),]); - break; - case 'exact_not': - Log::debug(sprintf('Set NOT %s_is_exact value "%s"', $field, $value->format('Y-m-d'))); - $this->collector->excludeObjectRange($value, clone $value, $field); - $this->operators->push(['type' => sprintf('not_%s_on', $field), 'value' => $value->format('Y-m-d'),]); - break; - case 'year': - Log::debug(sprintf('Set %s_is_exact YEAR value "%s"', $field, $value)); - $this->collector->objectYearIs($value, $field); - $this->operators->push(['type' => sprintf('%s_on_year', $field), 'value' => $value,]); - break; - case 'year_not': - Log::debug(sprintf('Set NOT %s_is_exact YEAR value "%s"', $field, $value)); - $this->collector->objectYearIsNot($value, $field); - $this->operators->push(['type' => sprintf('not_%s_on_year', $field), 'value' => $value,]); - break; - case 'month': - Log::debug(sprintf('Set %s_is_exact MONTH value "%s"', $field, $value)); - $this->collector->objectMonthIs($value, $field); - $this->operators->push(['type' => sprintf('%s_on_month', $field), 'value' => $value,]); - break; - case 'month_not': - Log::debug(sprintf('Set NOT %s_is_exact MONTH value "%s"', $field, $value)); - $this->collector->objectMonthIsNot($value, $field); - $this->operators->push(['type' => sprintf('not_%s_on_month', $field), 'value' => $value,]); - break; - case 'day': - Log::debug(sprintf('Set %s_is_exact DAY value "%s"', $field, $value)); - $this->collector->objectDayIs($value, $field); - $this->operators->push(['type' => sprintf('%s_on_day', $field), 'value' => $value,]); - break; - case 'day_not': - Log::debug(sprintf('Set NOT %s_is_exact DAY value "%s"', $field, $value)); - $this->collector->objectDayIsNot($value, $field); - $this->operators->push(['type' => sprintf('not_%s_on_day', $field), 'value' => $value,]); - break; - } - } - } - - /** - * @throws FireflyException - */ - private function setMetaDateAfterParams(string $field, array $range, bool $prohibited = false): void - { - /** - * @var string $key - * @var Carbon|string $value - */ - foreach ($range as $key => $value) { - $key = $prohibited ? sprintf('%s_not', $key) : $key; - switch ($key) { - default: - throw new FireflyException(sprintf('Cannot handle key "%s" in setMetaDateAfterParams()', $key)); - case 'exact': - $this->collector->setMetaAfter($value, $field); - $this->operators->push(['type' => sprintf('%s_after', $field), 'value' => $value->format('Y-m-d'),]); - break; - case 'year': - Log::debug(sprintf('Set %s_is_after YEAR value "%s"', $field, $value)); - $this->collector->metaYearAfter($value, $field); - $this->operators->push(['type' => sprintf('%s_after_year', $field), 'value' => $value,]); - break; - case 'month': - Log::debug(sprintf('Set %s_is_after MONTH value "%s"', $field, $value)); - $this->collector->metaMonthAfter($value, $field); - $this->operators->push(['type' => sprintf('%s_after_month', $field), 'value' => $value,]); - break; - case 'day': - Log::debug(sprintf('Set %s_is_after DAY value "%s"', $field, $value)); - $this->collector->metaDayAfter($value, $field); - $this->operators->push(['type' => sprintf('%s_after_day', $field), 'value' => $value,]); - break; - } - } - } - - /** - * @throws FireflyException - */ - private function setMetaDateBeforeParams(string $field, array $range, bool $prohibited = false): void - { - /** - * @var string $key - * @var Carbon|string $value - */ - foreach ($range as $key => $value) { - $key = $prohibited ? sprintf('%s_not', $key) : $key; - switch ($key) { - default: - throw new FireflyException(sprintf('Cannot handle key "%s" in setMetaDateBeforeParams()', $key)); - case 'exact': - $this->collector->setMetaBefore($value, $field); - $this->operators->push(['type' => sprintf('%s_before', $field), 'value' => $value->format('Y-m-d'),]); - break; - case 'year': - Log::debug(sprintf('Set %s_is_before YEAR value "%s"', $field, $value)); - $this->collector->metaYearBefore($value, $field); - $this->operators->push(['type' => sprintf('%s_before_year', $field), 'value' => $value,]); - break; - case 'month': - Log::debug(sprintf('Set %s_is_before MONTH value "%s"', $field, $value)); - $this->collector->metaMonthBefore($value, $field); - $this->operators->push(['type' => sprintf('%s_before_month', $field), 'value' => $value,]); - break; - case 'day': - Log::debug(sprintf('Set %s_is_before DAY value "%s"', $field, $value)); - $this->collector->metaDayBefore($value, $field); - $this->operators->push(['type' => sprintf('%s_before_day', $field), 'value' => $value,]); - break; - } - } - } - - /** - * - * @throws FireflyException - */ - private function setObjectDateAfterParams(string $field, array $range, bool $prohibited = false): void - { - /** - * @var string $key - * @var Carbon|string $value - */ - foreach ($range as $key => $value) { - $key = $prohibited ? sprintf('%s_not', $key) : $key; - switch ($key) { - default: - throw new FireflyException(sprintf('Cannot handle key "%s" in setObjectDateAfterParams()', $key)); - case 'exact': - $this->collector->setObjectAfter($value, $field); - $this->operators->push(['type' => sprintf('%s_after', $field), 'value' => $value->format('Y-m-d'),]); - break; - case 'year': - Log::debug(sprintf('Set date_is_after YEAR value "%s"', $value)); - $this->collector->objectYearAfter($value, $field); - $this->operators->push(['type' => sprintf('%s_after_year', $field), 'value' => $value,]); - break; - case 'month': - Log::debug(sprintf('Set date_is_after MONTH value "%s"', $value)); - $this->collector->objectMonthAfter($value, $field); - $this->operators->push(['type' => sprintf('%s_after_month', $field), 'value' => $value,]); - break; - case 'day': - Log::debug(sprintf('Set date_is_after DAY value "%s"', $value)); - $this->collector->objectDayAfter($value, $field); - $this->operators->push(['type' => sprintf('%s_after_day', $field), 'value' => $value,]); - break; - } - } - } - - /** - * - * @throws FireflyException - */ - private function setObjectDateBeforeParams(string $field, array $range, bool $prohibited = false): void - { - /** - * @var string $key - * @var Carbon|string $value - */ - foreach ($range as $key => $value) { - $key = $prohibited ? sprintf('%s_not', $key) : $key; - switch ($key) { - default: - throw new FireflyException(sprintf('Cannot handle key "%s" in setObjectDateBeforeParams()', $key)); - case 'exact': - $this->collector->setObjectBefore($value, $field); - $this->operators->push(['type' => sprintf('%s_before', $field), 'value' => $value->format('Y-m-d'),]); - break; - case 'year': - Log::debug(sprintf('Set date_is_before YEAR value "%s"', $value)); - $this->collector->objectYearBefore($value, $field); - $this->operators->push(['type' => sprintf('%s_before_year', $field), 'value' => $value,]); - break; - case 'month': - Log::debug(sprintf('Set date_is_before MONTH value "%s"', $value)); - $this->collector->objectMonthBefore($value, $field); - $this->operators->push(['type' => sprintf('%s_before_month', $field), 'value' => $value,]); - break; - case 'day': - Log::debug(sprintf('Set date_is_before DAY value "%s"', $value)); - $this->collector->objectDayBefore($value, $field); - $this->operators->push(['type' => sprintf('%s_before_day', $field), 'value' => $value,]); - break; - } - } - } - /** * * @throws FireflyException @@ -2034,4 +1316,722 @@ class OperatorQuerySearch implements SearchInterface } return true; } + + /** + * @param string $operator + * + * @return string + * @throws FireflyException + */ + public static function getRootOperator(string $operator): string + { + $original = $operator; + // if the string starts with "-" (not), we can remove it and recycle + // the configuration from the original operator. + if (str_starts_with($operator, '-')) { + $operator = substr($operator, 1); + } + + $config = config(sprintf('search.operators.%s', $operator)); + if (null === $config) { + throw new FireflyException(sprintf('No configuration for search operator "%s"', $operator)); + } + if (true === $config['alias']) { + $return = $config['alias_for']; + if (str_starts_with($original, '-')) { + $return = sprintf('-%s', $config['alias_for']); + } + Log::debug(sprintf('"%s" is an alias for "%s", so return that instead.', $original, $return)); + + return $return; + } + Log::debug(sprintf('"%s" is not an alias.', $operator)); + + return $original; + } + + /** + * searchDirection: 1 = source (default), 2 = destination, 3 = both + * stringPosition: 1 = start (default), 2 = end, 3 = contains, 4 = is + * + * @param string $value + * @param int $searchDirection + * @param int $stringPosition + * @param bool $prohibited + */ + private function searchAccount(string $value, int $searchDirection, int $stringPosition, bool $prohibited = false): void + { + Log::debug(sprintf('searchAccount("%s", %d, %d)', $value, $stringPosition, $searchDirection)); + + // search direction (default): for source accounts + $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::REVENUE]; + $collectorMethod = 'setSourceAccounts'; + if ($prohibited) { + $collectorMethod = 'excludeSourceAccounts'; + } + + // search direction: for destination accounts + if (2 === $searchDirection) { + // destination can be + $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE]; + $collectorMethod = 'setDestinationAccounts'; + if ($prohibited) { + $collectorMethod = 'excludeDestinationAccounts'; + } + } + // either account could be: + if (3 === $searchDirection) { + $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE, AccountType::REVENUE]; + $collectorMethod = 'setAccounts'; + if ($prohibited) { + $collectorMethod = 'excludeAccounts'; + } + } + // string position (default): starts with: + $stringMethod = 'str_starts_with'; + + // string position: ends with: + if (2 === $stringPosition) { + $stringMethod = 'str_ends_with'; + } + if (3 === $stringPosition) { + $stringMethod = 'str_contains'; + } + if (4 === $stringPosition) { + $stringMethod = 'stringIsEqual'; + } + + // get accounts: + $accounts = $this->accountRepository->searchAccount($value, $searchTypes, 1337); + if (0 === $accounts->count()) { + Log::debug('Found zero accounts, search for non existing account, NO results will be returned.'); + $this->collector->findNothing(); + + return; + } + Log::debug(sprintf('Found %d accounts, will filter.', $accounts->count())); + $filtered = $accounts->filter( + function (Account $account) use ($value, $stringMethod) { + return $stringMethod(strtolower($account->name), strtolower($value)); + } + ); + + if (0 === $filtered->count()) { + Log::debug('Left with zero accounts, so cannot find anything, NO results will be returned.'); + $this->collector->findNothing(); + + return; + } + Log::debug(sprintf('Left with %d, set as %s().', $filtered->count(), $collectorMethod)); + $this->collector->$collectorMethod($filtered); + } + + /** + * searchDirection: 1 = source (default), 2 = destination, 3 = both + * stringPosition: 1 = start (default), 2 = end, 3 = contains, 4 = is + * + * @param string $value + * @param int $searchDirection + * @param int $stringPosition + * @param bool $prohibited + */ + private function searchAccountNr(string $value, int $searchDirection, int $stringPosition, bool $prohibited = false): void + { + Log::debug(sprintf('searchAccountNr(%s, %d, %d)', $value, $searchDirection, $stringPosition)); + + // search direction (default): for source accounts + $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::REVENUE]; + $collectorMethod = 'setSourceAccounts'; + if (true === $prohibited) { + $collectorMethod = 'excludeSourceAccounts'; + } + + // search direction: for destination accounts + if (2 === $searchDirection) { + // destination can be + $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE]; + $collectorMethod = 'setDestinationAccounts'; + if (true === $prohibited) { + $collectorMethod = 'excludeDestinationAccounts'; + } + } + + // either account could be: + if (3 === $searchDirection) { + $searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE, AccountType::REVENUE]; + $collectorMethod = 'setAccounts'; + if (true === $prohibited) { + $collectorMethod = 'excludeAccounts'; + } + } + + // string position (default): starts with: + $stringMethod = 'str_starts_with'; + + // string position: ends with: + if (2 === $stringPosition) { + $stringMethod = 'str_ends_with'; + } + if (3 === $stringPosition) { + $stringMethod = 'str_contains'; + } + if (4 === $stringPosition) { + $stringMethod = 'stringIsEqual'; + } + + // search for accounts: + $accounts = $this->accountRepository->searchAccountNr($value, $searchTypes, 1337); + if (0 === $accounts->count()) { + Log::debug('Found zero accounts, search for invalid account.'); + $this->collector->findNothing(); + + return; + } + + // if found, do filter + Log::debug(sprintf('Found %d accounts, will filter.', $accounts->count())); + $filtered = $accounts->filter( + function (Account $account) use ($value, $stringMethod) { + // either IBAN or account number + $ibanMatch = $stringMethod(strtolower((string)$account->iban), strtolower((string)$value)); + $accountNrMatch = false; + /** @var AccountMeta $meta */ + foreach ($account->accountMeta as $meta) { + if ('account_number' === $meta->name && $stringMethod(strtolower($meta->data), strtolower($value))) { + $accountNrMatch = true; + } + } + + return $ibanMatch || $accountNrMatch; + } + ); + + if (0 === $filtered->count()) { + Log::debug('Left with zero, search for invalid account'); + $this->collector->findNothing(); + + return; + } + Log::debug(sprintf('Left with %d, set as %s().', $filtered->count(), $collectorMethod)); + $this->collector->$collectorMethod($filtered); + } + + /** + * @return Account + */ + private function getCashAccount(): Account + { + return $this->accountRepository->getCashAccount(); + } + + /** + * @param string $value + * + * @return TransactionCurrency|null + */ + private function findCurrency(string $value): ?TransactionCurrency + { + if (str_contains($value, '(') && str_contains($value, ')')) { + // bad method to split and get the currency code: + $parts = explode(' ', $value); + $value = trim($parts[count($parts) - 1], "() \t\n\r\0\x0B"); + } + $result = $this->currencyRepository->findByCodeNull($value); + if (null === $result) { + $result = $this->currencyRepository->findByNameNull($value); + } + + return $result; + } + + /** + * @param string $value + * + * @return array + * @throws FireflyException + */ + private function parseDateRange(string $value): array + { + $parser = new ParseDateString(); + if ($parser->isDateRange($value)) { + return $parser->parseRange($value); + } + $parsedDate = $parser->parseDate($value); + + return [ + 'exact' => $parsedDate, + ]; + } + + /** + * + * @throws FireflyException + */ + private function setExactDateParams(array $range, bool $prohibited = false): void + { + /** + * @var string $key + * @var Carbon|string $value + */ + foreach ($range as $key => $value) { + $key = $prohibited ? sprintf('%s_not', $key) : $key; + switch ($key) { + default: + throw new FireflyException(sprintf('Cannot handle key "%s" in setExactParameters()', $key)); + case 'exact': + Log::debug(sprintf('Set date_is_exact value "%s"', $value->format('Y-m-d'))); + $this->collector->setRange($value, $value); + $this->operators->push(['type' => 'date_on', 'value' => $value->format('Y-m-d'),]); + break; + case 'exact_not': + $this->collector->excludeRange($value, $value); + $this->operators->push(['type' => 'not_date_on', 'value' => $value->format('Y-m-d'),]); + break; + case 'year': + Log::debug(sprintf('Set date_is_exact YEAR value "%s"', $value)); + $this->collector->yearIs($value); + $this->operators->push(['type' => 'date_on_year', 'value' => $value,]); + break; + case 'year_not': + Log::debug(sprintf('Set date_is_exact_not YEAR value "%s"', $value)); + $this->collector->yearIsNot($value); + $this->operators->push(['type' => 'not_date_on_year', 'value' => $value,]); + break; + case 'month': + Log::debug(sprintf('Set date_is_exact MONTH value "%s"', $value)); + $this->collector->monthIs($value); + $this->operators->push(['type' => 'date_on_month', 'value' => $value,]); + break; + case 'month_not': + Log::debug(sprintf('Set date_is_exact not MONTH value "%s"', $value)); + $this->collector->monthIsNot($value); + $this->operators->push(['type' => 'not_date_on_month', 'value' => $value,]); + break; + case 'day': + Log::debug(sprintf('Set date_is_exact DAY value "%s"', $value)); + $this->collector->dayIs($value); + $this->operators->push(['type' => 'date_on_day', 'value' => $value,]); + break; + case 'day_not': + Log::debug(sprintf('Set not date_is_exact DAY value "%s"', $value)); + $this->collector->dayIsNot($value); + $this->operators->push(['type' => 'not_date_on_day', 'value' => $value,]); + break; + } + } + } + + /** + * + * @throws FireflyException + */ + private function setDateBeforeParams(array $range, bool $prohibited = false): void + { + /** + * @var string $key + * @var Carbon|string $value + */ + foreach ($range as $key => $value) { + $key = $prohibited ? sprintf('%s_not', $key) : $key; + switch ($key) { + default: + throw new FireflyException(sprintf('Cannot handle key "%s" in setDateBeforeParams()', $key)); + case 'exact': + $this->collector->setBefore($value); + $this->operators->push(['type' => 'date_before', 'value' => $value->format('Y-m-d'),]); + break; + case 'year': + Log::debug(sprintf('Set date_is_before YEAR value "%s"', $value)); + $this->collector->yearBefore($value); + $this->operators->push(['type' => 'date_before_year', 'value' => $value,]); + break; + case 'month': + Log::debug(sprintf('Set date_is_before MONTH value "%s"', $value)); + $this->collector->monthBefore($value); + $this->operators->push(['type' => 'date_before_month', 'value' => $value,]); + break; + case 'day': + Log::debug(sprintf('Set date_is_before DAY value "%s"', $value)); + $this->collector->dayBefore($value); + $this->operators->push(['type' => 'date_before_day', 'value' => $value,]); + break; + } + } + } + + /** + * + * @throws FireflyException + */ + private function setDateAfterParams(array $range, bool $prohibited = false) + { + /** + * @var string $key + * @var Carbon|string $value + */ + foreach ($range as $key => $value) { + $key = $prohibited ? sprintf('%s_not', $key) : $key; + switch ($key) { + default: + throw new FireflyException(sprintf('Cannot handle key "%s" in setDateAfterParams()', $key)); + case 'exact': + $this->collector->setAfter($value); + $this->operators->push(['type' => 'date_after', 'value' => $value->format('Y-m-d'),]); + break; + case 'year': + Log::debug(sprintf('Set date_is_after YEAR value "%s"', $value)); + $this->collector->yearAfter($value); + $this->operators->push(['type' => 'date_after_year', 'value' => $value,]); + break; + case 'month': + Log::debug(sprintf('Set date_is_after MONTH value "%s"', $value)); + $this->collector->monthAfter($value); + $this->operators->push(['type' => 'date_after_month', 'value' => $value,]); + break; + case 'day': + Log::debug(sprintf('Set date_is_after DAY value "%s"', $value)); + $this->collector->dayAfter($value); + $this->operators->push(['type' => 'date_after_day', 'value' => $value,]); + break; + } + } + } + + /** + * @throws FireflyException + */ + private function setExactMetaDateParams(string $field, array $range, bool $prohibited = false): void + { + Log::debug('Now in setExactMetaDateParams()'); + /** + * @var string $key + * @var Carbon|string $value + */ + foreach ($range as $key => $value) { + $key = $prohibited ? sprintf('%s_not', $key) : $key; + switch ($key) { + default: + throw new FireflyException(sprintf('Cannot handle key "%s" in setExactMetaDateParams()', $key)); + case 'exact': + Log::debug(sprintf('Set %s_is_exact value "%s"', $field, $value->format('Y-m-d'))); + $this->collector->setMetaDateRange($value, $value, $field); + $this->operators->push(['type' => sprintf('%s_on', $field), 'value' => $value->format('Y-m-d'),]); + break; + case 'exact_not': + Log::debug(sprintf('Set NOT %s_is_exact value "%s"', $field, $value->format('Y-m-d'))); + $this->collector->excludeMetaDateRange($value, $value, $field); + $this->operators->push(['type' => sprintf('not_%s_on', $field), 'value' => $value->format('Y-m-d'),]); + break; + case 'year': + Log::debug(sprintf('Set %s_is_exact YEAR value "%s"', $field, $value)); + $this->collector->metaYearIs($value, $field); + $this->operators->push(['type' => sprintf('%s_on_year', $field), 'value' => $value,]); + break; + case 'year_not': + Log::debug(sprintf('Set NOT %s_is_exact YEAR value "%s"', $field, $value)); + $this->collector->metaYearIsNot($value, $field); + $this->operators->push(['type' => sprintf('not_%s_on_year', $field), 'value' => $value,]); + break; + case 'month': + Log::debug(sprintf('Set %s_is_exact MONTH value "%s"', $field, $value)); + $this->collector->metaMonthIs($value, $field); + $this->operators->push(['type' => sprintf('%s_on_month', $field), 'value' => $value,]); + break; + case 'month_not': + Log::debug(sprintf('Set NOT %s_is_exact MONTH value "%s"', $field, $value)); + $this->collector->metaMonthIsNot($value, $field); + $this->operators->push(['type' => sprintf('not_%s_on_month', $field), 'value' => $value,]); + break; + case 'day': + Log::debug(sprintf('Set %s_is_exact DAY value "%s"', $field, $value)); + $this->collector->metaDayIs($value, $field); + $this->operators->push(['type' => sprintf('%s_on_day', $field), 'value' => $value,]); + break; + case 'day_not': + Log::debug(sprintf('Set NOT %s_is_exact DAY value "%s"', $field, $value)); + $this->collector->metaDayIsNot($value, $field); + $this->operators->push(['type' => sprintf('not_%s_on_day', $field), 'value' => $value,]); + break; + } + } + } + + /** + * @throws FireflyException + */ + private function setMetaDateBeforeParams(string $field, array $range, bool $prohibited = false): void + { + /** + * @var string $key + * @var Carbon|string $value + */ + foreach ($range as $key => $value) { + $key = $prohibited ? sprintf('%s_not', $key) : $key; + switch ($key) { + default: + throw new FireflyException(sprintf('Cannot handle key "%s" in setMetaDateBeforeParams()', $key)); + case 'exact': + $this->collector->setMetaBefore($value, $field); + $this->operators->push(['type' => sprintf('%s_before', $field), 'value' => $value->format('Y-m-d'),]); + break; + case 'year': + Log::debug(sprintf('Set %s_is_before YEAR value "%s"', $field, $value)); + $this->collector->metaYearBefore($value, $field); + $this->operators->push(['type' => sprintf('%s_before_year', $field), 'value' => $value,]); + break; + case 'month': + Log::debug(sprintf('Set %s_is_before MONTH value "%s"', $field, $value)); + $this->collector->metaMonthBefore($value, $field); + $this->operators->push(['type' => sprintf('%s_before_month', $field), 'value' => $value,]); + break; + case 'day': + Log::debug(sprintf('Set %s_is_before DAY value "%s"', $field, $value)); + $this->collector->metaDayBefore($value, $field); + $this->operators->push(['type' => sprintf('%s_before_day', $field), 'value' => $value,]); + break; + } + } + } + + /** + * @throws FireflyException + */ + private function setMetaDateAfterParams(string $field, array $range, bool $prohibited = false): void + { + /** + * @var string $key + * @var Carbon|string $value + */ + foreach ($range as $key => $value) { + $key = $prohibited ? sprintf('%s_not', $key) : $key; + switch ($key) { + default: + throw new FireflyException(sprintf('Cannot handle key "%s" in setMetaDateAfterParams()', $key)); + case 'exact': + $this->collector->setMetaAfter($value, $field); + $this->operators->push(['type' => sprintf('%s_after', $field), 'value' => $value->format('Y-m-d'),]); + break; + case 'year': + Log::debug(sprintf('Set %s_is_after YEAR value "%s"', $field, $value)); + $this->collector->metaYearAfter($value, $field); + $this->operators->push(['type' => sprintf('%s_after_year', $field), 'value' => $value,]); + break; + case 'month': + Log::debug(sprintf('Set %s_is_after MONTH value "%s"', $field, $value)); + $this->collector->metaMonthAfter($value, $field); + $this->operators->push(['type' => sprintf('%s_after_month', $field), 'value' => $value,]); + break; + case 'day': + Log::debug(sprintf('Set %s_is_after DAY value "%s"', $field, $value)); + $this->collector->metaDayAfter($value, $field); + $this->operators->push(['type' => sprintf('%s_after_day', $field), 'value' => $value,]); + break; + } + } + } + + /** + * @throws FireflyException + */ + private function setExactObjectDateParams(string $field, array $range, bool $prohibited = false): void + { + /** + * @var string $key + * @var Carbon|string $value + */ + foreach ($range as $key => $value) { + $key = $prohibited ? sprintf('%s_not', $key) : $key; + switch ($key) { + default: + throw new FireflyException(sprintf('Cannot handle key "%s" in setExactObjectDateParams()', $key)); + case 'exact': + Log::debug(sprintf('Set %s_is_exact value "%s"', $field, $value->format('Y-m-d'))); + $this->collector->setObjectRange($value, clone $value, $field); + $this->operators->push(['type' => sprintf('%s_on', $field), 'value' => $value->format('Y-m-d'),]); + break; + case 'exact_not': + Log::debug(sprintf('Set NOT %s_is_exact value "%s"', $field, $value->format('Y-m-d'))); + $this->collector->excludeObjectRange($value, clone $value, $field); + $this->operators->push(['type' => sprintf('not_%s_on', $field), 'value' => $value->format('Y-m-d'),]); + break; + case 'year': + Log::debug(sprintf('Set %s_is_exact YEAR value "%s"', $field, $value)); + $this->collector->objectYearIs($value, $field); + $this->operators->push(['type' => sprintf('%s_on_year', $field), 'value' => $value,]); + break; + case 'year_not': + Log::debug(sprintf('Set NOT %s_is_exact YEAR value "%s"', $field, $value)); + $this->collector->objectYearIsNot($value, $field); + $this->operators->push(['type' => sprintf('not_%s_on_year', $field), 'value' => $value,]); + break; + case 'month': + Log::debug(sprintf('Set %s_is_exact MONTH value "%s"', $field, $value)); + $this->collector->objectMonthIs($value, $field); + $this->operators->push(['type' => sprintf('%s_on_month', $field), 'value' => $value,]); + break; + case 'month_not': + Log::debug(sprintf('Set NOT %s_is_exact MONTH value "%s"', $field, $value)); + $this->collector->objectMonthIsNot($value, $field); + $this->operators->push(['type' => sprintf('not_%s_on_month', $field), 'value' => $value,]); + break; + case 'day': + Log::debug(sprintf('Set %s_is_exact DAY value "%s"', $field, $value)); + $this->collector->objectDayIs($value, $field); + $this->operators->push(['type' => sprintf('%s_on_day', $field), 'value' => $value,]); + break; + case 'day_not': + Log::debug(sprintf('Set NOT %s_is_exact DAY value "%s"', $field, $value)); + $this->collector->objectDayIsNot($value, $field); + $this->operators->push(['type' => sprintf('not_%s_on_day', $field), 'value' => $value,]); + break; + } + } + } + + /** + * + * @throws FireflyException + */ + private function setObjectDateBeforeParams(string $field, array $range, bool $prohibited = false): void + { + /** + * @var string $key + * @var Carbon|string $value + */ + foreach ($range as $key => $value) { + $key = $prohibited ? sprintf('%s_not', $key) : $key; + switch ($key) { + default: + throw new FireflyException(sprintf('Cannot handle key "%s" in setObjectDateBeforeParams()', $key)); + case 'exact': + $this->collector->setObjectBefore($value, $field); + $this->operators->push(['type' => sprintf('%s_before', $field), 'value' => $value->format('Y-m-d'),]); + break; + case 'year': + Log::debug(sprintf('Set date_is_before YEAR value "%s"', $value)); + $this->collector->objectYearBefore($value, $field); + $this->operators->push(['type' => sprintf('%s_before_year', $field), 'value' => $value,]); + break; + case 'month': + Log::debug(sprintf('Set date_is_before MONTH value "%s"', $value)); + $this->collector->objectMonthBefore($value, $field); + $this->operators->push(['type' => sprintf('%s_before_month', $field), 'value' => $value,]); + break; + case 'day': + Log::debug(sprintf('Set date_is_before DAY value "%s"', $value)); + $this->collector->objectDayBefore($value, $field); + $this->operators->push(['type' => sprintf('%s_before_day', $field), 'value' => $value,]); + break; + } + } + } + + /** + * + * @throws FireflyException + */ + private function setObjectDateAfterParams(string $field, array $range, bool $prohibited = false): void + { + /** + * @var string $key + * @var Carbon|string $value + */ + foreach ($range as $key => $value) { + $key = $prohibited ? sprintf('%s_not', $key) : $key; + switch ($key) { + default: + throw new FireflyException(sprintf('Cannot handle key "%s" in setObjectDateAfterParams()', $key)); + case 'exact': + $this->collector->setObjectAfter($value, $field); + $this->operators->push(['type' => sprintf('%s_after', $field), 'value' => $value->format('Y-m-d'),]); + break; + case 'year': + Log::debug(sprintf('Set date_is_after YEAR value "%s"', $value)); + $this->collector->objectYearAfter($value, $field); + $this->operators->push(['type' => sprintf('%s_after_year', $field), 'value' => $value,]); + break; + case 'month': + Log::debug(sprintf('Set date_is_after MONTH value "%s"', $value)); + $this->collector->objectMonthAfter($value, $field); + $this->operators->push(['type' => sprintf('%s_after_month', $field), 'value' => $value,]); + break; + case 'day': + Log::debug(sprintf('Set date_is_after DAY value "%s"', $value)); + $this->collector->objectDayAfter($value, $field); + $this->operators->push(['type' => sprintf('%s_after_day', $field), 'value' => $value,]); + break; + } + } + } + + /** + * @inheritDoc + */ + public function searchTime(): float + { + return microtime(true) - $this->startTime; + } + + /** + * @inheritDoc + */ + public function searchTransactions(): LengthAwarePaginator + { + if (0 === count($this->getWords()) && 0 === count($this->getOperators())) { + return new LengthAwarePaginator([], 0, 5, 1); + } + + return $this->collector->getPaginatedGroups(); + } + + /** + * @return array + */ + public function getWords(): array + { + return $this->words; + } + + /** + * @param Carbon $date + */ + public function setDate(Carbon $date): void + { + $this->date = $date; + } + + /** + * @inheritDoc + */ + public function setPage(int $page): void + { + $this->page = $page; + $this->collector->setPage($this->page); + } + + /** + * @inheritDoc + */ + public function setUser(User $user): void + { + $this->accountRepository->setUser($user); + $this->billRepository->setUser($user); + $this->categoryRepository->setUser($user); + $this->budgetRepository->setUser($user); + $this->tagRepository->setUser($user); + $this->collector = app(GroupCollectorInterface::class); + $this->collector->setUser($user); + $this->collector->withAccountInformation()->withCategoryInformation()->withBudgetInformation(); + + $this->setLimit((int)app('preferences')->getForUser($user, 'listPageSize', 50)->data); + } + + /** + * @param int $limit + */ + public function setLimit(int $limit): void + { + $this->limit = $limit; + $this->collector->setLimit($this->limit); + } } diff --git a/app/Support/Search/SearchInterface.php b/app/Support/Search/SearchInterface.php index 97bca2720b..100168f36e 100644 --- a/app/Support/Search/SearchInterface.php +++ b/app/Support/Search/SearchInterface.php @@ -59,7 +59,7 @@ interface SearchInterface public function hasModifiers(): bool; /** - * @param string $query + * @param string $query */ public function parseQuery(string $query); @@ -74,22 +74,22 @@ interface SearchInterface public function searchTransactions(): LengthAwarePaginator; /** - * @param Carbon $date + * @param Carbon $date */ public function setDate(Carbon $date): void; /** - * @param int $limit + * @param int $limit */ public function setLimit(int $limit): void; /** - * @param int $page + * @param int $page */ public function setPage(int $page): void; /** - * @param User $user + * @param User $user */ public function setUser(User $user); } diff --git a/app/Support/Steam.php b/app/Support/Steam.php index 552b80bcc6..49fe659146 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -48,58 +48,8 @@ use ValueError; class Steam { /** - * Gets balance at the end of current month by default - * - * @param Account $account - * @param Carbon $date - * @param TransactionCurrency|null $currency - * - * @return string - * @throws FireflyException - */ - public function balance(Account $account, Carbon $date, ?TransactionCurrency $currency = null): string - { - // abuse chart properties: - $cache = new CacheProperties(); - $cache->addProperty($account->id); - $cache->addProperty('balance'); - $cache->addProperty($date); - $cache->addProperty($currency ? $currency->id : 0); - if ($cache->has()) { - return $cache->get(); - } - /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class); - if (null === $currency) { - $currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user); - } - // first part: get all balances in own currency: - $transactions = $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) - ->where('transactions.transaction_currency_id', $currency->id) - ->get(['transactions.amount'])->toArray(); - $nativeBalance = $this->sumTransactions($transactions, 'amount'); - // get all balances in foreign currency: - $transactions = $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) - ->where('transactions.foreign_currency_id', $currency->id) - ->where('transactions.transaction_currency_id', '!=', $currency->id) - ->get(['transactions.foreign_amount'])->toArray(); - $foreignBalance = $this->sumTransactions($transactions, 'foreign_amount'); - $balance = bcadd($nativeBalance, $foreignBalance); - $virtual = null === $account->virtual_balance ? '0' : (string)$account->virtual_balance; - $balance = bcadd($balance, $virtual); - - $cache->store($balance); - - return $balance; - } - - /** - * @param Account $account - * @param Carbon $date + * @param Account $account + * @param Carbon $date * * @return string */ @@ -129,15 +79,34 @@ class Steam return bcadd($nativeBalance, $foreignBalance); } + /** + * @param array $transactions + * @param string $key + * + * @return string + */ + public function sumTransactions(array $transactions, string $key): string + { + $sum = '0'; + /** @var array $transaction */ + foreach ($transactions as $transaction) { + $value = (string)($transaction[$key] ?? '0'); + $value = '' === $value ? '0' : $value; + $sum = bcadd($sum, $value); + } + + return $sum; + } + /** * Gets the balance for the given account during the whole range, using this format:. * * [yyyy-mm-dd] => 123,2 * - * @param Account $account - * @param Carbon $start - * @param Carbon $end - * @param TransactionCurrency|null $currency + * @param Account $account + * @param Carbon $start + * @param Carbon $end + * @param TransactionCurrency|null $currency * * @return array * @throws FireflyException @@ -220,41 +189,60 @@ class Steam } /** - * @param Account $account - * @param Carbon $date + * Gets balance at the end of current month by default * - * @return array + * @param Account $account + * @param Carbon $date + * @param TransactionCurrency|null $currency + * + * @return string + * @throws FireflyException */ - public function balancePerCurrency(Account $account, Carbon $date): array + public function balance(Account $account, Carbon $date, ?TransactionCurrency $currency = null): string { // abuse chart properties: $cache = new CacheProperties(); $cache->addProperty($account->id); - $cache->addProperty('balance-per-currency'); + $cache->addProperty('balance'); $cache->addProperty($date); + $cache->addProperty($currency ? $currency->id : 0); if ($cache->has()) { return $cache->get(); } - $query = $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) - ->groupBy('transactions.transaction_currency_id'); - $balances = $query->get(['transactions.transaction_currency_id', DB::raw('SUM(transactions.amount) as sum_for_currency')]); - $return = []; - /** @var stdClass $entry */ - foreach ($balances as $entry) { - $return[(int)$entry->transaction_currency_id] = (string)$entry->sum_for_currency; + /** @var AccountRepositoryInterface $repository */ + $repository = app(AccountRepositoryInterface::class); + if (null === $currency) { + $currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user); } - $cache->store($return); + // first part: get all balances in own currency: + $transactions = $account->transactions() + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) + ->where('transactions.transaction_currency_id', $currency->id) + ->get(['transactions.amount'])->toArray(); + $nativeBalance = $this->sumTransactions($transactions, 'amount'); + // get all balances in foreign currency: + $transactions = $account->transactions() + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) + ->where('transactions.foreign_currency_id', $currency->id) + ->where('transactions.transaction_currency_id', '!=', $currency->id) + ->get(['transactions.foreign_amount'])->toArray(); + $foreignBalance = $this->sumTransactions($transactions, 'foreign_amount'); + $balance = bcadd($nativeBalance, $foreignBalance); + $virtual = null === $account->virtual_balance ? '0' : (string)$account->virtual_balance; + $balance = bcadd($balance, $virtual); - return $return; + $cache->store($balance); + + return $balance; } /** * This method always ignores the virtual balance. * - * @param Collection $accounts - * @param Carbon $date + * @param Collection $accounts + * @param Carbon $date * * @return array * @throws FireflyException @@ -286,8 +274,8 @@ class Steam /** * Same as above, but also groups per currency. * - * @param Collection $accounts - * @param Carbon $date + * @param Collection $accounts + * @param Carbon $date * * @return array */ @@ -315,11 +303,42 @@ class Steam return $result; } + /** + * @param Account $account + * @param Carbon $date + * + * @return array + */ + public function balancePerCurrency(Account $account, Carbon $date): array + { + // abuse chart properties: + $cache = new CacheProperties(); + $cache->addProperty($account->id); + $cache->addProperty('balance-per-currency'); + $cache->addProperty($date); + if ($cache->has()) { + return $cache->get(); + } + $query = $account->transactions() + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) + ->groupBy('transactions.transaction_currency_id'); + $balances = $query->get(['transactions.transaction_currency_id', DB::raw('SUM(transactions.amount) as sum_for_currency')]); + $return = []; + /** @var stdClass $entry */ + foreach ($balances as $entry) { + $return[(int)$entry->transaction_currency_id] = (string)$entry->sum_for_currency; + } + $cache->store($return); + + return $return; + } + /** * https://stackoverflow.com/questions/1642614/how-to-ceil-floor-and-round-bcmath-numbers * - * @param null|string $number - * @param int $precision + * @param null|string $number + * @param int $precision * @return string */ public function bcround(?string $number, int $precision = 0): string @@ -338,17 +357,17 @@ class Steam // Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision)); if (str_contains($number, '.')) { if ($number[0] !== '-') { - return bcadd($number, '0.'.str_repeat('0', $precision).'5', $precision); + return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision); } - return bcsub($number, '0.'.str_repeat('0', $precision).'5', $precision); + return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision); } return $number; } /** - * @param string $string + * @param string $string * * @return string */ @@ -410,37 +429,7 @@ class Steam } /** - * https://framework.zend.com/downloads/archives - * - * Convert a scientific notation to float - * Additionally fixed a problem with PHP <= 5.2.x with big integers - * - * @param string $value - * @return string - */ - public function floatalize(string $value): string - { - $value = strtoupper($value); - if (!str_contains($value, 'E')) { - return $value; - } - - $number = substr($value, 0, strpos($value, 'E')); - if (str_contains($number, '.')) { - $post = strlen(substr($number, strpos($number, '.') + 1)); - $mantis = substr($value, strpos($value, 'E') + 1); - if ($mantis < 0) { - $post += abs((int)$mantis); - } - // TODO careless float could break financial math. - return number_format((float)$value, $post, '.', ''); - } - // TODO careless float could break financial math. - return number_format((float)$value, 0, '.', ''); - } - - /** - * @param string $ipAddress + * @param string $ipAddress * @return string * @throws FireflyException */ @@ -455,24 +444,7 @@ class Steam } /** - * Get user's language. - * - * @return string - * @throws FireflyException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - public function getLanguage(): string // get preference - { - $preference = app('preferences')->get('language', config('firefly.default_language', 'en_US'))->data; - if (!is_string($preference)) { - throw new FireflyException(sprintf('Preference "language" must be a string, but is unexpectedly a "%s".', gettype($preference))); - } - return $preference; - } - - /** - * @param array $accounts + * @param array $accounts * * @return array */ @@ -518,7 +490,24 @@ class Steam } /** - * @param string $locale + * Get user's language. + * + * @return string + * @throws FireflyException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function getLanguage(): string // get preference + { + $preference = app('preferences')->get('language', config('firefly.default_language', 'en_US'))->data; + if (!is_string($preference)) { + throw new FireflyException(sprintf('Preference "language" must be a string, but is unexpectedly a "%s".', gettype($preference))); + } + return $preference; + } + + /** + * @param string $locale * * @return array */ @@ -551,8 +540,8 @@ class Steam /** * Make sure URL is safe. * - * @param string $unknownUrl - * @param string $safeUrl + * @param string $unknownUrl + * @param string $safeUrl * * @return string */ @@ -577,7 +566,7 @@ class Steam } /** - * @param string $amount + * @param string $amount * * @return string */ @@ -596,7 +585,37 @@ class Steam } /** - * @param string|null $amount + * https://framework.zend.com/downloads/archives + * + * Convert a scientific notation to float + * Additionally fixed a problem with PHP <= 5.2.x with big integers + * + * @param string $value + * @return string + */ + public function floatalize(string $value): string + { + $value = strtoupper($value); + if (!str_contains($value, 'E')) { + return $value; + } + + $number = substr($value, 0, strpos($value, 'E')); + if (str_contains($number, '.')) { + $post = strlen(substr($number, strpos($number, '.') + 1)); + $mantis = substr($value, strpos($value, 'E') + 1); + if ($mantis < 0) { + $post += abs((int)$mantis); + } + // TODO careless float could break financial math. + return number_format((float)$value, $post, '.', ''); + } + // TODO careless float could break financial math. + return number_format((float)$value, 0, '.', ''); + } + + /** + * @param string|null $amount * * @return string|null */ @@ -610,7 +629,7 @@ class Steam } /** - * @param string $string + * @param string $string * * @return int */ @@ -643,7 +662,7 @@ class Steam } /** - * @param string $amount + * @param string $amount * * @return string */ @@ -664,23 +683,4 @@ class Steam return $amount; } - - /** - * @param array $transactions - * @param string $key - * - * @return string - */ - public function sumTransactions(array $transactions, string $key): string - { - $sum = '0'; - /** @var array $transaction */ - foreach ($transactions as $transaction) { - $value = (string)($transaction[$key] ?? '0'); - $value = '' === $value ? '0' : $value; - $sum = bcadd($sum, $value); - } - - return $sum; - } } diff --git a/app/Support/System/OAuthKeys.php b/app/Support/System/OAuthKeys.php index 72c8006a6f..8a59ebf739 100644 --- a/app/Support/System/OAuthKeys.php +++ b/app/Support/System/OAuthKeys.php @@ -44,21 +44,22 @@ class OAuthKeys /** * */ - public static function generateKeys(): void + public static function verifyKeysRoutine(): void { - Artisan::registerCommand(new KeysCommand()); - Artisan::call('passport:keys'); - } + if (!self::keysInDatabase() && !self::hasKeyFiles()) { + self::generateKeys(); + self::storeKeysInDB(); - /** - * @return bool - */ - public static function hasKeyFiles(): bool - { - $private = storage_path('oauth-private.key'); - $public = storage_path('oauth-public.key'); + return; + } + if (self::keysInDatabase() && !self::hasKeyFiles()) { + self::restoreKeysFromDB(); - return file_exists($private) && file_exists($public); + return; + } + if (!self::keysInDatabase() && self::hasKeyFiles()) { + self::storeKeysInDB(); + } } /** @@ -73,7 +74,7 @@ class OAuthKeys try { $privateKey = (string)app('fireflyconfig')->get(self::PRIVATE_KEY)?->data; $publicKey = (string)app('fireflyconfig')->get(self::PUBLIC_KEY)?->data; - } catch (ContainerExceptionInterface|NotFoundExceptionInterface|FireflyException $e) { + } catch (ContainerExceptionInterface | NotFoundExceptionInterface | FireflyException $e) { Log::error(sprintf('Could not validate keysInDatabase(): %s', $e->getMessage())); Log::error($e->getTraceAsString()); } @@ -85,6 +86,37 @@ class OAuthKeys return false; } + /** + * @return bool + */ + public static function hasKeyFiles(): bool + { + $private = storage_path('oauth-private.key'); + $public = storage_path('oauth-public.key'); + + return file_exists($private) && file_exists($public); + } + + /** + * + */ + public static function generateKeys(): void + { + Artisan::registerCommand(new KeysCommand()); + Artisan::call('passport:keys'); + } + + /** + * + */ + public static function storeKeysInDB(): void + { + $private = storage_path('oauth-private.key'); + $public = storage_path('oauth-public.key'); + app('fireflyconfig')->set(self::PRIVATE_KEY, Crypt::encrypt(file_get_contents($private))); + app('fireflyconfig')->set(self::PUBLIC_KEY, Crypt::encrypt(file_get_contents($public))); + } + /** * @return bool * @throws ContainerExceptionInterface @@ -114,36 +146,4 @@ class OAuthKeys file_put_contents($public, $publicContent); return true; } - - /** - * - */ - public static function storeKeysInDB(): void - { - $private = storage_path('oauth-private.key'); - $public = storage_path('oauth-public.key'); - app('fireflyconfig')->set(self::PRIVATE_KEY, Crypt::encrypt(file_get_contents($private))); - app('fireflyconfig')->set(self::PUBLIC_KEY, Crypt::encrypt(file_get_contents($public))); - } - - /** - * - */ - public static function verifyKeysRoutine(): void - { - if (!self::keysInDatabase() && !self::hasKeyFiles()) { - self::generateKeys(); - self::storeKeysInDB(); - - return; - } - if (self::keysInDatabase() && !self::hasKeyFiles()) { - self::restoreKeysFromDB(); - - return; - } - if (!self::keysInDatabase() && self::hasKeyFiles()) { - self::storeKeysInDB(); - } - } } diff --git a/app/Support/Twig/AmountFormat.php b/app/Support/Twig/AmountFormat.php index 247f07f756..5ae6db2121 100644 --- a/app/Support/Twig/AmountFormat.php +++ b/app/Support/Twig/AmountFormat.php @@ -46,18 +46,6 @@ class AmountFormat extends AbstractExtension ]; } - /** - * {@inheritdoc} - */ - public function getFunctions(): array - { - return [ - $this->formatAmountByAccount(), - $this->formatAmountBySymbol(), - $this->formatAmountByCurrency(), - ]; - } - /** * @return TwigFilter */ @@ -74,6 +62,34 @@ class AmountFormat extends AbstractExtension ); } + /** + * @return TwigFilter + */ + protected function formatAmountPlain(): TwigFilter + { + return new TwigFilter( + 'formatAmountPlain', + static function (string $string): string { + $currency = app('amount')->getDefaultCurrency(); + + return app('amount')->formatAnything($currency, $string, false); + }, + ['is_safe' => ['html']] + ); + } + + /** + * {@inheritdoc} + */ + public function getFunctions(): array + { + return [ + $this->formatAmountByAccount(), + $this->formatAmountBySymbol(), + $this->formatAmountByCurrency(), + ]; + } + /** * Will format the amount by the currency related to the given account. * @@ -96,24 +112,6 @@ class AmountFormat extends AbstractExtension ); } - /** - * Will format the amount by the currency related to the given account. - * - * @return TwigFunction - */ - protected function formatAmountByCurrency(): TwigFunction - { - return new TwigFunction( - 'formatAmountByCurrency', - static function (TransactionCurrency $currency, string $amount, bool $coloured = null): string { - $coloured = $coloured ?? true; - - return app('amount')->formatAnything($currency, $amount, $coloured); - }, - ['is_safe' => ['html']] - ); - } - /** * Will format the amount by the currency related to the given account. * @@ -137,16 +135,18 @@ class AmountFormat extends AbstractExtension } /** - * @return TwigFilter + * Will format the amount by the currency related to the given account. + * + * @return TwigFunction */ - protected function formatAmountPlain(): TwigFilter + protected function formatAmountByCurrency(): TwigFunction { - return new TwigFilter( - 'formatAmountPlain', - static function (string $string): string { - $currency = app('amount')->getDefaultCurrency(); + return new TwigFunction( + 'formatAmountByCurrency', + static function (TransactionCurrency $currency, string $amount, bool $coloured = null): string { + $coloured = $coloured ?? true; - return app('amount')->formatAnything($currency, $string, false); + return app('amount')->formatAnything($currency, $amount, $coloured); }, ['is_safe' => ['html']] ); diff --git a/app/Support/Twig/General.php b/app/Support/Twig/General.php index 61b00204dd..d8ea9dfd13 100644 --- a/app/Support/Twig/General.php +++ b/app/Support/Twig/General.php @@ -53,99 +53,6 @@ class General extends AbstractExtension ]; } - /** - * {@inheritdoc} - */ - public function getFunctions(): array - { - return [ - $this->phpdate(), - $this->activeRouteStrict(), - $this->activeRoutePartial(), - $this->activeRoutePartialObjectType(), - $this->menuOpenRoutePartial(), - $this->formatDate(), - $this->getMetaField(), - $this->hasRole(), - $this->getRootSearchOperator(), - $this->carbonize(), - ]; - } - - /** - * Will return "active" when a part of the route matches the argument. - * ie. "accounts" will match "accounts.index". - * - * @return TwigFunction - */ - protected function activeRoutePartial(): TwigFunction - { - return new TwigFunction( - 'activeRoutePartial', - static function (): string { - $args = func_get_args(); - $route = $args[0]; // name of the route. - $name = Route::getCurrentRoute()->getName() ?? ''; - if (str_contains($name, $route)) { - return 'active'; - } - - return ''; - } - ); - } - - /** - * This function will return "active" when the current route matches the first argument (even partly) - * but, the variable $objectType has been set and matches the second argument. - * - * @return TwigFunction - */ - protected function activeRoutePartialObjectType(): TwigFunction - { - return new TwigFunction( - 'activeRoutePartialObjectType', - static function ($context): string { - [, $route, $objectType] = func_get_args(); - $activeObjectType = $context['objectType'] ?? false; - - if ($objectType === $activeObjectType - && false !== stripos( - Route::getCurrentRoute()->getName(), - $route - )) { - return 'active'; - } - - return ''; - }, - ['needs_context' => true] - ); - } - - /** - * Will return "active" when the current route matches the given argument - * exactly. - * - * @return TwigFunction - */ - protected function activeRouteStrict(): TwigFunction - { - return new TwigFunction( - 'activeRouteStrict', - static function (): string { - $args = func_get_args(); - $route = $args[0]; // name of the route. - - if (Route::getCurrentRoute()->getName() === $route) { - return 'active'; - } - - return ''; - } - ); - } - /** * Show account balance. Only used on the front page of Firefly III. * @@ -167,36 +74,6 @@ class General extends AbstractExtension ); } - /** - * @return TwigFunction - */ - protected function carbonize(): TwigFunction - { - return new TwigFunction( - 'carbonize', - static function (string $date): Carbon { - return new Carbon($date, config('app.timezone')); - } - ); - } - - /** - * Formats a string as a thing by converting it to a Carbon first. - * - * @return TwigFunction - */ - protected function formatDate(): TwigFunction - { - return new TwigFunction( - 'formatDate', - function (string $date, string $format): string { - $carbon = new Carbon($date); - - return $carbon->isoFormat($format); - } - ); - } - /** * Used to convert 1024 to 1kb etc. * @@ -222,104 +99,6 @@ class General extends AbstractExtension ); } - /** - * @return TwigFunction - * TODO remove me when layout v1 is deprecated. - */ - protected function getMetaField(): TwigFunction - { - return new TwigFunction( - 'accountGetMetaField', - static function (Account $account, string $field): string { - /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class); - $result = $repository->getMetaValue($account, $field); - if (null === $result) { - return ''; - } - - return $result; - } - ); - } - - protected function getRootSearchOperator(): TwigFunction - { - return new TwigFunction( - 'getRootSearchOperator', - static function (string $operator): string { - $result = OperatorQuerySearch::getRootOperator($operator); - - return str_replace('-', 'not_', $result); - } - ); - } - - /** - * Will return true if the user is of role X. - * - * @return TwigFunction - */ - protected function hasRole(): TwigFunction - { - return new TwigFunction( - 'hasRole', - static function (string $role): bool { - $repository = app(UserRepositoryInterface::class); - if ($repository->hasRole(auth()->user(), $role)) { - return true; - } - - return false; - } - ); - } - - /** - * @return TwigFilter - */ - protected function markdown(): TwigFilter - { - return new TwigFilter( - 'markdown', - static function (string $text): string { - $converter = new GithubFlavoredMarkdownConverter( - [ - 'allow_unsafe_links' => false, - 'max_nesting_level' => 3, - 'html_input' => 'escape', - ] - ); - - return (string)$converter->convert($text); - }, - ['is_safe' => ['html']] - ); - } - - /** - * Will return "menu-open" when a part of the route matches the argument. - * ie. "accounts" will match "accounts.index". - * - * @return TwigFunction - */ - protected function menuOpenRoutePartial(): TwigFunction - { - return new TwigFunction( - 'menuOpenRoutePartial', - static function (): string { - $args = func_get_args(); - $route = $args[0]; // name of the route. - $name = Route::getCurrentRoute()->getName() ?? ''; - if (str_contains($name, $route)) { - return 'menu-open'; - } - - return ''; - } - ); - } - /** * Show icon with attachment. * @@ -398,6 +177,28 @@ class General extends AbstractExtension ); } + /** + * @return TwigFilter + */ + protected function markdown(): TwigFilter + { + return new TwigFilter( + 'markdown', + static function (string $text): string { + $converter = new GithubFlavoredMarkdownConverter( + [ + 'allow_unsafe_links' => false, + 'max_nesting_level' => 3, + 'html_input' => 'escape', + ] + ); + + return (string)$converter->convert($text); + }, + ['is_safe' => ['html']] + ); + } + /** * Show URL host name * @@ -416,6 +217,25 @@ class General extends AbstractExtension ); } + /** + * {@inheritdoc} + */ + public function getFunctions(): array + { + return [ + $this->phpdate(), + $this->activeRouteStrict(), + $this->activeRoutePartial(), + $this->activeRoutePartialObjectType(), + $this->menuOpenRoutePartial(), + $this->formatDate(), + $this->getMetaField(), + $this->hasRole(), + $this->getRootSearchOperator(), + $this->carbonize(), + ]; + } + /** * Basic example thing for some views. * @@ -430,4 +250,184 @@ class General extends AbstractExtension } ); } + + /** + * Will return "active" when the current route matches the given argument + * exactly. + * + * @return TwigFunction + */ + protected function activeRouteStrict(): TwigFunction + { + return new TwigFunction( + 'activeRouteStrict', + static function (): string { + $args = func_get_args(); + $route = $args[0]; // name of the route. + + if (Route::getCurrentRoute()->getName() === $route) { + return 'active'; + } + + return ''; + } + ); + } + + /** + * Will return "active" when a part of the route matches the argument. + * ie. "accounts" will match "accounts.index". + * + * @return TwigFunction + */ + protected function activeRoutePartial(): TwigFunction + { + return new TwigFunction( + 'activeRoutePartial', + static function (): string { + $args = func_get_args(); + $route = $args[0]; // name of the route. + $name = Route::getCurrentRoute()->getName() ?? ''; + if (str_contains($name, $route)) { + return 'active'; + } + + return ''; + } + ); + } + + /** + * This function will return "active" when the current route matches the first argument (even partly) + * but, the variable $objectType has been set and matches the second argument. + * + * @return TwigFunction + */ + protected function activeRoutePartialObjectType(): TwigFunction + { + return new TwigFunction( + 'activeRoutePartialObjectType', + static function ($context): string { + [, $route, $objectType] = func_get_args(); + $activeObjectType = $context['objectType'] ?? false; + + if ($objectType === $activeObjectType + && false !== stripos( + Route::getCurrentRoute()->getName(), + $route + )) { + return 'active'; + } + + return ''; + }, + ['needs_context' => true] + ); + } + + /** + * Will return "menu-open" when a part of the route matches the argument. + * ie. "accounts" will match "accounts.index". + * + * @return TwigFunction + */ + protected function menuOpenRoutePartial(): TwigFunction + { + return new TwigFunction( + 'menuOpenRoutePartial', + static function (): string { + $args = func_get_args(); + $route = $args[0]; // name of the route. + $name = Route::getCurrentRoute()->getName() ?? ''; + if (str_contains($name, $route)) { + return 'menu-open'; + } + + return ''; + } + ); + } + + /** + * Formats a string as a thing by converting it to a Carbon first. + * + * @return TwigFunction + */ + protected function formatDate(): TwigFunction + { + return new TwigFunction( + 'formatDate', + function (string $date, string $format): string { + $carbon = new Carbon($date); + + return $carbon->isoFormat($format); + } + ); + } + + /** + * @return TwigFunction + * TODO remove me when layout v1 is deprecated. + */ + protected function getMetaField(): TwigFunction + { + return new TwigFunction( + 'accountGetMetaField', + static function (Account $account, string $field): string { + /** @var AccountRepositoryInterface $repository */ + $repository = app(AccountRepositoryInterface::class); + $result = $repository->getMetaValue($account, $field); + if (null === $result) { + return ''; + } + + return $result; + } + ); + } + + /** + * Will return true if the user is of role X. + * + * @return TwigFunction + */ + protected function hasRole(): TwigFunction + { + return new TwigFunction( + 'hasRole', + static function (string $role): bool { + $repository = app(UserRepositoryInterface::class); + if ($repository->hasRole(auth()->user(), $role)) { + return true; + } + + return false; + } + ); + } + + protected function getRootSearchOperator(): TwigFunction + { + return new TwigFunction( + 'getRootSearchOperator', + static function (string $operator): string { + $result = OperatorQuerySearch::getRootOperator($operator); + + return str_replace('-', 'not_', $result); + } + ); + } + + /** + * @return TwigFunction + */ + protected function carbonize(): TwigFunction + { + return new TwigFunction( + 'carbonize', + static function (string $date): Carbon { + return new Carbon($date, config('app.timezone')); + } + ); + } } diff --git a/app/Support/Twig/Rule.php b/app/Support/Twig/Rule.php index 1182eea8e4..adc616b129 100644 --- a/app/Support/Twig/Rule.php +++ b/app/Support/Twig/Rule.php @@ -33,25 +33,15 @@ use Twig\TwigFunction; class Rule extends AbstractExtension { /** - * @return TwigFunction + * @return array */ - public function allActionTriggers(): TwigFunction + public function getFunctions(): array { - return new TwigFunction( - 'allRuleActions', - static function () { - // array of valid values for actions - $ruleActions = array_keys(Config::get('firefly.rule-actions')); - $possibleActions = []; - foreach ($ruleActions as $key) { - $possibleActions[$key] = (string)trans('firefly.rule_action_'.$key.'_choice'); - } - unset($ruleActions); - asort($possibleActions); - - return $possibleActions; - } - ); + return [ + $this->allJournalTriggers(), + $this->allRuleTriggers(), + $this->allActionTriggers(), + ]; } /** @@ -82,7 +72,7 @@ class Rule extends AbstractExtension $possibleTriggers = []; foreach ($ruleTriggers as $key) { if ('user_action' !== $key) { - $possibleTriggers[$key] = (string)trans('firefly.rule_trigger_'.$key.'_choice'); + $possibleTriggers[$key] = (string)trans('firefly.rule_trigger_' . $key . '_choice'); } } unset($ruleTriggers); @@ -94,14 +84,24 @@ class Rule extends AbstractExtension } /** - * @return array + * @return TwigFunction */ - public function getFunctions(): array + public function allActionTriggers(): TwigFunction { - return [ - $this->allJournalTriggers(), - $this->allRuleTriggers(), - $this->allActionTriggers(), - ]; + return new TwigFunction( + 'allRuleActions', + static function () { + // array of valid values for actions + $ruleActions = array_keys(Config::get('firefly.rule-actions')); + $possibleActions = []; + foreach ($ruleActions as $key) { + $possibleActions[$key] = (string)trans('firefly.rule_action_' . $key . '_choice'); + } + unset($ruleActions); + asort($possibleActions); + + return $possibleActions; + } + ); } } diff --git a/app/Support/Twig/TransactionGroupTwig.php b/app/Support/Twig/TransactionGroupTwig.php index f99762766c..38e3005eb5 100644 --- a/app/Support/Twig/TransactionGroupTwig.php +++ b/app/Support/Twig/TransactionGroupTwig.php @@ -76,6 +76,201 @@ class TransactionGroupTwig extends AbstractExtension ); } + /** + * Generate normal amount for transaction from a transaction group. + * + * @param array $array + * + * @return string + */ + private function normalJournalArrayAmount(array $array): string + { + $type = $array['transaction_type_type'] ?? TransactionType::WITHDRAWAL; + $amount = $array['amount'] ?? '0'; + $colored = true; + $sourceType = $array['source_account_type'] ?? 'invalid'; + $amount = $this->signAmount($amount, $type, $sourceType); + + if ($type === TransactionType::TRANSFER) { + $colored = false; + } + + $result = app('amount')->formatFlat($array['currency_symbol'], (int)$array['currency_decimal_places'], $amount, $colored); + if ($type === TransactionType::TRANSFER) { + $result = sprintf('%s', $result); + } + + return $result; + } + + /** + * @param string $amount + * @param string $transactionType + * @param string $sourceType + * + * @return string + */ + private function signAmount(string $amount, string $transactionType, string $sourceType): string + { + // withdrawals stay negative + if ($transactionType !== TransactionType::WITHDRAWAL) { + $amount = bcmul($amount, '-1'); + } + + // opening balance and it comes from initial balance? its expense. + if ($transactionType === TransactionType::OPENING_BALANCE && AccountType::INITIAL_BALANCE !== $sourceType) { + $amount = bcmul($amount, '-1'); + } + + // reconciliation and it comes from reconciliation? + if ($transactionType === TransactionType::RECONCILIATION && AccountType::RECONCILIATION !== $sourceType) { + $amount = bcmul($amount, '-1'); + } + + return $amount; + } + + /** + * Generate foreign amount for transaction from a transaction group. + * + * @param array $array + * + * @return string + */ + private function foreignJournalArrayAmount(array $array): string + { + $type = $array['transaction_type_type'] ?? TransactionType::WITHDRAWAL; + $amount = $array['foreign_amount'] ?? '0'; + $colored = true; + + $sourceType = $array['source_account_type'] ?? 'invalid'; + $amount = $this->signAmount($amount, $type, $sourceType); + + if ($type === TransactionType::TRANSFER) { + $colored = false; + } + $result = app('amount')->formatFlat($array['foreign_currency_symbol'], (int)$array['foreign_currency_decimal_places'], $amount, $colored); + if ($type === TransactionType::TRANSFER) { + $result = sprintf('%s', $result); + } + + return $result; + } + + /** + * Shows the amount for a single journal object. + * + * @return TwigFunction + */ + public function journalObjectAmount(): TwigFunction + { + return new TwigFunction( + 'journalObjectAmount', + function (TransactionJournal $journal): string { + $result = $this->normalJournalObjectAmount($journal); + // now append foreign amount, if any. + if ($this->journalObjectHasForeign($journal)) { + $foreign = $this->foreignJournalObjectAmount($journal); + $result = sprintf('%s (%s)', $result, $foreign); + } + + return $result; + }, + ['is_safe' => ['html']] + ); + } + + /** + * Generate normal amount for transaction from a transaction group. + * + * @param TransactionJournal $journal + * + * @return string + */ + private function normalJournalObjectAmount(TransactionJournal $journal): string + { + $type = $journal->transactionType->type; + $first = $journal->transactions()->where('amount', '<', 0)->first(); + $currency = $journal->transactionCurrency; + $amount = $first->amount ?? '0'; + $colored = true; + $sourceType = $first->account()->first()->accountType()->first()->type; + + $amount = $this->signAmount($amount, $type, $sourceType); + + if ($type === TransactionType::TRANSFER) { + $colored = false; + } + $result = app('amount')->formatFlat($currency->symbol, (int)$currency->decimal_places, $amount, $colored); + if ($type === TransactionType::TRANSFER) { + $result = sprintf('%s', $result); + } + + return $result; + } + + /** + * @param TransactionJournal $journal + * + * @return bool + */ + private function journalObjectHasForeign(TransactionJournal $journal): bool + { + /** @var Transaction $first */ + $first = $journal->transactions()->where('amount', '<', 0)->first(); + + return '' !== $first->foreign_amount; + } + + /** + * Generate foreign amount for journal from a transaction group. + * + * @param TransactionJournal $journal + * + * @return string + */ + private function foreignJournalObjectAmount(TransactionJournal $journal): string + { + $type = $journal->transactionType->type; + /** @var Transaction $first */ + $first = $journal->transactions()->where('amount', '<', 0)->first(); + $currency = $first->foreignCurrency; + $amount = '' === $first->foreign_amount ? '0' : $first->foreign_amount; + $colored = true; + $sourceType = $first->account()->first()->accountType()->first()->type; + + $amount = $this->signAmount($amount, $type, $sourceType); + + if ($type === TransactionType::TRANSFER) { + $colored = false; + } + $result = app('amount')->formatFlat($currency->symbol, (int)$currency->decimal_places, $amount, $colored); + if ($type === TransactionType::TRANSFER) { + $result = sprintf('%s', $result); + } + + return $result; + } + + /** + * @return TwigFunction + */ + public function journalHasMeta(): TwigFunction + { + return new TwigFunction( + 'journalHasMeta', + static function (int $journalId, string $metaField) { + $count = DB::table('journal_meta') + ->where('name', $metaField) + ->where('transaction_journal_id', $journalId) + ->whereNull('deleted_at') + ->count(); + + return 1 === $count; + } + ); + } + /** * @return TwigFunction */ @@ -119,199 +314,4 @@ class TransactionGroupTwig extends AbstractExtension } ); } - - /** - * @return TwigFunction - */ - public function journalHasMeta(): TwigFunction - { - return new TwigFunction( - 'journalHasMeta', - static function (int $journalId, string $metaField) { - $count = DB::table('journal_meta') - ->where('name', $metaField) - ->where('transaction_journal_id', $journalId) - ->whereNull('deleted_at') - ->count(); - - return 1 === $count; - } - ); - } - - /** - * Shows the amount for a single journal object. - * - * @return TwigFunction - */ - public function journalObjectAmount(): TwigFunction - { - return new TwigFunction( - 'journalObjectAmount', - function (TransactionJournal $journal): string { - $result = $this->normalJournalObjectAmount($journal); - // now append foreign amount, if any. - if ($this->journalObjectHasForeign($journal)) { - $foreign = $this->foreignJournalObjectAmount($journal); - $result = sprintf('%s (%s)', $result, $foreign); - } - - return $result; - }, - ['is_safe' => ['html']] - ); - } - - /** - * Generate foreign amount for transaction from a transaction group. - * - * @param array $array - * - * @return string - */ - private function foreignJournalArrayAmount(array $array): string - { - $type = $array['transaction_type_type'] ?? TransactionType::WITHDRAWAL; - $amount = $array['foreign_amount'] ?? '0'; - $colored = true; - - $sourceType = $array['source_account_type'] ?? 'invalid'; - $amount = $this->signAmount($amount, $type, $sourceType); - - if ($type === TransactionType::TRANSFER) { - $colored = false; - } - $result = app('amount')->formatFlat($array['foreign_currency_symbol'], (int)$array['foreign_currency_decimal_places'], $amount, $colored); - if ($type === TransactionType::TRANSFER) { - $result = sprintf('%s', $result); - } - - return $result; - } - - /** - * Generate foreign amount for journal from a transaction group. - * - * @param TransactionJournal $journal - * - * @return string - */ - private function foreignJournalObjectAmount(TransactionJournal $journal): string - { - $type = $journal->transactionType->type; - /** @var Transaction $first */ - $first = $journal->transactions()->where('amount', '<', 0)->first(); - $currency = $first->foreignCurrency; - $amount = '' === $first->foreign_amount ? '0' : $first->foreign_amount; - $colored = true; - $sourceType = $first->account()->first()->accountType()->first()->type; - - $amount = $this->signAmount($amount, $type, $sourceType); - - if ($type === TransactionType::TRANSFER) { - $colored = false; - } - $result = app('amount')->formatFlat($currency->symbol, (int)$currency->decimal_places, $amount, $colored); - if ($type === TransactionType::TRANSFER) { - $result = sprintf('%s', $result); - } - - return $result; - } - - /** - * @param TransactionJournal $journal - * - * @return bool - */ - private function journalObjectHasForeign(TransactionJournal $journal): bool - { - /** @var Transaction $first */ - $first = $journal->transactions()->where('amount', '<', 0)->first(); - - return '' !== $first->foreign_amount; - } - - /** - * Generate normal amount for transaction from a transaction group. - * - * @param array $array - * - * @return string - */ - private function normalJournalArrayAmount(array $array): string - { - $type = $array['transaction_type_type'] ?? TransactionType::WITHDRAWAL; - $amount = $array['amount'] ?? '0'; - $colored = true; - $sourceType = $array['source_account_type'] ?? 'invalid'; - $amount = $this->signAmount($amount, $type, $sourceType); - - if ($type === TransactionType::TRANSFER) { - $colored = false; - } - - $result = app('amount')->formatFlat($array['currency_symbol'], (int)$array['currency_decimal_places'], $amount, $colored); - if ($type === TransactionType::TRANSFER) { - $result = sprintf('%s', $result); - } - - return $result; - } - - /** - * Generate normal amount for transaction from a transaction group. - * - * @param TransactionJournal $journal - * - * @return string - */ - private function normalJournalObjectAmount(TransactionJournal $journal): string - { - $type = $journal->transactionType->type; - $first = $journal->transactions()->where('amount', '<', 0)->first(); - $currency = $journal->transactionCurrency; - $amount = $first->amount ?? '0'; - $colored = true; - $sourceType = $first->account()->first()->accountType()->first()->type; - - $amount = $this->signAmount($amount, $type, $sourceType); - - if ($type === TransactionType::TRANSFER) { - $colored = false; - } - $result = app('amount')->formatFlat($currency->symbol, (int)$currency->decimal_places, $amount, $colored); - if ($type === TransactionType::TRANSFER) { - $result = sprintf('%s', $result); - } - - return $result; - } - - /** - * @param string $amount - * @param string $transactionType - * @param string $sourceType - * - * @return string - */ - private function signAmount(string $amount, string $transactionType, string $sourceType): string - { - // withdrawals stay negative - if ($transactionType !== TransactionType::WITHDRAWAL) { - $amount = bcmul($amount, '-1'); - } - - // opening balance and it comes from initial balance? its expense. - if ($transactionType === TransactionType::OPENING_BALANCE && AccountType::INITIAL_BALANCE !== $sourceType) { - $amount = bcmul($amount, '-1'); - } - - // reconciliation and it comes from reconciliation? - if ($transactionType === TransactionType::RECONCILIATION && AccountType::RECONCILIATION !== $sourceType) { - $amount = bcmul($amount, '-1'); - } - - return $amount; - } } diff --git a/app/TransactionRules/Actions/ActionInterface.php b/app/TransactionRules/Actions/ActionInterface.php index 4dd7e1161f..c8bd82a992 100644 --- a/app/TransactionRules/Actions/ActionInterface.php +++ b/app/TransactionRules/Actions/ActionInterface.php @@ -32,7 +32,7 @@ interface ActionInterface * Execute the action on an array. Returns "true" if the action was a success and the action * was applied. Returns false if otherwise. * - * @param array $journal + * @param array $journal * * @return bool */ diff --git a/app/TransactionRules/Actions/AddTag.php b/app/TransactionRules/Actions/AddTag.php index e865abb117..44ffabbafe 100644 --- a/app/TransactionRules/Actions/AddTag.php +++ b/app/TransactionRules/Actions/AddTag.php @@ -41,7 +41,7 @@ class AddTag implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/AppendDescription.php b/app/TransactionRules/Actions/AppendDescription.php index 0b24f8e4af..2a52c2cb79 100644 --- a/app/TransactionRules/Actions/AppendDescription.php +++ b/app/TransactionRules/Actions/AppendDescription.php @@ -38,7 +38,7 @@ class AppendDescription implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/AppendDescriptionToNotes.php b/app/TransactionRules/Actions/AppendDescriptionToNotes.php index 7da45b78a7..f5c0280e48 100644 --- a/app/TransactionRules/Actions/AppendDescriptionToNotes.php +++ b/app/TransactionRules/Actions/AppendDescriptionToNotes.php @@ -40,7 +40,7 @@ class AppendDescriptionToNotes implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/AppendNotes.php b/app/TransactionRules/Actions/AppendNotes.php index c0595a9e31..8d130b2521 100644 --- a/app/TransactionRules/Actions/AppendNotes.php +++ b/app/TransactionRules/Actions/AppendNotes.php @@ -39,7 +39,7 @@ class AppendNotes implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/AppendNotesToDescription.php b/app/TransactionRules/Actions/AppendNotesToDescription.php index d9d5445a14..20a48901d7 100644 --- a/app/TransactionRules/Actions/AppendNotesToDescription.php +++ b/app/TransactionRules/Actions/AppendNotesToDescription.php @@ -43,7 +43,7 @@ class AppendNotesToDescription implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/ClearBudget.php b/app/TransactionRules/Actions/ClearBudget.php index d2915f8e5f..24599dcc7e 100644 --- a/app/TransactionRules/Actions/ClearBudget.php +++ b/app/TransactionRules/Actions/ClearBudget.php @@ -39,7 +39,7 @@ class ClearBudget implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/ClearCategory.php b/app/TransactionRules/Actions/ClearCategory.php index 158b5b212d..c478ea05d8 100644 --- a/app/TransactionRules/Actions/ClearCategory.php +++ b/app/TransactionRules/Actions/ClearCategory.php @@ -39,7 +39,7 @@ class ClearCategory implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/ClearNotes.php b/app/TransactionRules/Actions/ClearNotes.php index bdac946b25..77757456df 100644 --- a/app/TransactionRules/Actions/ClearNotes.php +++ b/app/TransactionRules/Actions/ClearNotes.php @@ -39,7 +39,7 @@ class ClearNotes implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/ConvertToDeposit.php b/app/TransactionRules/Actions/ConvertToDeposit.php index c430e66da2..7084f1bb45 100644 --- a/app/TransactionRules/Actions/ConvertToDeposit.php +++ b/app/TransactionRules/Actions/ConvertToDeposit.php @@ -48,7 +48,7 @@ class ConvertToDeposit implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { @@ -86,7 +86,7 @@ class ConvertToDeposit implements ActionInterface try { $res = $this->convertWithdrawalArray($object); - } catch (JsonException|FireflyException $e) { + } catch (JsonException | FireflyException $e) { Log::debug('Could not convert withdrawal to deposit.'); Log::error($e->getMessage()); return false; @@ -101,7 +101,7 @@ class ConvertToDeposit implements ActionInterface try { $res = $this->convertTransferArray($object); - } catch (JsonException|FireflyException $e) { + } catch (JsonException | FireflyException $e) { Log::debug('Could not convert transfer to deposit.'); Log::error($e->getMessage()); return false; @@ -114,65 +114,11 @@ class ConvertToDeposit implements ActionInterface return false; } - /** - * Input is a transfer from A to B. - * Output is a deposit from C to B. - * The source account is replaced. - * - * @param TransactionJournal $journal - * - * @return bool - * @throws FireflyException - * @throws JsonException - */ - private function convertTransferArray(TransactionJournal $journal): bool - { - $user = $journal->user; - // find or create revenue account. - /** @var AccountFactory $factory */ - $factory = app(AccountFactory::class); - $factory->setUser($user); - - $repository = app(AccountRepositoryInterface::class); - $repository->setUser($user); - - $sourceAccount = $this->getSourceAccount($journal); - - // get the action value, or use the original source name in case the action value is empty: - // this becomes a new or existing (revenue) account, which is the source of the new deposit. - $opposingName = '' === $this->action->action_value ? $sourceAccount->name : $this->action->action_value; - // we check all possible source account types if one exists: - $validTypes = config('firefly.expected_source_types.source.Deposit'); - $opposingAccount = $repository->findByName($opposingName, $validTypes); - if (null === $opposingAccount) { - $opposingAccount = $factory->findOrCreate($opposingName, AccountType::REVENUE); - } - - Log::debug(sprintf('ConvertToDeposit. Action value is "%s", revenue name is "%s"', $this->action->action_value, $opposingAccount->name)); - - // update source transaction(s) to be revenue account - DB::table('transactions') - ->where('transaction_journal_id', '=', $journal->id) - ->where('amount', '<', 0) - ->update(['account_id' => $opposingAccount->id]); - - // change transaction type of journal: - $newType = TransactionType::whereType(TransactionType::DEPOSIT)->first(); - - DB::table('transaction_journals') - ->where('id', '=', $journal->id) - ->update(['transaction_type_id' => $newType->id, 'bill_id' => null]); - - Log::debug('Converted transfer to deposit.'); - - return true; - } - /** * Input is a withdrawal from A to B * Is converted to a deposit from C to A. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return bool * @throws FireflyException @@ -229,7 +175,7 @@ class ConvertToDeposit implements ActionInterface } /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal * @return Account * @throws FireflyException */ @@ -244,7 +190,7 @@ class ConvertToDeposit implements ActionInterface } /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal * @return Account * @throws FireflyException */ @@ -257,4 +203,58 @@ class ConvertToDeposit implements ActionInterface } return $sourceTransaction->account; } + + /** + * Input is a transfer from A to B. + * Output is a deposit from C to B. + * The source account is replaced. + * + * @param TransactionJournal $journal + * + * @return bool + * @throws FireflyException + * @throws JsonException + */ + private function convertTransferArray(TransactionJournal $journal): bool + { + $user = $journal->user; + // find or create revenue account. + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($user); + + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($user); + + $sourceAccount = $this->getSourceAccount($journal); + + // get the action value, or use the original source name in case the action value is empty: + // this becomes a new or existing (revenue) account, which is the source of the new deposit. + $opposingName = '' === $this->action->action_value ? $sourceAccount->name : $this->action->action_value; + // we check all possible source account types if one exists: + $validTypes = config('firefly.expected_source_types.source.Deposit'); + $opposingAccount = $repository->findByName($opposingName, $validTypes); + if (null === $opposingAccount) { + $opposingAccount = $factory->findOrCreate($opposingName, AccountType::REVENUE); + } + + Log::debug(sprintf('ConvertToDeposit. Action value is "%s", revenue name is "%s"', $this->action->action_value, $opposingAccount->name)); + + // update source transaction(s) to be revenue account + DB::table('transactions') + ->where('transaction_journal_id', '=', $journal->id) + ->where('amount', '<', 0) + ->update(['account_id' => $opposingAccount->id]); + + // change transaction type of journal: + $newType = TransactionType::whereType(TransactionType::DEPOSIT)->first(); + + DB::table('transaction_journals') + ->where('id', '=', $journal->id) + ->update(['transaction_type_id' => $newType->id, 'bill_id' => null]); + + Log::debug('Converted transfer to deposit.'); + + return true; + } } diff --git a/app/TransactionRules/Actions/ConvertToTransfer.php b/app/TransactionRules/Actions/ConvertToTransfer.php index bf78ae8025..9d3f06d18b 100644 --- a/app/TransactionRules/Actions/ConvertToTransfer.php +++ b/app/TransactionRules/Actions/ConvertToTransfer.php @@ -45,7 +45,7 @@ class ConvertToTransfer implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { @@ -140,45 +140,33 @@ class ConvertToTransfer implements ActionInterface } /** - * A deposit is from Revenue to Asset. - * We replace the Revenue with another asset. - * - * @param TransactionJournal $journal - * @param Account $opposing - * - * @return bool - * @throws FireflyException + * @param int $journalId + * @return string */ - private function convertDepositArray(TransactionJournal $journal, Account $opposing): bool + private function getSourceType(int $journalId): string { - $destAccount = $this->getDestinationAccount($journal); - if ((int)$destAccount->id === (int)$opposing->id) { - Log::error( - vsprintf( - 'Journal #%d has already has "%s" as a destination asset. ConvertToTransfer failed. (rule #%d).', - [$journal->id, $opposing->name, $this->action->rule_id] - ) - ); - - return false; + /** @var TransactionJournal $journal */ + $journal = TransactionJournal::find($journalId); + if (null === $journal) { + Log::error(sprintf('Journal #%d does not exist. Cannot convert to transfer.', $journalId)); + return ''; } + return (string)$journal->transactions()->where('amount', '<', 0)->first()?->account?->accountType?->type; + } - // update source transaction: - DB::table('transactions') - ->where('transaction_journal_id', '=', $journal->id) - ->where('amount', '<', 0) - ->update(['account_id' => $opposing->id]); - - // change transaction type of journal: - $newType = TransactionType::whereType(TransactionType::TRANSFER)->first(); - - DB::table('transaction_journals') - ->where('id', '=', $journal->id) - ->update(['transaction_type_id' => $newType->id, 'bill_id' => null]); - - Log::debug('Converted deposit to transfer.'); - - return true; + /** + * @param int $journalId + * @return string + */ + private function getDestinationType(int $journalId): string + { + /** @var TransactionJournal $journal */ + $journal = TransactionJournal::find($journalId); + if (null === $journal) { + Log::error(sprintf('Journal #%d does not exist. Cannot convert to transfer.', $journalId)); + return ''; + } + return (string)$journal->transactions()->where('amount', '>', 0)->first()?->account?->accountType?->type; } /** @@ -186,8 +174,8 @@ class ConvertToTransfer implements ActionInterface * We replace the Expense with another asset. * So this replaces the destination * - * @param TransactionJournal $journal - * @param Account $opposing + * @param TransactionJournal $journal + * @param Account $opposing * * @return bool * @throws FireflyException @@ -225,37 +213,7 @@ class ConvertToTransfer implements ActionInterface } /** - * @param TransactionJournal $journal - * @return Account - * @throws FireflyException - */ - private function getDestinationAccount(TransactionJournal $journal): Account - { - /** @var Transaction|null $destAccount */ - $destAccount = $journal->transactions()->where('amount', '>', 0)->first(); - if (null === $destAccount) { - throw new FireflyException(sprintf('Cannot find destination transaction for journal #%d', $journal->id)); - } - return $destAccount->account; - } - - /** - * @param int $journalId - * @return string - */ - private function getDestinationType(int $journalId): string - { - /** @var TransactionJournal $journal */ - $journal = TransactionJournal::find($journalId); - if (null === $journal) { - Log::error(sprintf('Journal #%d does not exist. Cannot convert to transfer.', $journalId)); - return ''; - } - return (string)$journal->transactions()->where('amount', '>', 0)->first()?->account?->accountType?->type; - } - - /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal * @return Account * @throws FireflyException */ @@ -270,17 +228,59 @@ class ConvertToTransfer implements ActionInterface } /** - * @param int $journalId - * @return string + * A deposit is from Revenue to Asset. + * We replace the Revenue with another asset. + * + * @param TransactionJournal $journal + * @param Account $opposing + * + * @return bool + * @throws FireflyException */ - private function getSourceType(int $journalId): string + private function convertDepositArray(TransactionJournal $journal, Account $opposing): bool { - /** @var TransactionJournal $journal */ - $journal = TransactionJournal::find($journalId); - if (null === $journal) { - Log::error(sprintf('Journal #%d does not exist. Cannot convert to transfer.', $journalId)); - return ''; + $destAccount = $this->getDestinationAccount($journal); + if ((int)$destAccount->id === (int)$opposing->id) { + Log::error( + vsprintf( + 'Journal #%d has already has "%s" as a destination asset. ConvertToTransfer failed. (rule #%d).', + [$journal->id, $opposing->name, $this->action->rule_id] + ) + ); + + return false; } - return (string)$journal->transactions()->where('amount', '<', 0)->first()?->account?->accountType?->type; + + // update source transaction: + DB::table('transactions') + ->where('transaction_journal_id', '=', $journal->id) + ->where('amount', '<', 0) + ->update(['account_id' => $opposing->id]); + + // change transaction type of journal: + $newType = TransactionType::whereType(TransactionType::TRANSFER)->first(); + + DB::table('transaction_journals') + ->where('id', '=', $journal->id) + ->update(['transaction_type_id' => $newType->id, 'bill_id' => null]); + + Log::debug('Converted deposit to transfer.'); + + return true; + } + + /** + * @param TransactionJournal $journal + * @return Account + * @throws FireflyException + */ + private function getDestinationAccount(TransactionJournal $journal): Account + { + /** @var Transaction|null $destAccount */ + $destAccount = $journal->transactions()->where('amount', '>', 0)->first(); + if (null === $destAccount) { + throw new FireflyException(sprintf('Cannot find destination transaction for journal #%d', $journal->id)); + } + return $destAccount->account; } } diff --git a/app/TransactionRules/Actions/ConvertToWithdrawal.php b/app/TransactionRules/Actions/ConvertToWithdrawal.php index a1d4fb9be3..293cc8da4b 100644 --- a/app/TransactionRules/Actions/ConvertToWithdrawal.php +++ b/app/TransactionRules/Actions/ConvertToWithdrawal.php @@ -48,7 +48,7 @@ class ConvertToWithdrawal implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { @@ -84,7 +84,7 @@ class ConvertToWithdrawal implements ActionInterface Log::debug('Going to transform a deposit to a withdrawal.'); try { $res = $this->convertDepositArray($object); - } catch (JsonException|FireflyException $e) { + } catch (JsonException | FireflyException $e) { Log::debug('Could not convert transfer to deposit.'); Log::error($e->getMessage()); return false; @@ -98,7 +98,7 @@ class ConvertToWithdrawal implements ActionInterface try { $res = $this->convertTransferArray($object); - } catch (JsonException|FireflyException $e) { + } catch (JsonException | FireflyException $e) { Log::debug('Could not convert transfer to deposit.'); Log::error($e->getMessage()); return false; @@ -112,7 +112,7 @@ class ConvertToWithdrawal implements ActionInterface } /** - * @param TransactionJournal $journal + * @param TransactionJournal $journal * @return bool * @throws FireflyException * @throws JsonException @@ -165,11 +165,41 @@ class ConvertToWithdrawal implements ActionInterface return true; } + /** + * @param TransactionJournal $journal + * @return Account + * @throws FireflyException + */ + private function getSourceAccount(TransactionJournal $journal): Account + { + /** @var Transaction|null $sourceTransaction */ + $sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first(); + if (null === $sourceTransaction) { + throw new FireflyException(sprintf('Cannot find source transaction for journal #%d', $journal->id)); + } + return $sourceTransaction->account; + } + + /** + * @param TransactionJournal $journal + * @return Account + * @throws FireflyException + */ + private function getDestinationAccount(TransactionJournal $journal): Account + { + /** @var Transaction|null $destAccount */ + $destAccount = $journal->transactions()->where('amount', '>', 0)->first(); + if (null === $destAccount) { + throw new FireflyException(sprintf('Cannot find destination transaction for journal #%d', $journal->id)); + } + return $destAccount->account; + } + /** * Input is a transfer from A to B. * Output is a withdrawal from A to C. * - * @param TransactionJournal $journal + * @param TransactionJournal $journal * * @return bool * @throws FireflyException @@ -216,34 +246,4 @@ class ConvertToWithdrawal implements ActionInterface return true; } - - /** - * @param TransactionJournal $journal - * @return Account - * @throws FireflyException - */ - private function getDestinationAccount(TransactionJournal $journal): Account - { - /** @var Transaction|null $destAccount */ - $destAccount = $journal->transactions()->where('amount', '>', 0)->first(); - if (null === $destAccount) { - throw new FireflyException(sprintf('Cannot find destination transaction for journal #%d', $journal->id)); - } - return $destAccount->account; - } - - /** - * @param TransactionJournal $journal - * @return Account - * @throws FireflyException - */ - private function getSourceAccount(TransactionJournal $journal): Account - { - /** @var Transaction|null $sourceTransaction */ - $sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first(); - if (null === $sourceTransaction) { - throw new FireflyException(sprintf('Cannot find source transaction for journal #%d', $journal->id)); - } - return $sourceTransaction->account; - } } diff --git a/app/TransactionRules/Actions/DeleteTransaction.php b/app/TransactionRules/Actions/DeleteTransaction.php index 3f357b2e6c..0f52553457 100644 --- a/app/TransactionRules/Actions/DeleteTransaction.php +++ b/app/TransactionRules/Actions/DeleteTransaction.php @@ -41,7 +41,7 @@ class DeleteTransaction implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/LinkToBill.php b/app/TransactionRules/Actions/LinkToBill.php index b1f6b463cb..a996116bfd 100644 --- a/app/TransactionRules/Actions/LinkToBill.php +++ b/app/TransactionRules/Actions/LinkToBill.php @@ -43,7 +43,7 @@ class LinkToBill implements ActionInterface * TriggerInterface constructor. * * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/MoveDescriptionToNotes.php b/app/TransactionRules/Actions/MoveDescriptionToNotes.php index d9208b6bce..611c1841a0 100644 --- a/app/TransactionRules/Actions/MoveDescriptionToNotes.php +++ b/app/TransactionRules/Actions/MoveDescriptionToNotes.php @@ -41,7 +41,7 @@ class MoveDescriptionToNotes implements ActionInterface * TriggerInterface constructor. * * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/MoveNotesToDescription.php b/app/TransactionRules/Actions/MoveNotesToDescription.php index 0771e48996..5c670629bd 100644 --- a/app/TransactionRules/Actions/MoveNotesToDescription.php +++ b/app/TransactionRules/Actions/MoveNotesToDescription.php @@ -47,7 +47,7 @@ class MoveNotesToDescription implements ActionInterface * TriggerInterface constructor. * * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/PrependDescription.php b/app/TransactionRules/Actions/PrependDescription.php index f2a12ef24b..c116370d9b 100644 --- a/app/TransactionRules/Actions/PrependDescription.php +++ b/app/TransactionRules/Actions/PrependDescription.php @@ -38,7 +38,7 @@ class PrependDescription implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/PrependNotes.php b/app/TransactionRules/Actions/PrependNotes.php index c98d18688d..25534fa25d 100644 --- a/app/TransactionRules/Actions/PrependNotes.php +++ b/app/TransactionRules/Actions/PrependNotes.php @@ -39,7 +39,7 @@ class PrependNotes implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/RemoveAllTags.php b/app/TransactionRules/Actions/RemoveAllTags.php index b819c44406..c2ee19ad0b 100644 --- a/app/TransactionRules/Actions/RemoveAllTags.php +++ b/app/TransactionRules/Actions/RemoveAllTags.php @@ -39,7 +39,7 @@ class RemoveAllTags implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/RemoveTag.php b/app/TransactionRules/Actions/RemoveTag.php index 1a5b3be1d9..c72454e67a 100644 --- a/app/TransactionRules/Actions/RemoveTag.php +++ b/app/TransactionRules/Actions/RemoveTag.php @@ -40,7 +40,7 @@ class RemoveTag implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/SetBudget.php b/app/TransactionRules/Actions/SetBudget.php index b9ed8c6171..0ce333dfcb 100644 --- a/app/TransactionRules/Actions/SetBudget.php +++ b/app/TransactionRules/Actions/SetBudget.php @@ -41,7 +41,7 @@ class SetBudget implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/SetCategory.php b/app/TransactionRules/Actions/SetCategory.php index 44669cc05a..a0fdab020e 100644 --- a/app/TransactionRules/Actions/SetCategory.php +++ b/app/TransactionRules/Actions/SetCategory.php @@ -41,7 +41,7 @@ class SetCategory implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/SetDescription.php b/app/TransactionRules/Actions/SetDescription.php index 2c74f756b9..26e3a2be9d 100644 --- a/app/TransactionRules/Actions/SetDescription.php +++ b/app/TransactionRules/Actions/SetDescription.php @@ -39,7 +39,7 @@ class SetDescription implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/SetDestinationAccount.php b/app/TransactionRules/Actions/SetDestinationAccount.php index 239b7b61fe..7cb68f68de 100644 --- a/app/TransactionRules/Actions/SetDestinationAccount.php +++ b/app/TransactionRules/Actions/SetDestinationAccount.php @@ -45,7 +45,7 @@ class SetDestinationAccount implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { @@ -133,7 +133,7 @@ class SetDestinationAccount implements ActionInterface } /** - * @param string $type + * @param string $type * * @return Account|null */ diff --git a/app/TransactionRules/Actions/SetNotes.php b/app/TransactionRules/Actions/SetNotes.php index 840a9f9c93..a1874c241c 100644 --- a/app/TransactionRules/Actions/SetNotes.php +++ b/app/TransactionRules/Actions/SetNotes.php @@ -39,7 +39,7 @@ class SetNotes implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { diff --git a/app/TransactionRules/Actions/SetSourceAccount.php b/app/TransactionRules/Actions/SetSourceAccount.php index 9e95c80bb5..6493411c4a 100644 --- a/app/TransactionRules/Actions/SetSourceAccount.php +++ b/app/TransactionRules/Actions/SetSourceAccount.php @@ -45,7 +45,7 @@ class SetSourceAccount implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { @@ -128,7 +128,7 @@ class SetSourceAccount implements ActionInterface } /** - * @param string $type + * @param string $type * * @return Account|null */ diff --git a/app/TransactionRules/Actions/UpdatePiggybank.php b/app/TransactionRules/Actions/UpdatePiggybank.php index f5b7b0b9e2..f0bc05c0aa 100644 --- a/app/TransactionRules/Actions/UpdatePiggybank.php +++ b/app/TransactionRules/Actions/UpdatePiggybank.php @@ -44,7 +44,7 @@ class UpdatePiggybank implements ActionInterface /** * TriggerInterface constructor. * - * @param RuleAction $action + * @param RuleAction $action */ public function __construct(RuleAction $action) { @@ -135,9 +135,56 @@ class UpdatePiggybank implements ActionInterface } /** - * @param PiggyBank $piggyBank - * @param TransactionJournal $journal - * @param string $amount + * @param User $user + * + * @return PiggyBank|null + */ + private function findPiggyBank(User $user): ?PiggyBank + { + return $user->piggyBanks()->where('piggy_banks.name', $this->action->action_value)->first(); + } + + /** + * @param PiggyBank $piggyBank + * @param TransactionJournal $journal + * @param string $amount + * @return void + */ + private function removeAmount(PiggyBank $piggyBank, TransactionJournal $journal, string $amount): void + { + $repository = app(PiggyBankRepositoryInterface::class); + $repository->setUser($journal->user); + + // how much can we remove from this piggy bank? + $toRemove = $repository->getCurrentAmount($piggyBank); + Log::debug(sprintf('Amount is %s, max to remove is %s', $amount, $toRemove)); + + // if $amount is bigger than $toRemove, shrink it. + $amount = -1 === bccomp($amount, $toRemove) ? $amount : $toRemove; + Log::debug(sprintf('Amount is now %s', $amount)); + + // if amount is zero, stop. + if (0 === bccomp('0', $amount)) { + app('log')->warning('Amount left is zero, stop.'); + + return; + } + + // make sure we can remove amount: + if (false === $repository->canRemoveAmount($piggyBank, $amount)) { + app('log')->warning(sprintf('Cannot remove %s from piggy bank.', $amount)); + + return; + } + Log::debug(sprintf('Will now remove %s from piggy bank.', $amount)); + + $repository->removeAmount($piggyBank, $amount, $journal); + } + + /** + * @param PiggyBank $piggyBank + * @param TransactionJournal $journal + * @param string $amount * @return void */ private function addAmount(PiggyBank $piggyBank, TransactionJournal $journal, string $amount): void @@ -176,51 +223,4 @@ class UpdatePiggybank implements ActionInterface $repository->addAmount($piggyBank, $amount, $journal); } - - /** - * @param User $user - * - * @return PiggyBank|null - */ - private function findPiggyBank(User $user): ?PiggyBank - { - return $user->piggyBanks()->where('piggy_banks.name', $this->action->action_value)->first(); - } - - /** - * @param PiggyBank $piggyBank - * @param TransactionJournal $journal - * @param string $amount - * @return void - */ - private function removeAmount(PiggyBank $piggyBank, TransactionJournal $journal, string $amount): void - { - $repository = app(PiggyBankRepositoryInterface::class); - $repository->setUser($journal->user); - - // how much can we remove from this piggy bank? - $toRemove = $repository->getCurrentAmount($piggyBank); - Log::debug(sprintf('Amount is %s, max to remove is %s', $amount, $toRemove)); - - // if $amount is bigger than $toRemove, shrink it. - $amount = -1 === bccomp($amount, $toRemove) ? $amount : $toRemove; - Log::debug(sprintf('Amount is now %s', $amount)); - - // if amount is zero, stop. - if (0 === bccomp('0', $amount)) { - app('log')->warning('Amount left is zero, stop.'); - - return; - } - - // make sure we can remove amount: - if (false === $repository->canRemoveAmount($piggyBank, $amount)) { - app('log')->warning(sprintf('Cannot remove %s from piggy bank.', $amount)); - - return; - } - Log::debug(sprintf('Will now remove %s from piggy bank.', $amount)); - - $repository->removeAmount($piggyBank, $amount, $journal); - } } diff --git a/app/TransactionRules/Engine/RuleEngineInterface.php b/app/TransactionRules/Engine/RuleEngineInterface.php index cca1956ee1..52890c070e 100644 --- a/app/TransactionRules/Engine/RuleEngineInterface.php +++ b/app/TransactionRules/Engine/RuleEngineInterface.php @@ -34,7 +34,7 @@ interface RuleEngineInterface /** * Add operators added to each search by the rule engine. * - * @param array $operator + * @param array $operator */ public function addOperator(array $operator): void; @@ -56,7 +56,7 @@ interface RuleEngineInterface public function getResults(): int; /** - * @param bool $refreshTriggers + * @param bool $refreshTriggers * @return void */ public function setRefreshTriggers(bool $refreshTriggers): void; @@ -64,19 +64,19 @@ interface RuleEngineInterface /** * Add entire rule groups for the engine to execute. * - * @param Collection $ruleGroups + * @param Collection $ruleGroups */ public function setRuleGroups(Collection $ruleGroups): void; /** * Add rules for the engine to execute. * - * @param Collection $rules + * @param Collection $rules */ public function setRules(Collection $rules): void; /** - * @param User $user + * @param User $user */ public function setUser(User $user): void; } diff --git a/app/TransactionRules/Engine/SearchRuleEngine.php b/app/TransactionRules/Engine/SearchRuleEngine.php index c8199c49a2..cb7ffa47b0 100644 --- a/app/TransactionRules/Engine/SearchRuleEngine.php +++ b/app/TransactionRules/Engine/SearchRuleEngine.php @@ -91,79 +91,129 @@ class SearchRuleEngine implements RuleEngineInterface } /** - * @inheritDoc - * @throws FireflyException - */ - public function fire(): void - { - $this->resultCount = []; - Log::debug('SearchRuleEngine::fire()!'); - - // if rules and no rule groups, file each rule separately. - if (0 !== $this->rules->count()) { - Log::debug(sprintf('SearchRuleEngine:: found %d rule(s) to fire.', $this->rules->count())); - foreach ($this->rules as $rule) { - $this->fireRule($rule); - } - Log::debug('SearchRuleEngine:: done processing all rules!'); - - return; - } - if (0 !== $this->groups->count()) { - Log::debug(sprintf('SearchRuleEngine:: found %d rule group(s) to fire.', $this->groups->count())); - // fire each group: - /** @var RuleGroup $group */ - foreach ($this->groups as $group) { - $this->fireGroup($group); - } - } - Log::debug('SearchRuleEngine:: done processing all rules!'); - } - - /** - * Return the number of changed transactions from the previous "fire" action. + * Finds the transactions a strict rule will execute on. * - * @return int + * @param Rule $rule + * + * @return Collection */ - public function getResults(): int + private function findStrictRule(Rule $rule): Collection { - return count($this->resultCount); - } + Log::debug(sprintf('Now in findStrictRule(#%d)', $rule->id ?? 0)); + $searchArray = []; + $triggers = []; + if ($this->refreshTriggers) { + $triggers = $rule->ruleTriggers()->orderBy('order', 'ASC')->get(); + } + if (!$this->refreshTriggers) { + $triggers = $rule->ruleTriggers; + } - /** - * @param bool $refreshTriggers - */ - public function setRefreshTriggers(bool $refreshTriggers): void - { - $this->refreshTriggers = $refreshTriggers; - } + /** @var RuleTrigger $ruleTrigger */ + foreach ($triggers as $ruleTrigger) { + if (false === $ruleTrigger->active) { + continue; + } - /** - * @inheritDoc - */ - public function setRuleGroups(Collection $ruleGroups): void - { - Log::debug(__METHOD__); - foreach ($ruleGroups as $group) { - if ($group instanceof RuleGroup) { - Log::debug(sprintf('Adding a rule group to the SearchRuleEngine: #%d ("%s")', $group->id, $group->title)); - $this->groups->push($group); + // if needs no context, value is different: + $needsContext = config(sprintf('search.operators.%s.needs_context', $ruleTrigger->trigger_type)) ?? true; + if (false === $needsContext) { + Log::debug(sprintf('SearchRuleEngine:: add a rule trigger: %s:true', $ruleTrigger->trigger_type)); + $searchArray[$ruleTrigger->trigger_type][] = 'true'; + } + if (true === $needsContext) { + Log::debug(sprintf('SearchRuleEngine:: add a rule trigger: %s:"%s"', $ruleTrigger->trigger_type, $ruleTrigger->trigger_value)); + $searchArray[$ruleTrigger->trigger_type][] = sprintf('"%s"', $ruleTrigger->trigger_value); } } + + + // add local operators: + foreach ($this->operators as $operator) { + Log::debug(sprintf('SearchRuleEngine:: add local added operator: %s:"%s"', $operator['type'], $operator['value'])); + $searchArray[$operator['type']][] = sprintf('"%s"', $operator['value']); + } + $date = today(config('app.timezone')); + if ($this->hasSpecificJournalTrigger($searchArray)) { + $date = $this->setDateFromJournalTrigger($searchArray); + } + // build and run the search engine. + $searchEngine = app(SearchInterface::class); + $searchEngine->setUser($this->user); + $searchEngine->setPage(1); + $searchEngine->setLimit(31337); + $searchEngine->setDate($date); + + foreach ($searchArray as $type => $searches) { + foreach ($searches as $value) { + $searchEngine->parseQuery(sprintf('%s:%s', $type, $value)); + } + } + + $result = $searchEngine->searchTransactions(); + + return $result->getCollection(); } /** - * @inheritDoc + * Search in the triggers of this particular search and if it contains + * one search operator for "journal_id" it means the date ranges + * in the search may need to be updated. + * + * @param array $array + * + * @return bool */ - public function setRules(Collection $rules): void + private function hasSpecificJournalTrigger(array $array): bool { - Log::debug(__METHOD__); - foreach ($rules as $rule) { - if ($rule instanceof Rule) { - Log::debug(sprintf('Adding a rule to the SearchRuleEngine: #%d ("%s")', $rule->id, $rule->title)); - $this->rules->push($rule); + Log::debug('Now in hasSpecificJournalTrigger.'); + $journalTrigger = false; + $dateTrigger = false; + foreach ($array as $triggerName => $values) { + if ('journal_id' === $triggerName && is_array($values) && 1 === count($values)) { + Log::debug('Found a journal_id trigger with 1 journal, true.'); + $journalTrigger = true; + } + if (in_array($triggerName, ['date_is', 'date', 'on', 'date_before', 'before', 'date_after', 'after'], true)) { + Log::debug('Found a date related trigger, set to true.'); + $dateTrigger = true; } } + $result = $journalTrigger && $dateTrigger; + Log::debug(sprintf('Result of hasSpecificJournalTrigger is %s.', var_export($result, true))); + + return $result; + } + + /** + * @param array $array + * + * @return Carbon + */ + private function setDateFromJournalTrigger(array $array): Carbon + { + Log::debug('Now in setDateFromJournalTrigger()'); + $journalId = 0; + foreach ($array as $triggerName => $values) { + if ('journal_id' === $triggerName && is_array($values) && 1 === count($values)) { + $journalId = (int)trim(($values[0] ?? '"0"'), '"'); // follows format "123". + Log::debug(sprintf('Found journal ID #%d', $journalId)); + } + } + if (0 !== $journalId) { + $repository = app(JournalRepositoryInterface::class); + $repository->setUser($this->user); + $journal = $repository->find($journalId); + if (null !== $journal) { + $date = $journal->date; + Log::debug(sprintf('Found journal #%d with date %s.', $journal->id, $journal->date->format('Y-m-d'))); + + return $date; + } + } + Log::debug('Found no journal, return default date.'); + + return today(config('app.timezone')); } /** @@ -176,7 +226,7 @@ class SearchRuleEngine implements RuleEngineInterface } /** - * @param Rule $rule + * @param Rule $rule * * @return Collection */ @@ -259,118 +309,39 @@ class SearchRuleEngine implements RuleEngineInterface } /** - * Finds the transactions a strict rule will execute on. - * - * @param Rule $rule - * - * @return Collection - */ - private function findStrictRule(Rule $rule): Collection - { - Log::debug(sprintf('Now in findStrictRule(#%d)', $rule->id ?? 0)); - $searchArray = []; - $triggers = []; - if ($this->refreshTriggers) { - $triggers = $rule->ruleTriggers()->orderBy('order', 'ASC')->get(); - } - if (!$this->refreshTriggers) { - $triggers = $rule->ruleTriggers; - } - - /** @var RuleTrigger $ruleTrigger */ - foreach ($triggers as $ruleTrigger) { - if (false === $ruleTrigger->active) { - continue; - } - - // if needs no context, value is different: - $needsContext = config(sprintf('search.operators.%s.needs_context', $ruleTrigger->trigger_type)) ?? true; - if (false === $needsContext) { - Log::debug(sprintf('SearchRuleEngine:: add a rule trigger: %s:true', $ruleTrigger->trigger_type)); - $searchArray[$ruleTrigger->trigger_type][] = 'true'; - } - if (true === $needsContext) { - Log::debug(sprintf('SearchRuleEngine:: add a rule trigger: %s:"%s"', $ruleTrigger->trigger_type, $ruleTrigger->trigger_value)); - $searchArray[$ruleTrigger->trigger_type][] = sprintf('"%s"', $ruleTrigger->trigger_value); - } - } - - - // add local operators: - foreach ($this->operators as $operator) { - Log::debug(sprintf('SearchRuleEngine:: add local added operator: %s:"%s"', $operator['type'], $operator['value'])); - $searchArray[$operator['type']][] = sprintf('"%s"', $operator['value']); - } - $date = today(config('app.timezone')); - if ($this->hasSpecificJournalTrigger($searchArray)) { - $date = $this->setDateFromJournalTrigger($searchArray); - } - // build and run the search engine. - $searchEngine = app(SearchInterface::class); - $searchEngine->setUser($this->user); - $searchEngine->setPage(1); - $searchEngine->setLimit(31337); - $searchEngine->setDate($date); - - foreach ($searchArray as $type => $searches) { - foreach ($searches as $value) { - $searchEngine->parseQuery(sprintf('%s:%s', $type, $value)); - } - } - - $result = $searchEngine->searchTransactions(); - - return $result->getCollection(); - } - - /** - * @param RuleGroup $group - * - * @return void + * @inheritDoc * @throws FireflyException */ - private function fireGroup(RuleGroup $group): void + public function fire(): void { - $all = false; - Log::debug(sprintf('Going to fire group #%d with %d rule(s)', $group->id, $group->rules->count())); - /** @var Rule $rule */ - foreach ($group->rules as $rule) { - Log::debug(sprintf('Going to fire rule #%d from group #%d', $rule->id, $group->id)); - $result = $this->fireRule($rule); - if (true === $result) { - $all = true; - } - if (true === $result && true === $rule->stop_processing) { - Log::debug(sprintf('The rule was triggered and rule->stop_processing = true, so group #%d will stop processing further rules.', $group->id)); + $this->resultCount = []; + Log::debug('SearchRuleEngine::fire()!'); - return; + // if rules and no rule groups, file each rule separately. + if (0 !== $this->rules->count()) { + Log::debug(sprintf('SearchRuleEngine:: found %d rule(s) to fire.', $this->rules->count())); + foreach ($this->rules as $rule) { + $this->fireRule($rule); + } + Log::debug('SearchRuleEngine:: done processing all rules!'); + + return; + } + if (0 !== $this->groups->count()) { + Log::debug(sprintf('SearchRuleEngine:: found %d rule group(s) to fire.', $this->groups->count())); + // fire each group: + /** @var RuleGroup $group */ + foreach ($this->groups as $group) { + $this->fireGroup($group); } } - } - - /** - * Return true if the rule is fired (the collection is larger than zero). - * - * @param Rule $rule - * - * @return bool - * @throws FireflyException - */ - private function fireNonStrictRule(Rule $rule): bool - { - Log::debug(sprintf('SearchRuleEngine::fireNonStrictRule(%d)!', $rule->id)); - $collection = $this->findNonStrictRule($rule); - - $this->processResults($rule, $collection); - Log::debug(sprintf('SearchRuleEngine:: done processing non-strict rule #%d', $rule->id)); - - return $collection->count() > 0; + Log::debug('SearchRuleEngine:: done processing all rules!'); } /** * Returns true if the rule has been triggered. * - * @param Rule $rule + * @param Rule $rule * * @return bool * @throws FireflyException @@ -396,7 +367,7 @@ class SearchRuleEngine implements RuleEngineInterface /** * Return true if the rule is fired (the collection is larger than zero). * - * @param Rule $rule + * @param Rule $rule * * @return bool * @throws FireflyException @@ -421,38 +392,8 @@ class SearchRuleEngine implements RuleEngineInterface } /** - * Search in the triggers of this particular search and if it contains - * one search operator for "journal_id" it means the date ranges - * in the search may need to be updated. - * - * @param array $array - * - * @return bool - */ - private function hasSpecificJournalTrigger(array $array): bool - { - Log::debug('Now in hasSpecificJournalTrigger.'); - $journalTrigger = false; - $dateTrigger = false; - foreach ($array as $triggerName => $values) { - if ('journal_id' === $triggerName && is_array($values) && 1 === count($values)) { - Log::debug('Found a journal_id trigger with 1 journal, true.'); - $journalTrigger = true; - } - if (in_array($triggerName, ['date_is', 'date', 'on', 'date_before', 'before', 'date_after', 'after'], true)) { - Log::debug('Found a date related trigger, set to true.'); - $dateTrigger = true; - } - } - $result = $journalTrigger && $dateTrigger; - Log::debug(sprintf('Result of hasSpecificJournalTrigger is %s.', var_export($result, true))); - - return $result; - } - - /** - * @param Rule $rule - * @param Collection $collection + * @param Rule $rule + * @param Collection $collection * * @throws FireflyException */ @@ -466,8 +407,45 @@ class SearchRuleEngine implements RuleEngineInterface } /** - * @param RuleAction $ruleAction - * @param array $transaction + * @param Rule $rule + * @param array $group + * + * @throws FireflyException + */ + private function processTransactionGroup(Rule $rule, array $group): void + { + Log::debug(sprintf('SearchRuleEngine:: Will now execute actions on transaction group #%d', $group['id'])); + /** @var array $transaction */ + foreach ($group['transactions'] as $transaction) { + $this->processTransactionJournal($rule, $transaction); + } + } + + /** + * @param Rule $rule + * @param array $transaction + * + * @throws FireflyException + */ + private function processTransactionJournal(Rule $rule, array $transaction): void + { + Log::debug(sprintf('SearchRuleEngine:: Will now execute actions on transaction journal #%d', $transaction['transaction_journal_id'])); + $actions = $rule->ruleActions()->orderBy('order', 'ASC')->get(); + /** @var RuleAction $ruleAction */ + foreach ($actions as $ruleAction) { + if (false === $ruleAction->active) { + continue; + } + $break = $this->processRuleAction($ruleAction, $transaction); + if (true === $break) { + break; + } + } + } + + /** + * @param RuleAction $ruleAction + * @param array $transaction * * @return bool * @throws FireflyException @@ -504,70 +482,92 @@ class SearchRuleEngine implements RuleEngineInterface } /** - * @param Rule $rule - * @param array $group + * Return true if the rule is fired (the collection is larger than zero). * + * @param Rule $rule + * + * @return bool * @throws FireflyException */ - private function processTransactionGroup(Rule $rule, array $group): void + private function fireNonStrictRule(Rule $rule): bool { - Log::debug(sprintf('SearchRuleEngine:: Will now execute actions on transaction group #%d', $group['id'])); - /** @var array $transaction */ - foreach ($group['transactions'] as $transaction) { - $this->processTransactionJournal($rule, $transaction); - } + Log::debug(sprintf('SearchRuleEngine::fireNonStrictRule(%d)!', $rule->id)); + $collection = $this->findNonStrictRule($rule); + + $this->processResults($rule, $collection); + Log::debug(sprintf('SearchRuleEngine:: done processing non-strict rule #%d', $rule->id)); + + return $collection->count() > 0; } /** - * @param Rule $rule - * @param array $transaction + * @param RuleGroup $group * + * @return void * @throws FireflyException */ - private function processTransactionJournal(Rule $rule, array $transaction): void + private function fireGroup(RuleGroup $group): void { - Log::debug(sprintf('SearchRuleEngine:: Will now execute actions on transaction journal #%d', $transaction['transaction_journal_id'])); - $actions = $rule->ruleActions()->orderBy('order', 'ASC')->get(); - /** @var RuleAction $ruleAction */ - foreach ($actions as $ruleAction) { - if (false === $ruleAction->active) { - continue; + $all = false; + Log::debug(sprintf('Going to fire group #%d with %d rule(s)', $group->id, $group->rules->count())); + /** @var Rule $rule */ + foreach ($group->rules as $rule) { + Log::debug(sprintf('Going to fire rule #%d from group #%d', $rule->id, $group->id)); + $result = $this->fireRule($rule); + if (true === $result) { + $all = true; } - $break = $this->processRuleAction($ruleAction, $transaction); - if (true === $break) { - break; + if (true === $result && true === $rule->stop_processing) { + Log::debug(sprintf('The rule was triggered and rule->stop_processing = true, so group #%d will stop processing further rules.', $group->id)); + + return; } } } /** - * @param array $array + * Return the number of changed transactions from the previous "fire" action. * - * @return Carbon + * @return int */ - private function setDateFromJournalTrigger(array $array): Carbon + public function getResults(): int { - Log::debug('Now in setDateFromJournalTrigger()'); - $journalId = 0; - foreach ($array as $triggerName => $values) { - if ('journal_id' === $triggerName && is_array($values) && 1 === count($values)) { - $journalId = (int)trim(($values[0] ?? '"0"'), '"'); // follows format "123". - Log::debug(sprintf('Found journal ID #%d', $journalId)); + return count($this->resultCount); + } + + /** + * @param bool $refreshTriggers + */ + public function setRefreshTriggers(bool $refreshTriggers): void + { + $this->refreshTriggers = $refreshTriggers; + } + + /** + * @inheritDoc + */ + public function setRuleGroups(Collection $ruleGroups): void + { + Log::debug(__METHOD__); + foreach ($ruleGroups as $group) { + if ($group instanceof RuleGroup) { + Log::debug(sprintf('Adding a rule group to the SearchRuleEngine: #%d ("%s")', $group->id, $group->title)); + $this->groups->push($group); } } - if (0 !== $journalId) { - $repository = app(JournalRepositoryInterface::class); - $repository->setUser($this->user); - $journal = $repository->find($journalId); - if (null !== $journal) { - $date = $journal->date; - Log::debug(sprintf('Found journal #%d with date %s.', $journal->id, $journal->date->format('Y-m-d'))); + } - return $date; + /** + * @inheritDoc + */ + public function setRules(Collection $rules): void + { + Log::debug(__METHOD__); + foreach ($rules as $rule) { + if ($rule instanceof Rule) { + Log::debug(sprintf('Adding a rule to the SearchRuleEngine: #%d ("%s")', $rule->id, $rule->title)); + $this->rules->push($rule); } } - Log::debug('Found no journal, return default date.'); - - return today(config('app.timezone')); } } diff --git a/app/TransactionRules/Factory/ActionFactory.php b/app/TransactionRules/Factory/ActionFactory.php index 8263b61275..0f7275e32e 100644 --- a/app/TransactionRules/Factory/ActionFactory.php +++ b/app/TransactionRules/Factory/ActionFactory.php @@ -45,7 +45,7 @@ class ActionFactory * with value "Groceries" this method will return a corresponding SetCategory object preset * to "Groceries". Any transaction journal then fed to this object will have its category changed. * - * @param RuleAction $action + * @param RuleAction $action * * @return ActionInterface * @@ -64,7 +64,7 @@ class ActionFactory * that will match the given action type (ie. "change_category") to the matching class name * (SetCategory) using the configuration (firefly.php). * - * @param string $actionType + * @param string $actionType * * @return string * @@ -75,12 +75,12 @@ class ActionFactory $actionTypes = self::getActionTypes(); if (!array_key_exists($actionType, $actionTypes)) { - throw new FireflyException('No such action exists ("'.e($actionType).'").'); + throw new FireflyException('No such action exists ("' . e($actionType) . '").'); } $class = $actionTypes[$actionType]; if (!class_exists($class)) { - throw new FireflyException('Could not instantiate class for rule action type "'.e($actionType).'" ('.e($class).').'); + throw new FireflyException('Could not instantiate class for rule action type "' . e($actionType) . '" (' . e($class) . ').'); } return $class; diff --git a/app/Transformers/AbstractTransformer.php b/app/Transformers/AbstractTransformer.php index 19780f730b..1e76cf7ac1 100644 --- a/app/Transformers/AbstractTransformer.php +++ b/app/Transformers/AbstractTransformer.php @@ -43,7 +43,7 @@ abstract class AbstractTransformer extends TransformerAbstract } /** - * @param ParameterBag $parameters + * @param ParameterBag $parameters */ final public function setParameters(ParameterBag $parameters): void { diff --git a/app/Transformers/AccountTransformer.php b/app/Transformers/AccountTransformer.php index 95471f7307..eaa82dca79 100644 --- a/app/Transformers/AccountTransformer.php +++ b/app/Transformers/AccountTransformer.php @@ -52,7 +52,7 @@ class AccountTransformer extends AbstractTransformer /** * Transform the account. * - * @param Account $account + * @param Account $account * * @return array * @throws FireflyException @@ -133,16 +133,16 @@ class AccountTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/accounts/'.$account->id, + 'uri' => '/accounts/' . $account->id, ], ], ]; } /** - * @param Account $account + * @param Account $account * - * @param string $accountType + * @param string $accountType * * @return string|null */ @@ -157,9 +157,47 @@ class AccountTransformer extends AbstractTransformer } /** - * @param Account $account - * @param string|null $accountRole - * @param string $accountType + * TODO duplicated in the V2 transformer. + * + * @return Carbon + */ + private function getDate(): Carbon + { + $date = today(config('app.timezone')); + if (null !== $this->parameters->get('date')) { + $date = $this->parameters->get('date'); + } + + return $date; + } + + /** + * @param Account $account + * + * @return array + * @throws FireflyException + * @throws JsonException + */ + private function getCurrency(Account $account): array + { + $currency = $this->repository->getAccountCurrency($account); + + // only grab default when result is null: + if (null === $currency) { + $currency = app('amount')->getDefaultCurrencyByUser($account->user); + } + $currencyId = (string)$currency->id; + $currencyCode = $currency->code; + $decimalPlaces = $currency->decimal_places; + $currencySymbol = $currency->symbol; + + return [$currencyId, $currencyCode, $currencySymbol, $decimalPlaces]; + } + + /** + * @param Account $account + * @param string|null $accountRole + * @param string $accountType * * @return array */ @@ -185,63 +223,8 @@ class AccountTransformer extends AbstractTransformer } /** - * @param Account $account - * - * @return array - * @throws FireflyException - * @throws JsonException - */ - private function getCurrency(Account $account): array - { - $currency = $this->repository->getAccountCurrency($account); - - // only grab default when result is null: - if (null === $currency) { - $currency = app('amount')->getDefaultCurrencyByUser($account->user); - } - $currencyId = (string)$currency->id; - $currencyCode = $currency->code; - $decimalPlaces = $currency->decimal_places; - $currencySymbol = $currency->symbol; - - return [$currencyId, $currencyCode, $currencySymbol, $decimalPlaces]; - } - - /** - * TODO duplicated in the V2 transformer. - * @return Carbon - */ - private function getDate(): Carbon - { - $date = today(config('app.timezone')); - if (null !== $this->parameters->get('date')) { - $date = $this->parameters->get('date'); - } - - return $date; - } - - /** - * @param Account $account - * @param string $accountType - * - * @return array - */ - private function getInterest(Account $account, string $accountType): array - { - $interest = null; - $interestPeriod = null; - if ('liabilities' === $accountType) { - $interest = $this->repository->getMetaValue($account, 'interest'); - $interestPeriod = $this->repository->getMetaValue($account, 'interest_period'); - } - - return [$interest, $interestPeriod]; - } - - /** - * @param Account $account - * @param string $accountType + * @param Account $account + * @param string $accountType * * @return array * @@ -262,4 +245,22 @@ class AccountTransformer extends AbstractTransformer return [$openingBalance, $openingBalanceDate]; } + + /** + * @param Account $account + * @param string $accountType + * + * @return array + */ + private function getInterest(Account $account, string $accountType): array + { + $interest = null; + $interestPeriod = null; + if ('liabilities' === $accountType) { + $interest = $this->repository->getMetaValue($account, 'interest'); + $interestPeriod = $this->repository->getMetaValue($account, 'interest_period'); + } + + return [$interest, $interestPeriod]; + } } diff --git a/app/Transformers/AttachmentTransformer.php b/app/Transformers/AttachmentTransformer.php index d71117f501..2429d02438 100644 --- a/app/Transformers/AttachmentTransformer.php +++ b/app/Transformers/AttachmentTransformer.php @@ -46,7 +46,7 @@ class AttachmentTransformer extends AbstractTransformer /** * Transform attachment. * - * @param Attachment $attachment + * @param Attachment $attachment * * @return array */ @@ -71,7 +71,7 @@ class AttachmentTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/attachment/'.$attachment->id, + 'uri' => '/attachment/' . $attachment->id, ], ], ]; diff --git a/app/Transformers/AvailableBudgetTransformer.php b/app/Transformers/AvailableBudgetTransformer.php index 2c50aedc5a..5f24686e0f 100644 --- a/app/Transformers/AvailableBudgetTransformer.php +++ b/app/Transformers/AvailableBudgetTransformer.php @@ -52,7 +52,7 @@ class AvailableBudgetTransformer extends AbstractTransformer /** * Transform the note. * - * @param AvailableBudget $availableBudget + * @param AvailableBudget $availableBudget * * @return array */ @@ -77,7 +77,7 @@ class AvailableBudgetTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/available_budgets/'.$availableBudget->id, + 'uri' => '/available_budgets/' . $availableBudget->id, ], ], ]; diff --git a/app/Transformers/BillTransformer.php b/app/Transformers/BillTransformer.php index 2564ac2f16..076f34f1c8 100644 --- a/app/Transformers/BillTransformer.php +++ b/app/Transformers/BillTransformer.php @@ -52,7 +52,7 @@ class BillTransformer extends AbstractTransformer /** * Transform the bill. * - * @param Bill $bill + * @param Bill $bill * * @return array */ @@ -137,63 +137,16 @@ class BillTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/bills/'.$bill->id, + 'uri' => '/bills/' . $bill->id, ], ], ]; } - /** - * Returns the latest date in the set, or start when set is empty. - * - * @param Collection $dates - * @param Carbon $default - * - * @return Carbon - */ - protected function lastPaidDate(Collection $dates, Carbon $default): Carbon - { - if (0 === $dates->count()) { - return $default; - } - $latest = $dates->first()->date; - /** @var TransactionJournal $journal */ - foreach ($dates as $journal) { - if ($journal->date->gte($latest)) { - $latest = $journal->date; - } - } - - return $latest; - } - - /** - * Given a bill and a date, this method will tell you at which moment this bill expects its next - * transaction. Whether or not it is there already, is not relevant. - * - * @param Bill $bill - * @param Carbon $date - * - * @return Carbon - */ - protected function nextDateMatch(Bill $bill, Carbon $date): Carbon - { - //Log::debug(sprintf('Now in nextDateMatch(%d, %s)', $bill->id, $date->format('Y-m-d'))); - $start = clone $bill->date; - //Log::debug(sprintf('Bill start date is %s', $start->format('Y-m-d'))); - while ($start < $date) { - $start = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip); - } - - //Log::debug(sprintf('End of loop, bill start date is now %s', $start->format('Y-m-d'))); - - return $start; - } - /** * Get the data the bill was paid and predict the next expected match. * - * @param Bill $bill + * @param Bill $bill * * @return array */ @@ -265,7 +218,31 @@ class BillTransformer extends AbstractTransformer } /** - * @param Bill $bill + * Returns the latest date in the set, or start when set is empty. + * + * @param Collection $dates + * @param Carbon $default + * + * @return Carbon + */ + protected function lastPaidDate(Collection $dates, Carbon $default): Carbon + { + if (0 === $dates->count()) { + return $default; + } + $latest = $dates->first()->date; + /** @var TransactionJournal $journal */ + foreach ($dates as $journal) { + if ($journal->date->gte($latest)) { + $latest = $journal->date; + } + } + + return $latest; + } + + /** + * @param Bill $bill * * @return array */ @@ -303,4 +280,27 @@ class BillTransformer extends AbstractTransformer return $simple->toArray(); } + + /** + * Given a bill and a date, this method will tell you at which moment this bill expects its next + * transaction. Whether or not it is there already, is not relevant. + * + * @param Bill $bill + * @param Carbon $date + * + * @return Carbon + */ + protected function nextDateMatch(Bill $bill, Carbon $date): Carbon + { + //Log::debug(sprintf('Now in nextDateMatch(%d, %s)', $bill->id, $date->format('Y-m-d'))); + $start = clone $bill->date; + //Log::debug(sprintf('Bill start date is %s', $start->format('Y-m-d'))); + while ($start < $date) { + $start = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip); + } + + //Log::debug(sprintf('End of loop, bill start date is now %s', $start->format('Y-m-d'))); + + return $start; + } } diff --git a/app/Transformers/BudgetLimitTransformer.php b/app/Transformers/BudgetLimitTransformer.php index 1afb62ae2b..f4d9ea6532 100644 --- a/app/Transformers/BudgetLimitTransformer.php +++ b/app/Transformers/BudgetLimitTransformer.php @@ -42,7 +42,7 @@ class BudgetLimitTransformer extends AbstractTransformer /** * Include Budget * - * @param BudgetLimit $limit + * @param BudgetLimit $limit * * @return Item */ @@ -54,7 +54,7 @@ class BudgetLimitTransformer extends AbstractTransformer /** * Transform the note. * - * @param BudgetLimit $budgetLimit + * @param BudgetLimit $budgetLimit * * @return array */ @@ -104,7 +104,7 @@ class BudgetLimitTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/budgets/limits/'.$budgetLimit->id, + 'uri' => '/budgets/limits/' . $budgetLimit->id, ], ], ]; diff --git a/app/Transformers/BudgetTransformer.php b/app/Transformers/BudgetTransformer.php index ca3daf4139..75411190d7 100644 --- a/app/Transformers/BudgetTransformer.php +++ b/app/Transformers/BudgetTransformer.php @@ -53,7 +53,7 @@ class BudgetTransformer extends AbstractTransformer /** * Transform a budget. * - * @param Budget $budget + * @param Budget $budget * * @return array */ @@ -106,14 +106,14 @@ class BudgetTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/budgets/'.$budget->id, + 'uri' => '/budgets/' . $budget->id, ], ], ]; } /** - * @param array $array + * @param array $array * * @return array */ diff --git a/app/Transformers/CategoryTransformer.php b/app/Transformers/CategoryTransformer.php index 9f1b9836e1..f04df6ced5 100644 --- a/app/Transformers/CategoryTransformer.php +++ b/app/Transformers/CategoryTransformer.php @@ -50,7 +50,7 @@ class CategoryTransformer extends AbstractTransformer /** * Convert category. * - * @param Category $category + * @param Category $category * * @return array */ @@ -80,14 +80,14 @@ class CategoryTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/categories/'.$category->id, + 'uri' => '/categories/' . $category->id, ], ], ]; } /** - * @param array $array + * @param array $array * * @return array */ diff --git a/app/Transformers/CurrencyTransformer.php b/app/Transformers/CurrencyTransformer.php index 3d3afef4d2..2c363f19eb 100644 --- a/app/Transformers/CurrencyTransformer.php +++ b/app/Transformers/CurrencyTransformer.php @@ -33,7 +33,7 @@ class CurrencyTransformer extends AbstractTransformer /** * Transform the currency. * - * @param TransactionCurrency $currency + * @param TransactionCurrency $currency * * @return array */ @@ -58,7 +58,7 @@ class CurrencyTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/currencies/'.$currency->id, + 'uri' => '/currencies/' . $currency->id, ], ], ]; diff --git a/app/Transformers/LinkTypeTransformer.php b/app/Transformers/LinkTypeTransformer.php index 6fd860acc6..13f3b36eb5 100644 --- a/app/Transformers/LinkTypeTransformer.php +++ b/app/Transformers/LinkTypeTransformer.php @@ -34,7 +34,7 @@ class LinkTypeTransformer extends AbstractTransformer /** * Transform the currency. * - * @param LinkType $linkType + * @param LinkType $linkType * * @return array */ @@ -51,7 +51,7 @@ class LinkTypeTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/link_types/'.$linkType->id, + 'uri' => '/link_types/' . $linkType->id, ], ], ]; diff --git a/app/Transformers/ObjectGroupTransformer.php b/app/Transformers/ObjectGroupTransformer.php index 7fa38b9f52..4bc4f70a8b 100644 --- a/app/Transformers/ObjectGroupTransformer.php +++ b/app/Transformers/ObjectGroupTransformer.php @@ -47,7 +47,7 @@ class ObjectGroupTransformer extends AbstractTransformer /** * Transform the account. * - * @param ObjectGroup $objectGroup + * @param ObjectGroup $objectGroup * * @return array */ @@ -64,7 +64,7 @@ class ObjectGroupTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/object_groups/'.$objectGroup->id, + 'uri' => '/object_groups/' . $objectGroup->id, ], ], ]; diff --git a/app/Transformers/PiggyBankEventTransformer.php b/app/Transformers/PiggyBankEventTransformer.php index e000cc2de0..0ab17a4f07 100644 --- a/app/Transformers/PiggyBankEventTransformer.php +++ b/app/Transformers/PiggyBankEventTransformer.php @@ -54,7 +54,7 @@ class PiggyBankEventTransformer extends AbstractTransformer /** * Convert piggy bank event. * - * @param PiggyBankEvent $event + * @param PiggyBankEvent $event * * @return array * @throws FireflyException @@ -95,7 +95,7 @@ class PiggyBankEventTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/piggy_bank_events/'.$event->id, + 'uri' => '/piggy_bank_events/' . $event->id, ], ], ]; diff --git a/app/Transformers/PiggyBankTransformer.php b/app/Transformers/PiggyBankTransformer.php index e50df975c6..0af30de935 100644 --- a/app/Transformers/PiggyBankTransformer.php +++ b/app/Transformers/PiggyBankTransformer.php @@ -55,7 +55,7 @@ class PiggyBankTransformer extends AbstractTransformer /** * Transform the piggy bank. * - * @param PiggyBank $piggyBank + * @param PiggyBank $piggyBank * * @return array * @throws FireflyException @@ -133,7 +133,7 @@ class PiggyBankTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/piggy_banks/'.$piggyBank->id, + 'uri' => '/piggy_banks/' . $piggyBank->id, ], ], ]; diff --git a/app/Transformers/PreferenceTransformer.php b/app/Transformers/PreferenceTransformer.php index 34298d9b4f..e108e3effb 100644 --- a/app/Transformers/PreferenceTransformer.php +++ b/app/Transformers/PreferenceTransformer.php @@ -33,7 +33,7 @@ class PreferenceTransformer extends AbstractTransformer /** * Transform the preference * - * @param Preference $preference + * @param Preference $preference * * @return array */ diff --git a/app/Transformers/RecurrenceTransformer.php b/app/Transformers/RecurrenceTransformer.php index b5f6069ded..f63dd9d65a 100644 --- a/app/Transformers/RecurrenceTransformer.php +++ b/app/Transformers/RecurrenceTransformer.php @@ -65,7 +65,7 @@ class RecurrenceTransformer extends AbstractTransformer /** * Transform the recurring transaction. * - * @param Recurrence $recurrence + * @param Recurrence $recurrence * * @return array * @throws FireflyException @@ -104,14 +104,14 @@ class RecurrenceTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/recurring/'.$recurrence->id, + 'uri' => '/recurring/' . $recurrence->id, ], ], ]; } /** - * @param Recurrence $recurrence + * @param Recurrence $recurrence * * @return array * @throws FireflyException @@ -150,76 +150,7 @@ class RecurrenceTransformer extends AbstractTransformer } /** - * @param RecurrenceTransaction $transaction - * @param array $array - * - * @return array - * @throws FireflyException - */ - private function getTransactionMeta(RecurrenceTransaction $transaction, array $array): array - { - Log::debug(sprintf('Now in %s', __METHOD__)); - $array['tags'] = []; - $array['category_id'] = null; - $array['category_name'] = null; - $array['budget_id'] = null; - $array['budget_name'] = null; - $array['piggy_bank_id'] = null; - $array['piggy_bank_name'] = null; - $array['bill_id'] = null; - $array['bill_name'] = null; - - /** @var RecurrenceTransactionMeta $transactionMeta */ - foreach ($transaction->recurrenceTransactionMeta as $transactionMeta) { - switch ($transactionMeta->name) { - default: - throw new FireflyException(sprintf('Recurrence transformer cant handle field "%s"', $transactionMeta->name)); - case 'bill_id': - $bill = $this->billRepos->find((int)$transactionMeta->value); - if (null !== $bill) { - $array['bill_id'] = (string)$bill->id; - $array['bill_name'] = $bill->name; - } - break; - case 'tags': - $array['tags'] = json_decode($transactionMeta->value); - break; - case 'piggy_bank_id': - $piggy = $this->piggyRepos->find((int)$transactionMeta->value); - if (null !== $piggy) { - $array['piggy_bank_id'] = (string)$piggy->id; - $array['piggy_bank_name'] = $piggy->name; - } - break; - case 'category_id': - $category = $this->factory->findOrCreate((int)$transactionMeta->value, null); - if (null !== $category) { - $array['category_id'] = (string)$category->id; - $array['category_name'] = $category->name; - } - break; - case 'category_name': - $category = $this->factory->findOrCreate(null, $transactionMeta->value); - if (null !== $category) { - $array['category_id'] = (string)$category->id; - $array['category_name'] = $category->name; - } - break; - case 'budget_id': - $budget = $this->budgetRepos->find((int)$transactionMeta->value); - if (null !== $budget) { - $array['budget_id'] = (string)$budget->id; - $array['budget_name'] = $budget->name; - } - break; - } - } - - return $array; - } - - /** - * @param Recurrence $recurrence + * @param Recurrence $recurrence * * @return array * @throws FireflyException @@ -305,4 +236,73 @@ class RecurrenceTransformer extends AbstractTransformer return $return; } + + /** + * @param RecurrenceTransaction $transaction + * @param array $array + * + * @return array + * @throws FireflyException + */ + private function getTransactionMeta(RecurrenceTransaction $transaction, array $array): array + { + Log::debug(sprintf('Now in %s', __METHOD__)); + $array['tags'] = []; + $array['category_id'] = null; + $array['category_name'] = null; + $array['budget_id'] = null; + $array['budget_name'] = null; + $array['piggy_bank_id'] = null; + $array['piggy_bank_name'] = null; + $array['bill_id'] = null; + $array['bill_name'] = null; + + /** @var RecurrenceTransactionMeta $transactionMeta */ + foreach ($transaction->recurrenceTransactionMeta as $transactionMeta) { + switch ($transactionMeta->name) { + default: + throw new FireflyException(sprintf('Recurrence transformer cant handle field "%s"', $transactionMeta->name)); + case 'bill_id': + $bill = $this->billRepos->find((int)$transactionMeta->value); + if (null !== $bill) { + $array['bill_id'] = (string)$bill->id; + $array['bill_name'] = $bill->name; + } + break; + case 'tags': + $array['tags'] = json_decode($transactionMeta->value); + break; + case 'piggy_bank_id': + $piggy = $this->piggyRepos->find((int)$transactionMeta->value); + if (null !== $piggy) { + $array['piggy_bank_id'] = (string)$piggy->id; + $array['piggy_bank_name'] = $piggy->name; + } + break; + case 'category_id': + $category = $this->factory->findOrCreate((int)$transactionMeta->value, null); + if (null !== $category) { + $array['category_id'] = (string)$category->id; + $array['category_name'] = $category->name; + } + break; + case 'category_name': + $category = $this->factory->findOrCreate(null, $transactionMeta->value); + if (null !== $category) { + $array['category_id'] = (string)$category->id; + $array['category_name'] = $category->name; + } + break; + case 'budget_id': + $budget = $this->budgetRepos->find((int)$transactionMeta->value); + if (null !== $budget) { + $array['budget_id'] = (string)$budget->id; + $array['budget_name'] = $budget->name; + } + break; + } + } + + return $array; + } } diff --git a/app/Transformers/RuleGroupTransformer.php b/app/Transformers/RuleGroupTransformer.php index 0c7f4ba1c1..bb83a5dc05 100644 --- a/app/Transformers/RuleGroupTransformer.php +++ b/app/Transformers/RuleGroupTransformer.php @@ -33,7 +33,7 @@ class RuleGroupTransformer extends AbstractTransformer /** * Transform the rule group * - * @param RuleGroup $ruleGroup + * @param RuleGroup $ruleGroup * * @return array */ @@ -50,7 +50,7 @@ class RuleGroupTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/rule_groups/'.$ruleGroup->id, + 'uri' => '/rule_groups/' . $ruleGroup->id, ], ], ]; diff --git a/app/Transformers/RuleTransformer.php b/app/Transformers/RuleTransformer.php index 58f2148ddf..2a0d3f80a5 100644 --- a/app/Transformers/RuleTransformer.php +++ b/app/Transformers/RuleTransformer.php @@ -50,7 +50,7 @@ class RuleTransformer extends AbstractTransformer /** * Transform the rule. * - * @param Rule $rule + * @param Rule $rule * * @return array * @throws FireflyException @@ -77,40 +77,14 @@ class RuleTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/rules/'.$rule->id, + 'uri' => '/rules/' . $rule->id, ], ], ]; } /** - * @param Rule $rule - * - * @return array - */ - private function actions(Rule $rule): array - { - $result = []; - $actions = $this->ruleRepository->getRuleActions($rule); - /** @var RuleAction $ruleAction */ - foreach ($actions as $ruleAction) { - $result[] = [ - 'id' => (string)$ruleAction->id, - 'created_at' => $ruleAction->created_at->toAtomString(), - 'updated_at' => $ruleAction->updated_at->toAtomString(), - 'type' => $ruleAction->action_type, - 'value' => $ruleAction->action_value, - 'order' => $ruleAction->order, - 'active' => $ruleAction->active, - 'stop_processing' => $ruleAction->stop_processing, - ]; - } - - return $result; - } - - /** - * @param Rule $rule + * @param Rule $rule * * @return string * @throws FireflyException @@ -133,7 +107,7 @@ class RuleTransformer extends AbstractTransformer } /** - * @param Rule $rule + * @param Rule $rule * * @return array */ @@ -160,4 +134,30 @@ class RuleTransformer extends AbstractTransformer return $result; } + + /** + * @param Rule $rule + * + * @return array + */ + private function actions(Rule $rule): array + { + $result = []; + $actions = $this->ruleRepository->getRuleActions($rule); + /** @var RuleAction $ruleAction */ + foreach ($actions as $ruleAction) { + $result[] = [ + 'id' => (string)$ruleAction->id, + 'created_at' => $ruleAction->created_at->toAtomString(), + 'updated_at' => $ruleAction->updated_at->toAtomString(), + 'type' => $ruleAction->action_type, + 'value' => $ruleAction->action_value, + 'order' => $ruleAction->order, + 'active' => $ruleAction->active, + 'stop_processing' => $ruleAction->stop_processing, + ]; + } + + return $result; + } } diff --git a/app/Transformers/TagTransformer.php b/app/Transformers/TagTransformer.php index 169a8ac206..067a508cd2 100644 --- a/app/Transformers/TagTransformer.php +++ b/app/Transformers/TagTransformer.php @@ -36,7 +36,7 @@ class TagTransformer extends AbstractTransformer * * TODO add spent, earned, transferred, etc. * - * @param Tag $tag + * @param Tag $tag * * @return array */ @@ -67,7 +67,7 @@ class TagTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/tags/'.$tag->id, + 'uri' => '/tags/' . $tag->id, ], ], ]; diff --git a/app/Transformers/TransactionGroupTransformer.php b/app/Transformers/TransactionGroupTransformer.php index 8ebdc65cd6..f8983940e3 100644 --- a/app/Transformers/TransactionGroupTransformer.php +++ b/app/Transformers/TransactionGroupTransformer.php @@ -78,7 +78,7 @@ class TransactionGroupTransformer extends AbstractTransformer } /** - * @param array $group + * @param array $group * * @return array */ @@ -97,441 +97,30 @@ class TransactionGroupTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/transactions/'.$first['transaction_group_id'], + 'uri' => '/transactions/' . $first['transaction_group_id'], ], ], ]; } /** - * @param TransactionGroup $group - * - * @return array - * @throws FireflyException - */ - public function transformObject(TransactionGroup $group): array - { - try { - $result = [ - 'id' => (int)$group->id, - 'created_at' => $group->created_at->toAtomString(), - 'updated_at' => $group->updated_at->toAtomString(), - 'user' => (int)$group->user_id, - 'group_title' => $group->title, - 'transactions' => $this->transformJournals($group->transactionJournals), - 'links' => [ - [ - 'rel' => 'self', - 'uri' => '/transactions/'.$group->id, - ], - ], - ]; - } catch (FireflyException $e) { - Log::error($e->getMessage()); - Log::error($e->getTraceAsString()); - throw new FireflyException(sprintf('Transaction group #%d is broken. Please check out your log files.', $group->id), 0, $e); - } - - // do something else. - - return $result; - } - - /** - * @param NullArrayObject $object - * @param string $key - * - * @return string|null - */ - private function dateFromArray(NullArrayObject $object, string $key): ?string - { - if (null === $object[$key]) { - return null; - } - - return $object[$key]->toAtomString(); - } - - /** - * @param string $type - * @param string $amount - * - * @return string - */ - private function getAmount(string $type, string $amount): string - { - return app('steam')->positive($amount); - } - - /** - * @param Bill|null $bill + * @param NullArrayObject $data * * @return array */ - private function getBill(?Bill $bill): array + private function transformTransactions(NullArrayObject $data): array { - $array = [ - 'id' => null, - 'name' => null, - ]; - if (null === $bill) { - return $array; - } - $array['id'] = (string)$bill->id; - $array['name'] = $bill->name; - - return $array; - } - - /** - * @param Budget|null $budget - * - * @return array - */ - private function getBudget(?Budget $budget): array - { - $array = [ - 'id' => null, - 'name' => null, - ]; - if (null === $budget) { - return $array; - } - $array['id'] = (int)$budget->id; - $array['name'] = $budget->name; - - return $array; - } - - /** - * @param Category|null $category - * - * @return array - */ - private function getCategory(?Category $category): array - { - $array = [ - 'id' => null, - 'name' => null, - ]; - if (null === $category) { - return $array; - } - $array['id'] = (int)$category->id; - $array['name'] = $category->name; - - return $array; - } - - /** - * @param NullArrayObject $dates - * - * @return array - */ - private function getDates(NullArrayObject $dates): array - { - $fields = [ - 'interest_date', - 'book_date', - 'process_date', - 'due_date', - 'payment_date', - 'invoice_date', - ]; - $return = []; - foreach ($fields as $field) { - $return[$field] = null; - if (null !== $dates[$field]) { - $return[$field] = $dates[$field]->toAtomString(); - } - } - - return $return; - } - - /** - * @param TransactionJournal $journal - * - * @return Transaction - * @throws FireflyException - */ - private function getDestinationTransaction(TransactionJournal $journal): Transaction - { - $result = $journal->transactions->first( - static function (Transaction $transaction) { - return (float)$transaction->amount > 0; // lame but it works - } - ); - if (null === $result) { - throw new FireflyException(sprintf('Journal #%d unexpectedly has no destination transaction.', $journal->id)); + $result = []; + $transactions = $data['transactions'] ?? []; + foreach ($transactions as $transaction) { + $result[] = $this->transformTransaction($transaction); } return $result; } /** - * @param string $type - * @param string|null $foreignAmount - * - * @return string|null - */ - private function getForeignAmount(string $type, ?string $foreignAmount): ?string - { - $result = null; - if (null !== $foreignAmount && '' !== $foreignAmount && bccomp('0', $foreignAmount) !== 0) { - $result = app('steam')->positive($foreignAmount); - } - - return $result; - } - - /** - * @param TransactionCurrency|null $currency - * - * @return array - */ - private function getForeignCurrency(?TransactionCurrency $currency): array - { - $array = [ - 'id' => null, - 'code' => null, - 'symbol' => null, - 'decimal_places' => null, - ]; - if (null === $currency) { - return $array; - } - $array['id'] = (int)$currency->id; - $array['code'] = $currency->code; - $array['symbol'] = $currency->symbol; - $array['decimal_places'] = (int)$currency->decimal_places; - - return $array; - } - - /** - * @param TransactionJournal $journal - * - * @return Location|null - */ - private function getLocation(TransactionJournal $journal): ?Location - { - return $journal->locations()->first(); - } - - /** - * @param int $journalId - * - * @return Location|null - */ - private function getLocationById(int $journalId): ?Location - { - return $this->groupRepos->getLocation($journalId); - } - - /** - * @param TransactionJournal $journal - * - * @return Transaction - * @throws FireflyException - */ - private function getSourceTransaction(TransactionJournal $journal): Transaction - { - $result = $journal->transactions->first( - static function (Transaction $transaction) { - return (float)$transaction->amount < 0; // lame but it works. - } - ); - if (null === $result) { - throw new FireflyException(sprintf('Journal #%d unexpectedly has no source transaction.', $journal->id)); - } - - return $result; - } - - /** - * @param int $journalId - * - * @return bool - */ - private function hasAttachments(int $journalId): bool - { - return $this->groupRepos->countAttachments($journalId) > 0; - } - - /** - * @param array $array - * @param string $key - * - * @return int|null - */ - private function integerFromArray(array $array, string $key): ?int - { - if (array_key_exists($key, $array)) { - return (int)$array[$key]; - } - - return null; - } - - /** - * @param array $array - * @param string $key - * @param string|null $default - * - * @return string|null - */ - private function stringFromArray(array $array, string $key, ?string $default): ?string - { - if (array_key_exists($key, $array) && null === $array[$key]) { - return null; - } - if (array_key_exists($key, $array) && null !== $array[$key]) { - if (0 === $array[$key]) { - return $default; - } - if ('0' === $array[$key]) { - return $default; - } - return (string)$array[$key]; - } - - if (null !== $default) { - return (string)$default; - } - - return null; - } - - /** - * @param TransactionJournal $journal - * - * @return array - * @throws FireflyException - */ - private function transformJournal(TransactionJournal $journal): array - { - $source = $this->getSourceTransaction($journal); - $destination = $this->getDestinationTransaction($journal); - $type = $journal->transactionType->type; - $currency = $source->transactionCurrency; - $amount = app('steam')->bcround($this->getAmount($type, (string)$source->amount), $currency->decimal_places ?? 0); - $foreignAmount = $this->getForeignAmount($type, null === $source->foreign_amount ? null : (string)$source->foreign_amount); - $metaFieldData = $this->groupRepos->getMetaFields($journal->id, $this->metaFields); - $metaDates = $this->getDates($this->groupRepos->getMetaDateFields($journal->id, $this->metaDateFields)); - $foreignCurrency = $this->getForeignCurrency($source->foreignCurrency); - $budget = $this->getBudget($journal->budgets->first()); - $category = $this->getCategory($journal->categories->first()); - $bill = $this->getBill($journal->bill); - - if (null !== $foreignAmount && null !== $source->foreignCurrency) { - $foreignAmount = app('steam')->bcround($foreignAmount, $foreignCurrency['decimal_places'] ?? 0); - } - - $longitude = null; - $latitude = null; - $zoomLevel = null; - $location = $this->getLocation($journal); - if (null !== $location) { - $longitude = $location->longitude; - $latitude = $location->latitude; - $zoomLevel = $location->zoom_level; - } - - return [ - 'user' => (int)$journal->user_id, - 'transaction_journal_id' => (int)$journal->id, - 'type' => strtolower($type), - 'date' => $journal->date->toAtomString(), - 'order' => $journal->order, - - 'currency_id' => (int)$currency->id, - 'currency_code' => $currency->code, - 'currency_symbol' => $currency->symbol, - 'currency_decimal_places' => (int)$currency->decimal_places, - - 'foreign_currency_id' => $foreignCurrency['id'], - 'foreign_currency_code' => $foreignCurrency['code'], - 'foreign_currency_symbol' => $foreignCurrency['symbol'], - 'foreign_currency_decimal_places' => $foreignCurrency['decimal_places'], - - 'amount' => app('steam')->bcround($amount, $currency->decimal_places), - 'foreign_amount' => $foreignAmount, - - 'description' => $journal->description, - - 'source_id' => (int)$source->account_id, - 'source_name' => $source->account->name, - 'source_iban' => $source->account->iban, - 'source_type' => $source->account->accountType->type, - - 'destination_id' => (int)$destination->account_id, - 'destination_name' => $destination->account->name, - 'destination_iban' => $destination->account->iban, - 'destination_type' => $destination->account->accountType->type, - - 'budget_id' => $budget['id'], - 'budget_name' => $budget['name'], - - 'category_id' => $category['id'], - 'category_name' => $category['name'], - - 'bill_id' => $bill['id'], - 'bill_name' => $bill['name'], - - 'reconciled' => $source->reconciled, - 'notes' => $this->groupRepos->getNoteText($journal->id), - 'tags' => $this->groupRepos->getTags($journal->id), - - 'internal_reference' => $metaFieldData['internal_reference'], - 'external_id' => $metaFieldData['external_id'], - 'original_source' => $metaFieldData['original_source'], - 'recurrence_id' => $metaFieldData['recurrence_id'], - 'bunq_payment_id' => $metaFieldData['bunq_payment_id'], - 'import_hash_v2' => $metaFieldData['import_hash_v2'], - - 'sepa_cc' => $metaFieldData['sepa_cc'], - 'sepa_ct_op' => $metaFieldData['sepa_ct_op'], - 'sepa_ct_id' => $metaFieldData['sepa_ct_id'], - 'sepa_db' => $metaFieldData['sepa_db'], - 'sepa_country' => $metaFieldData['sepa_country'], - 'sepa_ep' => $metaFieldData['sepa_ep'], - 'sepa_ci' => $metaFieldData['sepa_ci'], - 'sepa_batch_id' => $metaFieldData['sepa_batch_id'], - - 'interest_date' => $metaDates['interest_date'], - 'book_date' => $metaDates['book_date'], - 'process_date' => $metaDates['process_date'], - 'due_date' => $metaDates['due_date'], - 'payment_date' => $metaDates['payment_date'], - 'invoice_date' => $metaDates['invoice_date'], - - // location data - 'longitude' => $longitude, - 'latitude' => $latitude, - 'zoom_level' => $zoomLevel, - ]; - } - - /** - * @param Collection $transactionJournals - * - * @return array - * @throws FireflyException - */ - private function transformJournals(Collection $transactionJournals): array - { - $result = []; - /** @var TransactionJournal $journal */ - foreach ($transactionJournals as $journal) { - $result[] = $this->transformJournal($journal); - } - - return $result; - } - - /** - * @param array $transaction + * @param array $transaction * * @return array */ @@ -643,18 +232,429 @@ class TransactionGroupTransformer extends AbstractTransformer } /** - * @param NullArrayObject $data + * @param array $array + * @param string $key + * @param string|null $default + * + * @return string|null + */ + private function stringFromArray(array $array, string $key, ?string $default): ?string + { + if (array_key_exists($key, $array) && null === $array[$key]) { + return null; + } + if (array_key_exists($key, $array) && null !== $array[$key]) { + if (0 === $array[$key]) { + return $default; + } + if ('0' === $array[$key]) { + return $default; + } + return (string)$array[$key]; + } + + if (null !== $default) { + return (string)$default; + } + + return null; + } + + /** + * @param int $journalId + * + * @return Location|null + */ + private function getLocationById(int $journalId): ?Location + { + return $this->groupRepos->getLocation($journalId); + } + + /** + * @param TransactionJournal $journal + * + * @return Location|null + */ + private function getLocation(TransactionJournal $journal): ?Location + { + return $journal->locations()->first(); + } + + /** + * @param array $array + * @param string $key + * + * @return int|null + */ + private function integerFromArray(array $array, string $key): ?int + { + if (array_key_exists($key, $array)) { + return (int)$array[$key]; + } + + return null; + } + + /** + * @param NullArrayObject $object + * @param string $key + * + * @return string|null + */ + private function dateFromArray(NullArrayObject $object, string $key): ?string + { + if (null === $object[$key]) { + return null; + } + + return $object[$key]->toAtomString(); + } + + /** + * @param int $journalId + * + * @return bool + */ + private function hasAttachments(int $journalId): bool + { + return $this->groupRepos->countAttachments($journalId) > 0; + } + + /** + * @param TransactionGroup $group * * @return array + * @throws FireflyException */ - private function transformTransactions(NullArrayObject $data): array + public function transformObject(TransactionGroup $group): array { - $result = []; - $transactions = $data['transactions'] ?? []; - foreach ($transactions as $transaction) { - $result[] = $this->transformTransaction($transaction); + try { + $result = [ + 'id' => (int)$group->id, + 'created_at' => $group->created_at->toAtomString(), + 'updated_at' => $group->updated_at->toAtomString(), + 'user' => (int)$group->user_id, + 'group_title' => $group->title, + 'transactions' => $this->transformJournals($group->transactionJournals), + 'links' => [ + [ + 'rel' => 'self', + 'uri' => '/transactions/' . $group->id, + ], + ], + ]; + } catch (FireflyException $e) { + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); + throw new FireflyException(sprintf('Transaction group #%d is broken. Please check out your log files.', $group->id), 0, $e); + } + + // do something else. + + return $result; + } + + /** + * @param Collection $transactionJournals + * + * @return array + * @throws FireflyException + */ + private function transformJournals(Collection $transactionJournals): array + { + $result = []; + /** @var TransactionJournal $journal */ + foreach ($transactionJournals as $journal) { + $result[] = $this->transformJournal($journal); } return $result; } + + /** + * @param TransactionJournal $journal + * + * @return array + * @throws FireflyException + */ + private function transformJournal(TransactionJournal $journal): array + { + $source = $this->getSourceTransaction($journal); + $destination = $this->getDestinationTransaction($journal); + $type = $journal->transactionType->type; + $currency = $source->transactionCurrency; + $amount = app('steam')->bcround($this->getAmount($type, (string)$source->amount), $currency->decimal_places ?? 0); + $foreignAmount = $this->getForeignAmount($type, null === $source->foreign_amount ? null : (string)$source->foreign_amount); + $metaFieldData = $this->groupRepos->getMetaFields($journal->id, $this->metaFields); + $metaDates = $this->getDates($this->groupRepos->getMetaDateFields($journal->id, $this->metaDateFields)); + $foreignCurrency = $this->getForeignCurrency($source->foreignCurrency); + $budget = $this->getBudget($journal->budgets->first()); + $category = $this->getCategory($journal->categories->first()); + $bill = $this->getBill($journal->bill); + + if (null !== $foreignAmount && null !== $source->foreignCurrency) { + $foreignAmount = app('steam')->bcround($foreignAmount, $foreignCurrency['decimal_places'] ?? 0); + } + + $longitude = null; + $latitude = null; + $zoomLevel = null; + $location = $this->getLocation($journal); + if (null !== $location) { + $longitude = $location->longitude; + $latitude = $location->latitude; + $zoomLevel = $location->zoom_level; + } + + return [ + 'user' => (int)$journal->user_id, + 'transaction_journal_id' => (int)$journal->id, + 'type' => strtolower($type), + 'date' => $journal->date->toAtomString(), + 'order' => $journal->order, + + 'currency_id' => (int)$currency->id, + 'currency_code' => $currency->code, + 'currency_symbol' => $currency->symbol, + 'currency_decimal_places' => (int)$currency->decimal_places, + + 'foreign_currency_id' => $foreignCurrency['id'], + 'foreign_currency_code' => $foreignCurrency['code'], + 'foreign_currency_symbol' => $foreignCurrency['symbol'], + 'foreign_currency_decimal_places' => $foreignCurrency['decimal_places'], + + 'amount' => app('steam')->bcround($amount, $currency->decimal_places), + 'foreign_amount' => $foreignAmount, + + 'description' => $journal->description, + + 'source_id' => (int)$source->account_id, + 'source_name' => $source->account->name, + 'source_iban' => $source->account->iban, + 'source_type' => $source->account->accountType->type, + + 'destination_id' => (int)$destination->account_id, + 'destination_name' => $destination->account->name, + 'destination_iban' => $destination->account->iban, + 'destination_type' => $destination->account->accountType->type, + + 'budget_id' => $budget['id'], + 'budget_name' => $budget['name'], + + 'category_id' => $category['id'], + 'category_name' => $category['name'], + + 'bill_id' => $bill['id'], + 'bill_name' => $bill['name'], + + 'reconciled' => $source->reconciled, + 'notes' => $this->groupRepos->getNoteText($journal->id), + 'tags' => $this->groupRepos->getTags($journal->id), + + 'internal_reference' => $metaFieldData['internal_reference'], + 'external_id' => $metaFieldData['external_id'], + 'original_source' => $metaFieldData['original_source'], + 'recurrence_id' => $metaFieldData['recurrence_id'], + 'bunq_payment_id' => $metaFieldData['bunq_payment_id'], + 'import_hash_v2' => $metaFieldData['import_hash_v2'], + + 'sepa_cc' => $metaFieldData['sepa_cc'], + 'sepa_ct_op' => $metaFieldData['sepa_ct_op'], + 'sepa_ct_id' => $metaFieldData['sepa_ct_id'], + 'sepa_db' => $metaFieldData['sepa_db'], + 'sepa_country' => $metaFieldData['sepa_country'], + 'sepa_ep' => $metaFieldData['sepa_ep'], + 'sepa_ci' => $metaFieldData['sepa_ci'], + 'sepa_batch_id' => $metaFieldData['sepa_batch_id'], + + 'interest_date' => $metaDates['interest_date'], + 'book_date' => $metaDates['book_date'], + 'process_date' => $metaDates['process_date'], + 'due_date' => $metaDates['due_date'], + 'payment_date' => $metaDates['payment_date'], + 'invoice_date' => $metaDates['invoice_date'], + + // location data + 'longitude' => $longitude, + 'latitude' => $latitude, + 'zoom_level' => $zoomLevel, + ]; + } + + /** + * @param TransactionJournal $journal + * + * @return Transaction + * @throws FireflyException + */ + private function getSourceTransaction(TransactionJournal $journal): Transaction + { + $result = $journal->transactions->first( + static function (Transaction $transaction) { + return (float)$transaction->amount < 0; // lame but it works. + } + ); + if (null === $result) { + throw new FireflyException(sprintf('Journal #%d unexpectedly has no source transaction.', $journal->id)); + } + + return $result; + } + + /** + * @param TransactionJournal $journal + * + * @return Transaction + * @throws FireflyException + */ + private function getDestinationTransaction(TransactionJournal $journal): Transaction + { + $result = $journal->transactions->first( + static function (Transaction $transaction) { + return (float)$transaction->amount > 0; // lame but it works + } + ); + if (null === $result) { + throw new FireflyException(sprintf('Journal #%d unexpectedly has no destination transaction.', $journal->id)); + } + + return $result; + } + + /** + * @param string $type + * @param string $amount + * + * @return string + */ + private function getAmount(string $type, string $amount): string + { + return app('steam')->positive($amount); + } + + /** + * @param string $type + * @param string|null $foreignAmount + * + * @return string|null + */ + private function getForeignAmount(string $type, ?string $foreignAmount): ?string + { + $result = null; + if (null !== $foreignAmount && '' !== $foreignAmount && bccomp('0', $foreignAmount) !== 0) { + $result = app('steam')->positive($foreignAmount); + } + + return $result; + } + + /** + * @param NullArrayObject $dates + * + * @return array + */ + private function getDates(NullArrayObject $dates): array + { + $fields = [ + 'interest_date', + 'book_date', + 'process_date', + 'due_date', + 'payment_date', + 'invoice_date', + ]; + $return = []; + foreach ($fields as $field) { + $return[$field] = null; + if (null !== $dates[$field]) { + $return[$field] = $dates[$field]->toAtomString(); + } + } + + return $return; + } + + /** + * @param TransactionCurrency|null $currency + * + * @return array + */ + private function getForeignCurrency(?TransactionCurrency $currency): array + { + $array = [ + 'id' => null, + 'code' => null, + 'symbol' => null, + 'decimal_places' => null, + ]; + if (null === $currency) { + return $array; + } + $array['id'] = (int)$currency->id; + $array['code'] = $currency->code; + $array['symbol'] = $currency->symbol; + $array['decimal_places'] = (int)$currency->decimal_places; + + return $array; + } + + /** + * @param Budget|null $budget + * + * @return array + */ + private function getBudget(?Budget $budget): array + { + $array = [ + 'id' => null, + 'name' => null, + ]; + if (null === $budget) { + return $array; + } + $array['id'] = (int)$budget->id; + $array['name'] = $budget->name; + + return $array; + } + + /** + * @param Category|null $category + * + * @return array + */ + private function getCategory(?Category $category): array + { + $array = [ + 'id' => null, + 'name' => null, + ]; + if (null === $category) { + return $array; + } + $array['id'] = (int)$category->id; + $array['name'] = $category->name; + + return $array; + } + + /** + * @param Bill|null $bill + * + * @return array + */ + private function getBill(?Bill $bill): array + { + $array = [ + 'id' => null, + 'name' => null, + ]; + if (null === $bill) { + return $array; + } + $array['id'] = (string)$bill->id; + $array['name'] = $bill->name; + + return $array; + } } diff --git a/app/Transformers/TransactionLinkTransformer.php b/app/Transformers/TransactionLinkTransformer.php index 5b558fa857..82d717b5f7 100644 --- a/app/Transformers/TransactionLinkTransformer.php +++ b/app/Transformers/TransactionLinkTransformer.php @@ -46,7 +46,7 @@ class TransactionLinkTransformer extends AbstractTransformer } /** - * @param TransactionJournalLink $link + * @param TransactionJournalLink $link * * @return array */ @@ -65,7 +65,7 @@ class TransactionLinkTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/transaction_links/'.$link->id, + 'uri' => '/transaction_links/' . $link->id, ], ], ]; diff --git a/app/Transformers/UserTransformer.php b/app/Transformers/UserTransformer.php index 3f8b24b360..2d10f04d24 100644 --- a/app/Transformers/UserTransformer.php +++ b/app/Transformers/UserTransformer.php @@ -38,7 +38,7 @@ class UserTransformer extends AbstractTransformer /** * Transform user. * - * @param User $user + * @param User $user * * @return array * @throws FireflyException @@ -59,7 +59,7 @@ class UserTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/users/'.$user->id, + 'uri' => '/users/' . $user->id, ], ], ]; diff --git a/app/Transformers/V2/AbstractTransformer.php b/app/Transformers/V2/AbstractTransformer.php index 6a46d8f1b5..b2ef77d2c7 100644 --- a/app/Transformers/V2/AbstractTransformer.php +++ b/app/Transformers/V2/AbstractTransformer.php @@ -36,7 +36,7 @@ abstract class AbstractTransformer extends TransformerAbstract protected ParameterBag $parameters; /** - * @param Collection $objects + * @param Collection $objects * @return void */ abstract public function collectMetaData(Collection $objects): void; @@ -51,7 +51,7 @@ abstract class AbstractTransformer extends TransformerAbstract } /** - * @param ParameterBag $parameters + * @param ParameterBag $parameters */ final public function setParameters(ParameterBag $parameters): void { diff --git a/app/Transformers/V2/AccountTransformer.php b/app/Transformers/V2/AccountTransformer.php index 4c534a5dd0..a7e82727f0 100644 --- a/app/Transformers/V2/AccountTransformer.php +++ b/app/Transformers/V2/AccountTransformer.php @@ -73,10 +73,23 @@ class AccountTransformer extends AbstractTransformer } } + /** + * @return Carbon + */ + private function getDate(): Carbon + { + $date = today(config('app.timezone')); + if (null !== $this->parameters->get('date')) { + $date = $this->parameters->get('date'); + } + + return $date; + } + /** * Transform the account. * - * @param Account $account + * @param Account $account * * @return array */ @@ -128,22 +141,9 @@ class AccountTransformer extends AbstractTransformer 'links' => [ [ 'rel' => 'self', - 'uri' => '/accounts/'.$account->id, + 'uri' => '/accounts/' . $account->id, ], ], ]; } - - /** - * @return Carbon - */ - private function getDate(): Carbon - { - $date = today(config('app.timezone')); - if (null !== $this->parameters->get('date')) { - $date = $this->parameters->get('date'); - } - - return $date; - } } diff --git a/app/Transformers/V2/BudgetLimitTransformer.php b/app/Transformers/V2/BudgetLimitTransformer.php index 127aafe1e4..0b46b0fcae 100644 --- a/app/Transformers/V2/BudgetLimitTransformer.php +++ b/app/Transformers/V2/BudgetLimitTransformer.php @@ -49,7 +49,7 @@ class BudgetLimitTransformer extends AbstractTransformer /** * Include Budget * - * @param BudgetLimit $limit + * @param BudgetLimit $limit * * @return Item */ @@ -61,7 +61,7 @@ class BudgetLimitTransformer extends AbstractTransformer /** * Transform the note. * - * @param BudgetLimit $budgetLimit + * @param BudgetLimit $budgetLimit * * @return array */ diff --git a/app/Transformers/V2/BudgetTransformer.php b/app/Transformers/V2/BudgetTransformer.php index 9d532faf3e..8d25a2628d 100644 --- a/app/Transformers/V2/BudgetTransformer.php +++ b/app/Transformers/V2/BudgetTransformer.php @@ -58,7 +58,7 @@ class BudgetTransformer extends AbstractTransformer /** * Transform a budget. * - * @param Budget $budget + * @param Budget $budget * * @return array */ @@ -117,7 +117,7 @@ class BudgetTransformer extends AbstractTransformer } /** - * @param array $array + * @param array $array * * @return array */ diff --git a/app/Transformers/V2/PreferenceTransformer.php b/app/Transformers/V2/PreferenceTransformer.php index 20e8fc1671..44131339f3 100644 --- a/app/Transformers/V2/PreferenceTransformer.php +++ b/app/Transformers/V2/PreferenceTransformer.php @@ -42,7 +42,7 @@ class PreferenceTransformer extends AbstractTransformer /** * Transform the preference * - * @param Preference $preference + * @param Preference $preference * * @return array */ diff --git a/app/Transformers/V2/TransactionGroupTransformer.php b/app/Transformers/V2/TransactionGroupTransformer.php index 48477b608c..c06a9d4b23 100644 --- a/app/Transformers/V2/TransactionGroupTransformer.php +++ b/app/Transformers/V2/TransactionGroupTransformer.php @@ -80,7 +80,7 @@ class TransactionGroupTransformer extends AbstractTransformer } /** - * @param array $group + * @param array $group * * @return array */ @@ -104,52 +104,17 @@ class TransactionGroupTransformer extends AbstractTransformer } /** - * @param string|null $string - * @return Carbon|null + * @param array $transactions + * @return array */ - private function date(?string $string): ?Carbon + private function transformTransactions(array $transactions): array { - if (null === $string) { - return null; + $return = []; + /** @var array $transaction */ + foreach ($transactions as $transaction) { + $return[] = $this->transformTransaction($transaction); } - Log::debug(sprintf('Now in date("%s")', $string)); - if (10 === strlen($string)) { - return Carbon::createFromFormat('Y-m-d', $string, config('app.timezone')); - } - // 2022-01-01 01:01:01 - return Carbon::createFromFormat('Y-m-d H:i:s', substr($string, 0, 19), config('app.timezone')); - } - - /** - * TODO also in the old transformer. - * - * @param NullArrayObject $array - * @param string $key - * @param string|null $default - * - * @return string|null - */ - private function stringFromArray(NullArrayObject $array, string $key, ?string $default): ?string - { - //Log::debug(sprintf('%s: %s', $key, var_export($array[$key], true))); - if (null === $array[$key] && null === $default) { - return null; - } - if (0 === $array[$key]) { - return $default; - } - if ('0' === $array[$key]) { - return $default; - } - if (null !== $array[$key]) { - return (string)$array[$key]; - } - - if (null !== $default) { - return $default; - } - - return null; + return $return; } private function transformTransaction(array $transaction): array @@ -264,16 +229,51 @@ class TransactionGroupTransformer extends AbstractTransformer } /** - * @param array $transactions - * @return array + * TODO also in the old transformer. + * + * @param NullArrayObject $array + * @param string $key + * @param string|null $default + * + * @return string|null */ - private function transformTransactions(array $transactions): array + private function stringFromArray(NullArrayObject $array, string $key, ?string $default): ?string { - $return = []; - /** @var array $transaction */ - foreach ($transactions as $transaction) { - $return[] = $this->transformTransaction($transaction); + //Log::debug(sprintf('%s: %s', $key, var_export($array[$key], true))); + if (null === $array[$key] && null === $default) { + return null; } - return $return; + if (0 === $array[$key]) { + return $default; + } + if ('0' === $array[$key]) { + return $default; + } + if (null !== $array[$key]) { + return (string)$array[$key]; + } + + if (null !== $default) { + return $default; + } + + return null; + } + + /** + * @param string|null $string + * @return Carbon|null + */ + private function date(?string $string): ?Carbon + { + if (null === $string) { + return null; + } + Log::debug(sprintf('Now in date("%s")', $string)); + if (10 === strlen($string)) { + return Carbon::createFromFormat('Y-m-d', $string, config('app.timezone')); + } + // 2022-01-01 01:01:01 + return Carbon::createFromFormat('Y-m-d H:i:s', substr($string, 0, 19), config('app.timezone')); } } diff --git a/app/Transformers/WebhookAttemptTransformer.php b/app/Transformers/WebhookAttemptTransformer.php index 00fcb767d8..8576c3800f 100644 --- a/app/Transformers/WebhookAttemptTransformer.php +++ b/app/Transformers/WebhookAttemptTransformer.php @@ -33,7 +33,7 @@ class WebhookAttemptTransformer extends AbstractTransformer /** * Transform the preference * - * @param WebhookAttempt $attempt + * @param WebhookAttempt $attempt * * @return array */ diff --git a/app/Transformers/WebhookMessageTransformer.php b/app/Transformers/WebhookMessageTransformer.php index 398c6cda68..452aec5a06 100644 --- a/app/Transformers/WebhookMessageTransformer.php +++ b/app/Transformers/WebhookMessageTransformer.php @@ -35,7 +35,7 @@ class WebhookMessageTransformer extends AbstractTransformer /** * Transform the preference * - * @param WebhookMessage $message + * @param WebhookMessage $message * * @return array */ diff --git a/app/Transformers/WebhookTransformer.php b/app/Transformers/WebhookTransformer.php index 63bc4a8dfa..cad974fc53 100644 --- a/app/Transformers/WebhookTransformer.php +++ b/app/Transformers/WebhookTransformer.php @@ -46,7 +46,7 @@ class WebhookTransformer extends AbstractTransformer /** * Transform webhook. * - * @param Webhook $webhook + * @param Webhook $webhook * * @return array */ @@ -73,8 +73,8 @@ class WebhookTransformer extends AbstractTransformer } /** - * @param string $type - * @param int $value + * @param string $type + * @param int $value * @return string */ private function getEnum(string $type, int $value): string diff --git a/app/User.php b/app/User.php index e6dc89bb15..10b2507897 100644 --- a/app/User.php +++ b/app/User.php @@ -77,39 +77,39 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Class User. * - * @property int $id - * @property string $email - * @property bool $isAdmin - * @property bool $has2FA - * @property array $prefs - * @property string $password - * @property string $mfa_secret - * @property Collection $roles - * @property string $blocked_code - * @property bool $blocked - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property string|null $remember_token - * @property string|null $reset - * @property-read \Illuminate\Database\Eloquent\Collection|Account[] $accounts - * @property-read \Illuminate\Database\Eloquent\Collection|Attachment[] $attachments - * @property-read \Illuminate\Database\Eloquent\Collection|AvailableBudget[] $availableBudgets - * @property-read \Illuminate\Database\Eloquent\Collection|Bill[] $bills - * @property-read \Illuminate\Database\Eloquent\Collection|Budget[] $budgets - * @property-read \Illuminate\Database\Eloquent\Collection|Category[] $categories - * @property-read \Illuminate\Database\Eloquent\Collection|Client[] $clients + * @property int $id + * @property string $email + * @property bool $isAdmin + * @property bool $has2FA + * @property array $prefs + * @property string $password + * @property string $mfa_secret + * @property Collection $roles + * @property string $blocked_code + * @property bool $blocked + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property string|null $remember_token + * @property string|null $reset + * @property-read \Illuminate\Database\Eloquent\Collection|Account[] $accounts + * @property-read \Illuminate\Database\Eloquent\Collection|Attachment[] $attachments + * @property-read \Illuminate\Database\Eloquent\Collection|AvailableBudget[] $availableBudgets + * @property-read \Illuminate\Database\Eloquent\Collection|Bill[] $bills + * @property-read \Illuminate\Database\Eloquent\Collection|Budget[] $budgets + * @property-read \Illuminate\Database\Eloquent\Collection|Category[] $categories + * @property-read \Illuminate\Database\Eloquent\Collection|Client[] $clients * @property-read \Illuminate\Database\Eloquent\Collection|CurrencyExchangeRate[] $currencyExchangeRates - * @property-read DatabaseNotificationCollection|DatabaseNotification[] $notifications - * @property-read \Illuminate\Database\Eloquent\Collection|PiggyBank[] $piggyBanks - * @property-read \Illuminate\Database\Eloquent\Collection|Preference[] $preferences - * @property-read \Illuminate\Database\Eloquent\Collection|Recurrence[] $recurrences - * @property-read \Illuminate\Database\Eloquent\Collection|RuleGroup[] $ruleGroups - * @property-read \Illuminate\Database\Eloquent\Collection|Rule[] $rules - * @property-read \Illuminate\Database\Eloquent\Collection|Tag[] $tags - * @property-read \Illuminate\Database\Eloquent\Collection|Token[] $tokens - * @property-read \Illuminate\Database\Eloquent\Collection|TransactionGroup[] $transactionGroups - * @property-read \Illuminate\Database\Eloquent\Collection|TransactionJournal[] $transactionJournals - * @property-read \Illuminate\Database\Eloquent\Collection|Transaction[] $transactions + * @property-read DatabaseNotificationCollection|DatabaseNotification[] $notifications + * @property-read \Illuminate\Database\Eloquent\Collection|PiggyBank[] $piggyBanks + * @property-read \Illuminate\Database\Eloquent\Collection|Preference[] $preferences + * @property-read \Illuminate\Database\Eloquent\Collection|Recurrence[] $recurrences + * @property-read \Illuminate\Database\Eloquent\Collection|RuleGroup[] $ruleGroups + * @property-read \Illuminate\Database\Eloquent\Collection|Rule[] $rules + * @property-read \Illuminate\Database\Eloquent\Collection|Tag[] $tags + * @property-read \Illuminate\Database\Eloquent\Collection|Token[] $tokens + * @property-read \Illuminate\Database\Eloquent\Collection|TransactionGroup[] $transactionGroups + * @property-read \Illuminate\Database\Eloquent\Collection|TransactionJournal[] $transactionJournals + * @property-read \Illuminate\Database\Eloquent\Collection|Transaction[] $transactions * @method static Builder|User newModelQuery() * @method static Builder|User newQuery() * @method static Builder|User query() @@ -122,47 +122,47 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @method static Builder|User whereRememberToken($value) * @method static Builder|User whereReset($value) * @method static Builder|User whereUpdatedAt($value) - * @property string|null $objectguid - * @property-read int|null $accounts_count - * @property-read int|null $attachments_count - * @property-read int|null $available_budgets_count - * @property-read int|null $bills_count - * @property-read int|null $budgets_count - * @property-read int|null $categories_count - * @property-read int|null $clients_count - * @property-read int|null $currency_exchange_rates_count - * @property-read int|null $notifications_count - * @property-read int|null $piggy_banks_count - * @property-read int|null $preferences_count - * @property-read int|null $recurrences_count - * @property-read int|null $roles_count - * @property-read int|null $rule_groups_count - * @property-read int|null $rules_count - * @property-read int|null $tags_count - * @property-read int|null $tokens_count - * @property-read int|null $transaction_groups_count - * @property-read int|null $transaction_journals_count - * @property-read int|null $transactions_count + * @property string|null $objectguid + * @property-read int|null $accounts_count + * @property-read int|null $attachments_count + * @property-read int|null $available_budgets_count + * @property-read int|null $bills_count + * @property-read int|null $budgets_count + * @property-read int|null $categories_count + * @property-read int|null $clients_count + * @property-read int|null $currency_exchange_rates_count + * @property-read int|null $notifications_count + * @property-read int|null $piggy_banks_count + * @property-read int|null $preferences_count + * @property-read int|null $recurrences_count + * @property-read int|null $roles_count + * @property-read int|null $rule_groups_count + * @property-read int|null $rules_count + * @property-read int|null $tags_count + * @property-read int|null $tokens_count + * @property-read int|null $transaction_groups_count + * @property-read int|null $transaction_journals_count + * @property-read int|null $transactions_count * @method static Builder|User whereMfaSecret($value) * @method static Builder|User whereObjectguid($value) - * @property string|null $provider + * @property string|null $provider * @method static Builder|User whereProvider($value) - * @property-read \Illuminate\Database\Eloquent\Collection|ObjectGroup[] $objectGroups - * @property-read int|null $object_groups_count - * @property-read \Illuminate\Database\Eloquent\Collection|Webhook[] $webhooks - * @property-read int|null $webhooks_count - * @property string|null $two_factor_secret - * @property string|null $two_factor_recovery_codes - * @property string|null $guid - * @property string|null $domain + * @property-read \Illuminate\Database\Eloquent\Collection|ObjectGroup[] $objectGroups + * @property-read int|null $object_groups_count + * @property-read \Illuminate\Database\Eloquent\Collection|Webhook[] $webhooks + * @property-read int|null $webhooks_count + * @property string|null $two_factor_secret + * @property string|null $two_factor_recovery_codes + * @property string|null $guid + * @property string|null $domain * @method static Builder|User whereDomain($value) * @method static Builder|User whereGuid($value) * @method static Builder|User whereTwoFactorRecoveryCodes($value) * @method static Builder|User whereTwoFactorSecret($value) - * @property int|null $user_group_id - * @property-read \Illuminate\Database\Eloquent\Collection|GroupMembership[] $groupMemberships - * @property-read int|null $group_memberships_count - * @property-read UserGroup|null $userGroup + * @property int|null $user_group_id + * @property-read \Illuminate\Database\Eloquent\Collection|GroupMembership[] $groupMemberships + * @property-read int|null $group_memberships_count + * @property-read UserGroup|null $userGroup * @method static Builder|User whereUserGroupId($value) * @mixin Eloquent */ @@ -202,7 +202,7 @@ class User extends Authenticatable protected $table = 'users'; /** - * @param string $value + * @param string $value * * @return User * @throws NotFoundHttpException @@ -319,6 +319,7 @@ class User extends Authenticatable /** * Get the models LDAP domain. + * * @return string * @deprecated * @@ -330,6 +331,7 @@ class User extends Authenticatable /** * Get the database column name of the domain. + * * @return string * @deprecated * @@ -341,6 +343,7 @@ class User extends Authenticatable /** * Get the models LDAP GUID. + * * @return string * @deprecated * @@ -352,6 +355,7 @@ class User extends Authenticatable /** * Get the models LDAP GUID database column name. + * * @return string * @deprecated * @@ -413,13 +417,13 @@ class User extends Authenticatable /** * Get the notification routing information for the given driver. * - * @param string $driver - * @param Notification|null $notification + * @param string $driver + * @param Notification|null $notification * @return mixed */ public function routeNotificationFor($driver, $notification = null) { - if (method_exists($this, $method = 'routeNotificationFor'.Str::studly($driver))) { + if (method_exists($this, $method = 'routeNotificationFor' . Str::studly($driver))) { return $this->{$method}($notification); } $email = $this->email; @@ -441,7 +445,7 @@ class User extends Authenticatable } /** - * @param string $role + * @param string $role * * @return bool */ @@ -463,7 +467,7 @@ class User extends Authenticatable /** * Route notifications for the Slack channel. * - * @param Notification $notification + * @param Notification $notification * @return string * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface @@ -509,7 +513,7 @@ class User extends Authenticatable /** * Send the password reset notification. * - * @param string $token + * @param string $token */ public function sendPasswordResetNotification($token): void { @@ -522,7 +526,8 @@ class User extends Authenticatable /** * Set the models LDAP domain. - * @param string $domain + * + * @param string $domain * * @return void * @deprecated @@ -535,7 +540,8 @@ class User extends Authenticatable /** * Set the models LDAP GUID. - * @param string $guid + * + * @param string $guid * * @return void * @deprecated diff --git a/app/Validation/Account/DepositValidation.php b/app/Validation/Account/DepositValidation.php index 236de1f6b3..630a19cecd 100644 --- a/app/Validation/Account/DepositValidation.php +++ b/app/Validation/Account/DepositValidation.php @@ -33,22 +33,7 @@ use Illuminate\Support\Facades\Log; trait DepositValidation { /** - * @param array $accountTypes - * - * @return bool - */ - abstract protected function canCreateTypes(array $accountTypes): bool; - - /** - * @param array $validTypes - * @param array $data - * - * @return Account|null - */ - abstract protected function findExistingAccount(array $validTypes, array $data): ?Account; - - /** - * @param array $array + * @param array $array * * @return bool */ @@ -96,7 +81,22 @@ trait DepositValidation } /** - * @param array $array + * @param array $accountTypes + * + * @return bool + */ + abstract protected function canCreateTypes(array $accountTypes): bool; + + /** + * @param array $validTypes + * @param array $data + * + * @return Account|null + */ + abstract protected function findExistingAccount(array $validTypes, array $data): ?Account; + + /** + * @param array $array * * @return bool */ diff --git a/app/Validation/Account/LiabilityValidation.php b/app/Validation/Account/LiabilityValidation.php index 909b7e6f26..b9a94d3dce 100644 --- a/app/Validation/Account/LiabilityValidation.php +++ b/app/Validation/Account/LiabilityValidation.php @@ -34,7 +34,7 @@ use Illuminate\Support\Facades\Log; trait LiabilityValidation { /** - * @param array $array + * @param array $array * * @return bool */ @@ -72,7 +72,7 @@ trait LiabilityValidation /** * Source of a liability credit must be a liability or liability credit account. * - * @param array $array + * @param array $array * * @return bool */ diff --git a/app/Validation/Account/OBValidation.php b/app/Validation/Account/OBValidation.php index 976443f081..c52fe68407 100644 --- a/app/Validation/Account/OBValidation.php +++ b/app/Validation/Account/OBValidation.php @@ -34,14 +34,7 @@ use Illuminate\Support\Facades\Log; trait OBValidation { /** - * @param array $accountTypes - * - * @return bool - */ - abstract protected function canCreateTypes(array $accountTypes): bool; - - /** - * @param array $array + * @param array $array * * @return bool */ @@ -86,11 +79,18 @@ trait OBValidation return $result; } + /** + * @param array $accountTypes + * + * @return bool + */ + abstract protected function canCreateTypes(array $accountTypes): bool; + /** * Source of an opening balance can either be an asset account * or an "initial balance account". The latter can be created. * - * @param array $array + * @param array $array * * @return bool */ diff --git a/app/Validation/Account/ReconciliationValidation.php b/app/Validation/Account/ReconciliationValidation.php index f6439c303f..f3e3e1071a 100644 --- a/app/Validation/Account/ReconciliationValidation.php +++ b/app/Validation/Account/ReconciliationValidation.php @@ -36,7 +36,7 @@ trait ReconciliationValidation public ?Account $source; /** - * @param array $array + * @param array $array * * @return bool */ @@ -72,7 +72,8 @@ trait ReconciliationValidation /** * Basically the same check - * @param array $array + * + * @param array $array * * @return bool */ diff --git a/app/Validation/Account/TransferValidation.php b/app/Validation/Account/TransferValidation.php index 4e42c5643a..766f63676d 100644 --- a/app/Validation/Account/TransferValidation.php +++ b/app/Validation/Account/TransferValidation.php @@ -32,22 +32,7 @@ use Illuminate\Support\Facades\Log; trait TransferValidation { /** - * @param array $accountTypes - * - * @return bool - */ - abstract protected function canCreateTypes(array $accountTypes): bool; - - /** - * @param array $validTypes - * @param array $data - * - * @return Account|null - */ - abstract protected function findExistingAccount(array $validTypes, array $data): ?Account; - - /** - * @param array $array + * @param array $array * * @return bool */ @@ -89,7 +74,22 @@ trait TransferValidation } /** - * @param array $array + * @param array $accountTypes + * + * @return bool + */ + abstract protected function canCreateTypes(array $accountTypes): bool; + + /** + * @param array $validTypes + * @param array $data + * + * @return Account|null + */ + abstract protected function findExistingAccount(array $validTypes, array $data): ?Account; + + /** + * @param array $array * * @return bool */ diff --git a/app/Validation/Account/WithdrawalValidation.php b/app/Validation/Account/WithdrawalValidation.php index 888d5e1375..21e5522e41 100644 --- a/app/Validation/Account/WithdrawalValidation.php +++ b/app/Validation/Account/WithdrawalValidation.php @@ -33,22 +33,7 @@ use Illuminate\Support\Facades\Log; trait WithdrawalValidation { /** - * @param array $accountTypes - * - * @return bool - */ - abstract protected function canCreateTypes(array $accountTypes): bool; - - /** - * @param array $validTypes - * @param array $data - * - * @return Account|null - */ - abstract protected function findExistingAccount(array $validTypes, array $data): ?Account; - - /** - * @param array $array + * @param array $array * * @return bool */ @@ -84,7 +69,22 @@ trait WithdrawalValidation } /** - * @param array $array + * @param array $accountTypes + * + * @return bool + */ + abstract protected function canCreateTypes(array $accountTypes): bool; + + /** + * @param array $validTypes + * @param array $data + * + * @return Account|null + */ + abstract protected function findExistingAccount(array $validTypes, array $data): ?Account; + + /** + * @param array $array * * @return bool */ @@ -123,7 +123,7 @@ trait WithdrawalValidation } /** - * @param array $array + * @param array $array * * @return bool */ diff --git a/app/Validation/AccountValidator.php b/app/Validation/AccountValidator.php index 9dcee5f834..3e3027b8ae 100644 --- a/app/Validation/AccountValidator.php +++ b/app/Validation/AccountValidator.php @@ -83,7 +83,7 @@ class AccountValidator } /** - * @param Account|null $account + * @param Account|null $account */ public function setSource(?Account $account): void { @@ -97,7 +97,7 @@ class AccountValidator } /** - * @param Account|null $account + * @param Account|null $account */ public function setDestination(?Account $account): void { @@ -111,7 +111,7 @@ class AccountValidator } /** - * @param string $transactionType + * @param string $transactionType */ public function setTransactionType(string $transactionType): void { @@ -120,7 +120,7 @@ class AccountValidator } /** - * @param User $user + * @param User $user */ public function setUser(User $user): void { @@ -129,7 +129,7 @@ class AccountValidator } /** - * @param array $array + * @param array $array * * @return bool */ @@ -174,7 +174,7 @@ class AccountValidator } /** - * @param array $array + * @param array $array * * @return bool */ @@ -212,22 +212,7 @@ class AccountValidator } /** - * @param string $accountType - * - * @return bool - */ - protected function canCreateType(string $accountType): bool - { - $canCreate = [AccountType::EXPENSE, AccountType::REVENUE, AccountType::INITIAL_BALANCE, AccountType::LIABILITY_CREDIT]; - if (in_array($accountType, $canCreate, true)) { - return true; - } - - return false; - } - - /** - * @param array $accountTypes + * @param array $accountTypes * * @return bool */ @@ -248,8 +233,23 @@ class AccountValidator } /** - * @param array $validTypes - * @param array $data + * @param string $accountType + * + * @return bool + */ + protected function canCreateType(string $accountType): bool + { + $canCreate = [AccountType::EXPENSE, AccountType::REVENUE, AccountType::INITIAL_BALANCE, AccountType::LIABILITY_CREDIT]; + if (in_array($accountType, $canCreate, true)) { + return true; + } + + return false; + } + + /** + * @param array $validTypes + * @param array $data * * @return Account|null */ diff --git a/app/Validation/Administration/ValidatesAdministrationAccess.php b/app/Validation/Administration/ValidatesAdministrationAccess.php index 7181b21cff..6c76839ff3 100644 --- a/app/Validation/Administration/ValidatesAdministrationAccess.php +++ b/app/Validation/Administration/ValidatesAdministrationAccess.php @@ -37,8 +37,8 @@ use Illuminate\Validation\Validator; trait ValidatesAdministrationAccess { /** - * @param Validator $validator - * @param array $allowedRoles + * @param Validator $validator + * @param array $allowedRoles * @return void * @throws AuthenticationException * @throws FireflyException diff --git a/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php b/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php index f73add54e0..4e1637fca7 100644 --- a/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php +++ b/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php @@ -34,7 +34,7 @@ use JsonException; trait ValidatesBulkTransactionQuery { /** - * @param Validator $validator + * @param Validator $validator * * @throws JsonException */ diff --git a/app/Validation/AutoBudget/ValidatesAutoBudgetRequest.php b/app/Validation/AutoBudget/ValidatesAutoBudgetRequest.php index f35ca252ae..e641f9a406 100644 --- a/app/Validation/AutoBudget/ValidatesAutoBudgetRequest.php +++ b/app/Validation/AutoBudget/ValidatesAutoBudgetRequest.php @@ -31,7 +31,7 @@ use Illuminate\Validation\Validator; trait ValidatesAutoBudgetRequest { /** - * @param Validator $validator + * @param Validator $validator */ protected function validateAutoBudgetAmount(Validator $validator): void { diff --git a/app/Validation/CurrencyValidation.php b/app/Validation/CurrencyValidation.php index c7f0d7e7c9..ea963a6ff8 100644 --- a/app/Validation/CurrencyValidation.php +++ b/app/Validation/CurrencyValidation.php @@ -36,17 +36,10 @@ trait CurrencyValidation { public const TEST = 'Test'; - /** - * @param Validator $validator - * - * @return array - */ - abstract protected function getTransactionsArray(Validator $validator): array; - /** * If the transactions contain foreign amounts, there must also be foreign currency information. * - * @param Validator $validator + * @param Validator $validator */ protected function validateForeignCurrencyInformation(Validator $validator): void { @@ -70,7 +63,7 @@ trait CurrencyValidation && 0 !== bccomp('0', $transaction['foreign_amount']) ) { $validator->errors()->add( - 'transactions.'.$index.'.foreign_amount', + 'transactions.' . $index . '.foreign_amount', (string)trans('validation.require_currency_info') ); } @@ -81,10 +74,17 @@ trait CurrencyValidation $transaction )) { $validator->errors()->add( - 'transactions.'.$index.'.foreign_amount', + 'transactions.' . $index . '.foreign_amount', (string)trans('validation.require_currency_amount') ); } } } + + /** + * @param Validator $validator + * + * @return array + */ + abstract protected function getTransactionsArray(Validator $validator): array; } diff --git a/app/Validation/FireflyValidator.php b/app/Validation/FireflyValidator.php index e517b886bd..cfaa36ba60 100644 --- a/app/Validation/FireflyValidator.php +++ b/app/Validation/FireflyValidator.php @@ -56,8 +56,8 @@ use function is_string; class FireflyValidator extends Validator { /** - * @param mixed $attribute - * @param mixed $value + * @param mixed $attribute + * @param mixed $value * * @return bool * @throws IncompatibleWithGoogleAuthenticatorException @@ -81,9 +81,9 @@ class FireflyValidator extends Validator } /** - * @param mixed $attribute - * @param mixed $value - * @param mixed $parameters + * @param mixed $attribute + * @param mixed $value + * @param mixed $parameters * * @return bool */ @@ -100,8 +100,8 @@ class FireflyValidator extends Validator } /** - * @param mixed $attribute - * @param mixed $value + * @param mixed $attribute + * @param mixed $value * * @return bool */ @@ -120,8 +120,8 @@ class FireflyValidator extends Validator } /** - * @param mixed $attribute - * @param mixed $value + * @param mixed $attribute + * @param mixed $value * * @return bool */ @@ -221,7 +221,7 @@ class FireflyValidator extends Validator // take $first = substr($value, 0, 4); $last = substr($value, 4); - $iban = $last.$first; + $iban = $last . $first; $iban = trim(str_replace($search, $replace, $iban)); if (0 === strlen($iban)) { return false; @@ -240,9 +240,9 @@ class FireflyValidator extends Validator } /** - * @param mixed $attribute - * @param mixed $value - * @param mixed $parameters + * @param mixed $attribute + * @param mixed $value + * @param mixed $parameters * * @return bool */ @@ -255,9 +255,9 @@ class FireflyValidator extends Validator } /** - * @param mixed $attribute - * @param mixed $value - * @param mixed $parameters + * @param mixed $attribute + * @param mixed $value + * @param mixed $parameters * * @return bool */ @@ -270,9 +270,9 @@ class FireflyValidator extends Validator } /** - * @param mixed $attribute - * @param mixed $value - * @param mixed $parameters + * @param mixed $attribute + * @param mixed $value + * @param mixed $parameters * * @return bool */ @@ -289,9 +289,9 @@ class FireflyValidator extends Validator } /** - * @param string $attribute + * @param string $attribute * - * @param string|null $value + * @param string|null $value * * @return bool */ @@ -361,8 +361,8 @@ class FireflyValidator extends Validator /** * $attribute has the format triggers.%d.value. * - * @param string $attribute - * @param string|null $value + * @param string $attribute + * @param string|null $value * * @return bool */ @@ -442,8 +442,8 @@ class FireflyValidator extends Validator } /** - * @param mixed $attribute - * @param mixed $value + * @param mixed $attribute + * @param mixed $value * * @return bool */ @@ -464,9 +464,9 @@ class FireflyValidator extends Validator } /** - * @param mixed $attribute - * @param mixed $value - * @param mixed $parameters + * @param mixed $attribute + * @param mixed $value + * @param mixed $parameters * * @return bool */ @@ -505,9 +505,124 @@ class FireflyValidator extends Validator } /** - * @param mixed $attribute - * @param mixed $value - * @param mixed $parameters + * @return bool + */ + private function validateAccountAnonymously(): bool + { + if (!array_key_exists('user_id', $this->data)) { + return false; + } + + $user = User::find($this->data['user_id']); + $type = AccountType::find($this->data['account_type_id'])->first(); + $value = $this->data['name']; + + /** @var Account|null $result */ + $result = $user->accounts()->where('account_type_id', $type->id)->where('name', $value)->first(); + + return null === $result; + } + + /** + * @param string $value + * @param array $parameters + * @param string $type + * + * @return bool + */ + private function validateByAccountTypeString(string $value, array $parameters, string $type): bool + { + /** @var array|null $search */ + $search = Config::get('firefly.accountTypeByIdentifier.' . $type); + + if (null === $search) { + return false; + } + + $accountTypes = AccountType::whereIn('type', $search)->get(); + $ignore = (int)($parameters[0] ?? 0.0); + $accountTypeIds = $accountTypes->pluck('id')->toArray(); + /** @var Account|null $result */ + $result = auth()->user()->accounts()->whereIn('account_type_id', $accountTypeIds)->where('id', '!=', $ignore) + ->where('name', $value) + ->first(); + return null === $result; + } + + /** + * @param mixed $value + * @param mixed $parameters + * + * @return bool + */ + private function validateByAccountTypeId($value, $parameters): bool + { + $type = AccountType::find($this->data['account_type_id'])->first(); + $ignore = (int)($parameters[0] ?? 0.0); + + /** @var Account|null $result */ + $result = auth()->user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore) + ->where('name', $value) + ->first(); + + return null === $result; + } + + /** + * @param int $accountId + * @param mixed $value + * + * @return bool + */ + private function validateByParameterId(int $accountId, $value): bool + { + /** @var Account $existingAccount */ + $existingAccount = Account::find($accountId); + + $type = $existingAccount->accountType; + $ignore = $existingAccount->id; + + $entry = auth()->user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore) + ->where('name', $value) + ->first(); + + return null === $entry; + } + + /** + * @param mixed $value + * + * @return bool + */ + private function validateByAccountId($value): bool + { + /** @var Account $existingAccount */ + $existingAccount = Account::find($this->data['id']); + + $type = $existingAccount->accountType; + $ignore = $existingAccount->id; + + $entry = auth()->user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore) + ->where('name', $value) + ->first(); + + return null === $entry; + } + + /** + * @param string $value + * + * @return bool + */ + private function validateByAccountName(string $value): bool + { + return auth()->user()->accounts()->where('name', $value)->count() === 0; + } + + /** + * @param mixed $attribute + * @param mixed $value + * @param mixed $parameters * * @return bool */ @@ -557,17 +672,6 @@ class FireflyValidator extends Validator return false; } - /** - * @param string $field - * @param string $attribute - * @param string $value - * @return bool - */ - public function validateUniqueCurrency(string $field, string $attribute, string $value): bool - { - return 0 === DB::table('transaction_currencies')->where($field, $value)->whereNull('deleted_at')->count(); - } - /** * @param $attribute * @param $value @@ -578,6 +682,17 @@ class FireflyValidator extends Validator return $this->validateUniqueCurrency('code', (string)$attribute, (string)$value); } + /** + * @param string $field + * @param string $attribute + * @param string $value + * @return bool + */ + public function validateUniqueCurrency(string $field, string $attribute, string $value): bool + { + return 0 === DB::table('transaction_currencies')->where($field, $value)->whereNull('deleted_at')->count(); + } + /** * @param $attribute * @param $value @@ -599,9 +714,9 @@ class FireflyValidator extends Validator } /** - * @param mixed $value - * @param mixed $parameters - * @param mixed $something + * @param mixed $value + * @param mixed $parameters + * @param mixed $something * * @return bool */ @@ -654,9 +769,9 @@ class FireflyValidator extends Validator * parameter 1: the field * parameter 2: an id to ignore (when editing) * - * @param mixed $attribute - * @param mixed $value - * @param mixed $parameters + * @param mixed $attribute + * @param mixed $value + * @param mixed $parameters * * @return bool */ @@ -686,9 +801,9 @@ class FireflyValidator extends Validator } /** - * @param mixed $attribute - * @param mixed $value - * @param mixed $parameters + * @param mixed $attribute + * @param mixed $value + * @param mixed $parameters * * @return bool */ @@ -707,9 +822,9 @@ class FireflyValidator extends Validator } /** - * @param mixed $attribute - * @param mixed $value - * @param mixed $parameters + * @param mixed $attribute + * @param mixed $value + * @param mixed $parameters * * @return bool */ @@ -727,8 +842,8 @@ class FireflyValidator extends Validator } /** - * @param mixed $value - * @param mixed $parameters + * @param mixed $value + * @param mixed $parameters * * @return bool */ @@ -755,119 +870,4 @@ class FireflyValidator extends Validator return false; } - - /** - * @return bool - */ - private function validateAccountAnonymously(): bool - { - if (!array_key_exists('user_id', $this->data)) { - return false; - } - - $user = User::find($this->data['user_id']); - $type = AccountType::find($this->data['account_type_id'])->first(); - $value = $this->data['name']; - - /** @var Account|null $result */ - $result = $user->accounts()->where('account_type_id', $type->id)->where('name', $value)->first(); - - return null === $result; - } - - /** - * @param mixed $value - * - * @return bool - */ - private function validateByAccountId($value): bool - { - /** @var Account $existingAccount */ - $existingAccount = Account::find($this->data['id']); - - $type = $existingAccount->accountType; - $ignore = $existingAccount->id; - - $entry = auth()->user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore) - ->where('name', $value) - ->first(); - - return null === $entry; - } - - /** - * @param string $value - * - * @return bool - */ - private function validateByAccountName(string $value): bool - { - return auth()->user()->accounts()->where('name', $value)->count() === 0; - } - - /** - * @param mixed $value - * @param mixed $parameters - * - * @return bool - */ - private function validateByAccountTypeId($value, $parameters): bool - { - $type = AccountType::find($this->data['account_type_id'])->first(); - $ignore = (int)($parameters[0] ?? 0.0); - - /** @var Account|null $result */ - $result = auth()->user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore) - ->where('name', $value) - ->first(); - - return null === $result; - } - - /** - * @param string $value - * @param array $parameters - * @param string $type - * - * @return bool - */ - private function validateByAccountTypeString(string $value, array $parameters, string $type): bool - { - /** @var array|null $search */ - $search = Config::get('firefly.accountTypeByIdentifier.'.$type); - - if (null === $search) { - return false; - } - - $accountTypes = AccountType::whereIn('type', $search)->get(); - $ignore = (int)($parameters[0] ?? 0.0); - $accountTypeIds = $accountTypes->pluck('id')->toArray(); - /** @var Account|null $result */ - $result = auth()->user()->accounts()->whereIn('account_type_id', $accountTypeIds)->where('id', '!=', $ignore) - ->where('name', $value) - ->first(); - return null === $result; - } - - /** - * @param int $accountId - * @param mixed $value - * - * @return bool - */ - private function validateByParameterId(int $accountId, $value): bool - { - /** @var Account $existingAccount */ - $existingAccount = Account::find($accountId); - - $type = $existingAccount->accountType; - $ignore = $existingAccount->id; - - $entry = auth()->user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore) - ->where('name', $value) - ->first(); - - return null === $entry; - } } diff --git a/app/Validation/GroupValidation.php b/app/Validation/GroupValidation.php index 7f1f7d32aa..be25188c21 100644 --- a/app/Validation/GroupValidation.php +++ b/app/Validation/GroupValidation.php @@ -37,14 +37,7 @@ use Illuminate\Validation\Validator; trait GroupValidation { /** - * @param Validator $validator - * - * @return array - */ - abstract protected function getTransactionsArray(Validator $validator): array; - - /** - * @param Validator $validator + * @param Validator $validator */ protected function preventNoAccountInfo(Validator $validator): void { @@ -86,11 +79,18 @@ trait GroupValidation // only an issue if there is no transaction_journal_id } + /** + * @param Validator $validator + * + * @return array + */ + abstract protected function getTransactionsArray(Validator $validator): array; + /** * Adds an error to the "description" field when the user has submitted no descriptions and no * journal description. * - * @param Validator $validator + * @param Validator $validator */ protected function validateDescriptions(Validator $validator): void { @@ -116,7 +116,7 @@ trait GroupValidation } /** - * @param Validator $validator + * @param Validator $validator */ protected function validateGroupDescription(Validator $validator): void { @@ -134,11 +134,12 @@ trait GroupValidation } /** - * This method validates if the user has submitted transaction journal ID's for each array they submit, if they've submitted more than 1 transaction - * journal. This check is necessary because Firefly III isn't able to distinguish between journals without the ID. + * This method validates if the user has submitted transaction journal ID's for each array they submit, if they've + * submitted more than 1 transaction journal. This check is necessary because Firefly III isn't able to distinguish + * between journals without the ID. * - * @param Validator $validator - * @param TransactionGroup $transactionGroup + * @param Validator $validator + * @param TransactionGroup $transactionGroup */ protected function validateJournalIds(Validator $validator, TransactionGroup $transactionGroup): void { @@ -153,7 +154,7 @@ trait GroupValidation } // check each array: /** - * @var int $index + * @var int $index * @var array $transaction */ foreach ($transactions as $index => $transaction) { @@ -164,10 +165,10 @@ trait GroupValidation /** * Do the validation required by validateJournalIds. * - * @param Validator $validator - * @param int $index - * @param array $transaction - * @param TransactionGroup $transactionGroup + * @param Validator $validator + * @param int $index + * @param array $transaction + * @param TransactionGroup $transactionGroup * */ private function validateJournalId(Validator $validator, int $index, array $transaction, TransactionGroup $transactionGroup): void diff --git a/app/Validation/RecurrenceValidation.php b/app/Validation/RecurrenceValidation.php index 08e7af8982..2f5b35dd1a 100644 --- a/app/Validation/RecurrenceValidation.php +++ b/app/Validation/RecurrenceValidation.php @@ -43,7 +43,7 @@ trait RecurrenceValidation * * TODO Must always trigger when the type of the recurrence changes. * - * @param Validator $validator + * @param Validator $validator */ public function valUpdateAccountInfo(Validator $validator): void { @@ -119,7 +119,7 @@ trait RecurrenceValidation /** * Adds an error to the validator when there are no repetitions in the array of data. * - * @param Validator $validator + * @param Validator $validator */ public function validateOneRepetition(Validator $validator): void { @@ -134,7 +134,7 @@ trait RecurrenceValidation /** * Adds an error to the validator when there are no repetitions in the array of data. * - * @param Validator $validator + * @param Validator $validator */ public function validateOneRepetitionUpdate(Validator $validator): void { @@ -153,7 +153,7 @@ trait RecurrenceValidation * Validates that the recurrence has valid repetition information. It either doesn't stop, * or stops after X times or at X date. Not both of them., * - * @param Validator $validator + * @param Validator $validator */ public function validateRecurrenceRepetition(Validator $validator): void { @@ -186,7 +186,7 @@ trait RecurrenceValidation } /** - * @param Validator $validator + * @param Validator $validator */ public function validateRepetitionMoment(Validator $validator): void { @@ -198,7 +198,7 @@ trait RecurrenceValidation return; } /** - * @var int $index + * @var int $index * @var array $repetition */ foreach ($repetitions as $index => $repetition) { @@ -237,9 +237,9 @@ trait RecurrenceValidation /** * If the repetition type is daily, the moment should be empty. * - * @param Validator $validator - * @param int $index - * @param string $moment + * @param Validator $validator + * @param int $index + * @param string $moment */ protected function validateDaily(Validator $validator, int $index, string $moment): void { @@ -251,9 +251,9 @@ trait RecurrenceValidation /** * If the repetition type is monthly, the moment should be a day between 1-31 (inclusive). * - * @param Validator $validator - * @param int $index - * @param int $dayOfMonth + * @param Validator $validator + * @param int $index + * @param int $dayOfMonth */ protected function validateMonthly(Validator $validator, int $index, int $dayOfMonth): void { @@ -266,9 +266,9 @@ trait RecurrenceValidation * If the repetition type is "ndom", the first part must be between 1-5 (inclusive), for the week in the month, * and the second one must be between 1-7 (inclusive) for the day of the week. * - * @param Validator $validator - * @param int $index - * @param string $moment + * @param Validator $validator + * @param int $index + * @param string $moment */ protected function validateNdom(Validator $validator, int $index, string $moment): void { @@ -291,7 +291,38 @@ trait RecurrenceValidation } /** - * @param Validator $validator + * If the repetition type is weekly, the moment should be a day between 1-7 (inclusive). + * + * @param Validator $validator + * @param int $index + * @param int $dayOfWeek + */ + protected function validateWeekly(Validator $validator, int $index, int $dayOfWeek): void + { + if ($dayOfWeek < 1 || $dayOfWeek > 7) { + $validator->errors()->add(sprintf('repetitions.%d.moment', $index), (string)trans('validation.valid_recurrence_rep_moment')); + } + } + + /** + * If the repetition type is yearly, the moment should be a valid date. + * + * @param Validator $validator + * @param int $index + * @param string $moment + */ + protected function validateYearly(Validator $validator, int $index, string $moment): void + { + try { + Carbon::createFromFormat('Y-m-d', $moment); + } catch (InvalidArgumentException $e) { + Log::debug(sprintf('Invalid argument for Carbon: %s', $e->getMessage())); + $validator->errors()->add(sprintf('repetitions.%d.moment', $index), (string)trans('validation.valid_recurrence_rep_moment')); + } + } + + /** + * @param Validator $validator * @return void */ protected function validateTransactionId(Recurrence $recurrence, Validator $validator): void @@ -387,36 +418,4 @@ trait RecurrenceValidation } Log::debug('Done with ID validation.'); } - - - /** - * If the repetition type is weekly, the moment should be a day between 1-7 (inclusive). - * - * @param Validator $validator - * @param int $index - * @param int $dayOfWeek - */ - protected function validateWeekly(Validator $validator, int $index, int $dayOfWeek): void - { - if ($dayOfWeek < 1 || $dayOfWeek > 7) { - $validator->errors()->add(sprintf('repetitions.%d.moment', $index), (string)trans('validation.valid_recurrence_rep_moment')); - } - } - - /** - * If the repetition type is yearly, the moment should be a valid date. - * - * @param Validator $validator - * @param int $index - * @param string $moment - */ - protected function validateYearly(Validator $validator, int $index, string $moment): void - { - try { - Carbon::createFromFormat('Y-m-d', $moment); - } catch (InvalidArgumentException $e) { - Log::debug(sprintf('Invalid argument for Carbon: %s', $e->getMessage())); - $validator->errors()->add(sprintf('repetitions.%d.moment', $index), (string)trans('validation.valid_recurrence_rep_moment')); - } - } } diff --git a/app/Validation/TransactionValidation.php b/app/Validation/TransactionValidation.php index 1fa1080e50..7921466c45 100644 --- a/app/Validation/TransactionValidation.php +++ b/app/Validation/TransactionValidation.php @@ -42,7 +42,7 @@ trait TransactionValidation /** * Validates the given account information. Switches on given transaction type. * - * @param Validator $validator + * @param Validator $validator */ public function validateAccountInformation(Validator $validator): void { @@ -57,7 +57,7 @@ trait TransactionValidation Log::debug(sprintf('Going to loop %d transaction(s)', count($transactions))); /** - * @var int $index + * @var int $index * @var array $transaction */ foreach ($transactions as $index => $transaction) { @@ -69,142 +69,7 @@ trait TransactionValidation } /** - * Validates the given account information. Switches on given transaction type. - * - * @param Validator $validator - * @param TransactionGroup $transactionGroup - */ - public function validateAccountInformationUpdate(Validator $validator, TransactionGroup $transactionGroup): void - { - Log::debug('Now in validateAccountInformationUpdate()'); - $transactions = $this->getTransactionsArray($validator); - - /** - * @var int $index - * @var array $transaction - */ - foreach ($transactions as $index => $transaction) { - if (!is_int($index)) { - throw new FireflyException('Invalid data submitted: transaction is not array.'); - } - $this->validateSingleUpdate($validator, $index, $transaction, $transactionGroup); - } - } - - /** - * Adds an error to the validator when there are no transactions in the array of data. - * - * @param Validator $validator - */ - public function validateOneRecurrenceTransaction(Validator $validator): void - { - Log::debug('Now in validateOneRecurrenceTransaction()'); - $transactions = $this->getTransactionsArray($validator); - - // need at least one transaction - if (0 === count($transactions)) { - $validator->errors()->add('transactions', (string)trans('validation.at_least_one_transaction')); - } - } - - /** - * Adds an error to the validator when there are no transactions in the array of data. - * - * @param Validator $validator - */ - public function validateOneTransaction(Validator $validator): void - { - Log::debug('Now in validateOneTransaction'); - if ($validator->errors()->count() > 0) { - Log::debug('Validator already has errors, so return.'); - return; - } - $transactions = $this->getTransactionsArray($validator); - // need at least one transaction - if (0 === count($transactions)) { - $validator->errors()->add('transactions.0.description', (string)trans('validation.at_least_one_transaction')); - Log::debug('Added error: at_least_one_transaction.'); - - return; - } - Log::debug('Added NO errors.'); - } - - /** - * @param Validator $validator - */ - public function validateTransactionArray(Validator $validator): void - { - if ($validator->errors()->count() > 0) { - return; - } - $transactions = $this->getTransactionsArray($validator); - foreach ($transactions as $key => $value) { - if (!is_int($key)) { - $validator->errors()->add('transactions.0.description', (string)trans('validation.at_least_one_transaction')); - Log::debug('Added error: at_least_one_transaction.'); - - return; - } - } - } - - /** - * All types of splits must be equal. - * - * @param Validator $validator - */ - public function validateTransactionTypes(Validator $validator): void - { - if ($validator->errors()->count() > 0) { - return; - } - Log::debug('Now in validateTransactionTypes()'); - $transactions = $this->getTransactionsArray($validator); - - $types = []; - foreach ($transactions as $transaction) { - $types[] = $transaction['type'] ?? 'invalid'; - } - $unique = array_unique($types); - if (count($unique) > 1) { - $validator->errors()->add('transactions.0.type', (string)trans('validation.transaction_types_equal')); - - return; - } - $first = $unique[0] ?? 'invalid'; - if ('invalid' === $first) { - $validator->errors()->add('transactions.0.type', (string)trans('validation.invalid_transaction_type')); - } - } - - /** - * All types of splits must be equal. - * - * @param Validator $validator - */ - public function validateTransactionTypesForUpdate(Validator $validator): void - { - Log::debug('Now in validateTransactionTypesForUpdate()'); - $transactions = $this->getTransactionsArray($validator); - $types = []; - foreach ($transactions as $transaction) { - $originalType = $this->getOriginalType((int)($transaction['transaction_journal_id'] ?? 0)); - // if type is not set, fall back to the type of the journal, if one is given. - $types[] = $transaction['type'] ?? $originalType; - } - $unique = array_unique($types); - if (count($unique) > 1) { - app('log')->warning('Add error for mismatch transaction types.'); - $validator->errors()->add('transactions.0.type', (string)trans('validation.transaction_types_equal')); - - return; - } - Log::debug('No errors in validateTransactionTypesForUpdate()'); - } - - /** - * @param Validator $validator + * @param Validator $validator * * @return array */ @@ -231,42 +96,10 @@ trait TransactionValidation } /** - * @param Validator $validator - * @param string $transactionType - * @param int $index - * @param array $source - * @param array $destination - * @return void - */ - protected function sanityCheckReconciliation(Validator $validator, string $transactionType, int $index, array $source, array $destination): void - { - Log::debug('Now in sanityCheckReconciliation'); - if (TransactionType::RECONCILIATION === ucfirst($transactionType) && - null === $source['id'] && null === $source['name'] && null === $destination['id'] && null === $destination['name'] - ) { - Log::debug('Both are NULL, error!'); - $validator->errors()->add(sprintf('transactions.%d.source_id', $index), trans('validation.reconciliation_either_account')); - $validator->errors()->add(sprintf('transactions.%d.source_name', $index), trans('validation.reconciliation_either_account')); - $validator->errors()->add(sprintf('transactions.%d.destination_id', $index), trans('validation.reconciliation_either_account')); - $validator->errors()->add(sprintf('transactions.%d.destination_name', $index), trans('validation.reconciliation_either_account')); - } - - if (TransactionType::RECONCILIATION === $transactionType && - (null !== $source['id'] || null !== $source['name']) && - (null !== $destination['id'] || null !== $destination['name'])) { - Log::debug('Both are not NULL, error!'); - $validator->errors()->add(sprintf('transactions.%d.source_id', $index), trans('validation.reconciliation_either_account')); - $validator->errors()->add(sprintf('transactions.%d.source_name', $index), trans('validation.reconciliation_either_account')); - $validator->errors()->add(sprintf('transactions.%d.destination_id', $index), trans('validation.reconciliation_either_account')); - $validator->errors()->add(sprintf('transactions.%d.destination_name', $index), trans('validation.reconciliation_either_account')); - } - } - - /** - * @param Validator $validator - * @param int $index - * @param string $transactionType - * @param array $transaction + * @param Validator $validator + * @param int $index + * @param string $transactionType + * @param array $transaction */ protected function validateSingleAccount(Validator $validator, int $index, string $transactionType, array $transaction): void { @@ -321,345 +154,53 @@ trait TransactionValidation } /** - * @param Validator $validator - * @param int $index - * @param array $transaction - * @param TransactionGroup $transactionGroup + * @param Validator $validator + * @param string $transactionType + * @param int $index + * @param array $source + * @param array $destination + * @return void */ - protected function validateSingleUpdate(Validator $validator, int $index, array $transaction, TransactionGroup $transactionGroup): void + protected function sanityCheckReconciliation(Validator $validator, string $transactionType, int $index, array $source, array $destination): void { - Log::debug('Now validating single account update in validateSingleUpdate()'); - - // if no account types are given, just skip the check. - if ( - !array_key_exists('source_id', $transaction) - && !array_key_exists('source_name', $transaction) - && !array_key_exists('destination_id', $transaction) - && !array_key_exists('destination_name', $transaction)) { - Log::debug('No account data has been submitted so will not validating account info.'); - - return; - } - // create validator: - /** @var AccountValidator $accountValidator */ - $accountValidator = app(AccountValidator::class); - - // get the transaction type using the original transaction group: - $accountValidator->setTransactionType($this->getTransactionType($transactionGroup, [])); - - // validate if the submitted source and / or name are valid - if (array_key_exists('source_id', $transaction) || array_key_exists('source_name', $transaction)) { - Log::debug('Will try to validate source account information.'); - $sourceId = (int)($transaction['source_id'] ?? 0); - $sourceName = $transaction['source_name'] ?? null; - $validSource = $accountValidator->validateSource(['id' => $sourceId, 'name' => $sourceName]); - - // do something with result: - if (false === $validSource) { - app('log')->warning('Looks like the source account is not valid so complain to the user about it.'); - $validator->errors()->add(sprintf('transactions.%d.source_id', $index), $accountValidator->sourceError); - $validator->errors()->add(sprintf('transactions.%d.source_name', $index), $accountValidator->sourceError); - - return; - } - Log::debug('Source account info is valid.'); + Log::debug('Now in sanityCheckReconciliation'); + if (TransactionType::RECONCILIATION === ucfirst($transactionType) && + null === $source['id'] && null === $source['name'] && null === $destination['id'] && null === $destination['name'] + ) { + Log::debug('Both are NULL, error!'); + $validator->errors()->add(sprintf('transactions.%d.source_id', $index), trans('validation.reconciliation_either_account')); + $validator->errors()->add(sprintf('transactions.%d.source_name', $index), trans('validation.reconciliation_either_account')); + $validator->errors()->add(sprintf('transactions.%d.destination_id', $index), trans('validation.reconciliation_either_account')); + $validator->errors()->add(sprintf('transactions.%d.destination_name', $index), trans('validation.reconciliation_either_account')); } - if (array_key_exists('destination_id', $transaction) || array_key_exists('destination_name', $transaction)) { - Log::debug('Will try to validate destination account information.'); - // at this point the validator may not have a source account, because it was never submitted for validation. - // must add it ourselves or the validator can never check if the destination is correct. - // the $transaction array must have a journal id or it's just one, this was validated before. - if (null === $accountValidator->source) { - Log::debug('Account validator has no source account, must find it.'); - $source = $this->getOriginalSource($transaction, $transactionGroup); - if (null !== $source) { - Log::debug('Found a source!'); - $accountValidator->source = $source; - } - } - $destinationId = (int)($transaction['destination_id'] ?? 0); - $destinationName = $transaction['destination_name'] ?? null; - $array = ['id' => $destinationId, 'name' => $destinationName,]; - $validDestination = $accountValidator->validateDestination($array); - // do something with result: - if (false === $validDestination) { - app('log')->warning('Looks like the destination account is not valid so complain to the user about it.'); - $validator->errors()->add(sprintf('transactions.%d.destination_id', $index), $accountValidator->destError); - $validator->errors()->add(sprintf('transactions.%d.destination_name', $index), $accountValidator->destError); - } - Log::debug('Destination account info is valid.'); + if (TransactionType::RECONCILIATION === $transactionType && + (null !== $source['id'] || null !== $source['name']) && + (null !== $destination['id'] || null !== $destination['name'])) { + Log::debug('Both are not NULL, error!'); + $validator->errors()->add(sprintf('transactions.%d.source_id', $index), trans('validation.reconciliation_either_account')); + $validator->errors()->add(sprintf('transactions.%d.source_name', $index), trans('validation.reconciliation_either_account')); + $validator->errors()->add(sprintf('transactions.%d.destination_id', $index), trans('validation.reconciliation_either_account')); + $validator->errors()->add(sprintf('transactions.%d.destination_name', $index), trans('validation.reconciliation_either_account')); } - Log::debug('Done with validateSingleUpdate().'); - } - - /** - * @param array $array - * - * @return bool - */ - private function arrayEqual(array $array): bool - { - return 1 === count(array_unique($array)); - } - - /** - * @param array $transactions - * - * @return array - */ - private function collectComparisonData(array $transactions): array - { - $fields = ['source_id', 'destination_id', 'source_name', 'destination_name']; - $comparison = []; - foreach ($fields as $field) { - $comparison[$field] = []; - /** @var array $transaction */ - foreach ($transactions as $transaction) { - // source or destination may be omitted. If this is the case, use the original source / destination name + ID. - $originalData = $this->getOriginalData((int)($transaction['transaction_journal_id'] ?? 0)); - - // get field. - $comparison[$field][] = $transaction[$field] ?? $originalData[$field]; - } - } - - return $comparison; - } - - /** - * @param string $type - * @param array $comparison - * - * @return bool - */ - private function compareAccountData(string $type, array $comparison): bool - { - return match ($type) { - default => $this->compareAccountDataWithdrawal($comparison), - 'deposit' => $this->compareAccountDataDeposit($comparison), - 'transfer' => $this->compareAccountDataTransfer($comparison), - }; - } - - /** - * @param array $comparison - * - * @return bool - */ - private function compareAccountDataDeposit(array $comparison): bool - { - if ($this->arrayEqual($comparison['destination_id'])) { - // destination ID's are equal, return void. - return true; - } - if ($this->arrayEqual($comparison['destination_name'])) { - // destination names are equal, return void. - return true; - } - - return false; - } - - /** - * @param array $comparison - * - * @return bool - */ - private function compareAccountDataTransfer(array $comparison): bool - { - if ($this->arrayEqual($comparison['source_id'])) { - // source ID's are equal, return void. - return true; - } - if ($this->arrayEqual($comparison['source_name'])) { - // source names are equal, return void. - return true; - } - if ($this->arrayEqual($comparison['destination_id'])) { - // destination ID's are equal, return void. - return true; - } - if ($this->arrayEqual($comparison['destination_name'])) { - // destination names are equal, return void. - return true; - } - - return false; - } - - /** - * @param array $comparison - * - * @return bool - */ - private function compareAccountDataWithdrawal(array $comparison): bool - { - if ($this->arrayEqual($comparison['source_id'])) { - // source ID's are equal, return void. - return true; - } - if ($this->arrayEqual($comparison['source_name'])) { - // source names are equal, return void. - return true; - } - - return false; - } - - /** - * @param int $journalId - * - * @return array - */ - private function getOriginalData(int $journalId): array - { - $return = [ - 'source_id' => 0, - 'source_name' => '', - 'destination_id' => 0, - 'destination_name' => '', - ]; - if (0 === $journalId) { - return $return; - } - /** @var Transaction $source */ - $source = Transaction::where('transaction_journal_id', $journalId)->where('amount', '<', 0)->with(['account'])->first(); - if (null !== $source) { - $return['source_id'] = $source->account_id; - $return['source_name'] = $source->account->name; - } - /** @var Transaction $destination */ - $destination = Transaction::where('transaction_journal_id', $journalId)->where('amount', '>', 0)->with(['account'])->first(); - if (null !== $source) { - $return['destination_id'] = $destination->account_id; - $return['destination_name'] = $destination->account->name; - } - - return $return; - } - - /** - * @param array $transaction - * @param TransactionGroup $transactionGroup - * - * @return Account|null - */ - private function getOriginalSource(array $transaction, TransactionGroup $transactionGroup): ?Account - { - if (1 === $transactionGroup->transactionJournals->count()) { - $journal = $transactionGroup->transactionJournals->first(); - - return $journal->transactions()->where('amount', '<', 0)->first()->account; - } - /** @var TransactionJournal $journal */ - foreach ($transactionGroup->transactionJournals as $journal) { - if ((int)$journal->id === (int)$transaction['transaction_journal_id']) { - return $journal->transactions()->where('amount', '<', 0)->first()->account; - } - } - - return null; - } - - /** - * @param int $journalId - * - * @return string - */ - private function getOriginalType(int $journalId): string - { - if (0 === $journalId) { - return 'invalid'; - } - /** @var TransactionJournal|null $journal */ - $journal = TransactionJournal::with(['transactionType'])->find($journalId); - if (null !== $journal) { - return strtolower($journal->transactionType->type); - } - - return 'invalid'; - } - - /** - * @param TransactionGroup $group - * @param array $transactions - * - * @return string - */ - private function getTransactionType(TransactionGroup $group, array $transactions): string - { - return $transactions[0]['type'] ?? strtolower($group->transactionJournals()->first()->transactionType->type); - } - - /** - * @param array $transaction - * @return bool - */ - private function hasForeignCurrencyInfo(array $transaction): bool - { - if (!array_key_exists('foreign_currency_code', $transaction) && !array_key_exists('foreign_currency_id', $transaction)) { - return false; - } - if (!array_key_exists('foreign_amount', $transaction)) { - return false; - } - if ('' === $transaction['foreign_amount']) { - return false; - } - if (bccomp('0', $transaction['foreign_amount']) === 0) { - return false; - } - return true; - } - - /** - * @param Account $account - * @return bool - */ - private function isAsset(Account $account): bool - { - $type = $account->accountType?->type; - return $type === AccountType::ASSET; - } - - /** - * @param Account $account - * @return bool - */ - private function isLiability(Account $account): bool - { - $type = $account->accountType?->type; - if (in_array($type, config('firefly.valid_liabilities'), true)) { - return true; - } - return false; - } - - /** - * @param Account $account - * @return bool - */ - private function isLiabilityOrAsset(Account $account): bool - { - return $this->isLiability($account) || $this->isAsset($account); } /** * TODO describe this method. - * @param Validator $validator - * @param AccountValidator $accountValidator - * @param array $transaction - * @param string $transactionType - * @param int $index + * + * @param Validator $validator + * @param AccountValidator $accountValidator + * @param array $transaction + * @param string $transactionType + * @param int $index * @return void */ private function sanityCheckForeignCurrency( - Validator $validator, + Validator $validator, AccountValidator $accountValidator, - array $transaction, - string $transactionType, - int $index + array $transaction, + string $transactionType, + int $index ): void { Log::debug('Now in sanityCheckForeignCurrency()'); if (0 !== $validator->errors()->count()) { @@ -751,7 +292,321 @@ trait TransactionValidation } /** - * @param Validator $validator + * @param Account $account + * @return bool + */ + private function isLiabilityOrAsset(Account $account): bool + { + return $this->isLiability($account) || $this->isAsset($account); + } + + /** + * @param Account $account + * @return bool + */ + private function isLiability(Account $account): bool + { + $type = $account->accountType?->type; + if (in_array($type, config('firefly.valid_liabilities'), true)) { + return true; + } + return false; + } + + /** + * @param Account $account + * @return bool + */ + private function isAsset(Account $account): bool + { + $type = $account->accountType?->type; + return $type === AccountType::ASSET; + } + + /** + * @param array $transaction + * @return bool + */ + private function hasForeignCurrencyInfo(array $transaction): bool + { + if (!array_key_exists('foreign_currency_code', $transaction) && !array_key_exists('foreign_currency_id', $transaction)) { + return false; + } + if (!array_key_exists('foreign_amount', $transaction)) { + return false; + } + if ('' === $transaction['foreign_amount']) { + return false; + } + if (bccomp('0', $transaction['foreign_amount']) === 0) { + return false; + } + return true; + } + + /** + * Validates the given account information. Switches on given transaction type. + * + * @param Validator $validator + * @param TransactionGroup $transactionGroup + */ + public function validateAccountInformationUpdate(Validator $validator, TransactionGroup $transactionGroup): void + { + Log::debug('Now in validateAccountInformationUpdate()'); + $transactions = $this->getTransactionsArray($validator); + + /** + * @var int $index + * @var array $transaction + */ + foreach ($transactions as $index => $transaction) { + if (!is_int($index)) { + throw new FireflyException('Invalid data submitted: transaction is not array.'); + } + $this->validateSingleUpdate($validator, $index, $transaction, $transactionGroup); + } + } + + /** + * @param Validator $validator + * @param int $index + * @param array $transaction + * @param TransactionGroup $transactionGroup + */ + protected function validateSingleUpdate(Validator $validator, int $index, array $transaction, TransactionGroup $transactionGroup): void + { + Log::debug('Now validating single account update in validateSingleUpdate()'); + + // if no account types are given, just skip the check. + if ( + !array_key_exists('source_id', $transaction) + && !array_key_exists('source_name', $transaction) + && !array_key_exists('destination_id', $transaction) + && !array_key_exists('destination_name', $transaction)) { + Log::debug('No account data has been submitted so will not validating account info.'); + + return; + } + // create validator: + /** @var AccountValidator $accountValidator */ + $accountValidator = app(AccountValidator::class); + + // get the transaction type using the original transaction group: + $accountValidator->setTransactionType($this->getTransactionType($transactionGroup, [])); + + // validate if the submitted source and / or name are valid + if (array_key_exists('source_id', $transaction) || array_key_exists('source_name', $transaction)) { + Log::debug('Will try to validate source account information.'); + $sourceId = (int)($transaction['source_id'] ?? 0); + $sourceName = $transaction['source_name'] ?? null; + $validSource = $accountValidator->validateSource(['id' => $sourceId, 'name' => $sourceName]); + + // do something with result: + if (false === $validSource) { + app('log')->warning('Looks like the source account is not valid so complain to the user about it.'); + $validator->errors()->add(sprintf('transactions.%d.source_id', $index), $accountValidator->sourceError); + $validator->errors()->add(sprintf('transactions.%d.source_name', $index), $accountValidator->sourceError); + + return; + } + Log::debug('Source account info is valid.'); + } + + if (array_key_exists('destination_id', $transaction) || array_key_exists('destination_name', $transaction)) { + Log::debug('Will try to validate destination account information.'); + // at this point the validator may not have a source account, because it was never submitted for validation. + // must add it ourselves or the validator can never check if the destination is correct. + // the $transaction array must have a journal id or it's just one, this was validated before. + if (null === $accountValidator->source) { + Log::debug('Account validator has no source account, must find it.'); + $source = $this->getOriginalSource($transaction, $transactionGroup); + if (null !== $source) { + Log::debug('Found a source!'); + $accountValidator->source = $source; + } + } + $destinationId = (int)($transaction['destination_id'] ?? 0); + $destinationName = $transaction['destination_name'] ?? null; + $array = ['id' => $destinationId, 'name' => $destinationName,]; + $validDestination = $accountValidator->validateDestination($array); + // do something with result: + if (false === $validDestination) { + app('log')->warning('Looks like the destination account is not valid so complain to the user about it.'); + $validator->errors()->add(sprintf('transactions.%d.destination_id', $index), $accountValidator->destError); + $validator->errors()->add(sprintf('transactions.%d.destination_name', $index), $accountValidator->destError); + } + Log::debug('Destination account info is valid.'); + } + Log::debug('Done with validateSingleUpdate().'); + } + + /** + * @param TransactionGroup $group + * @param array $transactions + * + * @return string + */ + private function getTransactionType(TransactionGroup $group, array $transactions): string + { + return $transactions[0]['type'] ?? strtolower($group->transactionJournals()->first()->transactionType->type); + } + + /** + * @param array $transaction + * @param TransactionGroup $transactionGroup + * + * @return Account|null + */ + private function getOriginalSource(array $transaction, TransactionGroup $transactionGroup): ?Account + { + if (1 === $transactionGroup->transactionJournals->count()) { + $journal = $transactionGroup->transactionJournals->first(); + + return $journal->transactions()->where('amount', '<', 0)->first()->account; + } + /** @var TransactionJournal $journal */ + foreach ($transactionGroup->transactionJournals as $journal) { + if ((int)$journal->id === (int)$transaction['transaction_journal_id']) { + return $journal->transactions()->where('amount', '<', 0)->first()->account; + } + } + + return null; + } + + /** + * Adds an error to the validator when there are no transactions in the array of data. + * + * @param Validator $validator + */ + public function validateOneRecurrenceTransaction(Validator $validator): void + { + Log::debug('Now in validateOneRecurrenceTransaction()'); + $transactions = $this->getTransactionsArray($validator); + + // need at least one transaction + if (0 === count($transactions)) { + $validator->errors()->add('transactions', (string)trans('validation.at_least_one_transaction')); + } + } + + /** + * Adds an error to the validator when there are no transactions in the array of data. + * + * @param Validator $validator + */ + public function validateOneTransaction(Validator $validator): void + { + Log::debug('Now in validateOneTransaction'); + if ($validator->errors()->count() > 0) { + Log::debug('Validator already has errors, so return.'); + return; + } + $transactions = $this->getTransactionsArray($validator); + // need at least one transaction + if (0 === count($transactions)) { + $validator->errors()->add('transactions.0.description', (string)trans('validation.at_least_one_transaction')); + Log::debug('Added error: at_least_one_transaction.'); + + return; + } + Log::debug('Added NO errors.'); + } + + /** + * @param Validator $validator + */ + public function validateTransactionArray(Validator $validator): void + { + if ($validator->errors()->count() > 0) { + return; + } + $transactions = $this->getTransactionsArray($validator); + foreach ($transactions as $key => $value) { + if (!is_int($key)) { + $validator->errors()->add('transactions.0.description', (string)trans('validation.at_least_one_transaction')); + Log::debug('Added error: at_least_one_transaction.'); + + return; + } + } + } + + /** + * All types of splits must be equal. + * + * @param Validator $validator + */ + public function validateTransactionTypes(Validator $validator): void + { + if ($validator->errors()->count() > 0) { + return; + } + Log::debug('Now in validateTransactionTypes()'); + $transactions = $this->getTransactionsArray($validator); + + $types = []; + foreach ($transactions as $transaction) { + $types[] = $transaction['type'] ?? 'invalid'; + } + $unique = array_unique($types); + if (count($unique) > 1) { + $validator->errors()->add('transactions.0.type', (string)trans('validation.transaction_types_equal')); + + return; + } + $first = $unique[0] ?? 'invalid'; + if ('invalid' === $first) { + $validator->errors()->add('transactions.0.type', (string)trans('validation.invalid_transaction_type')); + } + } + + /** + * All types of splits must be equal. + * + * @param Validator $validator + */ + public function validateTransactionTypesForUpdate(Validator $validator): void + { + Log::debug('Now in validateTransactionTypesForUpdate()'); + $transactions = $this->getTransactionsArray($validator); + $types = []; + foreach ($transactions as $transaction) { + $originalType = $this->getOriginalType((int)($transaction['transaction_journal_id'] ?? 0)); + // if type is not set, fall back to the type of the journal, if one is given. + $types[] = $transaction['type'] ?? $originalType; + } + $unique = array_unique($types); + if (count($unique) > 1) { + app('log')->warning('Add error for mismatch transaction types.'); + $validator->errors()->add('transactions.0.type', (string)trans('validation.transaction_types_equal')); + + return; + } + Log::debug('No errors in validateTransactionTypesForUpdate()'); + } + + /** + * @param int $journalId + * + * @return string + */ + private function getOriginalType(int $journalId): string + { + if (0 === $journalId) { + return 'invalid'; + } + /** @var TransactionJournal|null $journal */ + $journal = TransactionJournal::with(['transactionType'])->find($journalId); + if (null !== $journal) { + return strtolower($journal->transactionType->type); + } + + return 'invalid'; + } + + /** + * @param Validator $validator */ private function validateEqualAccounts(Validator $validator): void { @@ -796,8 +651,8 @@ trait TransactionValidation } /** - * @param Validator $validator - * @param TransactionGroup $transactionGroup + * @param Validator $validator + * @param TransactionGroup $transactionGroup */ private function validateEqualAccountsForUpdate(Validator $validator, TransactionGroup $transactionGroup): void { @@ -835,4 +690,150 @@ trait TransactionValidation } Log::debug('No errors found in validateEqualAccountsForUpdate'); } + + /** + * @param array $transactions + * + * @return array + */ + private function collectComparisonData(array $transactions): array + { + $fields = ['source_id', 'destination_id', 'source_name', 'destination_name']; + $comparison = []; + foreach ($fields as $field) { + $comparison[$field] = []; + /** @var array $transaction */ + foreach ($transactions as $transaction) { + // source or destination may be omitted. If this is the case, use the original source / destination name + ID. + $originalData = $this->getOriginalData((int)($transaction['transaction_journal_id'] ?? 0)); + + // get field. + $comparison[$field][] = $transaction[$field] ?? $originalData[$field]; + } + } + + return $comparison; + } + + /** + * @param int $journalId + * + * @return array + */ + private function getOriginalData(int $journalId): array + { + $return = [ + 'source_id' => 0, + 'source_name' => '', + 'destination_id' => 0, + 'destination_name' => '', + ]; + if (0 === $journalId) { + return $return; + } + /** @var Transaction $source */ + $source = Transaction::where('transaction_journal_id', $journalId)->where('amount', '<', 0)->with(['account'])->first(); + if (null !== $source) { + $return['source_id'] = $source->account_id; + $return['source_name'] = $source->account->name; + } + /** @var Transaction $destination */ + $destination = Transaction::where('transaction_journal_id', $journalId)->where('amount', '>', 0)->with(['account'])->first(); + if (null !== $source) { + $return['destination_id'] = $destination->account_id; + $return['destination_name'] = $destination->account->name; + } + + return $return; + } + + /** + * @param string $type + * @param array $comparison + * + * @return bool + */ + private function compareAccountData(string $type, array $comparison): bool + { + return match ($type) { + default => $this->compareAccountDataWithdrawal($comparison), + 'deposit' => $this->compareAccountDataDeposit($comparison), + 'transfer' => $this->compareAccountDataTransfer($comparison), + }; + } + + /** + * @param array $comparison + * + * @return bool + */ + private function compareAccountDataWithdrawal(array $comparison): bool + { + if ($this->arrayEqual($comparison['source_id'])) { + // source ID's are equal, return void. + return true; + } + if ($this->arrayEqual($comparison['source_name'])) { + // source names are equal, return void. + return true; + } + + return false; + } + + /** + * @param array $array + * + * @return bool + */ + private function arrayEqual(array $array): bool + { + return 1 === count(array_unique($array)); + } + + /** + * @param array $comparison + * + * @return bool + */ + private function compareAccountDataDeposit(array $comparison): bool + { + if ($this->arrayEqual($comparison['destination_id'])) { + // destination ID's are equal, return void. + return true; + } + if ($this->arrayEqual($comparison['destination_name'])) { + // destination names are equal, return void. + return true; + } + + return false; + } + + /** + * @param array $comparison + * + * @return bool + */ + private function compareAccountDataTransfer(array $comparison): bool + { + if ($this->arrayEqual($comparison['source_id'])) { + // source ID's are equal, return void. + return true; + } + if ($this->arrayEqual($comparison['source_name'])) { + // source names are equal, return void. + return true; + } + if ($this->arrayEqual($comparison['destination_id'])) { + // destination ID's are equal, return void. + return true; + } + if ($this->arrayEqual($comparison['destination_name'])) { + // destination names are equal, return void. + return true; + } + + return false; + } } diff --git a/bootstrap/app.php b/bootstrap/app.php index 7180e36c15..c6dadd7ee1 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -36,8 +36,8 @@ bcscale(12); if (!function_exists('envNonEmpty')) { /** - * @param string $key - * @param null $default + * @param string $key + * @param null $default * * @return mixed|null */ @@ -54,8 +54,8 @@ if (!function_exists('envNonEmpty')) { if (!function_exists('stringIsEqual')) { /** - * @param string $left - * @param string $right + * @param string $left + * @param string $right * * @return bool */ @@ -66,7 +66,7 @@ if (!function_exists('stringIsEqual')) { } $app = new Illuminate\Foundation\Application( - realpath(__DIR__.'/../') + realpath(__DIR__ . '/../') ); /* diff --git a/composer.lock b/composer.lock index 54a71023c9..bd999cf1ef 100644 --- a/composer.lock +++ b/composer.lock @@ -3524,16 +3524,16 @@ }, { "name": "monolog/monolog", - "version": "3.3.1", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "9b5daeaffce5b926cac47923798bba91059e60e2" + "reference": "e2392369686d420ca32df3803de28b5d6f76867d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/9b5daeaffce5b926cac47923798bba91059e60e2", - "reference": "9b5daeaffce5b926cac47923798bba91059e60e2", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/e2392369686d420ca32df3803de28b5d6f76867d", + "reference": "e2392369686d420ca32df3803de28b5d6f76867d", "shasum": "" }, "require": { @@ -3548,7 +3548,7 @@ "doctrine/couchdb": "~1.0@dev", "elasticsearch/elasticsearch": "^7 || ^8", "ext-json": "*", - "graylog2/gelf-php": "^1.4.2 || ^2@dev", + "graylog2/gelf-php": "^1.4.2 || ^2.0", "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8", @@ -3556,7 +3556,7 @@ "phpstan/phpstan": "^1.9", "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-strict-rules": "^1.4", - "phpunit/phpunit": "^9.5.26", + "phpunit/phpunit": "^10.1", "predis/predis": "^1.1 || ^2", "ruflin/elastica": "^7", "symfony/mailer": "^5.4 || ^6", @@ -3609,7 +3609,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.3.1" + "source": "https://github.com/Seldaek/monolog/tree/3.4.0" }, "funding": [ { @@ -3621,7 +3621,7 @@ "type": "tidelift" } ], - "time": "2023-02-06T13:46:10+00:00" + "time": "2023-06-21T08:46:11+00:00" }, { "name": "nesbot/carbon", diff --git a/config/database.php b/config/database.php index 01629997bd..af30a9f4f4 100644 --- a/config/database.php +++ b/config/database.php @@ -137,7 +137,7 @@ return [ 'client' => env('REDIS_CLIENT', 'predis'), 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'predis'), - 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), + 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_'), ], 'default' => [ 'scheme' => envNonEmpty('REDIS_SCHEME', 'tcp'), diff --git a/config/filesystems.php b/config/filesystems.php index 1af22469ae..8deff7ba8f 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -88,7 +88,7 @@ return [ 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), - 'url' => env('APP_URL').'/storage', + 'url' => env('APP_URL') . '/storage', 'visibility' => 'public', ], diff --git a/config/firefly.php b/config/firefly.php index e5e2d9f99c..59568808cc 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -107,7 +107,7 @@ return [ 'webhooks' => true, 'handle_debts' => true, ], - 'version' => '6.0.14', + 'version' => '6.0.15', 'api_version' => '2.0.4', 'db_version' => 19, diff --git a/config/ide-helper.php b/config/ide-helper.php index f39619f398..95598ccdcf 100644 --- a/config/ide-helper.php +++ b/config/ide-helper.php @@ -86,7 +86,7 @@ return [ 'include_helpers' => false, 'helper_files' => [ - base_path().'/vendor/laravel/framework/src/Illuminate/Support/helpers.php', + base_path() . '/vendor/laravel/framework/src/Illuminate/Support/helpers.php', ], /* diff --git a/config/logging.php b/config/logging.php index 4b1369bcd8..ced49af529 100644 --- a/config/logging.php +++ b/config/logging.php @@ -89,7 +89,7 @@ return [ // daily, used in stack 'stack' by default: 'daily' => [ 'driver' => 'daily', - 'path' => storage_path('logs/ff3-'.PHP_SAPI.'.log'), + 'path' => storage_path('logs/ff3-' . PHP_SAPI . '.log'), 'level' => envNonEmpty('APP_LOG_LEVEL', 'info'), 'days' => 7, ], diff --git a/config/mail.php b/config/mail.php index f82ae13e05..baea55bdc0 100644 --- a/config/mail.php +++ b/config/mail.php @@ -65,7 +65,7 @@ return [ 'sendmail' => [ 'transport' => 'sendmail', - 'path' => '/usr/sbin/sendmail -bs', + 'path' => envNonEmpty('MAIL_SENDMAIL_COMMAND', '/usr/sbin/sendmail -bs'), ], 'log' => [ 'transport' => 'log', diff --git a/database/migrations/2016_06_16_000000_create_support_tables.php b/database/migrations/2016_06_16_000000_create_support_tables.php index b8d599b6f2..3845d7b6c7 100644 --- a/database/migrations/2016_06_16_000000_create_support_tables.php +++ b/database/migrations/2016_06_16_000000_create_support_tables.php @@ -95,30 +95,6 @@ class CreateSupportTables extends Migration } } - /** - * @return void - */ - private function createConfigurationTable(): void - { - if (!Schema::hasTable('configuration')) { - try { - Schema::create( - 'configuration', - static function (Blueprint $table) { - $table->increments('id'); - $table->timestamps(); - $table->softDeletes(); - $table->string('name', 50); - $table->text('data'); - } - ); - } catch (QueryException $e) { - Log::error(sprintf(self::TABLE_ERROR, 'configuration', $e->getMessage())); - Log::error(self::TABLE_ALREADY_EXISTS); - } - } - } - /** * @return void */ @@ -147,6 +123,32 @@ class CreateSupportTables extends Migration } } + /** + * @return void + */ + private function createTransactionTypeTable(): void + { + if (!Schema::hasTable('transaction_types')) { + try { + Schema::create( + 'transaction_types', + static function (Blueprint $table) { + $table->increments('id'); + $table->timestamps(); + $table->softDeletes(); + $table->string('type', 50); + + // type must be unique. + $table->unique(['type']); + } + ); + } catch (QueryException $e) { + Log::error(sprintf(self::TABLE_ERROR, 'transaction_types', $e->getMessage())); + Log::error(self::TABLE_ALREADY_EXISTS); + } + } + } + /** * @return void */ @@ -199,32 +201,6 @@ class CreateSupportTables extends Migration } } - /** - * @return void - */ - private function createPermissionRoleTable(): void - { - if (!Schema::hasTable('permission_role')) { - try { - Schema::create( - 'permission_role', - static function (Blueprint $table) { - $table->integer('permission_id')->unsigned(); - $table->integer('role_id')->unsigned(); - - $table->foreign('permission_id')->references('id')->on('permissions')->onUpdate('cascade')->onDelete('cascade'); - $table->foreign('role_id')->references('id')->on('roles')->onUpdate('cascade')->onDelete('cascade'); - - $table->primary(['permission_id', 'role_id']); - } - ); - } catch (QueryException $e) { - Log::error(sprintf(self::TABLE_ERROR, 'permission_role', $e->getMessage())); - Log::error(self::TABLE_ALREADY_EXISTS); - } - } - } - /** * @return void */ @@ -273,6 +249,32 @@ class CreateSupportTables extends Migration } } + /** + * @return void + */ + private function createPermissionRoleTable(): void + { + if (!Schema::hasTable('permission_role')) { + try { + Schema::create( + 'permission_role', + static function (Blueprint $table) { + $table->integer('permission_id')->unsigned(); + $table->integer('role_id')->unsigned(); + + $table->foreign('permission_id')->references('id')->on('permissions')->onUpdate('cascade')->onDelete('cascade'); + $table->foreign('role_id')->references('id')->on('roles')->onUpdate('cascade')->onDelete('cascade'); + + $table->primary(['permission_id', 'role_id']); + } + ); + } catch (QueryException $e) { + Log::error(sprintf(self::TABLE_ERROR, 'permission_role', $e->getMessage())); + Log::error(self::TABLE_ALREADY_EXISTS); + } + } + } + /** * @return void */ @@ -301,24 +303,22 @@ class CreateSupportTables extends Migration /** * @return void */ - private function createTransactionTypeTable(): void + private function createConfigurationTable(): void { - if (!Schema::hasTable('transaction_types')) { + if (!Schema::hasTable('configuration')) { try { Schema::create( - 'transaction_types', + 'configuration', static function (Blueprint $table) { $table->increments('id'); $table->timestamps(); $table->softDeletes(); - $table->string('type', 50); - - // type must be unique. - $table->unique(['type']); + $table->string('name', 50); + $table->text('data'); } ); } catch (QueryException $e) { - Log::error(sprintf(self::TABLE_ERROR, 'transaction_types', $e->getMessage())); + Log::error(sprintf(self::TABLE_ERROR, 'configuration', $e->getMessage())); Log::error(self::TABLE_ALREADY_EXISTS); } } diff --git a/database/migrations/2016_06_16_000002_create_main_tables.php b/database/migrations/2016_06_16_000002_create_main_tables.php index abfa0d45cf..cf4284e8d0 100644 --- a/database/migrations/2016_06_16_000002_create_main_tables.php +++ b/database/migrations/2016_06_16_000002_create_main_tables.php @@ -136,6 +136,54 @@ class CreateMainTables extends Migration } } + private function createPiggyBanksTable(): void + { + if (!Schema::hasTable('piggy_banks')) { + try { + Schema::create( + 'piggy_banks', + static function (Blueprint $table) { + $table->increments('id'); + $table->timestamps(); + $table->softDeletes(); + $table->integer('account_id', false, true); + $table->string('name', 1024); + $table->decimal('targetamount', 32, 12); + $table->date('startdate')->nullable(); + $table->date('targetdate')->nullable(); + $table->integer('order', false, true)->default(0); + $table->boolean('active')->default(0); + $table->boolean('encrypted')->default(1); + $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); + } + ); + } catch (QueryException $e) { + Log::error(sprintf(self::TABLE_ERROR, 'piggy_banks', $e->getMessage())); + Log::error(self::TABLE_ALREADY_EXISTS); + } + } + + if (!Schema::hasTable('piggy_bank_repetitions')) { + try { + Schema::create( + 'piggy_bank_repetitions', + static function (Blueprint $table) { + $table->increments('id'); + $table->timestamps(); + $table->integer('piggy_bank_id', false, true); + $table->date('startdate')->nullable(); + $table->date('targetdate')->nullable(); + $table->decimal('currentamount', 32, 12); + $table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade'); + } + ); + } catch (QueryException $e) { + Log::error(sprintf(self::TABLE_ERROR, 'piggy_bank_repetitions', $e->getMessage())); + Log::error(self::TABLE_ALREADY_EXISTS); + } + } + } + private function createAttachmentsTable(): void { if (!Schema::hasTable('attachments')) { @@ -296,55 +344,6 @@ class CreateMainTables extends Migration } } - - private function createPiggyBanksTable(): void - { - if (!Schema::hasTable('piggy_banks')) { - try { - Schema::create( - 'piggy_banks', - static function (Blueprint $table) { - $table->increments('id'); - $table->timestamps(); - $table->softDeletes(); - $table->integer('account_id', false, true); - $table->string('name', 1024); - $table->decimal('targetamount', 32, 12); - $table->date('startdate')->nullable(); - $table->date('targetdate')->nullable(); - $table->integer('order', false, true)->default(0); - $table->boolean('active')->default(0); - $table->boolean('encrypted')->default(1); - $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); - } - ); - } catch (QueryException $e) { - Log::error(sprintf(self::TABLE_ERROR, 'piggy_banks', $e->getMessage())); - Log::error(self::TABLE_ALREADY_EXISTS); - } - } - - if (!Schema::hasTable('piggy_bank_repetitions')) { - try { - Schema::create( - 'piggy_bank_repetitions', - static function (Blueprint $table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('piggy_bank_id', false, true); - $table->date('startdate')->nullable(); - $table->date('targetdate')->nullable(); - $table->decimal('currentamount', 32, 12); - $table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade'); - } - ); - } catch (QueryException $e) { - Log::error(sprintf(self::TABLE_ERROR, 'piggy_bank_repetitions', $e->getMessage())); - Log::error(self::TABLE_ALREADY_EXISTS); - } - } - } - private function createPreferencesTable(): void { if (!Schema::hasTable('preferences')) { diff --git a/database/migrations/2016_10_09_150037_expand_transactions_table.php b/database/migrations/2016_10_09_150037_expand_transactions_table.php index 0a91c74d5a..90729f7f0a 100644 --- a/database/migrations/2016_10_09_150037_expand_transactions_table.php +++ b/database/migrations/2016_10_09_150037_expand_transactions_table.php @@ -46,7 +46,7 @@ class ExpandTransactionsTable extends Migration $table->dropColumn('identifier'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not drop column "identifier": %s', $e->getMessage())); Log::error('If the column does not exist, this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2016_12_28_203205_changes_for_v431.php b/database/migrations/2016_12_28_203205_changes_for_v431.php index d7d4e36d16..661337aad8 100644 --- a/database/migrations/2016_12_28_203205_changes_for_v431.php +++ b/database/migrations/2016_12_28_203205_changes_for_v431.php @@ -74,7 +74,7 @@ class ChangesForV431 extends Migration $table->renameColumn('start_date', 'startdate'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -89,7 +89,7 @@ class ChangesForV431 extends Migration $table->dropColumn('end_date'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -103,7 +103,7 @@ class ChangesForV431 extends Migration $table->dropColumn('decimal_places'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -140,7 +140,7 @@ class ChangesForV431 extends Migration $table->renameColumn('startdate', 'start_date'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -170,7 +170,7 @@ class ChangesForV431 extends Migration $table->dropColumn('repeats'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -183,7 +183,7 @@ class ChangesForV431 extends Migration $table->dropColumn('repeat_freq'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2017_04_13_163623_changes_for_v440.php b/database/migrations/2017_04_13_163623_changes_for_v440.php index 92c062e7c8..17a461f0ac 100644 --- a/database/migrations/2017_04_13_163623_changes_for_v440.php +++ b/database/migrations/2017_04_13_163623_changes_for_v440.php @@ -52,7 +52,7 @@ class ChangesForV440 extends Migration } } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2017_06_02_105232_changes_for_v450.php b/database/migrations/2017_06_02_105232_changes_for_v450.php index f2e667d282..0e13a3d6ff 100644 --- a/database/migrations/2017_06_02_105232_changes_for_v450.php +++ b/database/migrations/2017_06_02_105232_changes_for_v450.php @@ -47,7 +47,7 @@ class ChangesForV450 extends Migration $table->dropColumn('foreign_amount'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -75,7 +75,7 @@ class ChangesForV450 extends Migration $table->dropColumn('foreign_currency_id'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2017_11_04_170844_changes_for_v470a.php b/database/migrations/2017_11_04_170844_changes_for_v470a.php index 92a32e5dd3..fcde3e5f20 100644 --- a/database/migrations/2017_11_04_170844_changes_for_v470a.php +++ b/database/migrations/2017_11_04_170844_changes_for_v470a.php @@ -47,7 +47,7 @@ class ChangesForV470a extends Migration $table->dropColumn('reconciled'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2018_03_19_141348_changes_for_v472.php b/database/migrations/2018_03_19_141348_changes_for_v472.php index 9a897f7169..5d512b366d 100644 --- a/database/migrations/2018_03_19_141348_changes_for_v472.php +++ b/database/migrations/2018_03_19_141348_changes_for_v472.php @@ -63,7 +63,7 @@ class ChangesForV472 extends Migration $table->dropColumn('order'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -85,7 +85,7 @@ class ChangesForV472 extends Migration $table->dropColumn('notes'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2018_04_07_210913_changes_for_v473.php b/database/migrations/2018_04_07_210913_changes_for_v473.php index a45a466407..0e641b93d4 100644 --- a/database/migrations/2018_04_07_210913_changes_for_v473.php +++ b/database/migrations/2018_04_07_210913_changes_for_v473.php @@ -54,7 +54,7 @@ class ChangesForV473 extends Migration $table->dropColumn('transaction_currency_id'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -68,7 +68,7 @@ class ChangesForV473 extends Migration $table->dropColumn('strict'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2018_09_05_195147_changes_for_v477.php b/database/migrations/2018_09_05_195147_changes_for_v477.php index 72f056d65d..dd7be70042 100644 --- a/database/migrations/2018_09_05_195147_changes_for_v477.php +++ b/database/migrations/2018_09_05_195147_changes_for_v477.php @@ -54,7 +54,7 @@ class ChangesForV477 extends Migration $table->dropColumn(['transaction_currency_id']); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2018_11_06_172532_changes_for_v479.php b/database/migrations/2018_11_06_172532_changes_for_v479.php index 797d3fa2d5..64bcf11901 100644 --- a/database/migrations/2018_11_06_172532_changes_for_v479.php +++ b/database/migrations/2018_11_06_172532_changes_for_v479.php @@ -49,7 +49,7 @@ class ChangesForV479 extends Migration $table->dropColumn(['enabled']); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2019_03_11_223700_fix_ldap_configuration.php b/database/migrations/2019_03_11_223700_fix_ldap_configuration.php index e50e253f9e..d9939f83d5 100644 --- a/database/migrations/2019_03_11_223700_fix_ldap_configuration.php +++ b/database/migrations/2019_03_11_223700_fix_ldap_configuration.php @@ -49,7 +49,7 @@ class FixLdapConfiguration extends Migration $table->dropColumn(['objectguid']); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2019_03_22_183214_changes_for_v480.php b/database/migrations/2019_03_22_183214_changes_for_v480.php index 34e7cc217c..1c0a1cf35f 100644 --- a/database/migrations/2019_03_22_183214_changes_for_v480.php +++ b/database/migrations/2019_03_22_183214_changes_for_v480.php @@ -58,7 +58,7 @@ class ChangesForV480 extends Migration } try { $table->dropColumn('transaction_group_id'); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not drop column: %s', $e->getMessage())); Log::error('If the column does not exist, this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -78,7 +78,7 @@ class ChangesForV480 extends Migration static function (Blueprint $table) { try { $table->dropColumn('stop_processing'); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not drop column: %s', $e->getMessage())); Log::error('If the column does not exist, this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -98,7 +98,7 @@ class ChangesForV480 extends Migration static function (Blueprint $table) { try { $table->dropColumn('mfa_secret'); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not drop column: %s', $e->getMessage())); Log::error('If the column does not exist, this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2020_06_30_202620_changes_for_v530a.php b/database/migrations/2020_06_30_202620_changes_for_v530a.php index 659faf7480..4c39d12788 100644 --- a/database/migrations/2020_06_30_202620_changes_for_v530a.php +++ b/database/migrations/2020_06_30_202620_changes_for_v530a.php @@ -50,7 +50,7 @@ class ChangesForV530a extends Migration $table->dropColumn('order'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2020_07_24_162820_changes_for_v540.php b/database/migrations/2020_07_24_162820_changes_for_v540.php index 597463d7cc..5db1c0e99a 100644 --- a/database/migrations/2020_07_24_162820_changes_for_v540.php +++ b/database/migrations/2020_07_24_162820_changes_for_v540.php @@ -50,7 +50,7 @@ class ChangesForV540 extends Migration $table->dropColumn('provider'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -64,7 +64,7 @@ class ChangesForV540 extends Migration $table->dropColumn('order'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -78,7 +78,7 @@ class ChangesForV540 extends Migration $table->dropColumn('end_date'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -91,7 +91,7 @@ class ChangesForV540 extends Migration $table->dropColumn('extension_date'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2020_11_12_070604_changes_for_v550.php b/database/migrations/2020_11_12_070604_changes_for_v550.php index e72dc37b3d..47f304ac71 100644 --- a/database/migrations/2020_11_12_070604_changes_for_v550.php +++ b/database/migrations/2020_11_12_070604_changes_for_v550.php @@ -78,7 +78,7 @@ class ChangesForV550 extends Migration $table->dropColumn('budget_limit_id'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -97,7 +97,7 @@ class ChangesForV550 extends Migration $table->dropColumn('period'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -110,7 +110,7 @@ class ChangesForV550 extends Migration $table->dropColumn('generated'); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2021_03_12_061213_changes_for_v550b2.php b/database/migrations/2021_03_12_061213_changes_for_v550b2.php index 1667f467ec..0487be2f7f 100644 --- a/database/migrations/2021_03_12_061213_changes_for_v550b2.php +++ b/database/migrations/2021_03_12_061213_changes_for_v550b2.php @@ -53,7 +53,7 @@ class ChangesForV550b2 extends Migration } } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2021_05_09_064644_add_ldap_columns_to_users_table.php b/database/migrations/2021_05_09_064644_add_ldap_columns_to_users_table.php index c4a357f3fb..d54bb6b1b3 100644 --- a/database/migrations/2021_05_09_064644_add_ldap_columns_to_users_table.php +++ b/database/migrations/2021_05_09_064644_add_ldap_columns_to_users_table.php @@ -43,7 +43,7 @@ class AddLdapColumnsToUsersTable extends Migration $table->dropColumn(['domain']); } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2021_08_28_073733_user_groups.php b/database/migrations/2021_08_28_073733_user_groups.php index b84c8db589..86ba5f08ff 100644 --- a/database/migrations/2021_08_28_073733_user_groups.php +++ b/database/migrations/2021_08_28_073733_user_groups.php @@ -73,7 +73,7 @@ class UserGroups extends Migration } } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } @@ -93,7 +93,7 @@ class UserGroups extends Migration } } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/migrations/2022_08_21_104626_add_user_groups.php b/database/migrations/2022_08_21_104626_add_user_groups.php index 1ef80cb314..6a67c21b21 100644 --- a/database/migrations/2022_08_21_104626_add_user_groups.php +++ b/database/migrations/2022_08_21_104626_add_user_groups.php @@ -75,7 +75,7 @@ return new class () extends Migration { } } ); - } catch (QueryException|ColumnDoesNotExist $e) { + } catch (QueryException | ColumnDoesNotExist $e) { Log::error(sprintf('Could not execute query: %s', $e->getMessage())); Log::error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.'); } diff --git a/database/seeders/ExchangeRateSeeder.php b/database/seeders/ExchangeRateSeeder.php index 8cd6b85001..ccb67c0297 100644 --- a/database/seeders/ExchangeRateSeeder.php +++ b/database/seeders/ExchangeRateSeeder.php @@ -72,11 +72,36 @@ class ExchangeRateSeeder extends Seeder } /** - * @param User $user - * @param TransactionCurrency $from - * @param TransactionCurrency $to - * @param string $date - * @param float $rate + * @param string $code + * @return TransactionCurrency|null + */ + private function getCurrency(string $code): ?TransactionCurrency + { + return TransactionCurrency::whereNull('deleted_at')->where('code', $code)->first(); + } + + /** + * @param User $user + * @param TransactionCurrency $from + * @param TransactionCurrency $to + * @param string $date + * @return bool + */ + private function hasRate(User $user, TransactionCurrency $from, TransactionCurrency $to, string $date): bool + { + return $user->currencyExchangeRates() + ->where('from_currency_id', $from->id) + ->where('to_currency_id', $to->id) + ->where('date', $date) + ->count() > 0; + } + + /** + * @param User $user + * @param TransactionCurrency $from + * @param TransactionCurrency $to + * @param string $date + * @param float $rate * @return void */ private function addRate(User $user, TransactionCurrency $from, TransactionCurrency $to, string $date, float $rate): void @@ -92,29 +117,4 @@ class ExchangeRateSeeder extends Seeder ] ); } - - /** - * @param string $code - * @return TransactionCurrency|null - */ - private function getCurrency(string $code): ?TransactionCurrency - { - return TransactionCurrency::whereNull('deleted_at')->where('code', $code)->first(); - } - - /** - * @param User $user - * @param TransactionCurrency $from - * @param TransactionCurrency $to - * @param string $date - * @return bool - */ - private function hasRate(User $user, TransactionCurrency $from, TransactionCurrency $to, string $date): bool - { - return $user->currencyExchangeRates() - ->where('from_currency_id', $from->id) - ->where('to_currency_id', $to->id) - ->where('date', $date) - ->count() > 0; - } } diff --git a/frontend/src/layouts/MainLayout.vue b/frontend/src/layouts/MainLayout.vue index 7d2489336e..7e7b0e4605 100644 --- a/frontend/src/layouts/MainLayout.vue +++ b/frontend/src/layouts/MainLayout.vue @@ -338,7 +338,7 @@ page container: q-ma-xs (margin all, xs) AND q-mb-md to give the page content so
- Firefly III v v6.0.14 © James Cole, AGPL-3.0-or-later. + Firefly III v v6.0.15 © James Cole, AGPL-3.0-or-later.