Purchase::with(['items.product'])->latest()->paginate(10), ]); } public function create(): Response { return Inertia::render('admin/manage/purchase/create', [ 'products' => Product::with(['prices', 'categories'])->active()->get(), 'cartItems' => PurchaseItem::with(['product.prices', 'product.categories']) ->where('user_id', auth()->id()) ->whereNull('purchase_id') ->latest() ->get(), ]); } public function store(PurchaseRequest $request): RedirectResponse { $validated = $request->validated(); try { DB::transaction(function () use ($validated) { $total = collect($validated['items'])->sum(fn ($item) => $item['quantity'] * $item['unit_price']); $purchase = Purchase::create([ 'purchase_date' => $validated['purchase_date'], 'note' => $validated['note'], 'total' => $total, ]); foreach ($validated['items'] as $item) { PurchaseItem::create([ 'user_id' => auth()->id(), 'purchase_id' => $purchase->id, 'product_id' => $item['product_id'], 'quantity' => $item['quantity'], 'unit_price' => $item['unit_price'], 'total_price' => $item['quantity'] * $item['unit_price'], ]); Product::find($item['product_id'])->increment('stock', $item['quantity']); } PurchaseItem::where('user_id', auth()->id()) ->whereNull('purchase_id') ->delete(); }); return redirect()->route('purchase.index')->with('success', 'Data berhasil disimpan'); } catch (\Throwable $e) { LogHelper::logException($e, 'Failed to store purchase', [ 'purchase_date' => $validated['purchase_date'] ?? null, 'items_count' => count($validated['items'] ?? []), ]); return redirect() ->back() ->withInput() ->with('error', 'Terjadi kesalahan, silakan hubungi pengembang'); } } public function edit(Purchase $purchase): Response { $purchase->load(['items.product']); return Inertia::render('admin/manage/purchase/edit', [ 'purchase' => $purchase, 'products' => Product::with(['prices', 'categories'])->active()->get(), ]); } public function update(PurchaseRequest $request, Purchase $purchase): RedirectResponse { $validated = $request->validated(); try { DB::transaction(function () use ($validated, $purchase) { $total = collect($validated['items'])->sum(fn ($item) => $item['quantity'] * $item['unit_price']); $purchase->update([ 'purchase_date' => $validated['purchase_date'], 'note' => $validated['note'], 'total' => $total, ]); foreach ($purchase->items as $item) { if ($item->product->stock < $item->quantity) { throw new \InvalidArgumentException("Stok produk {$item->product->name} tidak mencukupi untuk dibatalkan. Sisa stok: {$item->product->stock}"); } $item->product->decrement('stock', $item->quantity); } $purchase->items()->delete(); foreach ($validated['items'] as $item) { $purchase->items()->create([ 'user_id' => auth()->id(), 'product_id' => $item['product_id'], 'quantity' => $item['quantity'], 'unit_price' => $item['unit_price'], 'total_price' => $item['quantity'] * $item['unit_price'], ]); Product::find($item['product_id'])->increment('stock', $item['quantity']); } }); return redirect()->route('purchase.index')->with('success', 'Data berhasil diperbarui'); } catch (\InvalidArgumentException $e) { return redirect()->back()->withInput()->with('error', $e->getMessage()); } catch (\Throwable $e) { LogHelper::logException($e, 'Failed to update purchase', [ 'purchase_id' => $purchase->id, 'items_count' => count($validated['items'] ?? []), ]); return redirect() ->back() ->withInput() ->with('error', 'Terjadi kesalahan, silakan hubungi pengembang'); } } public function destroy(Purchase $purchase): RedirectResponse { try { DB::transaction(function () use ($purchase) { foreach ($purchase->items as $item) { if ($item->product->stock < $item->quantity) { throw new \InvalidArgumentException("Stok produk {$item->product->name} tidak mencukupi untuk dihapus. Sisa stok: {$item->product->stock}"); } $item->product->decrement('stock', $item->quantity); } $purchase->delete(); }); return redirect()->back()->with('success', 'Data berhasil dihapus'); } catch (\InvalidArgumentException $e) { return redirect()->back()->with('error', $e->getMessage()); } catch (\Throwable $e) { LogHelper::logException($e, 'Failed to delete purchase', [ 'purchase_id' => $purchase->id, ]); return redirect()->back()->with('error', 'Terjadi kesalahan, silakan hubungi pengembang'); } } public function bulkDestroy(Request $request): RedirectResponse { $ids = $request->input('ids'); try { DB::transaction(function () use ($ids) { $purchases = Purchase::with('items.product')->whereIn('id', $ids)->get(); foreach ($purchases as $purchase) { foreach ($purchase->items as $item) { if ($item->product->stock < $item->quantity) { throw new \InvalidArgumentException("Stok produk {$item->product->name} tidak mencukupi untuk dihapus. Sisa stok: {$item->product->stock}"); } $item->product->decrement('stock', $item->quantity); } $purchase->delete(); } }); return redirect()->back()->with('success', 'Data terpilih berhasil dihapus'); } catch (\InvalidArgumentException $e) { return redirect()->back()->with('error', $e->getMessage()); } catch (\Throwable $e) { LogHelper::logException($e, 'Failed to bulk delete purchases', [ 'ids' => $ids, ]); return redirect()->back()->with('error', 'Terjadi kesalahan, silakan hubungi pengembang'); } } }