diff --git a/src/components/pages/purchase/form/order/PurchaseOrderStaffApprovalForm.tsx b/src/components/pages/purchase/form/order/PurchaseOrderStaffApprovalForm.tsx index 029fd2e3..57af080f 100644 --- a/src/components/pages/purchase/form/order/PurchaseOrderStaffApprovalForm.tsx +++ b/src/components/pages/purchase/form/order/PurchaseOrderStaffApprovalForm.tsx @@ -33,6 +33,7 @@ import { Purchase, } from '@/types/api/purchase/purchase'; import { useRouter } from 'next/navigation'; +import { useApprovalSteps } from '@/components/pages/ApprovalSteps'; interface PurchaseOrderStaffApprovalFormProps { type?: 'add' | 'edit'; @@ -44,13 +45,43 @@ interface PurchaseOrderStaffApprovalFormProps { } const PurchaseOrderStaffApprovalForm = ({ - type = 'add', + type: propType, initialValues, onCancel, refreshApprovals, onModalClose, onRefetchData, }: PurchaseOrderStaffApprovalFormProps) => { + const { rawDataApprovals } = useApprovalSteps({ + latestApproval: initialValues?.approval, + approvalLines: [], + moduleName: 'PURCHASES', + moduleId: initialValues?.id?.toString() ?? '', + params: { + limit: 100, + group_step_number: true, + }, + }); + + const type = useMemo(() => { + if (propType && (propType === 'add' || propType === 'edit')) { + return propType; + } + + if (!rawDataApprovals || rawDataApprovals.length === 0) { + return 'add'; + } + + const firstApproval = rawDataApprovals[0]; + const hasOnlyInitialStep = + rawDataApprovals.length === 1 && + firstApproval?.step_number === 1 && + 'action' in firstApproval && + firstApproval.action === 'CREATED'; + + return hasOnlyInitialStep ? 'add' : 'edit'; + }, [rawDataApprovals, propType]); + const router = useRouter(); const searchParams = useSearchParams(); const deleteModal = useModal(); @@ -68,8 +99,6 @@ const PurchaseOrderStaffApprovalForm = ({ if (!initialValues?.approval) return false; const currentStep = initialValues.approval.step_number; - // Allow editing from step 3 onwards - // Hide delete/add buttons from step 4 onwards return currentStep >= 3; }, [initialValues?.approval]); @@ -77,8 +106,6 @@ const PurchaseOrderStaffApprovalForm = ({ if (!initialValues?.approval) return false; const currentStep = initialValues.approval.step_number; - // Show delete/add buttons only up to step 3 - // Hide from step 4 onwards return currentStep < 4; }, [initialValues?.approval]); @@ -231,18 +258,31 @@ const PurchaseOrderStaffApprovalForm = ({ (url: string) => SupplierApi.getSingle(Number(url.split('/').pop())) ); - const supplierProductOptions = useMemo(() => { + const baseSupplierProductOptions: OptionType[] = useMemo(() => { if (!supplierData || !isResponseSuccess(supplierData)) { return []; } const supplier = supplierData.data as SupplierProducts; const products = supplier.products || []; + + if (type === 'edit' && initialValues?.items) { + const currentProductIds = initialValues.items.map( + (item) => item.product_id + ); + return products + .filter((product) => currentProductIds.includes(product.id)) + .map((product) => ({ + value: product.id, + label: product.name, + })); + } + return products.map((product) => ({ value: product.id, label: product.name, })); - }, [supplierData]); + }, [supplierData, type, initialValues?.items]); // ===== FORM CONFIGURATION ===== const formikInitialValues = useMemo(() => { @@ -364,6 +404,8 @@ const PurchaseOrderStaffApprovalForm = ({ }, }); + const supplierProductOptions = baseSupplierProductOptions; + // ===== API DATA FETCHING ===== const purchaseItems = useMemo(() => { if (initialValues?.items) { @@ -426,6 +468,10 @@ const PurchaseOrderStaffApprovalForm = ({ const itemData = { purchase_item_id: purchaseItem.id, product_id: purchaseItem.product_id || 0, + product: { + value: purchaseItem.product_id || 0, + label: purchaseItem.product?.name || '', + }, warehouse_id: purchaseItem.warehouse_id || 0, qty: originalItem?.qty || purchaseItem.quantity || 0, price: type === 'edit' && originalItem ? originalItem.price : '', @@ -493,6 +539,34 @@ const PurchaseOrderStaffApprovalForm = ({ const product = val as OptionType | null; const productId = (product as OptionType)?.value || 0; + if (Number(productId) > 0) { + const currentItem = formik.values.items?.[idx]; + const warehouseId = currentItem?.warehouse_id || 0; + + const isDuplicate = formik.values.items?.some( + (item, itemIdx) => + itemIdx !== idx && + item.product_id === productId && + item.warehouse_id === warehouseId + ); + + if (isDuplicate) { + const existingItem = formik.values.items?.find( + (item, itemIdx) => + itemIdx !== idx && + item.product_id === productId && + item.warehouse_id === warehouseId + ); + const existingProductName = + existingItem?.product?.label || 'produk ini'; + + toast.error( + `Tidak bisa menambahkan item yang sama. ${existingProductName} sudah ada di gudang ini.` + ); + return; + } + } + formik.setFieldTouched(`items.${idx}.product`, true); formik.setFieldValue(`items.${idx}.product`, product); formik.setFieldTouched(`items.${idx}.product_id`, true); @@ -568,7 +642,9 @@ const PurchaseOrderStaffApprovalForm = ({ Total (Rp.) * - {canShowDeleteAddButtons && Action} + {canShowDeleteAddButtons && type === 'edit' && ( + Action + )} @@ -595,14 +671,16 @@ const PurchaseOrderStaffApprovalForm = ({ + handleProductChange(formItemIndex, val) + } options={supplierProductOptions} isClearable={false} isSearchable={false} + isDisabled={type === 'add'} className={{ wrapper: 'min-w-52 md:min-w-72 lg:min-w-80', @@ -770,7 +848,9 @@ const PurchaseOrderStaffApprovalForm = ({ handleProductChange(idx, val) }