authorizeAp('ap.sop.view'); $cycles = SopCycle::forBusiness($this->businessId()) ->orderByDesc('cycle_month') ->paginate(20); return view('advancedplanning::sop_cycles.index', compact('cycles')); } public function create() { $this->authorizeAp('ap.sop.manage'); $defaultMonth = now()->startOfMonth()->format('Y-m'); return view('advancedplanning::sop_cycles.create', compact('defaultMonth')); } public function store(Request $request) { $this->authorizeAp('ap.sop.manage'); $data = $request->validate([ 'cycle_month' => 'required|date_format:Y-m', 'notes' => 'nullable|string', ]); $cycle = $this->sopService->createCycle( $this->businessId(), Carbon::createFromFormat('Y-m', $data['cycle_month'])->startOfMonth() ); if (! empty($data['notes'])) { $cycle->update(['notes' => $data['notes']]); } $this->sopService->refreshPlans($cycle); return redirect()->action([self::class, 'show'], $cycle->id)->with('status', [ 'success' => true, 'msg' => __('advancedplanning::lang.sop_cycle_created'), ]); } public function show(int $id) { $this->authorizeAp('ap.sop.view'); $cycle = SopCycle::forBusiness($this->businessId()) ->with('createdBy') ->findOrFail($id); return view('advancedplanning::sop_cycles.show', compact('cycle')); } public function refresh(int $id) { $this->authorizeAp('ap.sop.manage'); $cycle = SopCycle::forBusiness($this->businessId())->findOrFail($id); $this->sopService->refreshPlans($cycle); return back()->with('status', [ 'success' => true, 'msg' => __('advancedplanning::lang.sop_plans_refreshed'), ]); } public function advanceStatus(Request $request, int $id) { $this->authorizeAp('ap.sop.manage'); $data = $request->validate([ 'status' => 'required|in:draft,consensus,approved', ]); $cycle = SopCycle::forBusiness($this->businessId())->findOrFail($id); try { $this->sopService->advanceStatus($cycle, $data['status']); } catch (\InvalidArgumentException $e) { return back()->with('status', ['success' => false, 'msg' => $e->getMessage()]); } return back()->with('status', [ 'success' => true, 'msg' => __('advancedplanning::lang.sop_status_updated'), ]); } }