parseDataTableQuery($request); return Inertia::render('admin/manage/stok-opnames/Index', [ 'stokOpnames' => $this->stokOpnameService->paginateForIndex($tableQuery), 'filters' => $this->dataTableFilters($tableQuery), ]); } public function create(): Response { return Inertia::render('admin/manage/stok-opnames/Create', [ 'catalog' => $this->stokOpnameService->catalogItems(), ]); } public function store(StokOpnameRequest $request): RedirectResponse { $this->stokOpnameService->create($request->validated(), $request->user()); $this->flashCreated('Stok Opname'); return redirect()->route('admin.manage.stok-opnames.index'); } /** * Auto-save draft via AJAX (creates or updates silently). */ public function autoSave(Request $request): \Illuminate\Http\JsonResponse { $user = $request->user(); if (! $user->can(\App\Enums\Permission::STOK_OPNAMES_CREATE->value) && ! $user->can(\App\Enums\Permission::STOK_OPNAMES_UPDATE->value)) { return response()->json(['message' => 'Unauthorized'], 403); } $validated = $request->validate([ 'stok_opname_id' => ['nullable', 'integer', 'exists:stok_opnames,id'], 'opname_date' => ['required', 'date'], 'notes' => ['nullable', 'string', 'max:1000'], 'items' => ['nullable', 'array'], 'items.*.product_variant_id' => ['required', 'integer', 'exists:product_variants,id'], 'items.*.physical_stock' => ['nullable', 'integer', 'min:0'], 'items.*.notes' => ['nullable', 'string', 'max:500'], ]); $stokOpname = $this->stokOpnameService->autoSave($validated, $user); return response()->json([ 'stok_opname_id' => $stokOpname->id, 'message' => 'Draft tersimpan otomatis.', ]); } public function edit(StokOpname $stokOpname): Response { return Inertia::render('admin/manage/stok-opnames/Edit', [ 'stokOpname' => $this->stokOpnameService->findForEdit($stokOpname), 'catalog' => $this->stokOpnameService->catalogItems(), ]); } public function update(StokOpnameRequest $request, StokOpname $stokOpname): RedirectResponse { $this->stokOpnameService->update($stokOpname, $request->validated()); $this->flashUpdated('Stok Opname'); return redirect()->route('admin.manage.stok-opnames.index'); } public function destroy(StokOpname $stokOpname): RedirectResponse { $this->stokOpnameService->delete($stokOpname); $this->flashDeleted('Stok Opname'); return redirect()->route('admin.manage.stok-opnames.index'); } public function submit(StokOpnameSubmitRequest $request, StokOpname $stokOpname): RedirectResponse { $this->stokOpnameService->submit($stokOpname, $request->user()); $this->flashSuccess('Stok opname berhasil diajukan untuk verifikasi.'); return redirect()->route('admin.manage.stok-opnames.index'); } public function verify(StokOpnameVerifyRequest $request, StokOpname $stokOpname): RedirectResponse { $this->stokOpnameService->verify( $stokOpname, $request->user(), $request->validated('verification_notes'), ); $this->flashSuccess('Stok opname berhasil diverifikasi dan stok telah disesuaikan.'); return redirect()->route('admin.manage.stok-opnames.index'); } public function reject(StokOpnameRejectRequest $request, StokOpname $stokOpname): RedirectResponse { $this->stokOpnameService->reject( $stokOpname, $request->user(), $request->validated('reason'), ); $this->flashSuccess('Stok opname berhasil ditolak.'); return redirect()->route('admin.manage.stok-opnames.index'); } }