From ff145abbe720f36604585005b26cf62873169f56 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Mon, 12 Aug 2024 16:13:03 -0500 Subject: [PATCH 01/17] use array for eager loading, makes ide prettier --- app/Http/Controllers/Users/UsersController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Users/UsersController.php b/app/Http/Controllers/Users/UsersController.php index 1e203e71d5..bad16458d6 100755 --- a/app/Http/Controllers/Users/UsersController.php +++ b/app/Http/Controllers/Users/UsersController.php @@ -232,7 +232,7 @@ class UsersController extends Controller $permissions = $request->input('permissions', []); app('request')->request->set('permissions', $permissions); - $user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed()->find($id); + $user = User::with(['assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc'])->withTrashed()->find($id); // User is valid - continue... if ($user) { @@ -263,7 +263,7 @@ class UsersController extends Controller $user->activated = $request->input('activated', 0); $user->jobtitle = $request->input('jobtitle', null); $user->phone = $request->input('phone'); - $user->location_id = $request->input('location_id', null); + $user->location_id = $request->input('location_id', null); //here $user->company_id = Company::getIdForUser($request->input('company_id', null)); $user->manager_id = $request->input('manager_id', null); $user->notes = $request->input('notes'); From cc3b8e0681f74276958c988d986de07cff3e798d Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Mon, 12 Aug 2024 16:58:21 -0500 Subject: [PATCH 02/17] this should more or less work, but i need to determine if this is the best way --- app/Http/Controllers/Users/UsersController.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Users/UsersController.php b/app/Http/Controllers/Users/UsersController.php index bad16458d6..96fbae49af 100755 --- a/app/Http/Controllers/Users/UsersController.php +++ b/app/Http/Controllers/Users/UsersController.php @@ -263,7 +263,16 @@ class UsersController extends Controller $user->activated = $request->input('activated', 0); $user->jobtitle = $request->input('jobtitle', null); $user->phone = $request->input('phone'); - $user->location_id = $request->input('location_id', null); //here + $user->location_id = $request->input('location_id', null); + if ($request->has('company_id')) { + if ($user->assets->count() > 0) { + if ($user->assets()->pluck('company_id') != $user->getRawOriginal('company_id')) { + { + return back()->with('error', 'this user has assets, check them in first'); + } + } + } + } $user->company_id = Company::getIdForUser($request->input('company_id', null)); $user->manager_id = $request->input('manager_id', null); $user->notes = $request->input('notes'); From ec863df0074ce785aa3ac80f4871accb8eb2145b Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Mon, 12 Aug 2024 16:58:53 -0500 Subject: [PATCH 03/17] rm conditional that might be unnecessary --- app/Http/Controllers/Users/UsersController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Users/UsersController.php b/app/Http/Controllers/Users/UsersController.php index 96fbae49af..adf2d5f3dd 100755 --- a/app/Http/Controllers/Users/UsersController.php +++ b/app/Http/Controllers/Users/UsersController.php @@ -266,11 +266,11 @@ class UsersController extends Controller $user->location_id = $request->input('location_id', null); if ($request->has('company_id')) { if ($user->assets->count() > 0) { - if ($user->assets()->pluck('company_id') != $user->getRawOriginal('company_id')) { + //if ($user->assets()->pluck('company_id') != $user->getRawOriginal('company_id')) { { return back()->with('error', 'this user has assets, check them in first'); } - } + //} } } $user->company_id = Company::getIdForUser($request->input('company_id', null)); From 09f2739298933ea8150a6dfda4aa19b3c5baa94f Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Tue, 13 Aug 2024 13:45:41 -0500 Subject: [PATCH 04/17] works, un-reassignable licenses are an issue --- app/Http/Controllers/Users/UsersController.php | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/app/Http/Controllers/Users/UsersController.php b/app/Http/Controllers/Users/UsersController.php index adf2d5f3dd..9ff0152484 100755 --- a/app/Http/Controllers/Users/UsersController.php +++ b/app/Http/Controllers/Users/UsersController.php @@ -186,7 +186,7 @@ class UsersController extends Controller { $this->authorize('update', User::class); - $user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed()->find($id); + $user = User::with(['assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc'])->withTrashed()->find($id); if ($user) { @@ -235,9 +235,15 @@ class UsersController extends Controller $user = User::with(['assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc'])->withTrashed()->find($id); // User is valid - continue... + + if ($user) { $this->authorize('update', $user); + if ($request->has('company_id') && $user->allAssignedCount() > 0 && Setting::getSettings()->full_multiple_companies_support) { + return back()->with('error', 'this user has assets, check them in first'); + } + // Figure out of this user was an admin before this edit $orig_permissions_array = $user->decodePermissions(); $orig_superuser = '0'; @@ -264,15 +270,7 @@ class UsersController extends Controller $user->jobtitle = $request->input('jobtitle', null); $user->phone = $request->input('phone'); $user->location_id = $request->input('location_id', null); - if ($request->has('company_id')) { - if ($user->assets->count() > 0) { - //if ($user->assets()->pluck('company_id') != $user->getRawOriginal('company_id')) { - { - return back()->with('error', 'this user has assets, check them in first'); - } - //} - } - } + $user->company_id = Company::getIdForUser($request->input('company_id', null)); $user->manager_id = $request->input('manager_id', null); $user->notes = $request->input('notes'); From 120cfd13c544fb79e69f5f59aa44f908b4a39947 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Tue, 13 Aug 2024 14:07:40 -0500 Subject: [PATCH 05/17] translation --- app/Http/Controllers/Users/UsersController.php | 2 +- resources/lang/en-US/admin/users/message.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Users/UsersController.php b/app/Http/Controllers/Users/UsersController.php index 9ff0152484..631ab3bc31 100755 --- a/app/Http/Controllers/Users/UsersController.php +++ b/app/Http/Controllers/Users/UsersController.php @@ -241,7 +241,7 @@ class UsersController extends Controller $this->authorize('update', $user); if ($request->has('company_id') && $user->allAssignedCount() > 0 && Setting::getSettings()->full_multiple_companies_support) { - return back()->with('error', 'this user has assets, check them in first'); + return back()->with('error', trans('admin/users/message.multi_company_items_assigned')); } // Figure out of this user was an admin before this edit diff --git a/resources/lang/en-US/admin/users/message.php b/resources/lang/en-US/admin/users/message.php index 4d014775bd..0f41d463e1 100644 --- a/resources/lang/en-US/admin/users/message.php +++ b/resources/lang/en-US/admin/users/message.php @@ -53,6 +53,7 @@ return array( 'ldap_could_not_search' => 'Could not search the LDAP server. Please check your LDAP server configuration in the LDAP config file.
Error from LDAP Server:', 'ldap_could_not_get_entries' => 'Could not get entries from the LDAP server. Please check your LDAP server configuration in the LDAP config file.
Error from LDAP Server:', 'password_ldap' => 'The password for this account is managed by LDAP/Active Directory. Please contact your IT department to change your password. ', + 'multi_company_items_assigned' => 'This user has items assigned, please check them in before moving companies.' ), 'deletefile' => array( From 20ec420ba3a51638f7934e5a3820907760fc544c Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 14 Aug 2024 13:53:29 -0500 Subject: [PATCH 06/17] not quite done, api side needs some work --- app/Http/Controllers/Api/UsersController.php | 2 +- .../Controllers/Users/UsersController.php | 122 ++++++++---------- app/Http/Requests/SaveUserRequest.php | 10 ++ routes/web/users.php | 5 +- 4 files changed, 70 insertions(+), 69 deletions(-) diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index 9200f80b1d..ae6968a475 100644 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -427,7 +427,7 @@ class UsersController extends Controller * @param \Illuminate\Http\Request $request * @param int $id */ - public function update(SaveUserRequest $request, $id) : JsonResponse + public function update(SaveUserRequest $request, User $user): JsonResponse { $this->authorize('update', User::class); diff --git a/app/Http/Controllers/Users/UsersController.php b/app/Http/Controllers/Users/UsersController.php index 631ab3bc31..e609727c00 100755 --- a/app/Http/Controllers/Users/UsersController.php +++ b/app/Http/Controllers/Users/UsersController.php @@ -214,90 +214,84 @@ class UsersController extends Controller * @return \Illuminate\Http\RedirectResponse * @throws \Illuminate\Auth\Access\AuthorizationException */ - public function update(SaveUserRequest $request, $id = null) + public function update(SaveUserRequest $request, User $user) { $this->authorize('update', User::class); // This is a janky hack to prevent people from changing admin demo user data on the public demo. // The $ids 1 and 2 are special since they are seeded as superadmins in the demo seeder. // Thanks, jerks. You are why we can't have nice things. - snipe - - if ((($id == 1) || ($id == 2)) && (config('app.lock_passwords'))) { + if ((($user->id == 1) || ($user->id == 2)) && (config('app.lock_passwords'))) { return redirect()->route('users.index')->with('error', trans('general.permission_denied_superuser_demo')); } - // We need to reverse the UI specific logic for our // permissions here before we update the user. $permissions = $request->input('permissions', []); app('request')->request->set('permissions', $permissions); - $user = User::with(['assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc'])->withTrashed()->find($id); + $user->load(['assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc'])->withTrashed(); - // User is valid - continue... + $this->authorize('update', $user); - - if ($user) { - $this->authorize('update', $user); - - if ($request->has('company_id') && $user->allAssignedCount() > 0 && Setting::getSettings()->full_multiple_companies_support) { - return back()->with('error', trans('admin/users/message.multi_company_items_assigned')); - } + //see if i can get this working at request level + //if ($request->has('company_id') && $user->allAssignedCount() > 0 && Setting::getSettings()->full_multiple_companies_support) { + // return back()->with('error', trans('admin/users/message.multi_company_items_assigned')); + //} // Figure out of this user was an admin before this edit - $orig_permissions_array = $user->decodePermissions(); - $orig_superuser = '0'; - if (is_array($orig_permissions_array)) { - if (array_key_exists('superuser', $orig_permissions_array)) { - $orig_superuser = $orig_permissions_array['superuser']; - } + $orig_permissions_array = $user->decodePermissions(); + $orig_superuser = '0'; + if (is_array($orig_permissions_array)) { + if (array_key_exists('superuser', $orig_permissions_array)) { + $orig_superuser = $orig_permissions_array['superuser']; } + } - // Only save groups if the user is a superuser - if (auth()->user()->isSuperUser()) { - $user->groups()->sync($request->input('groups')); - } + // Only save groups if the user is a superuser + if (auth()->user()->isSuperUser()) { + $user->groups()->sync($request->input('groups')); + } - // Update the user fields - $user->username = trim($request->input('username')); - $user->email = trim($request->input('email')); - $user->first_name = $request->input('first_name'); - $user->last_name = $request->input('last_name'); - $user->two_factor_optin = $request->input('two_factor_optin') ?: 0; - $user->locale = $request->input('locale'); - $user->employee_num = $request->input('employee_num'); - $user->activated = $request->input('activated', 0); - $user->jobtitle = $request->input('jobtitle', null); - $user->phone = $request->input('phone'); - $user->location_id = $request->input('location_id', null); + // Update the user fields + $user->username = trim($request->input('username')); + $user->email = trim($request->input('email')); + $user->first_name = $request->input('first_name'); + $user->last_name = $request->input('last_name'); + $user->two_factor_optin = $request->input('two_factor_optin') ?: 0; + $user->locale = $request->input('locale'); + $user->employee_num = $request->input('employee_num'); + $user->activated = $request->input('activated', 0); + $user->jobtitle = $request->input('jobtitle', null); + $user->phone = $request->input('phone'); + $user->location_id = $request->input('location_id', null); + $user->company_id = Company::getIdForUser($request->input('company_id', null)); + $user->manager_id = $request->input('manager_id', null); + $user->notes = $request->input('notes'); + $user->department_id = $request->input('department_id', null); + $user->address = $request->input('address', null); + $user->city = $request->input('city', null); + $user->state = $request->input('state', null); + $user->country = $request->input('country', null); + // if a user is editing themselves we should always keep activated true + $user->activated = $request->input('activated', $request->user()->is($user) ? 1 : 0); + $user->zip = $request->input('zip', null); + $user->remote = $request->input('remote', 0); + $user->vip = $request->input('vip', 0); + $user->website = $request->input('website', null); + $user->start_date = $request->input('start_date', null); + $user->end_date = $request->input('end_date', null); + $user->autoassign_licenses = $request->input('autoassign_licenses', 0); - $user->company_id = Company::getIdForUser($request->input('company_id', null)); - $user->manager_id = $request->input('manager_id', null); - $user->notes = $request->input('notes'); - $user->department_id = $request->input('department_id', null); - $user->address = $request->input('address', null); - $user->city = $request->input('city', null); - $user->state = $request->input('state', null); - $user->country = $request->input('country', null); - // if a user is editing themselves we should always keep activated true - $user->activated = $request->input('activated', $request->user()->is($user) ? 1 : 0); - $user->zip = $request->input('zip', null); - $user->remote = $request->input('remote', 0); - $user->vip = $request->input('vip', 0); - $user->website = $request->input('website', null); - $user->start_date = $request->input('start_date', null); - $user->end_date = $request->input('end_date', null); - $user->autoassign_licenses = $request->input('autoassign_licenses', 0); + // Update the location of any assets checked out to this user + Asset::where('assigned_type', User::class) + ->where('assigned_to', $user->id) + ->update(['location_id' => $request->input('location_id', null)]); - // Update the location of any assets checked out to this user - Asset::where('assigned_type', User::class) - ->where('assigned_to', $user->id) - ->update(['location_id' => $request->input('location_id', null)]); - - // Do we want to update the user password? - if ($request->filled('password')) { - $user->password = bcrypt($request->input('password')); - } + // Do we want to update the user password? + if ($request->filled('password')) { + $user->password = bcrypt($request->input('password')); + } // Update the location of any assets checked out to this user @@ -325,13 +319,7 @@ class UsersController extends Controller return redirect()->to(Helper::getRedirectOption($request, $user->id, 'Users')) ->with('success', trans('admin/users/message.success.update')); } - return redirect()->back()->withInput()->withErrors($user->getErrors()); - - - } - - return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found', compact('id'))); } /** diff --git a/app/Http/Requests/SaveUserRequest.php b/app/Http/Requests/SaveUserRequest.php index b38193c15a..f77defb0b0 100644 --- a/app/Http/Requests/SaveUserRequest.php +++ b/app/Http/Requests/SaveUserRequest.php @@ -31,9 +31,19 @@ class SaveUserRequest extends FormRequest */ public function rules() { + //dd($this->user); $rules = [ 'department_id' => 'nullable|exists:departments,id', 'manager_id' => 'nullable|exists:users,id', + 'company_id' => [ + // determines if the user is being moved between companies and checks to see if they have any items assigned + function ($attribute, $value, $fail) { + dd($this->user); + if (($this->has('company_id')) && ($this->user->allAssignedCount() > 0) && (Setting::getSettings()->full_multiple_companies_support)) { + $fail(trans('admin/users/message.error.multi_company_items_assigned')); + } + } + ] ]; switch ($this->method()) { diff --git a/routes/web/users.php b/routes/web/users.php index 95de200638..3bf1555cad 100644 --- a/routes/web/users.php +++ b/routes/web/users.php @@ -145,10 +145,13 @@ Route::group(['prefix' => 'users', 'middleware' => ['auth']], function () { ] )->name('users/bulkeditsave'); - + // pulling this out of the resource because I need route model binding in the request + Route::patch('/{user}', [Users\UsersController::class, 'update'])->name('users.update'); + Route::put('/{user}', [Users\UsersController::class, 'update'])->name('users.put-update'); }); Route::resource('users', Users\UsersController::class, [ 'middleware' => ['auth'], 'parameters' => ['user' => 'user_id'], + 'except' => ['update'] ]); \ No newline at end of file From f031309f8ffce5747c29e24d467b93cf61ace657 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 14 Aug 2024 16:09:15 -0500 Subject: [PATCH 07/17] set up api controller for route/model binding --- app/Http/Controllers/Api/UsersController.php | 18 +----------------- app/Http/Requests/SaveUserRequest.php | 1 - 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index ae6968a475..856b3b6a69 100644 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -431,9 +431,6 @@ class UsersController extends Controller { $this->authorize('update', User::class); - if ($user = User::find($id)) { - - $this->authorize('update', $user); /** @@ -443,12 +440,10 @@ class UsersController extends Controller * */ - - if ((($id == 1) || ($id == 2)) && (config('app.lock_passwords'))) { + if ((($user->id == 1) || ($user->id == 2)) && (config('app.lock_passwords'))) { return response()->json(Helper::formatStandardApiResponse('error', null, 'Permission denied. You cannot update user information via API on the demo.')); } - $user->fill($request->all()); if ($user->id == $request->input('manager_id')) { @@ -473,16 +468,13 @@ class UsersController extends Controller $user->permissions = $permissions_array; } - // Update the location of any assets checked out to this user Asset::where('assigned_type', User::class) ->where('assigned_to', $user->id)->update(['location_id' => $request->input('location_id', null)]); - app('App\Http\Requests\ImageUploadRequest')->handleImages($user, 600, 'image', 'avatars', 'avatar'); if ($user->save()) { - // Check if the request has groups passed and has a value, AND that the user us a superuser if (($request->has('groups')) && (auth()->user()->isSuperUser())) { @@ -496,18 +488,10 @@ class UsersController extends Controller // Sync the groups since the user is a superuser and the groups pass validation $user->groups()->sync($request->input('groups')); - - } - return response()->json(Helper::formatStandardApiResponse('success', (new UsersTransformer)->transformUser($user), trans('admin/users/message.success.update'))); } - return response()->json(Helper::formatStandardApiResponse('error', null, $user->getErrors())); - } - - return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.user_not_found', compact('id')))); - } /** diff --git a/app/Http/Requests/SaveUserRequest.php b/app/Http/Requests/SaveUserRequest.php index f77defb0b0..7598e7433d 100644 --- a/app/Http/Requests/SaveUserRequest.php +++ b/app/Http/Requests/SaveUserRequest.php @@ -38,7 +38,6 @@ class SaveUserRequest extends FormRequest 'company_id' => [ // determines if the user is being moved between companies and checks to see if they have any items assigned function ($attribute, $value, $fail) { - dd($this->user); if (($this->has('company_id')) && ($this->user->allAssignedCount() > 0) && (Setting::getSettings()->full_multiple_companies_support)) { $fail(trans('admin/users/message.error.multi_company_items_assigned')); } From afaf53cdfc37d49ba1afbbe178cd974fbb83920f Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 14 Aug 2024 18:14:21 -0500 Subject: [PATCH 08/17] failing ui test --- resources/views/users/edit.blade.php | 4 ++- routes/web/users.php | 3 +- tests/Feature/Users/Api/UpdateUserTest.php | 30 ++++++++++++++++++++ tests/Feature/Users/Ui/UpdateUserTest.php | 32 ++++++++++++++++++++++ 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/resources/views/users/edit.blade.php b/resources/views/users/edit.blade.php index e3f691f158..986c18ab6d 100755 --- a/resources/views/users/edit.blade.php +++ b/resources/views/users/edit.blade.php @@ -66,7 +66,9 @@
-
+ {{csrf_field()}} @if($user->id) diff --git a/routes/web/users.php b/routes/web/users.php index 3bf1555cad..e55541a937 100644 --- a/routes/web/users.php +++ b/routes/web/users.php @@ -146,8 +146,7 @@ Route::group(['prefix' => 'users', 'middleware' => ['auth']], function () { )->name('users/bulkeditsave'); // pulling this out of the resource because I need route model binding in the request - Route::patch('/{user}', [Users\UsersController::class, 'update'])->name('users.update'); - Route::put('/{user}', [Users\UsersController::class, 'update'])->name('users.put-update'); + Route::match(['put', 'patch'], '/{user}', [Users\UsersController::class, 'update'])->name('users.update'); }); Route::resource('users', Users\UsersController::class, [ diff --git a/tests/Feature/Users/Api/UpdateUserTest.php b/tests/Feature/Users/Api/UpdateUserTest.php index 1c66bbdda9..2901beea9a 100644 --- a/tests/Feature/Users/Api/UpdateUserTest.php +++ b/tests/Feature/Users/Api/UpdateUserTest.php @@ -2,6 +2,7 @@ namespace Tests\Feature\Users\Api; +use App\Models\Asset; use App\Models\Company; use App\Models\Department; use App\Models\Group; @@ -344,4 +345,33 @@ class UpdateUserTest extends TestCase $this->assertTrue($user->refresh()->groups->contains($groupB)); } + public function testMultiCompanyUserCannotBeMovedIfHasAsset() + { + $this->settings->enableMultipleFullCompanySupport(); + + $companyA = Company::factory()->create(); + $companyB = Company::factory()->create(); + + $user = User::factory()->create([ + 'company_id' => $companyA->id, + ]); + $superUser = User::factory()->superuser()->create(); + + $asset = Asset::factory()->create(); + + // no assets assigned, therefore success + $this->actingAsForApi($superUser)->patchJson(route('api.users.update', $user), [ + 'username' => 'test', + 'company_id' => $companyB->id, + ])->assertStatusMessageIs('success'); + + $asset->checkOut($user, $superUser); + + // asset assigned, therefore error + $this->actingAsForApi($superUser)->patchJson(route('api.users.update', $user), [ + 'username' => 'test', + 'company_id' => $companyB->id, + ])->assertMessagesAre('error'); + } + } diff --git a/tests/Feature/Users/Ui/UpdateUserTest.php b/tests/Feature/Users/Ui/UpdateUserTest.php index bef1d59a06..31530af7c5 100644 --- a/tests/Feature/Users/Ui/UpdateUserTest.php +++ b/tests/Feature/Users/Ui/UpdateUserTest.php @@ -2,6 +2,8 @@ namespace Tests\Feature\Users\Ui; +use App\Models\Asset; +use App\Models\Company; use App\Models\User; use Tests\TestCase; @@ -79,4 +81,34 @@ class UpdateUserTest extends TestCase $this->assertEquals(1, $admin->refresh()->activated); } + + public function testMultiCompanyUserCannotBeMovedIfHasAsset() + { + $this->settings->enableMultipleFullCompanySupport(); + + $companyA = Company::factory()->create(); + $companyB = Company::factory()->create(); + + $user = User::factory()->create([ + 'company_id' => $companyA->id, + ]); + $superUser = User::factory()->superuser()->create(); + + $asset = Asset::factory()->create(); + + // no assets assigned, therefore success + $this->actingAs($superUser)->put(route('users.update', $user), [ + 'first_name' => 'test', + 'username' => 'test', + 'company_id' => $companyB->id, + ])->assertRedirect(route('users.index')); + + //$asset->checkOut($user, $superUser); + + // asset assigned, therefore error + //$this->actingAs($superUser)->patchJson(route('users.update', $user), [ + // 'username' => 'test', + // 'company_id' => $companyB->id, + //])->assertMessagesAre('error'); + } } From 9622e05cf5b545bac1f506af085e6c7e27259848 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 14 Aug 2024 18:41:06 -0500 Subject: [PATCH 09/17] correct api test --- tests/Feature/Users/Api/UpdateUserTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Feature/Users/Api/UpdateUserTest.php b/tests/Feature/Users/Api/UpdateUserTest.php index 2901beea9a..e7314756dd 100644 --- a/tests/Feature/Users/Api/UpdateUserTest.php +++ b/tests/Feature/Users/Api/UpdateUserTest.php @@ -371,7 +371,7 @@ class UpdateUserTest extends TestCase $this->actingAsForApi($superUser)->patchJson(route('api.users.update', $user), [ 'username' => 'test', 'company_id' => $companyB->id, - ])->assertMessagesAre('error'); + ])->assertStatusMessageIs('error'); } } From dec4691c73b28bab35ed8fdb1ff83578ad517bb0 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Fri, 16 Aug 2024 12:50:09 -0500 Subject: [PATCH 10/17] should be good to go now --- routes/api.php | 8 +++++--- tests/Feature/Users/Api/UpdateUserTest.php | 14 ++++++++++++++ tests/Feature/Users/Ui/UpdateUserTest.php | 21 +++++++++++++-------- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/routes/api.php b/routes/api.php index 0eb0d834cf..c59654d65d 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1070,18 +1070,20 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi ] )->name('api.users.restore'); - }); + }); + + Route::match(['put', 'patch'], '{user}/update', [Api\UsersController::class, 'update']) + ->name('api.users.update'); Route::resource('users', Api\UsersController::class, ['names' => [ 'index' => 'api.users.index', 'show' => 'api.users.show', - 'update' => 'api.users.update', 'store' => 'api.users.store', 'destroy' => 'api.users.destroy', ], - 'except' => ['create', 'edit'], + 'except' => ['create', 'edit', 'update'], 'parameters' => ['user' => 'user_id'], ] ); // end users API routes diff --git a/tests/Feature/Users/Api/UpdateUserTest.php b/tests/Feature/Users/Api/UpdateUserTest.php index e7314756dd..4632a80c3d 100644 --- a/tests/Feature/Users/Api/UpdateUserTest.php +++ b/tests/Feature/Users/Api/UpdateUserTest.php @@ -365,6 +365,13 @@ class UpdateUserTest extends TestCase 'company_id' => $companyB->id, ])->assertStatusMessageIs('success'); + // same test but PUT + $this->actingAsForApi($superUser)->putJson(route('api.users.update', $user), [ + 'username' => 'test', + 'first_name' => 'Test', + 'company_id' => $companyB->id, + ])->assertStatusMessageIs('success'); + $asset->checkOut($user, $superUser); // asset assigned, therefore error @@ -372,6 +379,13 @@ class UpdateUserTest extends TestCase 'username' => 'test', 'company_id' => $companyB->id, ])->assertStatusMessageIs('error'); + + // same test but PUT + $this->actingAsForApi($superUser)->putJson(route('api.users.update', $user), [ + 'username' => 'test', + 'first_name' => 'Test', + 'company_id' => $companyB->id, + ])->assertStatusMessageIs('error'); } } diff --git a/tests/Feature/Users/Ui/UpdateUserTest.php b/tests/Feature/Users/Ui/UpdateUserTest.php index 31530af7c5..3e6867021f 100644 --- a/tests/Feature/Users/Ui/UpdateUserTest.php +++ b/tests/Feature/Users/Ui/UpdateUserTest.php @@ -98,17 +98,22 @@ class UpdateUserTest extends TestCase // no assets assigned, therefore success $this->actingAs($superUser)->put(route('users.update', $user), [ - 'first_name' => 'test', - 'username' => 'test', - 'company_id' => $companyB->id, + 'first_name' => 'test', + 'username' => 'test', + 'company_id' => $companyB->id, + 'redirect_option' => 'index' ])->assertRedirect(route('users.index')); - //$asset->checkOut($user, $superUser); + $asset->checkOut($user, $superUser); // asset assigned, therefore error - //$this->actingAs($superUser)->patchJson(route('users.update', $user), [ - // 'username' => 'test', - // 'company_id' => $companyB->id, - //])->assertMessagesAre('error'); + $response = $this->actingAs($superUser)->patchJson(route('users.update', $user), [ + 'first_name' => 'test', + 'username' => 'test', + 'company_id' => $companyB->id, + 'redirect_option' => 'index' + ]); + + $this->followRedirects($response)->assertSee('error'); } } From 70e5e0f9df91c10d94568c98168be1f5fdc5686a Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Fri, 16 Aug 2024 12:52:06 -0500 Subject: [PATCH 11/17] get rid of dd --- app/Http/Requests/SaveUserRequest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/Http/Requests/SaveUserRequest.php b/app/Http/Requests/SaveUserRequest.php index 7598e7433d..e16826d16c 100644 --- a/app/Http/Requests/SaveUserRequest.php +++ b/app/Http/Requests/SaveUserRequest.php @@ -31,7 +31,6 @@ class SaveUserRequest extends FormRequest */ public function rules() { - //dd($this->user); $rules = [ 'department_id' => 'nullable|exists:departments,id', 'manager_id' => 'nullable|exists:users,id', From a8cd1027f3cc1716b76461f9db7dbc17b8a130b4 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Tue, 20 Aug 2024 11:40:15 -0500 Subject: [PATCH 12/17] rm commented code --- app/Http/Controllers/Users/UsersController.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/Http/Controllers/Users/UsersController.php b/app/Http/Controllers/Users/UsersController.php index e609727c00..3da0c5a3ac 100755 --- a/app/Http/Controllers/Users/UsersController.php +++ b/app/Http/Controllers/Users/UsersController.php @@ -234,12 +234,7 @@ class UsersController extends Controller $this->authorize('update', $user); - //see if i can get this working at request level - //if ($request->has('company_id') && $user->allAssignedCount() > 0 && Setting::getSettings()->full_multiple_companies_support) { - // return back()->with('error', trans('admin/users/message.multi_company_items_assigned')); - //} - - // Figure out of this user was an admin before this edit + // Figure out of this user was an admin before this edit $orig_permissions_array = $user->decodePermissions(); $orig_superuser = '0'; if (is_array($orig_permissions_array)) { From de0565f5b35ec85cc39a9302637329bba3d4c83a Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 29 Aug 2024 11:24:06 +0100 Subject: [PATCH 13/17] Updated jquery UI Signed-off-by: snipe --- package-lock.json | 9 +++++---- package.json | 2 +- public/js/build/app.js | Bin 1007743 -> 1007743 bytes public/js/build/vendor.js | Bin 1768352 -> 1757666 bytes public/js/dist/all.js | Bin 2776096 -> 2765410 bytes public/mix-manifest.json | 6 +++--- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index f4d51c45a3..30770cde8a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "ekko-lightbox": "^5.1.1", "imagemin": "^8.0.1", "jquery-slimscroll": "^1.3.8", - "jquery-ui": "^1.13.3", + "jquery-ui": "^1.14.0", "jquery-validation": "^1.21.0", "jquery.iframe-transport": "^1.0.0", "jspdf-autotable": "^3.8.2", @@ -7067,10 +7067,11 @@ "license": "BSD-2-Clause" }, "node_modules/jquery-ui": { - "version": "1.13.3", - "license": "MIT", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.14.0.tgz", + "integrity": "sha512-mPfYKBoRCf0MzaT2cyW5i3IuZ7PfTITaasO5OFLAQxrHuI+ZxruPa+4/K1OMNT8oElLWGtIxc9aRbyw20BKr8g==", "dependencies": { - "jquery": ">=1.8.0 <4.0.0" + "jquery": ">=1.12.0 <5.0.0" } }, "node_modules/jquery-validation": { diff --git a/package.json b/package.json index a36144a17b..d0ce13579d 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "ekko-lightbox": "^5.1.1", "imagemin": "^8.0.1", "jquery-slimscroll": "^1.3.8", - "jquery-ui": "^1.13.3", + "jquery-ui": "^1.14.0", "jquery-validation": "^1.21.0", "jquery.iframe-transport": "^1.0.0", "jspdf-autotable": "^3.8.2", diff --git a/public/js/build/app.js b/public/js/build/app.js index c188a713b4e222dacb98670f4844e3b51818c8ff..3c80510129f314dbb9cc2ba1dba387ca0db1933c 100644 GIT binary patch delta 83 zcmex=!1n(E+lDQSYo0Kh=oxHZ|AeuJ5yWb@d&UUFOhC*G#4JF}3dC$c%nrmHK+Flm TTtLhX#5_REyWQ>?pJNpO@+%{5 delta 83 zcmex=!1n(E+lDQSYo0J0>ltrf|AeuJ5yWb@d&UUFOhC*G#4JF}3dC$c%nrmHK+Flm TTtLhX#5_REyWQ>?pJNpO^Cu&6 diff --git a/public/js/build/vendor.js b/public/js/build/vendor.js index 102713f1f3bff3d5b402d036a92b3c1727637d39..6f934b73d07c35e6867f5c9f63feb8799cb4f545 100644 GIT binary patch delta 3761 zcmai13vg3a8lKxWIp^No+>)kAA8gBMERfnJw15os0Yz{Td06aDt7vU6$!&Y-B`L{G zvD6AmMZjfu3)){Dv>>>Q;JCPehxLIXKAGJaadvimpeQV$_-NUR$V>L*rfpKjoz2Xd zIsdum{O9{$-+!|8Ld%KmEvvh@uB5Kyu9Pm*KJ$aSM@{w?6AzhKJaMw8c&exPCfdE* z98TFhm6PD0CCd$Ed(2;^uuU$osn}tyRsBthPD;EbY>m!*$y~HBnazOB9^Y?5!D&O% zcE~P8ry;WpjfTd@k!^F|DiOT5atQ7!L%FE4OyE070a$DJ%${=O7(PZ{Ek~=8lP58q z6_seOt5)%o1#&wnxrvlaDV;p6bn;{aEh#LXSX?ZS8z)fvOf<;?&(B98dSn6WOr}Q` zp(_@HK}p`km|I?(Un(N5%s zgPmv$^p%SyTK53jm}1zx{1VzhyVsz%P0+p`Wt5YGDA=&xt|?(sK{}YD1YT1DY;G)i z*}O?_X6{?jtZE8_#}+&uQb0NcDA|BA;rk89V~#0+J%_n;*t7xJY2~9x}w}W7e$m%JDC*>DWp}_ea$TFvFb8v3IdC;E&G4(g%ADM zRe!VWYiSLJbkg8e+LVC1prMFOgML4o5jo%|4f$Rr?2}uSYG#v94~80u9wb4{uY^V* zXj4LAH5dpJw_j-uDLz?O`~?D>z5{;;zpcT!Ft1)3WuH}DJ*du2R6i*sE*ITagWI{d z{cqlhS0#w27ULaU{oF><;0p%yP*C$~@)AW0HxM;Ulx3}YJ0l^*+vFu`AguZo5^N;? zpf6&$zcC~?MJHjlr%?^~1%AQ=qBkofrh_b#0})x%+Nn~9Kj(xvI=G`A|1*y1?+ti< zLINH1rP#0rtIm*S!qF5=y0XinnuL8`Y| zDCYQ+Ca8K>91R&M%&y8VY@(lHUf{TDdWz?<37)C9rb*rr;9)wFZljS={EIm>wU~b} zP8M{^6#hK}>C033DY?D;`0UAEayv`>&VNAshn*W!Rxm&_(wb3Z@LHpF`rHu8&YadV)TeAr z38gV*^G^uLCRYp$>sY>KBX%W5M^?1C;aPIPr)Z=C>i=MMz?m~bI-X$|lkbM3pEJfO z{aVOkEs*^hWi71GyT2APP0&3c*c}UkZR~Y0ZXC%=&=1R>&9cLhIVl$NR7M!n1X$lE z%z>kQLJqvm3j|X8h4FCCETqG{exVqC_)*9Nq_1W6dsM2m!6R6~}9opCodJZyO&=0VsI%Krz|rS6S#GNv4(EkF z%j$$qn{(Mx6N7l@M?4zVJ|Rl9_lo73#JS{z_m)czsj_ET&@XGQQlk{S!B#!mUcAO4nL%7e4UT+L!{xJSda}<)PmUZ=q~Ur_q57nw@<>bXj0^5^tiv z92PkTjQK*iVm@e}iaQfH2X6RG{1S4{W@p2~V{D^-Oe~~79~1v=gQ`Ap zEN$--KTZI9VL$`}3GF^FN^|2NZkb`7K4`^xF^l$AT63M|D2;jR>DXH9@3jn8i$?!t z%%%pSlqN@G>V?k^Tg#~Ewg?<-xh7a4@RrpEXP@N-s3@=?diWjd(n65_V?~+O#_P6O zVSgl|&sJ92u?t|sIcpC55a7+3^BxpNJ2aOAh*NxpY@1Ev%Jt z@)Dv-@4QdS5I}fL5Fmezv=?S}NiI0QjrBFXOUi?uE@=$B)g=`|cbAk8>mHVTP_{G4#zH9TaD1yYmWtb?Q#m8>30Xh}YoB#j- delta 11729 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 delta 11815 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 Date: Thu, 29 Aug 2024 11:29:00 +0100 Subject: [PATCH 14/17] Upgraded webpack Signed-off-by: snipe --- package-lock.json | 36 ++++++++++-------------------------- package.json | 2 +- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 30770cde8a..a5296ae5f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "signature_pad": "^4.2.0", "tableexport.jquery.plugin": "1.30.0", "tether": "^1.4.0", - "webpack": "^5.92.0" + "webpack": "^5.94.0" }, "devDependencies": { "all-contributors-cli": "^6.26.1", @@ -2105,25 +2105,10 @@ "@types/node": "*" } }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.5", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/express": { "version": "4.17.21", @@ -5310,9 +5295,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -10880,11 +10865,10 @@ "license": "BSD-2-Clause" }, "node_modules/webpack": { - "version": "5.92.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", - "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dependencies": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", @@ -10893,7 +10877,7 @@ "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", diff --git a/package.json b/package.json index d0ce13579d..3d8e3eda2d 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,6 @@ "signature_pad": "^4.2.0", "tableexport.jquery.plugin": "1.30.0", "tether": "^1.4.0", - "webpack": "^5.92.0" + "webpack": "^5.94.0" } } From ec2ea955d895b979d8285b2b5c497ef9c085b983 Mon Sep 17 00:00:00 2001 From: Brady Wetherington Date: Thu, 29 Aug 2024 12:35:14 +0100 Subject: [PATCH 15/17] Fix PATCH of purchase_cost for assets for comma as decimal separator --- app/Http/Requests/UpdateAssetRequest.php | 7 ++ app/Models/SnipeModel.php | 5 + tests/Feature/Assets/Api/UpdateAssetTest.php | 96 ++++++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/app/Http/Requests/UpdateAssetRequest.php b/app/Http/Requests/UpdateAssetRequest.php index a749e5816b..1b379358f9 100644 --- a/app/Http/Requests/UpdateAssetRequest.php +++ b/app/Http/Requests/UpdateAssetRequest.php @@ -4,6 +4,7 @@ namespace App\Http\Requests; use App\Http\Requests\Traits\MayContainCustomFields; use App\Models\Asset; +use App\Models\Setting; use Illuminate\Support\Facades\Gate; use Illuminate\Validation\Rule; @@ -41,6 +42,12 @@ class UpdateAssetRequest extends ImageUploadRequest ], ); + // if the purchase cost is passed in as a string **and** the digit_separator is ',' (as is common in the EU) + // then we tweak the purchase_cost rule to make it a string + if (Setting::getSettings()->digit_separator === '1.234,56' && is_string($this->input('purchase_cost'))) { + $rules['purchase_cost'] = ['nullable', 'string']; + } + return $rules; } } diff --git a/app/Models/SnipeModel.php b/app/Models/SnipeModel.php index af12c3d29b..f26946d22a 100644 --- a/app/Models/SnipeModel.php +++ b/app/Models/SnipeModel.php @@ -21,6 +21,11 @@ class SnipeModel extends Model */ public function setPurchaseCostAttribute($value) { + if (is_float($value)) { + //value is *already* a floating-point number. Just assign it directly + $this->attributes['purchase_cost'] = $value; + return; + } $value = Helper::ParseCurrency($value); if ($value == 0) { diff --git a/tests/Feature/Assets/Api/UpdateAssetTest.php b/tests/Feature/Assets/Api/UpdateAssetTest.php index 300d06ae50..7a4e411b3d 100644 --- a/tests/Feature/Assets/Api/UpdateAssetTest.php +++ b/tests/Feature/Assets/Api/UpdateAssetTest.php @@ -103,6 +103,102 @@ class UpdateAssetTest extends TestCase $this->assertEquals('2023-09-03 00:00:00', $updatedAsset->last_audit_date); } + public function testUpdatesPeriodAsCommaSeparatorForPurchaseCost() + { + $this->settings->set([ + 'default_currency' => 'EUR', + 'digit_separator' => '1.234,56', + ]); + + $original_asset = Asset::factory()->create(); + + $response = $this->actingAsForApi(User::factory()->superuser()->create()) + ->patchJson(route('api.assets.update', $original_asset->id), [ + 'asset_tag' => 'random-string', + 'model_id' => AssetModel::factory()->create()->id, + 'status_id' => Statuslabel::factory()->create()->id, + // API also accepts string for comma separated values + 'purchase_cost' => '1.112,34', + ]) + ->assertStatusMessageIs('success'); + + $asset = Asset::find($response['payload']['id']); + + $this->assertEquals(1112.34, $asset->purchase_cost); + } + + public function testUpdatesFloatForPurchaseCost() + { + $this->settings->set([ + 'default_currency' => 'EUR', + 'digit_separator' => '1.234,56', + ]); + + $original_asset = Asset::factory()->create(); + + $response = $this->actingAsForApi(User::factory()->superuser()->create()) + ->patchJson(route('api.assets.update', $original_asset->id), [ + 'asset_tag' => 'random-string', + 'model_id' => AssetModel::factory()->create()->id, + 'status_id' => Statuslabel::factory()->create()->id, + // API also accepts string for comma separated values + 'purchase_cost' => 12.34, + ]) + ->assertStatusMessageIs('success'); + + $asset = Asset::find($response['payload']['id']); + + $this->assertEquals(12.34, $asset->purchase_cost); + } + + public function testUpdatesUSDecimalForPurchaseCost() + { + $this->settings->set([ + 'default_currency' => 'EUR', + 'digit_separator' => '1,234.56', + ]); + + $original_asset = Asset::factory()->create(); + + $response = $this->actingAsForApi(User::factory()->superuser()->create()) + ->patchJson(route('api.assets.update', $original_asset->id), [ + 'asset_tag' => 'random-string', + 'model_id' => AssetModel::factory()->create()->id, + 'status_id' => Statuslabel::factory()->create()->id, + // API also accepts string for comma separated values + 'purchase_cost' => '5412.34', //NOTE - you cannot use thousands-separator here!!!! + ]) + ->assertStatusMessageIs('success'); + + $asset = Asset::find($response['payload']['id']); + + $this->assertEquals(5412.34, $asset->purchase_cost); + } + + public function testUpdatesFloatUSDecimalForPurchaseCost() + { + $this->settings->set([ + 'default_currency' => 'EUR', + 'digit_separator' => '1,234.56', + ]); + + $original_asset = Asset::factory()->create(); + + $response = $this->actingAsForApi(User::factory()->superuser()->create()) + ->patchJson(route('api.assets.update', $original_asset->id), [ + 'asset_tag' => 'random-string', + 'model_id' => AssetModel::factory()->create()->id, + 'status_id' => Statuslabel::factory()->create()->id, + // API also accepts string for comma separated values + 'purchase_cost' => 12.34, + ]) + ->assertStatusMessageIs('success'); + + $asset = Asset::find($response['payload']['id']); + + $this->assertEquals(12.34, $asset->purchase_cost); + } + public function testAssetEolDateIsCalculatedIfPurchaseDateUpdated() { $asset = Asset::factory()->laptopMbp()->noPurchaseOrEolDate()->create(); From b64ed254e022cb4fd363b7ffd5c99cfc46567d5d Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 29 Aug 2024 13:49:09 +0100 Subject: [PATCH 16/17] Fixed tests Signed-off-by: snipe --- resources/lang/en-US/admin/users/message.php | 2 +- tests/Feature/Users/Ui/ViewUserTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/lang/en-US/admin/users/message.php b/resources/lang/en-US/admin/users/message.php index 0f41d463e1..3f44226335 100644 --- a/resources/lang/en-US/admin/users/message.php +++ b/resources/lang/en-US/admin/users/message.php @@ -6,7 +6,7 @@ return array( 'declined' => 'You have successfully declined this asset.', 'bulk_manager_warn' => 'Your users have been successfully updated, however your manager entry was not saved because the manager you selected was also in the user list to be edited, and users may not be their own manager. Please select your users again, excluding the manager.', 'user_exists' => 'User already exists!', - 'user_not_found' => 'User does not exist.', + 'user_not_found' => 'User does not exist or you do not have permission view them.', 'user_login_required' => 'The login field is required', 'user_has_no_assets_assigned' => 'No assets currently assigned to user.', 'user_password_required' => 'The password is required.', diff --git a/tests/Feature/Users/Ui/ViewUserTest.php b/tests/Feature/Users/Ui/ViewUserTest.php index c412e9e789..791c804897 100644 --- a/tests/Feature/Users/Ui/ViewUserTest.php +++ b/tests/Feature/Users/Ui/ViewUserTest.php @@ -40,7 +40,7 @@ class ViewUserTest extends TestCase $this->actingAs(User::factory()->viewUsers()->for($companyA)->create()) ->get(route('users.print', ['userId' => $user->id])) - ->assertStatus(403); + ->assertStatus(302); $this->actingAs(User::factory()->viewUsers()->for($companyB)->create()) ->get(route('users.print', ['userId' => $user->id])) From da1e383295d6ee3940d6842979a73c1f14e6ff9a Mon Sep 17 00:00:00 2001 From: Brady Wetherington Date: Thu, 29 Aug 2024 14:09:23 +0100 Subject: [PATCH 17/17] Use the null-safe property accessor for new-user creation --- app/Http/Requests/SaveUserRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Requests/SaveUserRequest.php b/app/Http/Requests/SaveUserRequest.php index e16826d16c..f778d016df 100644 --- a/app/Http/Requests/SaveUserRequest.php +++ b/app/Http/Requests/SaveUserRequest.php @@ -37,7 +37,7 @@ class SaveUserRequest extends FormRequest 'company_id' => [ // determines if the user is being moved between companies and checks to see if they have any items assigned function ($attribute, $value, $fail) { - if (($this->has('company_id')) && ($this->user->allAssignedCount() > 0) && (Setting::getSettings()->full_multiple_companies_support)) { + if (($this->has('company_id')) && ($this->user?->allAssignedCount() > 0) && (Setting::getSettings()->full_multiple_companies_support)) { $fail(trans('admin/users/message.error.multi_company_items_assigned')); } }