From 39c8bd01a839c0cbdc5f35c934cd3173b66a7a54 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Mon, 29 Jun 2026 09:53:22 +0700 Subject: [PATCH] refactor: enhance stock verification logic and error handling in StockVerifyDialog --- .../manage/stocks/table/StockVerifyDialog.vue | 105 ++++++++++++------ 1 file changed, 71 insertions(+), 34 deletions(-) diff --git a/resources/js/pages/admin/manage/stocks/table/StockVerifyDialog.vue b/resources/js/pages/admin/manage/stocks/table/StockVerifyDialog.vue index c399523..0313946 100644 --- a/resources/js/pages/admin/manage/stocks/table/StockVerifyDialog.vue +++ b/resources/js/pages/admin/manage/stocks/table/StockVerifyDialog.vue @@ -2,7 +2,7 @@ import { useForm } from '@inertiajs/vue3'; import { computed, watch } from 'vue'; import { toast } from 'vue-sonner'; -import NumberInput from '@/components/form/number-input/NumberInput.vue'; +import { NumberInput } from '@/components/form/number-input'; import { RupiahInput } from '@/components/form/rupiah-input'; import { Button } from '@/components/ui/button'; import { @@ -51,10 +51,14 @@ const verifyForm = useForm({ cutting_result: res.cutting_result, original_sample: res.sample, original_outside_sample: res.original_outside_sample, - good: res.original_outside_sample, + good: res.cutting_result, reject: 0, })), - variant_prices: [] as VariantPriceRow[], + variant_prices: props.cutting.results.map(res => ({ + product_variant_id: res.product_variant?.id || 0, + name: `${res.product_variant?.product?.name || ''} (${res.product_variant?.name || ''})`, + prices: buildEmptyPrices(), + })), shared_prices: buildEmptyPrices(), }); @@ -67,7 +71,7 @@ watch(open, (isOpen) => { cutting_result: res.cutting_result, original_sample: res.sample, original_outside_sample: res.original_outside_sample, - good: res.original_outside_sample, + good: res.cutting_result, reject: 0, })); verifyForm.variant_prices = props.cutting.results.map(res => ({ @@ -80,6 +84,18 @@ watch(open, (isOpen) => { } }); +function onGoodChange(result: any, value: string | number) { + const val = Number(value) || 0; + result.good = val; + result.reject = Math.max(0, result.cutting_result - val); +} + +function onRejectChange(result: any, value: string | number) { + const val = Number(value) || 0; + result.reject = val; + result.good = Math.max(0, result.cutting_result - val); +} + function setSharedPrice(type: string, value: string) { verifyForm.shared_prices[type] = value; verifyForm.variant_prices = verifyForm.variant_prices.map((row) => ({ @@ -89,13 +105,13 @@ function setSharedPrice(type: string, value: string) { } const resultPricesErrors = computed(() => { - const message = (verifyForm.errors as Record).result_prices; - - return message ? [message] : []; + return Object.entries(verifyForm.errors) + .filter(([key]) => key === 'result_prices' || key.startsWith('result_prices.')) + .map(([_, message]) => message) as string[]; }); -function buildResultPricesPayload() { - return verifyForm.variant_prices.map((row) => ({ +function buildResultPricesPayload(variantPrices: VariantPriceRow[]) { + return variantPrices.map((row) => ({ product_variant_id: row.product_variant_id, prices: PRICE_TYPES.map((type) => ({ type, @@ -113,7 +129,7 @@ function submitVerify() { good, reject, })), - result_prices: buildResultPricesPayload(), + result_prices: buildResultPricesPayload(data.variant_prices), })) .post(verify.url(props.cutting.id), { preserveScroll: true, @@ -121,8 +137,22 @@ function submitVerify() { open.value = false; }, onError: (errors: Record) => { - if (errors.system) { - toast.error(errors.system); + const shown = new Set(); + + for (const [key, message] of Object.entries(errors)) { + if ( + key === 'result_prices' || + key.startsWith('result_prices.') || + key.startsWith('results.') || + key === 'verification_note' + ) { + continue; + } + + if (!shown.has(message)) { + shown.add(message); + toast.error(message); + } } }, }); @@ -145,31 +175,38 @@ function submitVerify() {
-
-

{{ result.name }}

-

- {{ result.cutting_result }} pcs - ({{ result.original_sample }} Sample, {{ - result.original_outside_sample }} Diluar Sample) -

-
-
-
- - + class="flex flex-col gap-1 rounded-lg border p-3"> +
+
+

{{ result.name }}

+

+ {{ result.cutting_result }} pcs + ({{ result.original_sample }} Sample, {{ + result.original_outside_sample }} Diluar Sample) +

-
- - +
+
+ + +
+
+ + +
+