where('status', '!=', 'disposed') ->with(['manager', 'subManager']); if ($productionLine) { $equipmentQuery->byLine($productionLine); } if ($equipmentId) { $equipmentQuery->where('id', $equipmentId); } $equipments = $equipmentQuery->orderBy('sort_order')->orderBy('name')->get(); $labels = InspectionCycle::columnLabels($cycle, $period); $userId = $this->apiUserId(); $result = []; foreach ($equipments as $equipment) { $templates = EquipmentInspectionTemplate::where('equipment_id', $equipment->id) ->byCycle($cycle) ->active() ->orderBy('sort_order') ->get(); if ($templates->isEmpty()) { continue; } $inspection = EquipmentInspection::where('equipment_id', $equipment->id) ->where('inspection_cycle', $cycle) ->where('year_month', $period) ->first(); $details = []; if ($inspection) { $details = EquipmentInspectionDetail::where('inspection_id', $inspection->id) ->get() ->groupBy(function ($d) { return $d->template_item_id.'_'.$d->check_date->format('Y-m-d'); }); } $result[] = [ 'equipment' => $equipment, 'templates' => $templates, 'inspection' => $inspection, 'details' => $details, 'labels' => $labels, 'can_inspect' => $equipment->canInspect($userId), ]; } return $result; } public function toggleDetail(int $equipmentId, int $templateItemId, string $checkDate, string $cycle = 'daily'): array { return DB::transaction(function () use ($equipmentId, $templateItemId, $checkDate, $cycle) { $equipment = Equipment::find($equipmentId); if (! $equipment) { throw new NotFoundHttpException(__('error.equipment.not_found')); } $userId = $this->apiUserId(); if (! $equipment->canInspect($userId)) { throw new AccessDeniedHttpException(__('error.equipment.no_inspect_permission')); } $period = InspectionCycle::resolvePeriod($cycle, $checkDate); if ($cycle === InspectionCycle::DAILY) { $tenantId = $this->tenantId(); $holidayDates = InspectionCycle::getHolidayDates($cycle, $period, $tenantId); if (InspectionCycle::isNonWorkingDay($checkDate, $holidayDates)) { throw new BadRequestHttpException(__('error.equipment.non_working_day')); } } $tenantId = $this->tenantId(); $inspection = EquipmentInspection::firstOrCreate( [ 'tenant_id' => $tenantId, 'equipment_id' => $equipmentId, 'inspection_cycle' => $cycle, 'year_month' => $period, ], [ 'created_by' => $userId, ] ); $detail = EquipmentInspectionDetail::where('inspection_id', $inspection->id) ->where('template_item_id', $templateItemId) ->where('check_date', $checkDate) ->first(); if ($detail) { $nextResult = EquipmentInspectionDetail::getNextResult($detail->result); if ($nextResult === null) { $detail->delete(); return ['result' => null, 'symbol' => '']; } $detail->update(['result' => $nextResult]); } else { $detail = EquipmentInspectionDetail::create([ 'inspection_id' => $inspection->id, 'template_item_id' => $templateItemId, 'check_date' => $checkDate, 'result' => 'good', ]); $nextResult = 'good'; } return [ 'result' => $nextResult, 'symbol' => EquipmentInspectionDetail::getResultSymbol($nextResult), ]; }); } public function setResult(int $equipmentId, int $templateItemId, string $checkDate, string $cycle, ?string $result): array { return DB::transaction(function () use ($equipmentId, $templateItemId, $checkDate, $cycle, $result) { $equipment = Equipment::find($equipmentId); if (! $equipment) { throw new NotFoundHttpException(__('error.equipment.not_found')); } $userId = $this->apiUserId(); if (! $equipment->canInspect($userId)) { throw new AccessDeniedHttpException(__('error.equipment.no_inspect_permission')); } $period = InspectionCycle::resolvePeriod($cycle, $checkDate); if ($cycle === InspectionCycle::DAILY) { $tenantId = $this->tenantId(); $holidayDates = InspectionCycle::getHolidayDates($cycle, $period, $tenantId); if (InspectionCycle::isNonWorkingDay($checkDate, $holidayDates)) { throw new BadRequestHttpException(__('error.equipment.non_working_day')); } } $tenantId = $this->tenantId(); $inspection = EquipmentInspection::firstOrCreate( [ 'tenant_id' => $tenantId, 'equipment_id' => $equipmentId, 'inspection_cycle' => $cycle, 'year_month' => $period, ], [ 'created_by' => $userId, ] ); $detail = EquipmentInspectionDetail::where('inspection_id', $inspection->id) ->where('template_item_id', $templateItemId) ->where('check_date', $checkDate) ->first(); if ($result === null) { if ($detail) { $detail->delete(); } return ['result' => null, 'symbol' => '']; } if ($detail) { $detail->update(['result' => $result]); } else { $detail = EquipmentInspectionDetail::create([ 'inspection_id' => $inspection->id, 'template_item_id' => $templateItemId, 'check_date' => $checkDate, 'result' => $result, ]); } return [ 'result' => $result, 'symbol' => EquipmentInspectionDetail::getResultSymbol($result), ]; }); } public function updateNotes(int $equipmentId, string $yearMonth, array $data, string $cycle = 'daily'): EquipmentInspection { return DB::transaction(function () use ($equipmentId, $yearMonth, $data, $cycle) { $tenantId = $this->tenantId(); $userId = $this->apiUserId(); $inspection = EquipmentInspection::firstOrCreate( [ 'tenant_id' => $tenantId, 'equipment_id' => $equipmentId, 'inspection_cycle' => $cycle, 'year_month' => $yearMonth, ], [ 'created_by' => $userId, ] ); $inspection->update($data); return $inspection->fresh(); }); } public function resetInspection(int $equipmentId, string $cycle, string $period): int { return DB::transaction(function () use ($equipmentId, $cycle, $period) { $equipment = Equipment::find($equipmentId); if (! $equipment) { throw new NotFoundHttpException(__('error.equipment.not_found')); } $userId = $this->apiUserId(); if (! $equipment->canInspect($userId)) { throw new AccessDeniedHttpException(__('error.equipment.no_inspect_permission')); } $tenantId = $this->tenantId(); $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, ]); return $deleted; }); } public function saveTemplate(int $equipmentId, array $data): EquipmentInspectionTemplate { return DB::transaction(function () use ($equipmentId, $data) { $tenantId = $this->tenantId(); return EquipmentInspectionTemplate::create(array_merge($data, [ 'tenant_id' => $tenantId, 'equipment_id' => $equipmentId, ])); }); } public function updateTemplate(int $id, array $data): EquipmentInspectionTemplate { return DB::transaction(function () use ($id, $data) { $template = EquipmentInspectionTemplate::find($id); if (! $template) { throw new NotFoundHttpException(__('error.equipment.template_not_found')); } $template->update($data); return $template->fresh(); }); } public function deleteTemplate(int $id): bool { return DB::transaction(function () use ($id) { $template = EquipmentInspectionTemplate::find($id); if (! $template) { throw new NotFoundHttpException(__('error.equipment.template_not_found')); } return $template->delete(); }); } public function copyTemplates(int $equipmentId, string $sourceCycle, array $targetCycles): array { return DB::transaction(function () use ($equipmentId, $sourceCycle, $targetCycles) { $tenantId = $this->tenantId(); $sourceTemplates = EquipmentInspectionTemplate::where('equipment_id', $equipmentId) ->byCycle($sourceCycle) ->active() ->orderBy('sort_order') ->get(); if ($sourceTemplates->isEmpty()) { throw new BadRequestHttpException(__('error.equipment.no_source_templates')); } $copiedCount = 0; $skippedCount = 0; foreach ($targetCycles as $targetCycle) { foreach ($sourceTemplates as $template) { $exists = EquipmentInspectionTemplate::where('equipment_id', $equipmentId) ->where('inspection_cycle', $targetCycle) ->where('item_no', $template->item_no) ->exists(); if ($exists) { $skippedCount++; continue; } EquipmentInspectionTemplate::create([ 'tenant_id' => $tenantId, 'equipment_id' => $equipmentId, 'inspection_cycle' => $targetCycle, 'item_no' => $template->item_no, 'check_point' => $template->check_point, 'check_item' => $template->check_item, 'check_timing' => $template->check_timing, 'check_frequency' => $template->check_frequency, 'check_method' => $template->check_method, 'sort_order' => $template->sort_order, 'is_active' => true, ]); $copiedCount++; } } return [ 'copied' => $copiedCount, 'skipped' => $skippedCount, 'source_count' => $sourceTemplates->count(), 'target_cycles' => $targetCycles, ]; }); } public function getTemplatesByEquipment(int $equipmentId, ?string $cycle = null): \Illuminate\Database\Eloquent\Collection { return EquipmentInspectionTemplate::where('equipment_id', $equipmentId) ->when($cycle, fn ($q) => $q->byCycle($cycle)) ->active() ->orderBy('sort_order') ->get(); } public function getActiveCycles(int $equipmentId): array { return EquipmentInspectionTemplate::where('equipment_id', $equipmentId) ->active() ->distinct() ->pluck('inspection_cycle') ->toArray(); } }