From c025e258397ffe09b64a8808d632cdd6930a20f7 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Mon, 26 Feb 2024 14:32:50 -0600 Subject: [PATCH 001/207] just the basics and notes, pushing to keep track --- app/Http/Controllers/Api/AssetsController.php | 10 ++-- app/Http/Requests/UpdateAssetRequest.php | 57 +++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 app/Http/Requests/UpdateAssetRequest.php diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index 77a329f39..0f3bff394 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api; use App\Events\CheckoutableCheckedIn; use App\Http\Requests\StoreAssetRequest; +use App\Http\Requests\UpdateAssetRequest; use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Crypt; use Illuminate\Support\Facades\Gate; @@ -621,13 +622,12 @@ class AssetsController extends Controller * @since [v4.0] * @return \Illuminate\Http\JsonResponse */ - public function update(ImageUploadRequest $request, $id) + public function update(UpdateAssetRequest $request, Asset $id) { - $this->authorize('update', Asset::class); - if ($asset = Asset::find($id)) { - $asset->fill($request->all()); + $asset->fill($request->validated()); + // TODO: how much of this should go to validator? ($request->filled('model_id')) ? $asset->model()->associate(AssetModel::find($request->get('model_id'))) : null; ($request->filled('rtd_location_id')) ? @@ -691,6 +691,8 @@ class AssetsController extends Controller return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200); } + // TODO: can this be moved up to ModelNotFound exception handler? would remove a couple lines here if we could use laravel's awesome route-model binding. + // (would also need to confirm that then _everything_ expects a 200 when a model isn't found) return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200); } diff --git a/app/Http/Requests/UpdateAssetRequest.php b/app/Http/Requests/UpdateAssetRequest.php new file mode 100644 index 000000000..3c5286a1c --- /dev/null +++ b/app/Http/Requests/UpdateAssetRequest.php @@ -0,0 +1,57 @@ +has('asset_tag')) { + // TODO: not sure if i'll be able to use the route model binding here because of not-found return stuff, need to test + $asset_tag = $this->asset->asset_tag; + } + if (!$this->has('model_id')) { + $model_id = $this->asset->model_id; + } + if (!$this->has('status_id')) { + $status_id = $this->asset->status_id; + } + + $this->merge([ + 'asset_tag' => $asset_tag, + 'model_id' => $model_id, + 'status_id' => $status_id, + ]); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + $rules = array_merge( + (new Asset())->getRules(), + parent::rules(), + ); + + return $rules; + } +} From eac01868caa039b38b45cdf667d7f29fa5f94782 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Tue, 5 Mar 2024 11:02:55 -0600 Subject: [PATCH 002/207] not all working, but pushing to work on something else --- app/Http/Controllers/Api/AssetsController.php | 10 +++------- app/Http/Requests/UpdateAssetRequest.php | 5 ++++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index 0f3bff394..ec8e65e5c 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -622,10 +622,9 @@ class AssetsController extends Controller * @since [v4.0] * @return \Illuminate\Http\JsonResponse */ - public function update(UpdateAssetRequest $request, Asset $id) + public function update(UpdateAssetRequest $request, Asset $asset) { - if ($asset = Asset::find($id)) { - $asset->fill($request->validated()); + $asset->update($request->validated()); // TODO: how much of this should go to validator? ($request->filled('model_id')) ? @@ -689,11 +688,8 @@ class AssetsController extends Controller } return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200); - } - // TODO: can this be moved up to ModelNotFound exception handler? would remove a couple lines here if we could use laravel's awesome route-model binding. - // (would also need to confirm that then _everything_ expects a 200 when a model isn't found) - return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200); + // TODO: confirm that everything expects a _200_ model not found exception } diff --git a/app/Http/Requests/UpdateAssetRequest.php b/app/Http/Requests/UpdateAssetRequest.php index 3c5286a1c..f33f2d075 100644 --- a/app/Http/Requests/UpdateAssetRequest.php +++ b/app/Http/Requests/UpdateAssetRequest.php @@ -3,7 +3,6 @@ namespace App\Http\Requests; use App\Models\Asset; -use Illuminate\Foundation\Http\FormRequest; use Illuminate\Support\Facades\Gate; class UpdateAssetRequest extends ImageUploadRequest @@ -20,6 +19,10 @@ class UpdateAssetRequest extends ImageUploadRequest public function prepareForValidation() { + dump($this->asset); + $asset = $this->route('asset'); + dump($asset); + dump($this->route()->getName()); // the following are 'required' attributes that may or may not be present on an patch request // so supplying them here instead of doing funky array modification to the rules if (!$this->has('asset_tag')) { From b239b3a4dbccbf8538d98d7efe282b34bf660508 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Fri, 8 Mar 2024 18:24:41 -0600 Subject: [PATCH 003/207] some good progress, lots of testing needs to be done on the new inclusion of SubstituteBindings --- app/Http/Controllers/Api/AssetsController.php | 105 +++++++++--------- app/Http/Kernel.php | 1 + app/Http/Requests/UpdateAssetRequest.php | 24 +--- routes/api.php | 9 +- 4 files changed, 61 insertions(+), 78 deletions(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index ec8e65e5c..0f1879ba5 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -618,78 +618,77 @@ class AssetsController extends Controller * Accepts a POST request to update an asset * * @author [A. Gianotto] [] - * @param \App\Http\Requests\ImageUploadRequest $request * @since [v4.0] * @return \Illuminate\Http\JsonResponse */ public function update(UpdateAssetRequest $request, Asset $asset) { - $asset->update($request->validated()); + $asset->fill($request->validated()); - // TODO: how much of this should go to validator? - ($request->filled('model_id')) ? - $asset->model()->associate(AssetModel::find($request->get('model_id'))) : null; - ($request->filled('rtd_location_id')) ? - $asset->location_id = $request->get('rtd_location_id') : ''; - ($request->filled('company_id')) ? - $asset->company_id = Company::getIdForCurrentUser($request->get('company_id')) : ''; + // TODO: how much of this can go in the validator? + ($request->filled('model_id')) ? + $asset->model()->associate(AssetModel::find($request->get('model_id'))) : null; + ($request->filled('rtd_location_id')) ? + $asset->location_id = $request->get('rtd_location_id') : ''; + ($request->filled('company_id')) ? + $asset->company_id = Company::getIdForCurrentUser($request->get('company_id')) : ''; - ($request->filled('rtd_location_id')) ? - $asset->location_id = $request->get('rtd_location_id') : null; + ($request->filled('rtd_location_id')) ? + $asset->location_id = $request->get('rtd_location_id') : null; - /** - * this is here just legacy reasons. Api\AssetController - * used image_source once to allow encoded image uploads. - */ - if ($request->has('image_source')) { - $request->offsetSet('image', $request->offsetGet('image_source')); - } + /** + * this is here just legacy reasons. Api\AssetController + * used image_source once to allow encoded image uploads. + */ + if ($request->has('image_source')) { + $request->offsetSet('image', $request->offsetGet('image_source')); + } - $asset = $request->handleImages($asset); - $model = AssetModel::find($asset->model_id); - - // Update custom fields - if (($model) && (isset($model->fieldset))) { - foreach ($model->fieldset->fields as $field) { - if ($request->has($field->db_column)) { - if ($field->field_encrypted == '1') { - if (Gate::allows('admin')) { - $asset->{$field->db_column} = \Crypt::encrypt($request->input($field->db_column)); - } - } else { - $asset->{$field->db_column} = $request->input($field->db_column); + $asset = $request->handleImages($asset); + $model = AssetModel::find($asset->model_id); + + // Update custom fields + if (($model) && (isset($model->fieldset))) { + foreach ($model->fieldset->fields as $field) { + if ($request->has($field->db_column)) { + if ($field->field_encrypted == '1') { + if (Gate::allows('admin')) { + $asset->{$field->db_column} = \Crypt::encrypt($request->input($field->db_column)); } + } else { + $asset->{$field->db_column} = $request->input($field->db_column); } } } + } - if ($asset->save()) { - if (($request->filled('assigned_user')) && ($target = User::find($request->get('assigned_user')))) { - $location = $target->location_id; - } elseif (($request->filled('assigned_asset')) && ($target = Asset::find($request->get('assigned_asset')))) { - $location = $target->location_id; + if ($asset->save()) { + if (($request->filled('assigned_user')) && ($target = User::find($request->get('assigned_user')))) { + $location = $target->location_id; + } elseif (($request->filled('assigned_asset')) && ($target = Asset::find($request->get('assigned_asset')))) { + $location = $target->location_id; - Asset::where('assigned_type', \App\Models\Asset::class)->where('assigned_to', $id) - ->update(['location_id' => $target->location_id]); - } elseif (($request->filled('assigned_location')) && ($target = Location::find($request->get('assigned_location')))) { - $location = $target->id; - } - - if (isset($target)) { - $asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name')), $location); - } - - if ($asset->image) { - $asset->image = $asset->getImageUrl(); - } - - return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success'))); + Asset::where('assigned_type', \App\Models\Asset::class)->where('assigned_to', $id) + ->update(['location_id' => $target->location_id]); + } elseif (($request->filled('assigned_location')) && ($target = Location::find($request->get('assigned_location')))) { + $location = $target->id; } - return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200); + if (isset($target)) { + $asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name')), $location); + } - // TODO: confirm that everything expects a _200_ model not found exception + if ($asset->image) { + $asset->image = $asset->getImageUrl(); + } + + return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success'))); + } + + return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200); + + // TODO: confirm that everything expects a _200_ model not found exception } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 36014dc7d..55340dc41 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -48,6 +48,7 @@ class Kernel extends HttpKernel 'api' => [ 'auth:api', + \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ]; diff --git a/app/Http/Requests/UpdateAssetRequest.php b/app/Http/Requests/UpdateAssetRequest.php index f33f2d075..7fd2826f1 100644 --- a/app/Http/Requests/UpdateAssetRequest.php +++ b/app/Http/Requests/UpdateAssetRequest.php @@ -19,27 +19,12 @@ class UpdateAssetRequest extends ImageUploadRequest public function prepareForValidation() { - dump($this->asset); - $asset = $this->route('asset'); - dump($asset); - dump($this->route()->getName()); // the following are 'required' attributes that may or may not be present on an patch request // so supplying them here instead of doing funky array modification to the rules - if (!$this->has('asset_tag')) { - // TODO: not sure if i'll be able to use the route model binding here because of not-found return stuff, need to test - $asset_tag = $this->asset->asset_tag; - } - if (!$this->has('model_id')) { - $model_id = $this->asset->model_id; - } - if (!$this->has('status_id')) { - $status_id = $this->asset->status_id; - } - - $this->merge([ - 'asset_tag' => $asset_tag, - 'model_id' => $model_id, - 'status_id' => $status_id, + return $this->merge([ + 'asset_tag' => $this->asset_tag ?? $this->asset->asset_tag, + 'model_id' => $this->model_id ?? $this->asset->model_id, + 'status_id' => $this->status_id ?? $this->asset->status_id, ]); } @@ -53,6 +38,7 @@ class UpdateAssetRequest extends ImageUploadRequest $rules = array_merge( (new Asset())->getRules(), parent::rules(), + //['model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array'] ); return $rules; diff --git a/routes/api.php b/routes/api.php index 842e6210d..9ad3ae2c1 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,7 +1,6 @@ 'v1', 'middleware' => ['api', 'throttle:api']], functi }); - - - + // pulling this out of resource route group to begin normalizing + Route::patch('/hardware/{asset}', [Api\AssetsController::class, 'update'])->name('api.assets.update'); Route::resource('hardware', Api\AssetsController::class, ['names' => [ 'index' => 'api.assets.index', 'show' => 'api.assets.show', - 'update' => 'api.assets.update', 'store' => 'api.assets.store', 'destroy' => 'api.assets.destroy', ], - 'except' => ['create', 'edit'], + 'except' => ['create', 'edit', 'update'], 'parameters' => ['asset' => 'asset_id'], ] ); // end assets API routes From c8341d9dc4a653daae81be980e7cb1b32d0179ef Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Fri, 8 Mar 2024 19:48:47 -0600 Subject: [PATCH 004/207] aha, got it working. --- app/Http/Controllers/Api/AssetsController.php | 6 ++++-- app/Http/Requests/UpdateAssetRequest.php | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index 0f1879ba5..c67571b73 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -626,8 +626,10 @@ class AssetsController extends Controller $asset->fill($request->validated()); // TODO: how much of this can go in the validator? - ($request->filled('model_id')) ? - $asset->model()->associate(AssetModel::find($request->get('model_id'))) : null; + // this is _always_ filled now, see UpdateAssetRequest + // i'm leaving this here for now, but when would we ever want model_id to be `null`?? + ($request->validated()['model_id']) ? + $asset->model()->associate(AssetModel::find($request->validated()['model_id'])) : null; ($request->filled('rtd_location_id')) ? $asset->location_id = $request->get('rtd_location_id') : ''; ($request->filled('company_id')) ? diff --git a/app/Http/Requests/UpdateAssetRequest.php b/app/Http/Requests/UpdateAssetRequest.php index 7fd2826f1..afee0fb90 100644 --- a/app/Http/Requests/UpdateAssetRequest.php +++ b/app/Http/Requests/UpdateAssetRequest.php @@ -38,7 +38,6 @@ class UpdateAssetRequest extends ImageUploadRequest $rules = array_merge( (new Asset())->getRules(), parent::rules(), - //['model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array'] ); return $rules; From eb8f1dd5533340e0ccd857631e5578caeee627b9 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Sat, 9 Mar 2024 12:29:26 -0600 Subject: [PATCH 005/207] some cleanup --- app/Http/Controllers/Api/AssetsController.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index c67571b73..4361dc40d 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -627,16 +627,16 @@ class AssetsController extends Controller // TODO: how much of this can go in the validator? // this is _always_ filled now, see UpdateAssetRequest - // i'm leaving this here for now, but when would we ever want model_id to be `null`?? + // i'm leaving it like this for now, but when would we ever want model_id to be `null`?? + // it actually breaks at the model validation if it gets to null... ($request->validated()['model_id']) ? $asset->model()->associate(AssetModel::find($request->validated()['model_id'])) : null; - ($request->filled('rtd_location_id')) ? - $asset->location_id = $request->get('rtd_location_id') : ''; - ($request->filled('company_id')) ? - $asset->company_id = Company::getIdForCurrentUser($request->get('company_id')) : ''; - - ($request->filled('rtd_location_id')) ? - $asset->location_id = $request->get('rtd_location_id') : null; + ($request->validated()['rtd_location_id']) ? + $asset->location_id = $request->validated()['rtd_location_id'] : ''; + ($request->validated()['company_id']) ? + $asset->company_id = Company::getIdForCurrentUser($request->validated()['company_id']) : ''; + ($request->validated()['rtd_location_id']) ? + $asset->location_id = $request->validated()['rtd_location_id'] : null; /** * this is here just legacy reasons. Api\AssetController @@ -647,7 +647,7 @@ class AssetsController extends Controller } $asset = $request->handleImages($asset); - $model = AssetModel::find($asset->model_id); + $model = $asset->model; // Update custom fields if (($model) && (isset($model->fieldset))) { @@ -655,7 +655,7 @@ class AssetsController extends Controller if ($request->has($field->db_column)) { if ($field->field_encrypted == '1') { if (Gate::allows('admin')) { - $asset->{$field->db_column} = \Crypt::encrypt($request->input($field->db_column)); + $asset->{$field->db_column} = Crypt::encrypt($request->input($field->db_column)); } } else { $asset->{$field->db_column} = $request->input($field->db_column); From 6732b6601ed1c395b59d00100047f78131ec808c Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Tue, 12 Mar 2024 18:33:59 -0500 Subject: [PATCH 006/207] some cool progress, but something with unique not working --- app/Models/Asset.php | 75 ++++++++---- app/Providers/ValidationServiceProvider.php | 15 +++ tests/Feature/Api/Assets/AssetUpdateTest.php | 117 +++++++++++++++++++ 3 files changed, 184 insertions(+), 23 deletions(-) create mode 100644 tests/Feature/Api/Assets/AssetUpdateTest.php diff --git a/app/Models/Asset.php b/app/Models/Asset.php index c2a2a8d99..2e03323d3 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -18,6 +18,7 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Facades\Storage; +use Illuminate\Validation\Rule; use Watson\Validating\ValidatingTrait; /** @@ -88,30 +89,58 @@ class Asset extends Depreciable 'deleted_at' => 'datetime', ]; - protected $rules = [ - 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', - 'status_id' => 'required|integer|exists:status_labels,id', - 'asset_tag' => 'required|min:1|max:255|unique_undeleted:assets,asset_tag|not_array', - 'name' => 'nullable|max:255', - 'company_id' => 'nullable|integer|exists:companies,id', - 'warranty_months' => 'nullable|numeric|digits_between:0,240', - 'last_checkout' => 'nullable|date_format:Y-m-d H:i:s', - 'expected_checkin' => 'nullable|date', - 'location_id' => 'nullable|exists:locations,id', - 'rtd_location_id' => 'nullable|exists:locations,id', - 'purchase_date' => 'nullable|date|date_format:Y-m-d', - 'serial' => 'nullable|unique_undeleted:assets,serial', - 'purchase_cost' => 'nullable|numeric|gte:0', - 'supplier_id' => 'nullable|exists:suppliers,id', - 'asset_eol_date' => 'nullable|date', - 'eol_explicit' => 'nullable|boolean', - 'byod' => 'nullable|boolean', - 'order_number' => 'nullable|string|max:191', - 'notes' => 'nullable|string|max:65535', - 'assigned_to' => 'nullable|integer', - 'requestable' => 'nullable|boolean', - ]; + //protected $rules = [ + // 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', + // 'status_id' => 'required|integer|exists:status_labels,id', + // 'asset_tag' => ['required', 'min:1', 'max:255', 'unique_undeleted:assets,asset_tag', 'not_array', Rule::unique('assets')->ignore($this->id)->withoutTrashed()], + // 'name' => 'nullable|max:255', + // 'company_id' => 'nullable|integer|exists:companies,id', + // 'warranty_months' => 'nullable|numeric|digits_between:0,240', + // 'last_checkout' => 'nullable|date_format:Y-m-d H:i:s', + // 'expected_checkin' => 'nullable|date', + // 'location_id' => 'nullable|exists:locations,id', + // 'rtd_location_id' => 'nullable|exists:locations,id', + // 'purchase_date' => 'nullable|date|date_format:Y-m-d', + // 'serial' => 'nullable|unique_undeleted:assets,serial', + // 'purchase_cost' => 'nullable|numeric|gte:0', + // 'supplier_id' => 'nullable|exists:suppliers,id', + // 'asset_eol_date' => 'nullable|date', + // 'eol_explicit' => 'nullable|boolean', + // 'byod' => 'nullable|boolean', + // 'order_number' => 'nullable|string|max:191', + // 'notes' => 'nullable|string|max:65535', + // 'assigned_to' => 'nullable|integer', + // 'requestable' => 'nullable|boolean', + //]; + public function getRulesAttribute() + { + $rule = Rule::unique('assets')->ignore($this->id)->withoutTrashed(); + $asset = $this->id; + return [ + 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', + 'status_id' => 'required|integer|exists:status_labels,id', + 'asset_tag' => ['required', 'min:1', 'max:255', Rule::unique('assets', 'asset_tag')->ignore($this->id, 'id')->withoutTrashed()], + 'name' => 'nullable|max:255', + 'company_id' => 'nullable|integer|exists:companies,id', + 'warranty_months' => 'nullable|numeric|digits_between:0,240', + 'last_checkout' => 'nullable|date_format:Y-m-d H:i:s', + 'expected_checkin' => 'nullable|date', + 'location_id' => 'nullable|exists:locations,id', + 'rtd_location_id' => 'nullable|exists:locations,id', + 'purchase_date' => 'nullable|date|date_format:Y-m-d', + 'serial' => 'nullable|unique_undeleted:assets,serial', + 'purchase_cost' => 'nullable|numeric|gte:0', + 'supplier_id' => 'nullable|exists:suppliers,id', + 'asset_eol_date' => 'nullable|date', + 'eol_explicit' => 'nullable|boolean', + 'byod' => 'nullable|boolean', + 'order_number' => 'nullable|string|max:191', + 'notes' => 'nullable|string|max:65535', + 'assigned_to' => 'nullable|integer', + 'requestable' => 'nullable|boolean', + ]; + } /** * The attributes that are mass assignable. diff --git a/app/Providers/ValidationServiceProvider.php b/app/Providers/ValidationServiceProvider.php index 50468c8d7..172e99bf4 100644 --- a/app/Providers/ValidationServiceProvider.php +++ b/app/Providers/ValidationServiceProvider.php @@ -79,6 +79,21 @@ class ValidationServiceProvider extends ServiceProvider return $count < 1; } + //else { + // if (($parameters[0] == 'assets') && ($attribute == 'serial') && (Setting::getSettings()->unique_serial != '1')) { + // return true; + // } + // + // $count = DB::table($parameters[0]) + // ->select('id') + // ->where($attribute, '=', $value) + // ->whereNull('deleted_at') + // ->where('id', '!=', $parameters[1]) + // ->where('id', '!=', $parameters[2]) + // ->count(); + // + // return $count < 1; + //} }); /** diff --git a/tests/Feature/Api/Assets/AssetUpdateTest.php b/tests/Feature/Api/Assets/AssetUpdateTest.php new file mode 100644 index 000000000..bd5377efd --- /dev/null +++ b/tests/Feature/Api/Assets/AssetUpdateTest.php @@ -0,0 +1,117 @@ +create(); + + $this->actingAsForApi(User::factory()->create()) + ->patchJson(route('api.assets.update', $asset->id)) + ->assertForbidden(); + } + + public function testAllAssetAttributesAreStored() + { + $asset = Asset::factory()->create(); + $user = User::factory()->editAssets()->create(); + $userAssigned = User::factory()->create(); + $company = Company::factory()->create(); + $location = Location::factory()->create(); + $model = AssetModel::factory()->create(); + $rtdLocation = Location::factory()->create(); + $status = Statuslabel::factory()->create(); + $supplier = Supplier::factory()->create(); + + $response = $this->actingAsForApi($user) + ->patchJson(route('api.assets.update', $asset->id), [ + 'asset_eol_date' => '2024-06-02', + 'asset_tag' => 'random_string', + 'assigned_user' => $userAssigned->id, + 'company_id' => $company->id, + 'last_audit_date' => '2023-09-03', + 'location_id' => $location->id, + 'model_id' => $model->id, + 'name' => 'A New Asset', + 'notes' => 'Some notes', + 'order_number' => '5678', + 'purchase_cost' => '123.45', + 'purchase_date' => '2023-09-02', + 'requestable' => true, + 'rtd_location_id' => $rtdLocation->id, + 'serial' => '1234567890', + 'status_id' => $status->id, + 'supplier_id' => $supplier->id, + 'warranty_months' => 10, + ]) + ->assertOk() + ->assertStatusMessageIs('success') + ->json(); + + $updatedAsset = Asset::find($response['payload']['id']); + + // TODO: this isn't working, i assume `adminuser` is the user that created asset + //$this->assertTrue($updatedAsset->adminuser->is($user)); + + $this->assertEquals('2024-06-02', $updatedAsset->asset_eol_date); + $this->assertEquals('random_string', $updatedAsset->asset_tag); + $this->assertEquals($userAssigned->id, $updatedAsset->assigned_to); + $this->assertTrue($updatedAsset->company->is($company)); + // TODO: this doesn't work + //$this->assertTrue($updatedAsset->location->is($location)); + $this->assertTrue($updatedAsset->model->is($model)); + $this->assertEquals('A New Asset', $updatedAsset->name); + $this->assertEquals('Some notes', $updatedAsset->notes); + $this->assertEquals('5678', $updatedAsset->order_number); + $this->assertEquals('123.45', $updatedAsset->purchase_cost); + $this->assertTrue($updatedAsset->purchase_date->is('2023-09-02')); + $this->assertEquals('1', $updatedAsset->requestable); + $this->assertTrue($updatedAsset->defaultLoc->is($rtdLocation)); + $this->assertEquals('1234567890', $updatedAsset->serial); + $this->assertTrue($updatedAsset->assetstatus->is($status)); + $this->assertTrue($updatedAsset->supplier->is($supplier)); + $this->assertEquals(10, $updatedAsset->warranty_months); + } + + public function testArchivedDepreciateAndPhysicalCanBeNull() + { + $model = AssetModel::factory()->ipadModel()->create(); + $status = Statuslabel::factory()->create(); + $asset = Asset::factory()->create(); + + $this->settings->enableAutoIncrement(); + + $response = $this->actingAsForApi(User::factory()->superuser()->create()) + ->patchJson(route('api.assets.update', $asset->id), [ + 'archive' => null, + 'depreciate' => null, + 'physical' => null + ]) + ->dd() + ->assertOk() + ->assertStatusMessageIs('success') + ->json(); + + $asset = Asset::find($response['payload']['id']); + $this->assertEquals(0, $asset->archived); + $this->assertEquals(1, $asset->physical); + $this->assertEquals(0, $asset->depreciate); + } + +} \ No newline at end of file From 04d7884af8d90809276b5fb1b5ae5fff24ef5dee Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Tue, 12 Mar 2024 23:17:40 -0500 Subject: [PATCH 007/207] some more testing stuff --- app/Http/Controllers/Api/AssetsController.php | 12 ++++++------ app/Models/Asset.php | 9 ++++++--- tests/Feature/Api/Assets/AssetStoreTest.php | 2 ++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index 4361dc40d..bc415c0f3 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -631,12 +631,12 @@ class AssetsController extends Controller // it actually breaks at the model validation if it gets to null... ($request->validated()['model_id']) ? $asset->model()->associate(AssetModel::find($request->validated()['model_id'])) : null; - ($request->validated()['rtd_location_id']) ? - $asset->location_id = $request->validated()['rtd_location_id'] : ''; - ($request->validated()['company_id']) ? - $asset->company_id = Company::getIdForCurrentUser($request->validated()['company_id']) : ''; - ($request->validated()['rtd_location_id']) ? - $asset->location_id = $request->validated()['rtd_location_id'] : null; + //($request->validated()['rtd_location_id']) ? + // $asset->location_id = $request->validated()['rtd_location_id'] : ''; + //($request->validated()['company_id']) ? + // $asset->company_id = Company::getIdForCurrentUser($request->validated()['company_id']) : ''; + //($request->validated()['rtd_location_id']) ? + // $asset->location_id = $request->validated()['rtd_location_id'] : null; /** * this is here just legacy reasons. Api\AssetController diff --git a/app/Models/Asset.php b/app/Models/Asset.php index 2e03323d3..303624b42 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -115,12 +115,15 @@ class Asset extends Depreciable public function getRulesAttribute() { - $rule = Rule::unique('assets')->ignore($this->id)->withoutTrashed(); - $asset = $this->id; return [ 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', 'status_id' => 'required|integer|exists:status_labels,id', - 'asset_tag' => ['required', 'min:1', 'max:255', Rule::unique('assets', 'asset_tag')->ignore($this->id, 'id')->withoutTrashed()], + 'asset_tag' => [ + 'required', + 'min:1', + 'max:255', + Rule::unique('assets')->ignore(15)->withoutTrashed() + ], 'name' => 'nullable|max:255', 'company_id' => 'nullable|integer|exists:companies,id', 'warranty_months' => 'nullable|numeric|digits_between:0,240', diff --git a/tests/Feature/Api/Assets/AssetStoreTest.php b/tests/Feature/Api/Assets/AssetStoreTest.php index 92a58a500..631944190 100644 --- a/tests/Feature/Api/Assets/AssetStoreTest.php +++ b/tests/Feature/Api/Assets/AssetStoreTest.php @@ -149,9 +149,11 @@ class AssetStoreTest extends TestCase 'purchase_date' => '2021-01-01', 'status_id' => $status->id, ]) + //->dd() ->assertOk() ->assertStatusMessageIs('success') ->json(); + return $response; $asset = Asset::find($response['payload']['id']); $this->assertEquals('2024-01-01', $asset->asset_eol_date); From 8962ced0383dde162d664864e36f514c59046946 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 13 Mar 2024 10:40:50 -0500 Subject: [PATCH 008/207] push to switch branches --- app/Models/Asset.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/Models/Asset.php b/app/Models/Asset.php index 303624b42..9eeb8c59c 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -244,8 +244,12 @@ class Asset extends Depreciable $this->{$field->db_column} = filter_var($this->{$field->db_column}, FILTER_VALIDATE_BOOLEAN); } } + $this->rules = array_merge( + $this->rules, + $model->fieldset->validation_rules(), + ); - $this->rules += $model->fieldset->validation_rules(); + //$this->rules += $model->fieldset->validation_rules(); if ($this->model->fieldset){ foreach ($this->model->fieldset->fields as $field){ From f01b205486c3bdf57adf12b993ca29319f53e181 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 13 Mar 2024 15:10:51 -0500 Subject: [PATCH 009/207] some changes --- app/Models/Asset.php | 108 +++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/app/Models/Asset.php b/app/Models/Asset.php index 9eeb8c59c..c1ab89cb7 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -89,61 +89,61 @@ class Asset extends Depreciable 'deleted_at' => 'datetime', ]; - //protected $rules = [ - // 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', - // 'status_id' => 'required|integer|exists:status_labels,id', - // 'asset_tag' => ['required', 'min:1', 'max:255', 'unique_undeleted:assets,asset_tag', 'not_array', Rule::unique('assets')->ignore($this->id)->withoutTrashed()], - // 'name' => 'nullable|max:255', - // 'company_id' => 'nullable|integer|exists:companies,id', - // 'warranty_months' => 'nullable|numeric|digits_between:0,240', - // 'last_checkout' => 'nullable|date_format:Y-m-d H:i:s', - // 'expected_checkin' => 'nullable|date', - // 'location_id' => 'nullable|exists:locations,id', - // 'rtd_location_id' => 'nullable|exists:locations,id', - // 'purchase_date' => 'nullable|date|date_format:Y-m-d', - // 'serial' => 'nullable|unique_undeleted:assets,serial', - // 'purchase_cost' => 'nullable|numeric|gte:0', - // 'supplier_id' => 'nullable|exists:suppliers,id', - // 'asset_eol_date' => 'nullable|date', - // 'eol_explicit' => 'nullable|boolean', - // 'byod' => 'nullable|boolean', - // 'order_number' => 'nullable|string|max:191', - // 'notes' => 'nullable|string|max:65535', - // 'assigned_to' => 'nullable|integer', - // 'requestable' => 'nullable|boolean', - //]; + protected $rules = [ + 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', + 'status_id' => 'required|integer|exists:status_labels,id', + 'asset_tag' => 'required|min:1|max:255|not_array|unique:assets,asset_tag,asset,id,deleted_at,"NULL"', + 'name' => 'nullable|max:255', + 'company_id' => 'nullable|integer|exists:companies,id', + 'warranty_months' => 'nullable|numeric|digits_between:0,240', + 'last_checkout' => 'nullable|date_format:Y-m-d H:i:s', + 'expected_checkin' => 'nullable|date', + 'location_id' => 'nullable|exists:locations,id', + 'rtd_location_id' => 'nullable|exists:locations,id', + 'purchase_date' => 'nullable|date|date_format:Y-m-d', + 'serial' => 'nullable|unique_undeleted:assets,serial', + 'purchase_cost' => 'nullable|numeric|gte:0', + 'supplier_id' => 'nullable|exists:suppliers,id', + 'asset_eol_date' => 'nullable|date', + 'eol_explicit' => 'nullable|boolean', + 'byod' => 'nullable|boolean', + 'order_number' => 'nullable|string|max:191', + 'notes' => 'nullable|string|max:65535', + 'assigned_to' => 'nullable|integer', + 'requestable' => 'nullable|boolean', + ]; - public function getRulesAttribute() - { - return [ - 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', - 'status_id' => 'required|integer|exists:status_labels,id', - 'asset_tag' => [ - 'required', - 'min:1', - 'max:255', - Rule::unique('assets')->ignore(15)->withoutTrashed() - ], - 'name' => 'nullable|max:255', - 'company_id' => 'nullable|integer|exists:companies,id', - 'warranty_months' => 'nullable|numeric|digits_between:0,240', - 'last_checkout' => 'nullable|date_format:Y-m-d H:i:s', - 'expected_checkin' => 'nullable|date', - 'location_id' => 'nullable|exists:locations,id', - 'rtd_location_id' => 'nullable|exists:locations,id', - 'purchase_date' => 'nullable|date|date_format:Y-m-d', - 'serial' => 'nullable|unique_undeleted:assets,serial', - 'purchase_cost' => 'nullable|numeric|gte:0', - 'supplier_id' => 'nullable|exists:suppliers,id', - 'asset_eol_date' => 'nullable|date', - 'eol_explicit' => 'nullable|boolean', - 'byod' => 'nullable|boolean', - 'order_number' => 'nullable|string|max:191', - 'notes' => 'nullable|string|max:65535', - 'assigned_to' => 'nullable|integer', - 'requestable' => 'nullable|boolean', - ]; - } + //public function getRulesAttribute() + //{ + // return [ + // 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', + // 'status_id' => 'required|integer|exists:status_labels,id', + // 'asset_tag' => [ + // 'required', + // 'min:1', + // 'max:255', + // Rule::unique('assets')->ignore(15)->withoutTrashed() + // ], + // 'name' => 'nullable|max:255', + // 'company_id' => 'nullable|integer|exists:companies,id', + // 'warranty_months' => 'nullable|numeric|digits_between:0,240', + // 'last_checkout' => 'nullable|date_format:Y-m-d H:i:s', + // 'expected_checkin' => 'nullable|date', + // 'location_id' => 'nullable|exists:locations,id', + // 'rtd_location_id' => 'nullable|exists:locations,id', + // 'purchase_date' => 'nullable|date|date_format:Y-m-d', + // 'serial' => 'nullable|unique_undeleted:assets,serial', + // 'purchase_cost' => 'nullable|numeric|gte:0', + // 'supplier_id' => 'nullable|exists:suppliers,id', + // 'asset_eol_date' => 'nullable|date', + // 'eol_explicit' => 'nullable|boolean', + // 'byod' => 'nullable|boolean', + // 'order_number' => 'nullable|string|max:191', + // 'notes' => 'nullable|string|max:65535', + // 'assigned_to' => 'nullable|integer', + // 'requestable' => 'nullable|boolean', + // ]; + //} /** * The attributes that are mass assignable. From f6ab0f8f463ecbc27f4e186fe16668a7811438e8 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 13 Mar 2024 15:57:10 -0500 Subject: [PATCH 010/207] lots of cleanup to do, but this DOES work --- app/Http/Requests/UpdateAssetRequest.php | 28 ++++++++++++++++++++---- app/Models/Asset.php | 2 +- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/app/Http/Requests/UpdateAssetRequest.php b/app/Http/Requests/UpdateAssetRequest.php index afee0fb90..71792b85f 100644 --- a/app/Http/Requests/UpdateAssetRequest.php +++ b/app/Http/Requests/UpdateAssetRequest.php @@ -4,6 +4,7 @@ namespace App\Http\Requests; use App\Models\Asset; use Illuminate\Support\Facades\Gate; +use Illuminate\Validation\Rule; class UpdateAssetRequest extends ImageUploadRequest { @@ -35,10 +36,29 @@ class UpdateAssetRequest extends ImageUploadRequest */ public function rules() { - $rules = array_merge( - (new Asset())->getRules(), - parent::rules(), - ); + $rules = [ + 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', + 'status_id' => 'required|integer|exists:status_labels,id', + 'asset_tag' => ['required', 'min:1', 'max:255', 'not_array', Rule::unique('assets', 'asset_tag')->ignore($this->asset)->withoutTrashed()], + 'name' => 'nullable|max:255', + 'company_id' => 'nullable|integer|exists:companies,id', + 'warranty_months' => 'nullable|numeric|digits_between:0,240', + 'last_checkout' => 'nullable|date_format:Y-m-d H:i:s', + 'expected_checkin' => 'nullable|date', + 'location_id' => 'nullable|exists:locations,id', + 'rtd_location_id' => 'nullable|exists:locations,id', + 'purchase_date' => 'nullable|date|date_format:Y-m-d', + 'serial' => 'nullable|unique_undeleted:assets,serial', + 'purchase_cost' => 'nullable|numeric|gte:0', + 'supplier_id' => 'nullable|exists:suppliers,id', + 'asset_eol_date' => 'nullable|date', + 'eol_explicit' => 'nullable|boolean', + 'byod' => 'nullable|boolean', + 'order_number' => 'nullable|string|max:191', + 'notes' => 'nullable|string|max:65535', + 'assigned_to' => 'nullable|integer', + 'requestable' => 'nullable|boolean', + ]; return $rules; } diff --git a/app/Models/Asset.php b/app/Models/Asset.php index c1ab89cb7..3219e50e1 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -92,7 +92,7 @@ class Asset extends Depreciable protected $rules = [ 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', 'status_id' => 'required|integer|exists:status_labels,id', - 'asset_tag' => 'required|min:1|max:255|not_array|unique:assets,asset_tag,asset,id,deleted_at,"NULL"', + 'asset_tag' => 'required|min:1|max:255|unique_undeleted:assets,asset_tag|not_array', 'name' => 'nullable|max:255', 'company_id' => 'nullable|integer|exists:companies,id', 'warranty_months' => 'nullable|numeric|digits_between:0,240', From 86ab880c90d2ef7249e0838222842e80e65aa5f1 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Tue, 19 Mar 2024 15:34:59 -0500 Subject: [PATCH 011/207] buncha progress --- database/factories/AssetFactory.php | 11 +++++ tests/Feature/Api/Assets/AssetStoreTest.php | 1 - tests/Feature/Api/Assets/AssetUpdateTest.php | 51 +++++++++++++++----- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/database/factories/AssetFactory.php b/database/factories/AssetFactory.php index 432495bcc..c010dfb52 100644 --- a/database/factories/AssetFactory.php +++ b/database/factories/AssetFactory.php @@ -48,6 +48,7 @@ class AssetFactory extends Factory 'assigned_type' => null, 'next_audit_date' => null, 'last_checkout' => null, + 'asset_eol_date' => null ]; } @@ -352,4 +353,14 @@ class AssetFactory extends Factory { return $this->state(['requestable' => false]); } + + public function noPurchaseOrEolDate() + { + return $this->afterCreating(function (Asset $asset) { + $asset->update([ + 'purchase_date' => null, + 'asset_eol_date' => null + ]); + }); + } } diff --git a/tests/Feature/Api/Assets/AssetStoreTest.php b/tests/Feature/Api/Assets/AssetStoreTest.php index 631944190..eee0da392 100644 --- a/tests/Feature/Api/Assets/AssetStoreTest.php +++ b/tests/Feature/Api/Assets/AssetStoreTest.php @@ -153,7 +153,6 @@ class AssetStoreTest extends TestCase ->assertOk() ->assertStatusMessageIs('success') ->json(); - return $response; $asset = Asset::find($response['payload']['id']); $this->assertEquals('2024-01-01', $asset->asset_eol_date); diff --git a/tests/Feature/Api/Assets/AssetUpdateTest.php b/tests/Feature/Api/Assets/AssetUpdateTest.php index bd5377efd..17bb72fa3 100644 --- a/tests/Feature/Api/Assets/AssetUpdateTest.php +++ b/tests/Feature/Api/Assets/AssetUpdateTest.php @@ -27,6 +27,16 @@ class AssetUpdateTest extends TestCase ->assertForbidden(); } + public function testGivenPermissionUpdateAssetIsAllower() + + { + $asset = Asset::factory()->create(); + + $this->actingAsForApi(User::factory()->editAssets()->create()) + ->patchJson(route('api.assets.update', $asset->id)) + ->assertOk(); + } + public function testAllAssetAttributesAreStored() { $asset = Asset::factory()->create(); @@ -89,29 +99,44 @@ class AssetUpdateTest extends TestCase $this->assertEquals(10, $updatedAsset->warranty_months); } - public function testArchivedDepreciateAndPhysicalCanBeNull() + public function testAssetEolDateIsCalculatedIfPurchaseDateUpdated() { - $model = AssetModel::factory()->ipadModel()->create(); - $status = Statuslabel::factory()->create(); + $model = AssetModel::factory()->mbp13Model()->create(); $asset = Asset::factory()->create(); $this->settings->enableAutoIncrement(); - $response = $this->actingAsForApi(User::factory()->superuser()->create()) - ->patchJson(route('api.assets.update', $asset->id), [ - 'archive' => null, - 'depreciate' => null, - 'physical' => null + $response = $this->actingAsForApi(User::factory()->editAssets()->create()) + ->patchJson((route('api.assets.update', $asset->id)), [ + 'model_id' => $model->id, + 'purchase_date' => '2021-01-01', ]) - ->dd() + //->dd() ->assertOk() ->assertStatusMessageIs('success') ->json(); - $asset = Asset::find($response['payload']['id']); - $this->assertEquals(0, $asset->archived); - $this->assertEquals(1, $asset->physical); - $this->assertEquals(0, $asset->depreciate); + $this->assertEquals('2024-01-01', $asset->asset_eol_date); + } + + public function testAssetEolDateIsNotCalculatedIfPurchaseDateNotSet() + { + $asset = Asset::factory()->laptopMbp()->noPurchaseOrEolDate()->create(); + + $this->settings->enableAutoIncrement(); + + $response = $this->actingAsForApi(User::factory()->editAssets()->create()) + ->patchJson(route('api.assets.update', $asset->id), [ + 'name' => 'test asset', + 'asset_eol_date' => '2022-01-01' + ]) + ->assertOk() + ->assertStatusMessageIs('success') + ->json(); + + $asset->refresh(); + + $this->assertEquals('2022-01-01', $asset->asset_eol_date); } } \ No newline at end of file From c0110e7f29bd6f3b68c7d07bdcacd1319ae8e2fa Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Tue, 19 Mar 2024 19:27:35 -0500 Subject: [PATCH 012/207] some more tests and refinement --- app/Http/Requests/UpdateAssetRequest.php | 12 +-- tests/Feature/Api/Assets/AssetUpdateTest.php | 93 +++++++++++++++++++- 2 files changed, 98 insertions(+), 7 deletions(-) diff --git a/app/Http/Requests/UpdateAssetRequest.php b/app/Http/Requests/UpdateAssetRequest.php index 71792b85f..97282036f 100644 --- a/app/Http/Requests/UpdateAssetRequest.php +++ b/app/Http/Requests/UpdateAssetRequest.php @@ -23,9 +23,9 @@ class UpdateAssetRequest extends ImageUploadRequest // the following are 'required' attributes that may or may not be present on an patch request // so supplying them here instead of doing funky array modification to the rules return $this->merge([ - 'asset_tag' => $this->asset_tag ?? $this->asset->asset_tag, - 'model_id' => $this->model_id ?? $this->asset->model_id, - 'status_id' => $this->status_id ?? $this->asset->status_id, + //'asset_tag' => $this->asset_tag ?? $this->asset->asset_tag, + //'model_id' => $this->model_id ?? $this->asset->model_id, + //'status_id' => $this->status_id ?? $this->asset->status_id, ]); } @@ -37,9 +37,9 @@ class UpdateAssetRequest extends ImageUploadRequest public function rules() { $rules = [ - 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', - 'status_id' => 'required|integer|exists:status_labels,id', - 'asset_tag' => ['required', 'min:1', 'max:255', 'not_array', Rule::unique('assets', 'asset_tag')->ignore($this->asset)->withoutTrashed()], + 'model_id' => 'integer|exists:models,id,deleted_at,NULL|not_array', + 'status_id' => 'integer|exists:status_labels,id', + 'asset_tag' => ['min:1', 'max:255', 'not_array', Rule::unique('assets', 'asset_tag')->ignore($this->asset)->withoutTrashed()], 'name' => 'nullable|max:255', 'company_id' => 'nullable|integer|exists:companies,id', 'warranty_months' => 'nullable|numeric|digits_between:0,240', diff --git a/tests/Feature/Api/Assets/AssetUpdateTest.php b/tests/Feature/Api/Assets/AssetUpdateTest.php index 17bb72fa3..79a9eb4e0 100644 --- a/tests/Feature/Api/Assets/AssetUpdateTest.php +++ b/tests/Feature/Api/Assets/AssetUpdateTest.php @@ -11,6 +11,8 @@ use App\Models\Supplier; use App\Models\User; use Carbon\Carbon; use Illuminate\Testing\Fluent\AssertableJson; + +// TODO: DELETE INTERACTSWITHSETTINGS BEFORE FINAL PR use Tests\Support\InteractsWithSettings; use Tests\TestCase; @@ -125,7 +127,7 @@ class AssetUpdateTest extends TestCase $this->settings->enableAutoIncrement(); - $response = $this->actingAsForApi(User::factory()->editAssets()->create()) + $this->actingAsForApi(User::factory()->editAssets()->create()) ->patchJson(route('api.assets.update', $asset->id), [ 'name' => 'test asset', 'asset_eol_date' => '2022-01-01' @@ -139,4 +141,93 @@ class AssetUpdateTest extends TestCase $this->assertEquals('2022-01-01', $asset->asset_eol_date); } + public function testAssetEolExplicitIsSetIfAssetEolDateIsExplicitlySet() + { + $asset = Asset::factory()->laptopMbp()->create(); + + $this->actingAsForApi(User::factory()->editAssets()->create()) + ->patchJson(route('api.assets.update', $asset->id), [ + 'asset_eol_date' => '2025-01-01', + ]) + ->assertOk() + ->assertStatusMessageIs('success') + ->json(); + + $asset->refresh(); + + $this->assertEquals('2025-01-01', $asset->asset_eol_date); + $this->assertTrue($asset->eol_explicit); + } + + public function testAssetTagCannotUpdateToNullValue() + { + $asset = Asset::factory()->laptopMbp()->create(); + + $this->actingAsForApi(User::factory()->editAssets()->create()) + ->patchJson(route('api.assets.update', $asset->id), [ + 'asset_tag' => null, + ]) + ->assertOk() + ->assertStatusMessageIs('error'); + } + + public function testAssetTagCannotUpdateToEmptyStringValue() + { + $asset = Asset::factory()->laptopMbp()->create(); + + $this->actingAsForApi(User::factory()->editAssets()->create()) + ->patchJson(route('api.assets.update', $asset->id), [ + 'asset_tag' => "", + ]) + ->assertOk() + ->assertStatusMessageIs('error'); + } + + public function testModelIdCannotUpdateToNullValue() + { + $asset = Asset::factory()->laptopMbp()->create(); + + $this->actingAsForApi(User::factory()->editAssets()->create()) + ->patchJson(route('api.assets.update', $asset->id), [ + 'model_id' => null + ]) + ->assertOk() + ->assertStatusMessageIs('error'); + } + + public function testModelIdCannotUpdateToEmptyStringValue() + { + $asset = Asset::factory()->laptopMbp()->create(); + + $this->actingAsForApi(User::factory()->editAssets()->create()) + ->patchJson(route('api.assets.update', $asset->id), [ + 'model_id' => "" + ]) + ->assertOk() + ->assertStatusMessageIs('error'); + } + + public function testStatusIdCannotUpdateToNullValue() + { + $asset = Asset::factory()->laptopMbp()->create(); + + $this->actingAsForApi(User::factory()->editAssets()->create()) + ->patchJson(route('api.assets.update', $asset->id), [ + 'status_id' => null + ]) + ->assertOk() + ->assertStatusMessageIs('error'); + } + + public function testStatusIdCannotUpdateToEmptyStringValue() + { + $asset = Asset::factory()->laptopMbp()->create(); + + $this->actingAsForApi(User::factory()->editAssets()->create()) + ->patchJson(route('api.assets.update', $asset->id), [ + 'status_id' => "" + ]) + ->assertOk() + ->assertStatusMessageIs('error'); + } } \ No newline at end of file From 1e810d24266d1f33940ace10b408318b7ebf5739 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Tue, 19 Mar 2024 19:47:26 -0500 Subject: [PATCH 013/207] most tests now passing, still one broken --- app/Http/Controllers/Api/AssetsController.php | 12 +++++------- tests/Feature/Api/Assets/AssetUpdateTest.php | 13 +++++++------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index bc415c0f3..f798232a7 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -629,14 +629,12 @@ class AssetsController extends Controller // this is _always_ filled now, see UpdateAssetRequest // i'm leaving it like this for now, but when would we ever want model_id to be `null`?? // it actually breaks at the model validation if it gets to null... - ($request->validated()['model_id']) ? + ($request->has('model_id')) ? $asset->model()->associate(AssetModel::find($request->validated()['model_id'])) : null; - //($request->validated()['rtd_location_id']) ? - // $asset->location_id = $request->validated()['rtd_location_id'] : ''; - //($request->validated()['company_id']) ? - // $asset->company_id = Company::getIdForCurrentUser($request->validated()['company_id']) : ''; - //($request->validated()['rtd_location_id']) ? - // $asset->location_id = $request->validated()['rtd_location_id'] : null; + ($request->has('company_id')) ? + $asset->company_id = Company::getIdForCurrentUser($request->validated()['company_id']) : null; + ($request->has('rtd_location_id')) ? + $asset->location_id = $request->validated()['rtd_location_id'] : null; /** * this is here just legacy reasons. Api\AssetController diff --git a/tests/Feature/Api/Assets/AssetUpdateTest.php b/tests/Feature/Api/Assets/AssetUpdateTest.php index 79a9eb4e0..c134c70db 100644 --- a/tests/Feature/Api/Assets/AssetUpdateTest.php +++ b/tests/Feature/Api/Assets/AssetUpdateTest.php @@ -29,13 +29,15 @@ class AssetUpdateTest extends TestCase ->assertForbidden(); } - public function testGivenPermissionUpdateAssetIsAllower() + public function testGivenPermissionUpdateAssetIsAllowed() { $asset = Asset::factory()->create(); $this->actingAsForApi(User::factory()->editAssets()->create()) - ->patchJson(route('api.assets.update', $asset->id)) + ->patchJson(route('api.assets.update', $asset->id), [ + 'name' => 'test' + ]) ->assertOk(); } @@ -103,21 +105,20 @@ class AssetUpdateTest extends TestCase public function testAssetEolDateIsCalculatedIfPurchaseDateUpdated() { - $model = AssetModel::factory()->mbp13Model()->create(); - $asset = Asset::factory()->create(); + $asset = Asset::factory()->laptopMbp()->create(); $this->settings->enableAutoIncrement(); $response = $this->actingAsForApi(User::factory()->editAssets()->create()) ->patchJson((route('api.assets.update', $asset->id)), [ - 'model_id' => $model->id, 'purchase_date' => '2021-01-01', ]) - //->dd() ->assertOk() ->assertStatusMessageIs('success') ->json(); + $asset->refresh(); + $this->assertEquals('2024-01-01', $asset->asset_eol_date); } From 0ffceb96918503fdd50fb677339f2ec854f07239 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 20 Mar 2024 00:07:52 -0500 Subject: [PATCH 014/207] some notes and a little progress --- app/Http/Controllers/Api/AssetsController.php | 5 +++-- tests/Feature/Api/Assets/AssetUpdateTest.php | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index f798232a7..f3715ce6a 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -633,8 +633,9 @@ class AssetsController extends Controller $asset->model()->associate(AssetModel::find($request->validated()['model_id'])) : null; ($request->has('company_id')) ? $asset->company_id = Company::getIdForCurrentUser($request->validated()['company_id']) : null; - ($request->has('rtd_location_id')) ? - $asset->location_id = $request->validated()['rtd_location_id'] : null; + // TODO: this seems like bad logic maybe? it means that if you submit an rtd_location_id and a location_id in the same request location_id is overwritten with rtd_location_id. seems wrong. + //($request->has('rtd_location_id')) ? + // $asset->location_id = $request->validated()['rtd_location_id'] : null; /** * this is here just legacy reasons. Api\AssetController diff --git a/tests/Feature/Api/Assets/AssetUpdateTest.php b/tests/Feature/Api/Assets/AssetUpdateTest.php index c134c70db..76f4a027f 100644 --- a/tests/Feature/Api/Assets/AssetUpdateTest.php +++ b/tests/Feature/Api/Assets/AssetUpdateTest.php @@ -81,14 +81,14 @@ class AssetUpdateTest extends TestCase $updatedAsset = Asset::find($response['payload']['id']); // TODO: this isn't working, i assume `adminuser` is the user that created asset + // maybe i don't need to test this on an update??? //$this->assertTrue($updatedAsset->adminuser->is($user)); $this->assertEquals('2024-06-02', $updatedAsset->asset_eol_date); $this->assertEquals('random_string', $updatedAsset->asset_tag); $this->assertEquals($userAssigned->id, $updatedAsset->assigned_to); $this->assertTrue($updatedAsset->company->is($company)); - // TODO: this doesn't work - //$this->assertTrue($updatedAsset->location->is($location)); + $this->assertTrue($updatedAsset->location->is($location)); $this->assertTrue($updatedAsset->model->is($model)); $this->assertEquals('A New Asset', $updatedAsset->name); $this->assertEquals('Some notes', $updatedAsset->notes); @@ -109,7 +109,7 @@ class AssetUpdateTest extends TestCase $this->settings->enableAutoIncrement(); - $response = $this->actingAsForApi(User::factory()->editAssets()->create()) + $this->actingAsForApi(User::factory()->editAssets()->create()) ->patchJson((route('api.assets.update', $asset->id)), [ 'purchase_date' => '2021-01-01', ]) @@ -119,6 +119,7 @@ class AssetUpdateTest extends TestCase $asset->refresh(); + // what's the problem here? logic problem? might need to skip this for this PR $this->assertEquals('2024-01-01', $asset->asset_eol_date); } From e1addc5aef8ce236029a88d8262b8d0b5693683c Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 20 Mar 2024 13:16:36 -0500 Subject: [PATCH 015/207] oops, typo from conflict resolve --- database/factories/AssetFactory.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/database/factories/AssetFactory.php b/database/factories/AssetFactory.php index 797839a55..3fa23e921 100644 --- a/database/factories/AssetFactory.php +++ b/database/factories/AssetFactory.php @@ -362,6 +362,8 @@ class AssetFactory extends Factory 'purchase_date' => null, 'asset_eol_date' => null ]); + }); + } /** * This allows bypassing model level validation if you want to purposefully * create an asset in an invalid state. Validation is turned back on From fdf0be09db2a85e497dc166ba1eb3fa0124fb179 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 20 Mar 2024 13:43:01 -0500 Subject: [PATCH 016/207] all tests passing --- app/Http/Requests/UpdateAssetRequest.php | 45 ++++++++++---------- tests/Feature/Api/Assets/AssetUpdateTest.php | 4 +- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/app/Http/Requests/UpdateAssetRequest.php b/app/Http/Requests/UpdateAssetRequest.php index 97282036f..33d69f2ba 100644 --- a/app/Http/Requests/UpdateAssetRequest.php +++ b/app/Http/Requests/UpdateAssetRequest.php @@ -36,30 +36,29 @@ class UpdateAssetRequest extends ImageUploadRequest */ public function rules() { - $rules = [ - 'model_id' => 'integer|exists:models,id,deleted_at,NULL|not_array', - 'status_id' => 'integer|exists:status_labels,id', + return [ + 'model_id' => ['integer', 'exists:models,id,deleted_at,NULL', 'not_array'], + 'status_id' => ['integer', 'exists:status_labels,id'], 'asset_tag' => ['min:1', 'max:255', 'not_array', Rule::unique('assets', 'asset_tag')->ignore($this->asset)->withoutTrashed()], - 'name' => 'nullable|max:255', - 'company_id' => 'nullable|integer|exists:companies,id', - 'warranty_months' => 'nullable|numeric|digits_between:0,240', - 'last_checkout' => 'nullable|date_format:Y-m-d H:i:s', - 'expected_checkin' => 'nullable|date', - 'location_id' => 'nullable|exists:locations,id', - 'rtd_location_id' => 'nullable|exists:locations,id', - 'purchase_date' => 'nullable|date|date_format:Y-m-d', - 'serial' => 'nullable|unique_undeleted:assets,serial', - 'purchase_cost' => 'nullable|numeric|gte:0', - 'supplier_id' => 'nullable|exists:suppliers,id', - 'asset_eol_date' => 'nullable|date', - 'eol_explicit' => 'nullable|boolean', - 'byod' => 'nullable|boolean', - 'order_number' => 'nullable|string|max:191', - 'notes' => 'nullable|string|max:65535', - 'assigned_to' => 'nullable|integer', - 'requestable' => 'nullable|boolean', + 'name' => ['nullable', 'max:255'], + 'company_id' => ['nullable', 'integer', 'exists:companies,id'], + 'warranty_months' => ['nullable', 'numeric', 'digits_between:0,240'], + 'last_checkout' => ['nullable', 'date_format:Y-m-d H:i:s'], + 'expected_checkin' => ['nullable', 'date'], + 'location_id' => ['nullable', 'exists:locations,id'], + 'rtd_location_id' => ['nullable', 'exists:locations,id'], + 'purchase_date' => ['nullable', 'date', 'date_format:Y-m-d'], + 'serial' => ['nullable', 'unique_undeleted:assets,serial'], + 'purchase_cost' => ['nullable', 'numeric', 'gte:0'], + 'supplier_id' => ['nullable', 'exists:suppliers,id'], + 'asset_eol_date' => ['nullable', 'date'], + 'eol_explicit' => ['nullable', 'boolean'], + 'byod' => ['nullable', 'boolean'], + 'order_number' => ['nullable', 'string', 'max:191'], + 'notes' => ['nullable', 'string', 'max:65535'], + 'assigned_to' => ['nullable', 'integer'], + 'requestable' => ['nullable', 'boolean'], + parent::rules(), ]; - - return $rules; } } diff --git a/tests/Feature/Api/Assets/AssetUpdateTest.php b/tests/Feature/Api/Assets/AssetUpdateTest.php index 76f4a027f..9cec10362 100644 --- a/tests/Feature/Api/Assets/AssetUpdateTest.php +++ b/tests/Feature/Api/Assets/AssetUpdateTest.php @@ -105,10 +105,11 @@ class AssetUpdateTest extends TestCase public function testAssetEolDateIsCalculatedIfPurchaseDateUpdated() { - $asset = Asset::factory()->laptopMbp()->create(); + $asset = Asset::factory()->laptopMbp()->noPurchaseOrEolDate()->create(); $this->settings->enableAutoIncrement(); + $this->actingAsForApi(User::factory()->editAssets()->create()) ->patchJson((route('api.assets.update', $asset->id)), [ 'purchase_date' => '2021-01-01', @@ -119,7 +120,6 @@ class AssetUpdateTest extends TestCase $asset->refresh(); - // what's the problem here? logic problem? might need to skip this for this PR $this->assertEquals('2024-01-01', $asset->asset_eol_date); } From c155e4a7c9f9fc647571578886a062cb2150c05b Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 20 Mar 2024 13:52:22 -0500 Subject: [PATCH 017/207] new test for not found assets --- tests/Feature/Api/Assets/AssetUpdateTest.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/Feature/Api/Assets/AssetUpdateTest.php b/tests/Feature/Api/Assets/AssetUpdateTest.php index 9cec10362..bea962b15 100644 --- a/tests/Feature/Api/Assets/AssetUpdateTest.php +++ b/tests/Feature/Api/Assets/AssetUpdateTest.php @@ -20,6 +20,13 @@ class AssetUpdateTest extends TestCase { use InteractsWithSettings; + public function testThatANonExistentAssetIdReturnsError() + { + $this->actingAsForApi(User::factory()->editAssets()->createAssets()->create()) + ->patchJson(route('api.assets.update', 123456789)) + ->assertStatusMessageIs('error'); + } + public function testRequiresPermissionToUpdateAsset() { $asset = Asset::factory()->create(); From d18aa1db98a67dea60e753a2af1405f680058b8d Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 20 Mar 2024 15:18:15 -0500 Subject: [PATCH 018/207] some more cleanup + tests --- app/Http/Controllers/Api/AssetsController.php | 27 ++++++------- app/Http/Requests/UpdateAssetRequest.php | 11 ------ tests/Feature/Api/Assets/AssetUpdateTest.php | 39 ++++++++++++++++++- 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index 299c2b43e..8c3474353 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -626,23 +626,22 @@ class AssetsController extends Controller * * @author [A. Gianotto] [] * @since [v4.0] - * @return \Illuminate\Http\JsonResponse */ - public function update(UpdateAssetRequest $request, Asset $asset) + public function update(UpdateAssetRequest $request, Asset $asset): JsonResponse { $asset->fill($request->validated()); - // TODO: how much of this can go in the validator? - // this is _always_ filled now, see UpdateAssetRequest - // i'm leaving it like this for now, but when would we ever want model_id to be `null`?? - // it actually breaks at the model validation if it gets to null... - ($request->has('model_id')) ? - $asset->model()->associate(AssetModel::find($request->validated()['model_id'])) : null; - ($request->has('company_id')) ? - $asset->company_id = Company::getIdForCurrentUser($request->validated()['company_id']) : null; - // TODO: this seems like bad logic maybe? it means that if you submit an rtd_location_id and a location_id in the same request location_id is overwritten with rtd_location_id. seems wrong. - //($request->has('rtd_location_id')) ? - // $asset->location_id = $request->validated()['rtd_location_id'] : null; + + if ($request->has('model_id')) { + $asset->model()->associate(AssetModel::find($request->validated()['model_id'])); + } + if ($request->has('company_id')) { + $asset->company_id = Company::getIdForCurrentUser($request->validated()['company_id']); + } + if ($request->has('rtd_location_id') && !$request->has('location_id')) { + $asset->location_id = $request->validated()['rtd_location_id']; + } + /** * this is here just legacy reasons. Api\AssetController @@ -695,8 +694,6 @@ class AssetsController extends Controller } return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200); - - // TODO: confirm that everything expects a _200_ model not found exception } diff --git a/app/Http/Requests/UpdateAssetRequest.php b/app/Http/Requests/UpdateAssetRequest.php index 33d69f2ba..fe22e1759 100644 --- a/app/Http/Requests/UpdateAssetRequest.php +++ b/app/Http/Requests/UpdateAssetRequest.php @@ -18,17 +18,6 @@ class UpdateAssetRequest extends ImageUploadRequest return Gate::allows('update', new Asset); } - public function prepareForValidation() - { - // the following are 'required' attributes that may or may not be present on an patch request - // so supplying them here instead of doing funky array modification to the rules - return $this->merge([ - //'asset_tag' => $this->asset_tag ?? $this->asset->asset_tag, - //'model_id' => $this->model_id ?? $this->asset->model_id, - //'status_id' => $this->status_id ?? $this->asset->status_id, - ]); - } - /** * Get the validation rules that apply to the request. * diff --git a/tests/Feature/Api/Assets/AssetUpdateTest.php b/tests/Feature/Api/Assets/AssetUpdateTest.php index bea962b15..773ba97e9 100644 --- a/tests/Feature/Api/Assets/AssetUpdateTest.php +++ b/tests/Feature/Api/Assets/AssetUpdateTest.php @@ -9,8 +9,6 @@ use App\Models\Location; use App\Models\Statuslabel; use App\Models\Supplier; use App\Models\User; -use Carbon\Carbon; -use Illuminate\Testing\Fluent\AssertableJson; // TODO: DELETE INTERACTSWITHSETTINGS BEFORE FINAL PR use Tests\Support\InteractsWithSettings; @@ -239,4 +237,41 @@ class AssetUpdateTest extends TestCase ->assertOk() ->assertStatusMessageIs('error'); } + + public function testIfRtdLocationIdIsSetWithoutLocationIdAssetReturnsToDefault() + { + $location = Location::factory()->create(); + $asset = Asset::factory()->laptopMbp()->create([ + 'location_id' => $location->id + ]); + $rtdLocation = Location::factory()->create(); + + $this->actingAsForApi(User::factory()->editAssets()->create()) + ->patchJson(route('api.assets.update', $asset->id), [ + 'rtd_location_id' => $rtdLocation->id + ]); + + $asset->refresh(); + + $this->assertTrue($asset->defaultLoc->is($rtdLocation)); + $this->assertTrue($asset->location->is($rtdLocation)); + } + + public function testIfLocationAndRtdLocationAreSetLocationIdIsLocation() + { + $location = Location::factory()->create(); + $asset = Asset::factory()->laptopMbp()->create(); + $rtdLocation = Location::factory()->create(); + + $this->actingAsForApi(User::factory()->editAssets()->create()) + ->patchJson(route('api.assets.update', $asset->id), [ + 'rtd_location_id' => $rtdLocation->id, + 'location_id' => $location->id + ]); + + $asset->refresh(); + + $this->assertTrue($asset->defaultLoc->is($rtdLocation)); + $this->assertTrue($asset->location->is($location)); + } } \ No newline at end of file From e3e01e07b14599b89c6de98b8d870d1dcaf9e409 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 20 Mar 2024 15:23:45 -0500 Subject: [PATCH 019/207] final cleanup --- app/Models/Asset.php | 38 +------------------- app/Providers/ValidationServiceProvider.php | 16 --------- tests/Feature/Api/Assets/AssetStoreTest.php | 1 - tests/Feature/Api/Assets/AssetUpdateTest.php | 4 --- 4 files changed, 1 insertion(+), 58 deletions(-) diff --git a/app/Models/Asset.php b/app/Models/Asset.php index 3219e50e1..806ecbb0c 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -113,38 +113,6 @@ class Asset extends Depreciable 'requestable' => 'nullable|boolean', ]; - //public function getRulesAttribute() - //{ - // return [ - // 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', - // 'status_id' => 'required|integer|exists:status_labels,id', - // 'asset_tag' => [ - // 'required', - // 'min:1', - // 'max:255', - // Rule::unique('assets')->ignore(15)->withoutTrashed() - // ], - // 'name' => 'nullable|max:255', - // 'company_id' => 'nullable|integer|exists:companies,id', - // 'warranty_months' => 'nullable|numeric|digits_between:0,240', - // 'last_checkout' => 'nullable|date_format:Y-m-d H:i:s', - // 'expected_checkin' => 'nullable|date', - // 'location_id' => 'nullable|exists:locations,id', - // 'rtd_location_id' => 'nullable|exists:locations,id', - // 'purchase_date' => 'nullable|date|date_format:Y-m-d', - // 'serial' => 'nullable|unique_undeleted:assets,serial', - // 'purchase_cost' => 'nullable|numeric|gte:0', - // 'supplier_id' => 'nullable|exists:suppliers,id', - // 'asset_eol_date' => 'nullable|date', - // 'eol_explicit' => 'nullable|boolean', - // 'byod' => 'nullable|boolean', - // 'order_number' => 'nullable|string|max:191', - // 'notes' => 'nullable|string|max:65535', - // 'assigned_to' => 'nullable|integer', - // 'requestable' => 'nullable|boolean', - // ]; - //} - /** * The attributes that are mass assignable. * @@ -244,12 +212,8 @@ class Asset extends Depreciable $this->{$field->db_column} = filter_var($this->{$field->db_column}, FILTER_VALIDATE_BOOLEAN); } } - $this->rules = array_merge( - $this->rules, - $model->fieldset->validation_rules(), - ); - //$this->rules += $model->fieldset->validation_rules(); + $this->rules += $model->fieldset->validation_rules(); if ($this->model->fieldset){ foreach ($this->model->fieldset->fields as $field){ diff --git a/app/Providers/ValidationServiceProvider.php b/app/Providers/ValidationServiceProvider.php index 172e99bf4..bf9f5c55c 100644 --- a/app/Providers/ValidationServiceProvider.php +++ b/app/Providers/ValidationServiceProvider.php @@ -63,7 +63,6 @@ class ValidationServiceProvider extends ServiceProvider * `unique_undeleted:table,fieldname` in your rules out of the box */ Validator::extend('unique_undeleted', function ($attribute, $value, $parameters, $validator) { - if (count($parameters)) { // This is a bit of a shim, but serial doesn't have any other rules around it other than that it's nullable @@ -79,21 +78,6 @@ class ValidationServiceProvider extends ServiceProvider return $count < 1; } - //else { - // if (($parameters[0] == 'assets') && ($attribute == 'serial') && (Setting::getSettings()->unique_serial != '1')) { - // return true; - // } - // - // $count = DB::table($parameters[0]) - // ->select('id') - // ->where($attribute, '=', $value) - // ->whereNull('deleted_at') - // ->where('id', '!=', $parameters[1]) - // ->where('id', '!=', $parameters[2]) - // ->count(); - // - // return $count < 1; - //} }); /** diff --git a/tests/Feature/Api/Assets/AssetStoreTest.php b/tests/Feature/Api/Assets/AssetStoreTest.php index eee0da392..92a58a500 100644 --- a/tests/Feature/Api/Assets/AssetStoreTest.php +++ b/tests/Feature/Api/Assets/AssetStoreTest.php @@ -149,7 +149,6 @@ class AssetStoreTest extends TestCase 'purchase_date' => '2021-01-01', 'status_id' => $status->id, ]) - //->dd() ->assertOk() ->assertStatusMessageIs('success') ->json(); diff --git a/tests/Feature/Api/Assets/AssetUpdateTest.php b/tests/Feature/Api/Assets/AssetUpdateTest.php index 773ba97e9..369f967ad 100644 --- a/tests/Feature/Api/Assets/AssetUpdateTest.php +++ b/tests/Feature/Api/Assets/AssetUpdateTest.php @@ -85,10 +85,6 @@ class AssetUpdateTest extends TestCase $updatedAsset = Asset::find($response['payload']['id']); - // TODO: this isn't working, i assume `adminuser` is the user that created asset - // maybe i don't need to test this on an update??? - //$this->assertTrue($updatedAsset->adminuser->is($user)); - $this->assertEquals('2024-06-02', $updatedAsset->asset_eol_date); $this->assertEquals('random_string', $updatedAsset->asset_tag); $this->assertEquals($userAssigned->id, $updatedAsset->assigned_to); From e7b990334123188ae0d7b79d0fb453715dea3f18 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 20 Mar 2024 15:29:06 -0500 Subject: [PATCH 020/207] delete some extra lines --- app/Http/Controllers/Api/AssetsController.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index 8c3474353..9463ebd2a 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -631,7 +631,6 @@ class AssetsController extends Controller { $asset->fill($request->validated()); - if ($request->has('model_id')) { $asset->model()->associate(AssetModel::find($request->validated()['model_id'])); } @@ -642,7 +641,6 @@ class AssetsController extends Controller $asset->location_id = $request->validated()['rtd_location_id']; } - /** * this is here just legacy reasons. Api\AssetController * used image_source once to allow encoded image uploads. @@ -669,7 +667,6 @@ class AssetsController extends Controller } } - if ($asset->save()) { if (($request->filled('assigned_user')) && ($target = User::find($request->get('assigned_user')))) { $location = $target->location_id; @@ -689,10 +686,8 @@ class AssetsController extends Controller if ($asset->image) { $asset->image = $asset->getImageUrl(); } - return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success'))); } - return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200); } From 8cc1397aced6596b83ceed81ca041c9475ce18e7 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 20 Mar 2024 15:36:53 -0500 Subject: [PATCH 021/207] rm a couple unnecessary --- tests/Feature/Api/Assets/AssetUpdateTest.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/Feature/Api/Assets/AssetUpdateTest.php b/tests/Feature/Api/Assets/AssetUpdateTest.php index 369f967ad..c130efc77 100644 --- a/tests/Feature/Api/Assets/AssetUpdateTest.php +++ b/tests/Feature/Api/Assets/AssetUpdateTest.php @@ -9,8 +9,6 @@ use App\Models\Location; use App\Models\Statuslabel; use App\Models\Supplier; use App\Models\User; - -// TODO: DELETE INTERACTSWITHSETTINGS BEFORE FINAL PR use Tests\Support\InteractsWithSettings; use Tests\TestCase; @@ -108,9 +106,6 @@ class AssetUpdateTest extends TestCase { $asset = Asset::factory()->laptopMbp()->noPurchaseOrEolDate()->create(); - $this->settings->enableAutoIncrement(); - - $this->actingAsForApi(User::factory()->editAssets()->create()) ->patchJson((route('api.assets.update', $asset->id)), [ 'purchase_date' => '2021-01-01', @@ -128,8 +123,6 @@ class AssetUpdateTest extends TestCase { $asset = Asset::factory()->laptopMbp()->noPurchaseOrEolDate()->create(); - $this->settings->enableAutoIncrement(); - $this->actingAsForApi(User::factory()->editAssets()->create()) ->patchJson(route('api.assets.update', $asset->id), [ 'name' => 'test asset', From be282dd0381704061f21c1fbadb37f7abecbe5d2 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Thu, 21 Mar 2024 09:26:45 -0500 Subject: [PATCH 022/207] resolve a couple issues --- app/Http/Controllers/Api/AssetsController.php | 2 +- app/Http/Requests/UpdateAssetRequest.php | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index 9463ebd2a..1b671386a 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -673,7 +673,7 @@ class AssetsController extends Controller } elseif (($request->filled('assigned_asset')) && ($target = Asset::find($request->get('assigned_asset')))) { $location = $target->location_id; - Asset::where('assigned_type', \App\Models\Asset::class)->where('assigned_to', $id) + Asset::where('assigned_type', \App\Models\Asset::class)->where('assigned_to', $asset->id) ->update(['location_id' => $target->location_id]); } elseif (($request->filled('assigned_location')) && ($target = Location::find($request->get('assigned_location')))) { $location = $target->id; diff --git a/app/Http/Requests/UpdateAssetRequest.php b/app/Http/Requests/UpdateAssetRequest.php index fe22e1759..edc9dd4af 100644 --- a/app/Http/Requests/UpdateAssetRequest.php +++ b/app/Http/Requests/UpdateAssetRequest.php @@ -25,7 +25,7 @@ class UpdateAssetRequest extends ImageUploadRequest */ public function rules() { - return [ + $rules = array_merge([ 'model_id' => ['integer', 'exists:models,id,deleted_at,NULL', 'not_array'], 'status_id' => ['integer', 'exists:status_labels,id'], 'asset_tag' => ['min:1', 'max:255', 'not_array', Rule::unique('assets', 'asset_tag')->ignore($this->asset)->withoutTrashed()], @@ -47,7 +47,9 @@ class UpdateAssetRequest extends ImageUploadRequest 'notes' => ['nullable', 'string', 'max:65535'], 'assigned_to' => ['nullable', 'integer'], 'requestable' => ['nullable', 'boolean'], - parent::rules(), - ]; + ], + parent::rules() + ); + return $rules; } } From 60ca634eff04967bfbebd13fa812003b4ddf2987 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Thu, 21 Mar 2024 12:04:53 -0500 Subject: [PATCH 023/207] remove interactswithsettings --- tests/Feature/Api/Assets/AssetUpdateTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Feature/Api/Assets/AssetUpdateTest.php b/tests/Feature/Api/Assets/AssetUpdateTest.php index c130efc77..3805f4b3d 100644 --- a/tests/Feature/Api/Assets/AssetUpdateTest.php +++ b/tests/Feature/Api/Assets/AssetUpdateTest.php @@ -9,12 +9,10 @@ use App\Models\Location; use App\Models\Statuslabel; use App\Models\Supplier; use App\Models\User; -use Tests\Support\InteractsWithSettings; use Tests\TestCase; class AssetUpdateTest extends TestCase { - use InteractsWithSettings; public function testThatANonExistentAssetIdReturnsError() { From 39c15b2868335e087e8b24bb36d4b8bc8e2ceb64 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 27 Mar 2024 10:35:25 -0500 Subject: [PATCH 024/207] reformat array --- app/Models/Asset.php | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/app/Models/Asset.php b/app/Models/Asset.php index 806ecbb0c..112c79aee 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -90,27 +90,27 @@ class Asset extends Depreciable ]; protected $rules = [ - 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', - 'status_id' => 'required|integer|exists:status_labels,id', - 'asset_tag' => 'required|min:1|max:255|unique_undeleted:assets,asset_tag|not_array', - 'name' => 'nullable|max:255', - 'company_id' => 'nullable|integer|exists:companies,id', + 'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array', + 'status_id' => 'required|integer|exists:status_labels,id', + 'asset_tag' => 'required|min:1|max:255|unique_undeleted:assets,asset_tag|not_array', + 'name' => 'nullable|max:255', + 'company_id' => 'nullable|integer|exists:companies,id', 'warranty_months' => 'nullable|numeric|digits_between:0,240', - 'last_checkout' => 'nullable|date_format:Y-m-d H:i:s', + 'last_checkout' => 'nullable|date_format:Y-m-d H:i:s', 'expected_checkin' => 'nullable|date', - 'location_id' => 'nullable|exists:locations,id', + 'location_id' => 'nullable|exists:locations,id', 'rtd_location_id' => 'nullable|exists:locations,id', - 'purchase_date' => 'nullable|date|date_format:Y-m-d', - 'serial' => 'nullable|unique_undeleted:assets,serial', - 'purchase_cost' => 'nullable|numeric|gte:0', - 'supplier_id' => 'nullable|exists:suppliers,id', - 'asset_eol_date' => 'nullable|date', - 'eol_explicit' => 'nullable|boolean', - 'byod' => 'nullable|boolean', - 'order_number' => 'nullable|string|max:191', - 'notes' => 'nullable|string|max:65535', - 'assigned_to' => 'nullable|integer', - 'requestable' => 'nullable|boolean', + 'purchase_date' => 'nullable|date|date_format:Y-m-d', + 'serial' => 'nullable|unique_undeleted:assets,serial', + 'purchase_cost' => 'nullable|numeric|gte:0', + 'supplier_id' => 'nullable|exists:suppliers,id', + 'asset_eol_date' => 'nullable|date', + 'eol_explicit' => 'nullable|boolean', + 'byod' => 'nullable|boolean', + 'order_number' => 'nullable|string|max:191', + 'notes' => 'nullable|string|max:65535', + 'assigned_to' => 'nullable|integer', + 'requestable' => 'nullable|boolean', ]; /** From 701411c1b9526bea7f8e8490655d12ac43040123 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 27 Mar 2024 13:53:57 -0500 Subject: [PATCH 025/207] get rid of a couple unnecessary changes --- app/Models/Asset.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Models/Asset.php b/app/Models/Asset.php index f9c9ce15e..fa5214181 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -18,7 +18,6 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Facades\Storage; -use Illuminate\Validation\Rule; use Watson\Validating\ValidatingTrait; /** @@ -115,7 +114,8 @@ class Asset extends Depreciable 'requestable' => 'nullable|boolean', ]; - /** + + /** * The attributes that are mass assignable. * * @var array From 1d4a7a7b025f054ecd74b3cc2db04fd41bd29d18 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 27 Mar 2024 14:05:30 -0500 Subject: [PATCH 026/207] added audit dates --- app/Http/Requests/UpdateAssetRequest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Http/Requests/UpdateAssetRequest.php b/app/Http/Requests/UpdateAssetRequest.php index edc9dd4af..2ca2a2b80 100644 --- a/app/Http/Requests/UpdateAssetRequest.php +++ b/app/Http/Requests/UpdateAssetRequest.php @@ -34,6 +34,8 @@ class UpdateAssetRequest extends ImageUploadRequest 'warranty_months' => ['nullable', 'numeric', 'digits_between:0,240'], 'last_checkout' => ['nullable', 'date_format:Y-m-d H:i:s'], 'expected_checkin' => ['nullable', 'date'], + 'last_audit_date' => 'nullable|date_format:Y-m-d H:i:s', + 'next_audit_date' => 'nullable|date|after:last_audit_date', 'location_id' => ['nullable', 'exists:locations,id'], 'rtd_location_id' => ['nullable', 'exists:locations,id'], 'purchase_date' => ['nullable', 'date', 'date_format:Y-m-d'], From cec84b857bf2e9089f811ee290f2ace80b0104a6 Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 27 Mar 2024 14:39:23 -0500 Subject: [PATCH 027/207] fixed last audit date + test --- app/Http/Controllers/Api/AssetsController.php | 3 +++ tests/Feature/Api/Assets/AssetUpdateTest.php | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index 38f135681..008e5dc2f 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -645,6 +645,9 @@ class AssetsController extends Controller if ($request->has('rtd_location_id') && !$request->has('location_id')) { $asset->location_id = $request->validated()['rtd_location_id']; } + if ($request->input('last_audit_date')) { + $asset->last_audit_date = Carbon::parse($request->input('last_audit_date'))->startOfDay()->format('Y-m-d H:i:s'); + } /** * this is here just legacy reasons. Api\AssetController diff --git a/tests/Feature/Api/Assets/AssetUpdateTest.php b/tests/Feature/Api/Assets/AssetUpdateTest.php index 3805f4b3d..ec00724cd 100644 --- a/tests/Feature/Api/Assets/AssetUpdateTest.php +++ b/tests/Feature/Api/Assets/AssetUpdateTest.php @@ -60,7 +60,7 @@ class AssetUpdateTest extends TestCase 'asset_tag' => 'random_string', 'assigned_user' => $userAssigned->id, 'company_id' => $company->id, - 'last_audit_date' => '2023-09-03', + 'last_audit_date' => '2023-09-03 12:23:45', 'location_id' => $location->id, 'model_id' => $model->id, 'name' => 'A New Asset', @@ -98,6 +98,7 @@ class AssetUpdateTest extends TestCase $this->assertTrue($updatedAsset->assetstatus->is($status)); $this->assertTrue($updatedAsset->supplier->is($supplier)); $this->assertEquals(10, $updatedAsset->warranty_months); + $this->assertEquals('2023-09-03 00:00:00', $updatedAsset->last_audit_date->format('Y-m-d H:i:s')); } public function testAssetEolDateIsCalculatedIfPurchaseDateUpdated() From f7bbec6be49c21c0319ab9046fb3e6450ac64281 Mon Sep 17 00:00:00 2001 From: "steve@degga.net" Date: Sun, 31 Mar 2024 22:18:44 -0400 Subject: [PATCH 028/207] Makes all manufacturer URLs dynamic, not just warranty lookup. --- app/Models/Manufacturer.php | 4 ++-- app/Presenters/AssetPresenter.php | 7 +++---- resources/views/hardware/view.blade.php | 20 ++++++++++---------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/app/Models/Manufacturer.php b/app/Models/Manufacturer.php index 5408d50c3..85907f7dd 100755 --- a/app/Models/Manufacturer.php +++ b/app/Models/Manufacturer.php @@ -22,9 +22,9 @@ class Manufacturer extends SnipeModel // Declare the rules for the form validation protected $rules = [ 'name' => 'required|min:2|max:255|unique:manufacturers,name,NULL,id,deleted_at,NULL', - 'url' => 'url|nullable', + 'url' => 'nullable|starts_with:http://,https://,afp://,facetime://,file://,irc://', 'support_email' => 'email|nullable', - 'support_url' => 'nullable|url', + 'support_url' => 'nullable|starts_with:http://,https://,afp://,facetime://,file://,irc://', 'warranty_lookup_url' => 'nullable|starts_with:http://,https://,afp://,facetime://,file://,irc://' ]; diff --git a/app/Presenters/AssetPresenter.php b/app/Presenters/AssetPresenter.php index 163ee1b60..16bb38417 100644 --- a/app/Presenters/AssetPresenter.php +++ b/app/Presenters/AssetPresenter.php @@ -556,13 +556,12 @@ class AssetPresenter extends Presenter } /** - * Used to take user created warranty URL and dynamically fill in the needed values per asset + * Used to take user created URL and dynamically fill in the needed values per asset * @return string */ - public function dynamicWarrantyUrl() + public function dynamicWarrantyUrl($dynamic_url) { - $warranty_lookup_url = $this->model->model->manufacturer->warranty_lookup_url; - $url = (str_replace('{LOCALE}',\App\Models\Setting::getSettings()->locale, $warranty_lookup_url)); + $url = (str_replace('{LOCALE}',\App\Models\Setting::getSettings()->locale, $dynamic_url)); $url = (str_replace('{SERIAL}', urlencode($this->model->serial), $url)); $url = (str_replace('{MODEL_NAME}', urlencode($this->model->model->name), $url)); $url = (str_replace('{MODEL_NUMBER}', urlencode($this->model->model->model_number), $url)); diff --git a/resources/views/hardware/view.blade.php b/resources/views/hardware/view.blade.php index 461f2a468..570cf2745 100755 --- a/resources/views/hardware/view.blade.php +++ b/resources/views/hardware/view.blade.php @@ -281,22 +281,22 @@
  • {{ $asset->model->manufacturer->name }}
  • @endcan - @if (($asset->model) && ($asset->model->manufacturer->url)) + @if (($asset->model->manufacturer) && ($asset->model->manufacturer->url!=''))
  • - - {{ $asset->model->manufacturer->url }} - + + {{ $asset->present()->dynamicUrl($asset->model->manufacturer->url) }} +
  • @endif - @if (($asset->model) && ($asset->model->manufacturer->support_url)) + @if (($asset->model->manufacturer) && ($asset->model->manufacturer->support_url!=''))
  • - - {{ $asset->model->manufacturer->support_url }} - + + {{$asset>present()>dynamicUrl($asset>model>manufacturer->support_url) }} +
  • @endif @@ -304,8 +304,8 @@ @if (($asset->model->manufacturer) && ($asset->model->manufacturer->warranty_lookup_url!=''))
  • - - {{ $asset->present()->dynamicWarrantyUrl() }} + + {{ $asset->present()->dynamicUrl($asset->model->manufacturer->warranty_lookup_url) }}
  • From 83ce04dc8dbcd6b9e137514e0d926da2dbfa93d2 Mon Sep 17 00:00:00 2001 From: "steve@degga.net" Date: Sun, 31 Mar 2024 22:31:06 -0400 Subject: [PATCH 029/207] Fixes syntax error. --- resources/views/hardware/view.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/hardware/view.blade.php b/resources/views/hardware/view.blade.php index 570cf2745..9100787dc 100755 --- a/resources/views/hardware/view.blade.php +++ b/resources/views/hardware/view.blade.php @@ -295,7 +295,7 @@
  • - {{$asset>present()>dynamicUrl($asset>model>manufacturer->support_url) }} + {{ $asset->present()->dynamicUrl($asset->model->manufacturer->support_url) }}
  • From bf10fd0cf03489168d919e5c48284588234710cb Mon Sep 17 00:00:00 2001 From: "steve@degga.net" Date: Sun, 31 Mar 2024 22:37:41 -0400 Subject: [PATCH 030/207] Rename dynamicUrl() method --- app/Presenters/AssetPresenter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Presenters/AssetPresenter.php b/app/Presenters/AssetPresenter.php index 16bb38417..b86135f33 100644 --- a/app/Presenters/AssetPresenter.php +++ b/app/Presenters/AssetPresenter.php @@ -559,7 +559,7 @@ class AssetPresenter extends Presenter * Used to take user created URL and dynamically fill in the needed values per asset * @return string */ - public function dynamicWarrantyUrl($dynamic_url) + public function dynamicUrl($dynamic_url) { $url = (str_replace('{LOCALE}',\App\Models\Setting::getSettings()->locale, $dynamic_url)); $url = (str_replace('{SERIAL}', urlencode($this->model->serial), $url)); From 0a90df2b14ed22109b4dce39208d53d6f50d37ac Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 3 Apr 2024 14:40:14 -0500 Subject: [PATCH 031/207] alright conflicts resolved --- app/Http/Controllers/Api/AssetsController.php | 39 +++++-------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index 29ae97579..28dcaab2f 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -658,11 +658,11 @@ class AssetsController extends Controller */ if ($request->has('image_source')) { $request->offsetSet('image', $request->offsetGet('image_source')); - } + } $asset = $request->handleImages($asset); $model = $asset->model; - + // Update custom fields if (($model) && (isset($model->fieldset))) { foreach ($model->fieldset->fields as $field) { @@ -692,43 +692,24 @@ class AssetsController extends Controller $location = $target->location_id; } elseif (($request->filled('assigned_asset')) && ($target = Asset::find($request->get('assigned_asset')))) { $location = $target->location_id; - - Asset::where('assigned_type', \App\Models\Asset::class)->where('assigned_to', $asset->id) + Asset::where('assigned_type', Asset::class)->where('assigned_to', $asset->id) ->update(['location_id' => $target->location_id]); } elseif (($request->filled('assigned_location')) && ($target = Location::find($request->get('assigned_location')))) { $location = $target->id; } - - if ($asset->save()) { - if (($request->filled('assigned_user')) && ($target = User::find($request->get('assigned_user')))) { - $location = $target->location_id; - } elseif (($request->filled('assigned_asset')) && ($target = Asset::find($request->get('assigned_asset')))) { - $location = $target->location_id; - - Asset::where('assigned_type', \App\Models\Asset::class)->where('assigned_to', $id) - ->update(['location_id' => $target->location_id]); - } elseif (($request->filled('assigned_location')) && ($target = Location::find($request->get('assigned_location')))) { - $location = $target->id; - } - - if (isset($target)) { - $asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name')), $location); - } - - if ($asset->image) { - $asset->image = $asset->getImageUrl(); - } - - return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success'))); - // commenting to make this clear, this was removed in favor of the above temporarily because it breaks jamf2snipe - // return response()->json(Helper::formatStandardApiResponse('success', (new AssetsTransformer)->transformAsset($asset), trans('admin/hardware/message.update.success'))); + if (isset($target)) { + $asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', + e($request->get('name')), $location); } if ($asset->image) { $asset->image = $asset->getImageUrl(); } - return response()->json(Helper::formatStandardApiResponse('success', (new AssetsTransformer)->transformAsset($asset), trans('admin/hardware/message.update.success'))); + + return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success'))); + // commenting to make this clear, this was removed in favor of the above temporarily because it breaks jamf2snipe + // return response()->json(Helper::formatStandardApiResponse('success', (new AssetsTransformer)->transformAsset($asset), trans('admin/hardware/message.update.success'))); } return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200); } From 3e564eaf192d4d9417bdac61acdd37db4e23cf05 Mon Sep 17 00:00:00 2001 From: "steve@degga.net" Date: Wed, 3 Apr 2024 20:09:37 -0400 Subject: [PATCH 032/207] fixed accidentally forgot update a call to the old dynamicWarrantyUrl() method in hardware/view.blade.php --- resources/views/hardware/view.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/hardware/view.blade.php b/resources/views/hardware/view.blade.php index 9100787dc..10be0f4b3 100755 --- a/resources/views/hardware/view.blade.php +++ b/resources/views/hardware/view.blade.php @@ -575,7 +575,7 @@ {{ trans('admin/hardware/form.months') }} @if (($asset->model) && ($asset->model->manufacturer) && ($asset->model->manufacturer->warranty_lookup_url!='')) - + @endif From 3fcc06748125bdc3d0ea99a4944885453807aff0 Mon Sep 17 00:00:00 2001 From: "steve@degga.net" Date: Thu, 4 Apr 2024 10:27:44 -0400 Subject: [PATCH 033/207] Removes accidental changes on two lines --- resources/views/hardware/view.blade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/views/hardware/view.blade.php b/resources/views/hardware/view.blade.php index 10be0f4b3..ec7d909aa 100755 --- a/resources/views/hardware/view.blade.php +++ b/resources/views/hardware/view.blade.php @@ -286,7 +286,7 @@ {{ $asset->present()->dynamicUrl($asset->model->manufacturer->url) }} - +