From 37bc7a85e59be56ecdb74346ecfff18f8599c7d7 Mon Sep 17 00:00:00 2001 From: rstubryan Date: Fri, 6 Mar 2026 10:52:59 +0700 Subject: [PATCH] refactor(FE): Add depletion product handling in inventory adjustment forms --- .../adjustment/InventoryAdjustmentTable.tsx | 3 + .../form/InventoryAdjustmentForm.schema.ts | 12 ++ .../form/InventoryAdjustmentForm.tsx | 148 +++++++++++++----- 3 files changed, 126 insertions(+), 37 deletions(-) diff --git a/src/components/pages/inventory/adjustment/InventoryAdjustmentTable.tsx b/src/components/pages/inventory/adjustment/InventoryAdjustmentTable.tsx index fe7a2f77..90b68b7d 100644 --- a/src/components/pages/inventory/adjustment/InventoryAdjustmentTable.tsx +++ b/src/components/pages/inventory/adjustment/InventoryAdjustmentTable.tsx @@ -282,6 +282,9 @@ const InventoryAdjustmentTable = () => { if (recordingOption) { return recordingOption.label; } + if (subtypeValue === 'RECORDING_DEPLETION_OUT') { + return 'Recording Depletion'; + } return subtypeValue || '-'; }; diff --git a/src/components/pages/inventory/adjustment/form/InventoryAdjustmentForm.schema.ts b/src/components/pages/inventory/adjustment/form/InventoryAdjustmentForm.schema.ts index de9c9eaa..cee01e00 100644 --- a/src/components/pages/inventory/adjustment/form/InventoryAdjustmentForm.schema.ts +++ b/src/components/pages/inventory/adjustment/form/InventoryAdjustmentForm.schema.ts @@ -26,6 +26,11 @@ export type InventoryAdjustmentFormSchemaType = { label: string; } | null; product_id: number; + depletion_product: { + value: number; + label: string; + } | null; + depletion_product_id: number; transaction_type: string; transaction_subtype: string; qty: number | string; @@ -80,6 +85,13 @@ export const InventoryAdjustmentFormSchema: Yup.ObjectSchema(null); const [selectedTransactionSubtype, setSelectedTransactionSubtype] = useState(null); + const [selectedDepletionProduct, setSelectedDepletionProduct] = + useState(null); const [selectedProjectFlockLocationId, setSelectedProjectFlockLocationId] = useState(''); @@ -185,6 +187,15 @@ const InventoryAdjustmentForm = ({ rawData: products, } = useSelect(ProductApi.basePath, 'id', 'name', 'search'); + const { + setInputValue: setDepletionProductInputValue, + options: depletionProductOptions, + isLoadingOptions: isLoadingDepletionProductOptions, + loadMore: loadMoreDepletionProducts, + } = useSelect(ProductApi.basePath, 'id', 'name', 'search', { + is_depletion: 'true', + }); + const productOptions = useMemo(() => { if (!isResponseSuccess(products)) return []; @@ -241,6 +252,8 @@ const InventoryAdjustmentForm = ({ project_flock_kandang_id: 0, product: null, product_id: 0, + depletion_product: null, + depletion_product_id: 0, transaction_type: '', transaction_subtype: '', qty: '', @@ -260,7 +273,10 @@ const InventoryAdjustmentForm = ({ setInventoryAdjustmentFormErrorMessage(''); const payload: CreateInventoryAdjustmentPayload = { project_flock_kandang_id: values.project_flock_kandang_id, - product_id: values.product_id, + product_id: + values.depletion_product_id > 0 + ? values.depletion_product_id + : values.product_id, transaction_subtype: values.transaction_subtype, qty: Number(values.qty), price: Number(values.price), @@ -275,6 +291,8 @@ const InventoryAdjustmentForm = ({ }, }); + const { setFieldValue, setFieldTouched, resetForm, setValues } = formik; + const transactionSubtypeOptions = useMemo(() => { const transactionType = selectedTransactionType?.value; @@ -321,19 +339,31 @@ const InventoryAdjustmentForm = ({ useEffect(() => { if (selectedTransactionType?.value === 'RECORDING' && selectedProduct) { setSelectedTransactionSubtype(null); - formik.setFieldValue('transaction_subtype', ''); + setFieldValue('transaction_subtype', ''); } - }, [selectedProduct, selectedTransactionType]); + }, [setFieldValue, selectedProduct, selectedTransactionType]); + + const isDepletionProductVisible = useMemo(() => { + return selectedTransactionSubtype?.value === 'RECORDING_DEPLETION_IN'; + }, [selectedTransactionSubtype]); + + useEffect(() => { + if (!isDepletionProductVisible) { + setSelectedDepletionProduct(null); + setFieldValue('depletion_product', null); + setFieldValue('depletion_product_id', 0); + } + }, [isDepletionProductVisible, setFieldValue]); // ===== EVENT HANDLERS ===== const locationChangeHandler = (val: OptionType | OptionType[] | null) => { const location = val as OptionType | null; const locationId = location ? Number(location.value) : 0; - formik.setFieldTouched('location', true); - formik.setFieldValue('location', location); - formik.setFieldTouched('location_id', true); - formik.setFieldValue('location_id', locationId); + setFieldTouched('location', true); + setFieldValue('location', location); + setFieldTouched('location_id', true); + setFieldValue('location_id', locationId); setSelectedLocation(location); setSelectedProjectFlock(null); @@ -348,10 +378,10 @@ const InventoryAdjustmentForm = ({ const projectFlock = val as OptionType | null; const projectFlockId = Number(projectFlock?.value); - formik.setFieldTouched('project_flock', true); - formik.setFieldValue('project_flock', projectFlock); - formik.setFieldTouched('project_flock_id', true); - formik.setFieldValue('project_flock_id', projectFlockId); + setFieldTouched('project_flock', true); + setFieldValue('project_flock', projectFlock); + setFieldTouched('project_flock_id', true); + setFieldValue('project_flock_id', projectFlockId); setSelectedProjectFlock(projectFlock); setSelectedKandang(null); @@ -362,44 +392,58 @@ const InventoryAdjustmentForm = ({ const kandang = val as OptionType | null; const kandangId = Number(kandang?.value); - formik.setFieldTouched('kandang', true); - formik.setFieldValue('kandang', kandang); - formik.setFieldTouched('kandang_id', true); - formik.setFieldValue('kandang_id', kandangId); + setFieldTouched('kandang', true); + setFieldValue('kandang', kandang); + setFieldTouched('kandang_id', true); + setFieldValue('kandang_id', kandangId); setSelectedKandang(kandang); setSelectedProduct(null); - formik.setFieldTouched('project_flock_kandang', true); - formik.setFieldTouched('project_flock_kandang_id', true); + setFieldTouched('project_flock_kandang', true); + setFieldTouched('project_flock_kandang_id', true); }; const productChangeHandler = (val: OptionType | OptionType[] | null) => { const product = val as OptionType | null; const productId = (product?.value as number) ?? 0; - formik.setFieldTouched('product', true); - formik.setFieldValue('product', product); - formik.setFieldTouched('product_id', true); - formik.setFieldValue('product_id', productId); + setFieldTouched('product', true); + setFieldValue('product', product); + setFieldTouched('product_id', true); + setFieldValue('product_id', productId); setSelectedProduct(product); }; + const depletionProductChangeHandler = ( + val: OptionType | OptionType[] | null + ) => { + const depletionProduct = val as OptionType | null; + const depletionProductId = (depletionProduct?.value as number) ?? 0; + + setFieldTouched('depletion_product', true); + setFieldValue('depletion_product', depletionProduct); + setFieldTouched('depletion_product_id', true); + setFieldValue('depletion_product_id', depletionProductId); + + setSelectedDepletionProduct(depletionProduct); + }; + useEffect(() => { const transactionType = formik.values.transaction_type; if (!transactionType) { setSelectedTransactionSubtype(null); - formik.setFieldValue('transaction_subtype', ''); + setFieldValue('transaction_subtype', ''); return; } setSelectedTransactionSubtype(null); - formik.setFieldValue('transaction_subtype', ''); - formik.setFieldTouched('transaction_subtype', true); + setFieldValue('transaction_subtype', ''); + setFieldTouched('transaction_subtype', true); if (transactionType === 'PEMBELIAN') { - formik.setFieldValue( + setFieldValue( 'transaction_subtype', TRANSACTION_SUBTYPE_OPTIONS.PEMBELIAN.value ); @@ -408,7 +452,7 @@ const InventoryAdjustmentForm = ({ label: TRANSACTION_SUBTYPE_OPTIONS.PEMBELIAN.label, }); } else if (transactionType === 'PENJUALAN') { - formik.setFieldValue( + setFieldValue( 'transaction_subtype', TRANSACTION_SUBTYPE_OPTIONS.PENJUALAN.value ); @@ -417,7 +461,7 @@ const InventoryAdjustmentForm = ({ label: TRANSACTION_SUBTYPE_OPTIONS.PENJUALAN.label, }); } - }, [formik.values.transaction_type]); + }, [setFieldTouched, setFieldValue, formik.values.transaction_type]); const transactionTypeChangeHandler = ( val: OptionType | OptionType[] | null @@ -425,8 +469,8 @@ const InventoryAdjustmentForm = ({ const typeOption = val as OptionType | null; const selectedType = typeOption?.value as string; - formik.setFieldValue('transaction_type', selectedType); - formik.setFieldTouched('transaction_type', true); + setFieldValue('transaction_type', selectedType); + setFieldTouched('transaction_type', true); setSelectedTransactionType(typeOption); }; @@ -437,20 +481,21 @@ const InventoryAdjustmentForm = ({ const subtypeOption = val as OptionType | null; const selectedSubtype = subtypeOption?.value as string; - formik.setFieldTouched('transaction_subtype', true); - formik.setFieldValue('transaction_subtype', selectedSubtype); + setFieldTouched('transaction_subtype', true); + setFieldValue('transaction_subtype', selectedSubtype); setSelectedTransactionSubtype(subtypeOption); }; const resetHandler = () => { - formik.resetForm(); + resetForm(); setSelectedLocation(null); setSelectedProjectFlock(null); setSelectedKandang(null); setSelectedProduct(null); setSelectedTransactionType(null); setSelectedTransactionSubtype(null); + setSelectedDepletionProduct(null); setSelectedProjectFlockLocationId(''); }; @@ -460,14 +505,18 @@ const InventoryAdjustmentForm = ({ projectFlockKandangLookup.project_flock_kandang_id; if (formik.values.project_flock_kandang_id !== projectFlockKandangId) { - formik.setFieldValue('project_flock_kandang_id', projectFlockKandangId); - formik.setFieldValue('project_flock_kandang', { + setFieldValue('project_flock_kandang_id', projectFlockKandangId); + setFieldValue('project_flock_kandang', { value: projectFlockKandangId, label: `${projectFlockKandangLookup.project_flock.flock_name} - ${projectFlockKandangLookup.kandang.name}`, }); } } - }, [projectFlockKandangLookup, formik.values.project_flock_kandang_id]); + }, [ + projectFlockKandangLookup, + formik.values.project_flock_kandang_id, + setFieldValue, + ]); useEffect(() => { if (initialValues && type === 'detail') { @@ -519,7 +568,7 @@ const InventoryAdjustmentForm = ({ }); } - formik.setValues({ + setValues({ location: initialValues.location ? { value: initialValues.location.id, @@ -550,6 +599,8 @@ const InventoryAdjustmentForm = ({ } : null, product_id: initialValues.product_warehouse?.product?.id ?? 0, + depletion_product: null, + depletion_product_id: 0, transaction_type: transactionType, transaction_subtype: transactionSubtype, qty: initialValues.qty ?? '', @@ -557,7 +608,7 @@ const InventoryAdjustmentForm = ({ notes: initialValues.notes ?? '', }); } - }, [formik.setValues, initialValues, type]); + }, [setValues, initialValues, type]); // ===== Formik Error List ===== const { formErrorList, close, handleFormSubmit } = useFormikErrorList(formik); @@ -729,6 +780,29 @@ const InventoryAdjustmentForm = ({ isSearchable /> + {/* RECORDING_DEPLETION_IN */} + {isDepletionProductVisible && ( + + )} + {/* Number Input Quantity */}