From 4f23af869fd1fd221fbd2c2e80e9ea747516c5fe Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Sun, 14 Jun 2026 02:59:29 +0700 Subject: [PATCH] feat: add stock availability validation during order processing and display specific error messages in POS form --- app/Services/Manage/OrderService.php | 28 +++++++++++++++++++ .../admin/manage/orders/OrderPosForm.vue | 5 ++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/app/Services/Manage/OrderService.php b/app/Services/Manage/OrderService.php index 59b8a0c..7d80e2b 100644 --- a/app/Services/Manage/OrderService.php +++ b/app/Services/Manage/OrderService.php @@ -199,6 +199,12 @@ public function syncDraftItem(array $validated, User $user): array } $quantity = (int) $validated['quantity']; + if ($quantity > $variant->stock) { + throw ValidationException::withMessages([ + 'quantity' => "Stok tidak mencukupi. Stok saat ini: {$variant->stock} pcs.", + ]); + } + $unitPrice = (int) $price->price; $subtotal = $unitPrice * $quantity; @@ -311,6 +317,17 @@ public function create(array $validated, User $user): Order ]); foreach ($draftItems as $item) { + $variant = ProductVariant::query()->with('product')->lockForUpdate()->find($item->product_variant_id); + if ($variant === null) { + throw ValidationException::withMessages([ + 'items' => 'Varian produk tidak ditemukan.', + ]); + } + if ($variant->stock < $item->quantity) { + throw ValidationException::withMessages([ + 'items' => "Stok produk {$variant->product->name} ({$variant->name}) tidak mencukupi. Stok saat ini: {$variant->stock} pcs.", + ]); + } $item->order_id = $order->id; $item->save(); $this->decrementStock($item); @@ -371,6 +388,17 @@ public function update(Order $order, array $validated): void $order->save(); foreach ($lineItems as $itemData) { + $variant = ProductVariant::query()->with('product')->lockForUpdate()->find($itemData['product_variant_id']); + if ($variant === null) { + throw ValidationException::withMessages([ + 'items' => 'Varian produk tidak ditemukan.', + ]); + } + if ($variant->stock < $itemData['quantity']) { + throw ValidationException::withMessages([ + 'items' => "Stok produk {$variant->product->name} ({$variant->name}) tidak mencukupi. Stok saat ini: {$variant->stock} pcs.", + ]); + } $orderItem = $order->items()->create($itemData); $this->decrementStock($orderItem); } diff --git a/resources/js/components/admin/manage/orders/OrderPosForm.vue b/resources/js/components/admin/manage/orders/OrderPosForm.vue index e740ef2..4c21adf 100644 --- a/resources/js/components/admin/manage/orders/OrderPosForm.vue +++ b/resources/js/components/admin/manage/orders/OrderPosForm.vue @@ -349,8 +349,9 @@ function submit() { form.transform(() => payload).post(props.submitUrl, { forceFormData: true, - onError: () => { - toast.error('Gagal menyimpan data. Periksa kembali formulir.'); + onError: (errors) => { + const firstError = Object.values(errors)[0]; + toast.error(firstError || 'Gagal menyimpan data. Periksa kembali formulir.'); }, }); }