diff --git a/app/Http/Controllers/Api/Admin/EquipmentInspectionController.php b/app/Http/Controllers/Api/Admin/EquipmentInspectionController.php index dac92965..18276faa 100644 --- a/app/Http/Controllers/Api/Admin/EquipmentInspectionController.php +++ b/app/Http/Controllers/Api/Admin/EquipmentInspectionController.php @@ -148,6 +148,62 @@ public function updateNotes(Request $request): JsonResponse } } + public function resetInspection(Request $request): JsonResponse + { + $request->validate([ + 'equipment_id' => 'required|integer', + 'cycle' => 'required|string', + 'period' => 'required|string', + ]); + + try { + $deleted = $this->inspectionService->resetEquipmentInspection( + $request->input('equipment_id'), + $request->input('cycle'), + $request->input('period') + ); + + return response()->json([ + 'success' => true, + 'message' => "점검 데이터 {$deleted}건이 초기화되었습니다.", + 'data' => ['deleted' => $deleted], + ]); + } catch (\Exception $e) { + $status = $e->getMessage() === '점검 권한이 없습니다.' ? 403 : 400; + + return response()->json([ + 'success' => false, + 'message' => $e->getMessage(), + ], $status); + } + } + + public function resetAllInspections(Request $request): JsonResponse + { + $request->validate([ + 'cycle' => 'required|string', + 'period' => 'required|string', + ]); + + try { + $deleted = $this->inspectionService->resetAllInspections( + $request->input('cycle'), + $request->input('period') + ); + + return response()->json([ + 'success' => true, + 'message' => "전체 점검 데이터 {$deleted}건이 초기화되었습니다.", + 'data' => ['deleted' => $deleted], + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => $e->getMessage(), + ], 400); + } + } + public function storeTemplate(Request $request, int $equipmentId): JsonResponse { $request->validate([ diff --git a/app/Services/EquipmentInspectionService.php b/app/Services/EquipmentInspectionService.php index 91648655..e19416cf 100644 --- a/app/Services/EquipmentInspectionService.php +++ b/app/Services/EquipmentInspectionService.php @@ -224,6 +224,71 @@ public function updateInspectionNotes(int $equipmentId, string $yearMonth, array return $inspection->fresh(); } + /** + * 개별 설비 점검 데이터 초기화 (해당 주기/기간) + */ + public function resetEquipmentInspection(int $equipmentId, string $cycle, string $period): int + { + $equipment = Equipment::findOrFail($equipmentId); + if (! $equipment->canInspect()) { + throw new \Exception('점검 권한이 없습니다.'); + } + + $tenantId = session('selected_tenant_id', 1); + + $inspection = EquipmentInspection::where('tenant_id', $tenantId) + ->where('equipment_id', $equipmentId) + ->where('inspection_cycle', $cycle) + ->where('year_month', $period) + ->first(); + + if (! $inspection) { + return 0; + } + + $deleted = EquipmentInspectionDetail::where('inspection_id', $inspection->id)->delete(); + $inspection->update([ + 'overall_judgment' => null, + 'repair_note' => null, + 'issue_note' => null, + 'inspector_id' => null, + 'updated_by' => auth()->id(), + ]); + + return $deleted; + } + + /** + * 전체 점검 데이터 초기화 (해당 주기/기간의 모든 설비) + */ + public function resetAllInspections(string $cycle, string $period): int + { + $tenantId = session('selected_tenant_id', 1); + + $inspections = EquipmentInspection::where('tenant_id', $tenantId) + ->where('inspection_cycle', $cycle) + ->where('year_month', $period) + ->get(); + + if ($inspections->isEmpty()) { + return 0; + } + + $totalDeleted = 0; + foreach ($inspections as $inspection) { + $totalDeleted += EquipmentInspectionDetail::where('inspection_id', $inspection->id)->delete(); + $inspection->update([ + 'overall_judgment' => null, + 'repair_note' => null, + 'issue_note' => null, + 'inspector_id' => null, + 'updated_by' => auth()->id(), + ]); + } + + return $totalDeleted; + } + public function getMonthlyStats(string $yearMonth): array { $totalEquipments = Equipment::where('is_active', true) diff --git a/resources/views/equipment/inspections/index.blade.php b/resources/views/equipment/inspections/index.blade.php index 23b20453..e7632364 100644 --- a/resources/views/equipment/inspections/index.blade.php +++ b/resources/views/equipment/inspections/index.blade.php @@ -62,10 +62,13 @@ class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none foc @endforeach -
+
+
@@ -127,6 +130,77 @@ function updatePeriodValue() { } } + function getCurrentPeriod() { + if (currentCycle === 'daily') { + return document.getElementById('periodMonth').value; + } + return document.getElementById('periodYear').value; + } + + function resetEquipment(equipmentId, equipmentName) { + const period = getCurrentPeriod(); + showConfirm( + `${equipmentName}${period} 점검 데이터를 모두 초기화하시겠습니까?
이 작업은 되돌릴 수 없습니다.`, + function() { + fetch('/api/admin/equipment/inspections/reset', { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + 'X-CSRF-TOKEN': '{{ csrf_token() }}', + 'Accept': 'application/json', + }, + body: JSON.stringify({ + equipment_id: equipmentId, + cycle: currentCycle, + period: period, + }) + }) + .then(r => r.json()) + .then(data => { + if (data.success) { + showToast(data.message, 'success'); + htmx.trigger('#inspection-grid', 'filterSubmit'); + } else { + showToast(data.message || '초기화에 실패했습니다.', 'error'); + } + }); + }, + { title: '점검 초기화', icon: 'warning', confirmText: '초기화', cancelText: '취소' } + ); + } + + function resetAllInspections() { + const period = getCurrentPeriod(); + const cycleLabel = document.querySelector('.cycle-tab.bg-white')?.textContent?.trim() || currentCycle; + showConfirm( + `${period} ${cycleLabel} 점검의 전체 데이터를 초기화하시겠습니까?
모든 설비의 점검 기록이 삭제됩니다. 이 작업은 되돌릴 수 없습니다.`, + function() { + fetch('/api/admin/equipment/inspections/reset-all', { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + 'X-CSRF-TOKEN': '{{ csrf_token() }}', + 'Accept': 'application/json', + }, + body: JSON.stringify({ + cycle: currentCycle, + period: period, + }) + }) + .then(r => r.json()) + .then(data => { + if (data.success) { + showToast(data.message, 'success'); + htmx.trigger('#inspection-grid', 'filterSubmit'); + } else { + showToast(data.message || '초기화에 실패했습니다.', 'error'); + } + }); + }, + { title: '전체 점검 초기화', icon: 'warning', confirmText: '전체 초기화', cancelText: '취소' } + ); + } + function toggleCell(equipmentId, templateItemId, checkDate, cell) { fetch('/api/admin/equipment/inspections/detail', { method: 'PATCH', diff --git a/resources/views/equipment/partials/inspection-grid.blade.php b/resources/views/equipment/partials/inspection-grid.blade.php index 569413e3..e4e2b540 100644 --- a/resources/views/equipment/partials/inspection-grid.blade.php +++ b/resources/views/equipment/partials/inspection-grid.blade.php @@ -75,6 +75,12 @@ rowspan="{{ $rowCount }}" style="min-width: 80px;">
{{ $equipment->equipment_code }}
{{ Str::limit($equipment->name, 8) }}
+ @if($canInspect) + + @endif @endif diff --git a/routes/api.php b/routes/api.php index ffc7814f..822f0de5 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1030,6 +1030,8 @@ Route::patch('/inspections/detail', [\App\Http\Controllers\Api\Admin\EquipmentInspectionController::class, 'toggleDetail'])->name('inspections.toggle'); Route::patch('/inspections/notes', [\App\Http\Controllers\Api\Admin\EquipmentInspectionController::class, 'updateNotes'])->name('inspections.notes'); Route::patch('/inspections/set-result', [\App\Http\Controllers\Api\Admin\EquipmentInspectionController::class, 'setResult'])->name('inspections.set-result'); + Route::delete('/inspections/reset', [\App\Http\Controllers\Api\Admin\EquipmentInspectionController::class, 'resetInspection'])->name('inspections.reset'); + Route::delete('/inspections/reset-all', [\App\Http\Controllers\Api\Admin\EquipmentInspectionController::class, 'resetAllInspections'])->name('inspections.reset-all'); // 수리이력 Route::get('/repairs', [\App\Http\Controllers\Api\Admin\EquipmentRepairController::class, 'index'])->name('repairs.index');