input('date', now()->toDateString()); $company = $request->input('company') ?? ''; $report = PmisDailyWorkReport::tenant($this->tenantId()) ->where('date', $date) ->when($company, fn ($q) => $q->where('company_name', $company)) ->first(); if (! $report) { $report = PmisDailyWorkReport::create([ 'tenant_id' => $this->tenantId(), 'date' => $date, 'company_name' => $company, 'weather' => '맑음', 'status' => 'draft', ]); } $report->load(['workers', 'equipments', 'materials', 'volumes', 'photos']); return response()->json($report); } public function monthStatus(Request $request): JsonResponse { $year = $request->integer('year', now()->year); $month = $request->integer('month', now()->month); $company = $request->input('company') ?? ''; $reports = PmisDailyWorkReport::tenant($this->tenantId()) ->whereYear('date', $year) ->whereMonth('date', $month) ->when($company, fn ($q) => $q->where('company_name', $company)) ->withCount(['workers', 'equipments', 'materials', 'volumes', 'photos']) ->get(); $result = []; foreach ($reports as $r) { $day = (int) $r->date->format('d'); $hasData = $r->workers_count > 0 || $r->equipments_count > 0 || $r->materials_count > 0 || $r->volumes_count > 0 || $r->photos_count > 0 || $r->work_content_today; if ($hasData) { $result[$day] = $r->status; } } return response()->json($result); } public function update(Request $request, int $id): JsonResponse { $report = PmisDailyWorkReport::tenant($this->tenantId())->findOrFail($id); $validated = $request->validate([ 'weather' => 'sometimes|string|max:50', 'temp_low' => 'sometimes|nullable|numeric', 'temp_high' => 'sometimes|nullable|numeric', 'precipitation' => 'sometimes|nullable|numeric', 'snowfall' => 'sometimes|nullable|numeric', 'fine_dust' => 'sometimes|nullable|string|max:50', 'ultra_fine_dust' => 'sometimes|nullable|string|max:50', 'work_content_today' => 'sometimes|nullable|string', 'work_content_tomorrow' => 'sometimes|nullable|string', 'notes' => 'sometimes|nullable|string', 'status' => 'sometimes|in:draft,review,approved', 'options' => 'sometimes|nullable|array', ]); // NOT NULL string 컬럼의 null → 빈 문자열 변환 foreach (['fine_dust', 'ultra_fine_dust', 'weather'] as $col) { if (array_key_exists($col, $validated) && $validated[$col] === null) { $validated[$col] = ''; } } $report->update($validated); $report->load(['workers', 'equipments', 'materials', 'volumes', 'photos']); return response()->json($report); } public function destroy(int $id): JsonResponse { $report = PmisDailyWorkReport::tenant($this->tenantId())->findOrFail($id); $report->delete(); return response()->json(['message' => '삭제되었습니다.']); } public function saveReviewers(Request $request, int $id): JsonResponse { $report = PmisDailyWorkReport::tenant($this->tenantId())->findOrFail($id); $reviewers = $request->input('reviewers', []); $options = $report->options ?? []; $options['reviewers'] = $reviewers; $report->update(['options' => $options]); return response()->json(['message' => '검토자가 저장되었습니다.']); } // ─── Worker CRUD ─── public function workerStore(Request $request): JsonResponse { $v = $request->validate([ 'report_id' => 'required|integer|exists:pmis_daily_work_reports,id', 'work_type' => 'required|string|max:200', 'job_type' => 'required|string|max:200', 'prev_cumulative' => 'nullable|integer|min:0', 'today_count' => 'nullable|integer|min:0', ]); $v['tenant_id'] = $this->tenantId(); $v['prev_cumulative'] = $v['prev_cumulative'] ?? 0; $v['today_count'] = $v['today_count'] ?? 0; $v['sort_order'] = (PmisWorkReportWorker::where('report_id', $v['report_id'])->max('sort_order') ?? 0) + 1; return response()->json(PmisWorkReportWorker::create($v), 201); } public function workerUpdate(Request $request, int $id): JsonResponse { $w = PmisWorkReportWorker::where('tenant_id', $this->tenantId())->findOrFail($id); $w->update($request->validate([ 'work_type' => 'sometimes|string|max:200', 'job_type' => 'sometimes|string|max:200', 'prev_cumulative' => 'nullable|integer|min:0', 'today_count' => 'nullable|integer|min:0', ])); return response()->json($w); } public function workerDestroy(int $id): JsonResponse { PmisWorkReportWorker::where('tenant_id', $this->tenantId())->findOrFail($id)->delete(); return response()->json(['message' => '삭제되었습니다.']); } // ─── Equipment CRUD ─── public function equipmentStore(Request $request): JsonResponse { $v = $request->validate([ 'report_id' => 'required|integer|exists:pmis_daily_work_reports,id', 'equipment_name' => 'required|string|max:200', 'specification' => 'nullable|string|max:300', 'prev_cumulative' => 'nullable|integer|min:0', 'today_count' => 'nullable|integer|min:0', ]); $v['tenant_id'] = $this->tenantId(); $v['specification'] = $v['specification'] ?? ''; $v['prev_cumulative'] = $v['prev_cumulative'] ?? 0; $v['today_count'] = $v['today_count'] ?? 0; $v['sort_order'] = (PmisWorkReportEquipment::where('report_id', $v['report_id'])->max('sort_order') ?? 0) + 1; return response()->json(PmisWorkReportEquipment::create($v), 201); } public function equipmentUpdate(Request $request, int $id): JsonResponse { $e = PmisWorkReportEquipment::where('tenant_id', $this->tenantId())->findOrFail($id); $e->update($request->validate([ 'equipment_name' => 'sometimes|string|max:200', 'specification' => 'nullable|string|max:300', 'prev_cumulative' => 'nullable|integer|min:0', 'today_count' => 'nullable|integer|min:0', ])); return response()->json($e); } public function equipmentDestroy(int $id): JsonResponse { PmisWorkReportEquipment::where('tenant_id', $this->tenantId())->findOrFail($id)->delete(); return response()->json(['message' => '삭제되었습니다.']); } // ─── Material CRUD ─── public function materialStore(Request $request): JsonResponse { $v = $request->validate([ 'report_id' => 'required|integer|exists:pmis_daily_work_reports,id', 'material_name' => 'required|string|max:200', 'specification' => 'nullable|string|max:300', 'unit' => 'nullable|string|max:50', 'design_qty' => 'nullable|numeric|min:0', 'prev_cumulative' => 'nullable|numeric|min:0', 'today_count' => 'nullable|numeric|min:0', ]); $v['tenant_id'] = $this->tenantId(); $v['sort_order'] = (PmisWorkReportMaterial::where('report_id', $v['report_id'])->max('sort_order') ?? 0) + 1; return response()->json(PmisWorkReportMaterial::create($v), 201); } public function materialUpdate(Request $request, int $id): JsonResponse { $m = PmisWorkReportMaterial::where('tenant_id', $this->tenantId())->findOrFail($id); $m->update($request->validate([ 'material_name' => 'sometimes|string|max:200', 'specification' => 'nullable|string|max:300', 'unit' => 'nullable|string|max:50', 'design_qty' => 'nullable|numeric|min:0', 'prev_cumulative' => 'nullable|numeric|min:0', 'today_count' => 'nullable|numeric|min:0', ])); return response()->json($m); } public function materialDestroy(int $id): JsonResponse { PmisWorkReportMaterial::where('tenant_id', $this->tenantId())->findOrFail($id)->delete(); return response()->json(['message' => '삭제되었습니다.']); } // ─── Volume CRUD ─── public function volumeStore(Request $request): JsonResponse { $v = $request->validate([ 'report_id' => 'required|integer|exists:pmis_daily_work_reports,id', 'work_type' => 'required|string|max:200', 'sub_work_type' => 'nullable|string|max:200', 'unit' => 'nullable|string|max:50', 'design_qty' => 'nullable|numeric|min:0', 'prev_cumulative' => 'nullable|numeric|min:0', 'today_count' => 'nullable|numeric|min:0', ]); $v['tenant_id'] = $this->tenantId(); $v['sort_order'] = (PmisWorkReportVolume::where('report_id', $v['report_id'])->max('sort_order') ?? 0) + 1; return response()->json(PmisWorkReportVolume::create($v), 201); } public function volumeUpdate(Request $request, int $id): JsonResponse { $vol = PmisWorkReportVolume::where('tenant_id', $this->tenantId())->findOrFail($id); $vol->update($request->validate([ 'work_type' => 'sometimes|string|max:200', 'sub_work_type' => 'nullable|string|max:200', 'unit' => 'nullable|string|max:50', 'design_qty' => 'nullable|numeric|min:0', 'prev_cumulative' => 'nullable|numeric|min:0', 'today_count' => 'nullable|numeric|min:0', ])); return response()->json($vol); } public function volumeDestroy(int $id): JsonResponse { PmisWorkReportVolume::where('tenant_id', $this->tenantId())->findOrFail($id)->delete(); return response()->json(['message' => '삭제되었습니다.']); } // ─── Photo CRUD ─── public function photoStore(Request $request): JsonResponse { $v = $request->validate([ 'report_id' => 'required|integer|exists:pmis_daily_work_reports,id', 'location' => 'nullable|string|max:200', 'content' => 'nullable|string|max:500', 'photo' => 'nullable|image|max:10240', ]); $path = ''; if ($request->hasFile('photo')) { $path = $request->file('photo')->store('pmis/work-report-photos', 'public'); } $photo = PmisWorkReportPhoto::create([ 'tenant_id' => $this->tenantId(), 'report_id' => $v['report_id'], 'photo_path' => $path, 'location' => $v['location'] ?? '', 'content' => $v['content'] ?? '', 'photo_date' => now()->toDateString(), 'sort_order' => (PmisWorkReportPhoto::where('report_id', $v['report_id'])->max('sort_order') ?? 0) + 1, ]); return response()->json($photo, 201); } public function photoDestroy(int $id): JsonResponse { PmisWorkReportPhoto::where('tenant_id', $this->tenantId())->findOrFail($id)->delete(); return response()->json(['message' => '삭제되었습니다.']); } }