From fa655f065b4914a6fc6ce6811a9eac6963e962f2 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 23 Nov 2024 16:14:47 +0100 Subject: [PATCH] Part of new API, cleanup code. --- app/Api/V2/Request/UserGroup/StoreRequest.php | 13 ++++++- .../Internal/Update/JournalUpdateService.php | 7 ++-- app/Transformers/V2/UserGroupTransformer.php | 25 +++++++++++-- resources/lang/en_US/validation.php | 1 + routes/api.php | 36 ++++++++++--------- 5 files changed, 59 insertions(+), 23 deletions(-) diff --git a/app/Api/V2/Request/UserGroup/StoreRequest.php b/app/Api/V2/Request/UserGroup/StoreRequest.php index 38685c84d9..5c845338d0 100644 --- a/app/Api/V2/Request/UserGroup/StoreRequest.php +++ b/app/Api/V2/Request/UserGroup/StoreRequest.php @@ -48,8 +48,19 @@ class StoreRequest extends FormRequest public function rules(): array { + $roles = []; + foreach(UserRoleEnum::cases() as $role) { + $roles[] = $role->value; + } + $string = implode(',', $roles); + return [ - 'title' => 'unique:user_groups,title|required|min:1|max:255', + 'title' => 'unique:user_groups,title|required|min:1|max:255', + 'members' => 'required|min:1', + 'members.*.user_email' => 'email|missing_with:members.*.user_id', + 'members.*.user_id' => 'integer|exists:users,id|missing_with:members.*.user_email', + 'members.*.roles' => 'required|array|min:1', + 'members.*.roles.*' => sprintf('required|in:%s',$string), ]; } } diff --git a/app/Services/Internal/Update/JournalUpdateService.php b/app/Services/Internal/Update/JournalUpdateService.php index 8b103c78b2..b61799fa04 100644 --- a/app/Services/Internal/Update/JournalUpdateService.php +++ b/app/Services/Internal/Update/JournalUpdateService.php @@ -26,6 +26,7 @@ namespace FireflyIII\Services\Internal\Update; use Carbon\Carbon; use Carbon\Exceptions\InvalidDateException; use Carbon\Exceptions\InvalidFormatException; +use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Events\TriggeredAuditLog; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\TagFactory; @@ -720,15 +721,15 @@ class JournalUpdateService // if the transaction is a TRANSFER, and the foreign amount and currency are set (like they seem to be) // the correct fields to update in the destination transaction are NOT the foreign amount and currency // but rather the normal amount and currency. This is new behavior. - - if (TransactionType::TRANSFER === $this->transactionJournal->transactionType->type) { + $isTransfer = TransactionTypeEnum::TRANSFER->value === $this->transactionJournal->transactionType->type; + if ($isTransfer) { Log::debug('Switch amounts, store in amount and not foreign_amount'); $dest->transaction_currency_id = $foreignCurrency->id; $dest->amount = app('steam')->positive($foreignAmount); $dest->foreign_amount = app('steam')->positive($source->amount); $dest->foreign_currency_id = $source->transaction_currency_id; } - if (TransactionType::TRANSFER !== $this->transactionJournal->transactionType->type) { + if (!$isTransfer) { $dest->foreign_currency_id = $foreignCurrency->id; $dest->foreign_amount = app('steam')->positive($foreignAmount); } diff --git a/app/Transformers/V2/UserGroupTransformer.php b/app/Transformers/V2/UserGroupTransformer.php index 0094befd5e..34db4a2818 100644 --- a/app/Transformers/V2/UserGroupTransformer.php +++ b/app/Transformers/V2/UserGroupTransformer.php @@ -65,7 +65,7 @@ class UserGroupTransformer extends AbstractTransformer /** @var GroupMembership $groupMembership */ foreach ($groupMemberships as $groupMembership) { $this->memberships[$userGroupId][] = [ - 'user_id' => (string)$groupMembership->user_id, + 'user_id' => (string) $groupMembership->user_id, 'user_email' => $groupMembership->user->email, 'role' => $groupMembership->userRole->title, 'you' => $groupMembership->user_id === $user->id, @@ -73,6 +73,7 @@ class UserGroupTransformer extends AbstractTransformer } } } + $this->mergeMemberships(); } return $objects; @@ -90,8 +91,28 @@ class UserGroupTransformer extends AbstractTransformer 'in_use' => $this->inUse[$userGroup->id] ?? false, 'title' => $userGroup->title, 'can_see_members' => $this->membershipsVisible[$userGroup->id] ?? false, - 'members' => $this->memberships[$userGroup->id] ?? [], + 'members' => array_values($this->memberships[$userGroup->id] ?? []), ]; // if the user has a specific role in this group, then collect the memberships. } + + private function mergeMemberships(): void + { + $new = []; + foreach ($this->memberships as $groupId => $members) { + $new[$groupId] ??= []; + + foreach ($members as $member) { + $mail = $member['user_email']; + $new[$groupId][$mail] ??= [ + 'user_id' => $member['user_id'], + 'user_email' => $member['user_email'], + 'you' => $member['you'], + 'roles' => [], + ]; + $new[$groupId][$mail]['roles'][] = $member['role']; + } + } + $this->memberships = $new; + } } diff --git a/resources/lang/en_US/validation.php b/resources/lang/en_US/validation.php index ce9ce7a914..915b4bac9f 100644 --- a/resources/lang/en_US/validation.php +++ b/resources/lang/en_US/validation.php @@ -262,6 +262,7 @@ return [ 'gte.file' => 'The :attribute must be greater than or equal to :value kilobytes.', 'gte.string' => 'The :attribute must be greater than or equal to :value characters.', 'gte.array' => 'The :attribute must have :value items or more.', + 'missing_with' => 'The :attribute cannot be combined with another field.', 'amount_required_for_auto_budget' => 'The amount is required.', 'auto_budget_amount_positive' => 'The amount must be more than zero.', diff --git a/routes/api.php b/routes/api.php index f062ba65a3..61ba1e4659 100644 --- a/routes/api.php +++ b/routes/api.php @@ -53,6 +53,24 @@ Route::group( } ); +// USER GROUP ROUTES +Route::group( + [ + 'namespace' => 'FireflyIII\Api\V2\Controllers\UserGroup', + 'prefix' => 'v2/user-groups', + 'as' => 'api.v2.user-groups.', + ], + static function (): void { + Route::get('', ['uses' => 'IndexController@index', 'as' => 'index']); + Route::post('', ['uses' => 'StoreController@store', 'as' => 'store']); + Route::get('{userGroup}', ['uses' => 'ShowController@show', 'as' => 'show']); + // Route::put('{userGroup}', ['uses' => 'UpdateController@update', 'as' => 'update']); + // Route::post('{userGroup}/use', ['uses' => 'UpdateController@useUserGroup', 'as' => 'use']); + // Route::put('{userGroup}/update-membership', ['uses' => 'UpdateController@updateMembership', 'as' => 'updateMembership']); + // Route::delete('{userGroup}', ['uses' => 'DestroyController@destroy', 'as' => 'destroy']); + } +); + // CHART ROUTES Route::group( [ @@ -221,23 +239,7 @@ Route::group( } ); -// V2 API route for user groups (administrations). -Route::group( - [ - 'namespace' => 'FireflyIII\Api\V2\Controllers\UserGroup', - 'prefix' => 'v2/user-groups', - 'as' => 'api.v2.user-groups.', - ], - static function (): void { - // Route::get('', ['uses' => 'IndexController@index', 'as' => 'index']); - // Route::post('', ['uses' => 'StoreController@store', 'as' => 'store']); - // Route::get('{userGroup}', ['uses' => 'ShowController@show', 'as' => 'show']); - // Route::put('{userGroup}', ['uses' => 'UpdateController@update', 'as' => 'update']); - // Route::post('{userGroup}/use', ['uses' => 'UpdateController@useUserGroup', 'as' => 'use']); - // Route::put('{userGroup}/update-membership', ['uses' => 'UpdateController@updateMembership', 'as' => 'updateMembership']); - // Route::delete('{userGroup}', ['uses' => 'DestroyController@destroy', 'as' => 'destroy']); - } -); + // V2 JSON API ROUTES // JsonApiRoute::server('v2')->prefix('v2')