From 2e8c51be9c3e7bbe24b4c454220425f27dc8738f Mon Sep 17 00:00:00 2001 From: snipe Date: Fri, 9 May 2025 11:35:30 +0100 Subject: [PATCH] First steps for #16883 - bulk asset auduting via API Signed-off-by: snipe --- app/Http/Controllers/Api/AssetsController.php | 53 ++++++++++++++----- routes/api.php | 2 +- tests/Feature/Assets/Api/AuditAssetTest.php | 30 +++++++++++ 3 files changed, 72 insertions(+), 13 deletions(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index 5f6e1d1a1403..55ce4ded98e7 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -1072,24 +1072,40 @@ public function checkinByTag(Request $request, $tag = null): JsonResponse * @since [v4.0] */ public function audit(Request $request, Asset $asset): JsonResponse - { + $this->authorize('audit', Asset::class); $settings = Setting::getSettings(); $dt = Carbon::now()->addMonths($settings->audit_interval)->toDateString(); - // Allow the asset tag to be passed in the payload (legacy method) + + // Allow the asset tag to be passed in the form payload if ($request->filled('asset_tag')) { - $asset = Asset::where('asset_tag', '=', $request->input('asset_tag'))->first(); + + // Check if it's an array or a string + if (is_array($request->input('asset_tag'))) { + $asset_tag = $request->input('asset_tag'); + $multi_audit = true; + \Log::error('Multi-audit'); + } else { + // If it's a string, make it into an array so we can use it in the whereIn query + $asset_tag = [$request->input('asset_tag')]; + $multi_audit = false; + \Log::error('Single audit'); + } + + $assets = Asset::whereIn('asset_tag', $asset_tag)->get(); } - if ($asset) { + foreach ($assets as $asset) { $originalValues = $asset->getRawOriginal(); $asset->next_audit_date = $dt; + $asset->last_audit_date = date('Y-m-d H:i:s'); + // Overwrite next_audit_date if it was specified in the request if ($request->filled('next_audit_date')) { $asset->next_audit_date = $request->input('next_audit_date'); } @@ -1100,15 +1116,25 @@ public function audit(Request $request, Asset $asset): JsonResponse $asset->location_id = $request->input('location_id'); } - $asset->last_audit_date = date('Y-m-d H:i:s'); // Set up the payload for re-display in the API response - $payload = [ - 'id' => $asset->id, - 'asset_tag' => $asset->asset_tag, - 'note' => $request->input('note'), - 'next_audit_date' => Helper::getFormattedDateObject($asset->next_audit_date), - ]; + + if ($multi_audit === true) { + $payload = [ + 'id' => $asset->id, + 'asset_tag' => $asset->asset_tag, + 'note' => $request->input('note'), + 'next_audit_date' => Helper::getFormattedDateObject($asset->next_audit_date), + ]; + } else { + $payload[] = [ + 'id' => $asset->id, + 'asset_tag' => $asset->asset_tag, + 'note' => $request->input('note'), + 'next_audit_date' => Helper::getFormattedDateObject($asset->next_audit_date), + ]; + } + /** @@ -1176,11 +1202,14 @@ public function audit(Request $request, Asset $asset): JsonResponse */ if ($asset->isValid() && $asset->save()) { $asset->logAudit(request('note'), request('location_id'), null, $originalValues); - return response()->json(Helper::formatStandardApiResponse('success', $payload, trans('admin/hardware/message.audit.success'))); } } + if (count($payload) > 0) { + return response()->json(Helper::formatStandardApiResponse('success', $payload, trans('admin/hardware/message.audit.success'))); + } + // No matching asset for the asset tag that was passed. return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200); diff --git a/routes/api.php b/routes/api.php index 60e7c3cddf1e..a154d011ab31 100644 --- a/routes/api.php +++ b/routes/api.php @@ -511,7 +511,7 @@ ->where(['action' => 'audit|audits|checkins', 'upcoming_status' => 'due|overdue|due-or-overdue']); - // Legacy URL for audit + // Bulk audit for RFID, also works as a legacy endpoint Route::post('audit', [ Api\AssetsController::class, diff --git a/tests/Feature/Assets/Api/AuditAssetTest.php b/tests/Feature/Assets/Api/AuditAssetTest.php index f93a65ae6d84..3fc40e189df7 100644 --- a/tests/Feature/Assets/Api/AuditAssetTest.php +++ b/tests/Feature/Assets/Api/AuditAssetTest.php @@ -53,6 +53,36 @@ public function testLegacyAssetAuditIsSaved() } + public function testAssetAuditWithTagsArrayIsSaved() + { + $asset1 = Asset::factory()->create(); + $asset2 = Asset::factory()->create(); + $asset3 = Asset::factory()->create(); + + $this->actingAsForApi(User::factory()->auditAssets()->create()) + ->postJson(route('api.asset.audit.legacy'), [ + 'asset_tag' => [ + $asset1->asset_tag, + $asset2->asset_tag, + $asset3->asset_tag + ], + 'note' => 'test', + ]) + ->assertStatusMessageIs('success') + ->assertJson( + [ + 'messages' =>trans('admin/hardware/message.audit.success'), + 'payload' => [ + 'id' => $asset1->id, + 'asset_tag' => $asset1->asset_tag, + 'note' => 'test' + ], + ]) + ->assertStatus(200); + + } + + public function testAssetAuditIsSaved() { $asset = Asset::factory()->create();