authorize('viewAny', Submission::class); $user = auth()->user(); $query = Submission::query()->with(['dataCentre', 'reportingCycle', 'consultant', 'assignedOfficer']); // Perunding: hanya serahan sendiri. if (! $user->can('serahan.lihat_semua')) { $query->where('consultant_id', $user->consultant?->id ?? 0); } if ($request->filled('cycle')) { $query->where('reporting_cycle_id', $request->cycle); } if ($request->filled('status')) { $query->where('status', $request->status); } if ($request->filled('consultant') && $user->can('serahan.lihat_semua')) { $query->where('consultant_id', $request->consultant); } $submissions = $query->latest()->paginate(15)->withQueryString(); $cycles = ReportingCycle::orderByDesc('renewal_year')->get(); return view('submissions.index', compact('submissions', 'cycles')); } /** Borang pilih pusat data + kitaran untuk memulakan serahan. */ public function create(Request $request) { $this->authorize('create', Submission::class); $consultant = auth()->user()->consultant; abort_unless($consultant, 403, 'Akaun anda tiada profil perunding.'); $dataCentres = DataCentre::where('current_consultant_id', $consultant->id)->aktif()->get(); $cycles = ReportingCycle::aktif()->orderByDesc('renewal_year')->get(); return view('submissions.create', compact('dataCentres', 'cycles')); } public function store(Request $request) { $this->authorize('create', Submission::class); $consultant = auth()->user()->consultant; abort_unless($consultant, 403); $data = $request->validate([ 'data_centre_id' => ['required', 'exists:data_centres,id'], 'reporting_cycle_id' => ['required', 'exists:reporting_cycles,id'], ], [], ['data_centre_id' => 'pusat data', 'reporting_cycle_id' => 'kitaran pelaporan']); $dataCentre = DataCentre::findOrFail($data['data_centre_id']); // Pastikan pusat data ini milik perunding. abort_unless((int) $dataCentre->current_consultant_id === (int) $consultant->id, 403, 'Anda tidak ditugaskan untuk pusat data ini.'); $cycle = ReportingCycle::findOrFail($data['reporting_cycle_id']); $submission = $this->workflow->findOrCreateDraft($dataCentre, $cycle); return redirect()->route('submissions.edit', $submission) ->with('success', 'Serahan draf disediakan. Sila lengkapkan senarai semak.'); } /** Borang pengisian senarai semak (perunding). */ public function edit(Submission $submission) { $this->authorize('update', $submission); $submission->load([ 'dataCentre', 'reportingCycle', 'checklistTemplate', 'answers', 'documents', 'correctionRequests', ]); $template = $submission->checklistTemplate; $template?->load(['sections.scopes', 'sections.items.scope', 'formulas']); $answers = $submission->answers->keyBy('checklist_item_id'); return view('submissions.fill', compact('submission', 'template', 'answers')); } public function update(Request $request, Submission $submission) { $this->authorize('update', $submission); $answers = $request->input('answers', []); $this->workflow->saveAnswers($submission, $answers); return back()->with('success', 'Draf senarai semak disimpan.'); } public function submit(Request $request, Submission $submission) { $this->authorize('update', $submission); // Simpan dahulu jawapan terkini jika dihantar bersama. if ($request->has('answers')) { $this->workflow->saveAnswers($submission, $request->input('answers', [])); } $this->workflow->submit($submission, auth()->user()); return redirect()->route('submissions.show', $submission) ->with('success', 'Serahan berjaya dihantar kepada JPP.'); } public function show(Submission $submission) { $this->authorize('view', $submission); $submission->load([ 'dataCentre', 'reportingCycle', 'consultant', 'assignedOfficer', 'checklistTemplate.sections.scopes', 'checklistTemplate.sections.items.scope', 'answers', 'results', 'documents.uploadedBy', 'statusHistories.changedBy', 'correctionRequests.item', 'correctionRequests.createdBy', 'comments.user', ]); $template = $submission->checklistTemplate; $answers = $submission->answers->keyBy('checklist_item_id'); $officers = \App\Models\User::role(['Pegawai JPP', 'Penolong Pegawai', 'Kerani', 'JPP Admin'])->get(); return view('submissions.show', compact('submission', 'template', 'answers', 'officers')); } }