mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
refactor(FE): Add depletion product handling in inventory adjustment
forms
This commit is contained in:
@@ -282,6 +282,9 @@ const InventoryAdjustmentTable = () => {
|
|||||||
if (recordingOption) {
|
if (recordingOption) {
|
||||||
return recordingOption.label;
|
return recordingOption.label;
|
||||||
}
|
}
|
||||||
|
if (subtypeValue === 'RECORDING_DEPLETION_OUT') {
|
||||||
|
return 'Recording Depletion';
|
||||||
|
}
|
||||||
return subtypeValue || '-';
|
return subtypeValue || '-';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ export type InventoryAdjustmentFormSchemaType = {
|
|||||||
label: string;
|
label: string;
|
||||||
} | null;
|
} | null;
|
||||||
product_id: number;
|
product_id: number;
|
||||||
|
depletion_product: {
|
||||||
|
value: number;
|
||||||
|
label: string;
|
||||||
|
} | null;
|
||||||
|
depletion_product_id: number;
|
||||||
transaction_type: string;
|
transaction_type: string;
|
||||||
transaction_subtype: string;
|
transaction_subtype: string;
|
||||||
qty: number | string;
|
qty: number | string;
|
||||||
@@ -80,6 +85,13 @@ export const InventoryAdjustmentFormSchema: Yup.ObjectSchema<InventoryAdjustment
|
|||||||
.min(1, 'Produk wajib diisi!')
|
.min(1, 'Produk wajib diisi!')
|
||||||
.required('Produk wajib diisi!')
|
.required('Produk wajib diisi!')
|
||||||
.typeError('Produk wajib diisi!'),
|
.typeError('Produk wajib diisi!'),
|
||||||
|
depletion_product: Yup.object({
|
||||||
|
value: Yup.number().min(1).required(),
|
||||||
|
label: Yup.string().required(),
|
||||||
|
}).nullable(),
|
||||||
|
depletion_product_id: Yup.number()
|
||||||
|
.default(0)
|
||||||
|
.typeError('Jenis deplesi harus berupa angka'),
|
||||||
transaction_type: Yup.string()
|
transaction_type: Yup.string()
|
||||||
.min(1, 'Tipe transaksi wajib diisi!')
|
.min(1, 'Tipe transaksi wajib diisi!')
|
||||||
.oneOf(
|
.oneOf(
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ const InventoryAdjustmentForm = ({
|
|||||||
useState<OptionType | null>(null);
|
useState<OptionType | null>(null);
|
||||||
const [selectedTransactionSubtype, setSelectedTransactionSubtype] =
|
const [selectedTransactionSubtype, setSelectedTransactionSubtype] =
|
||||||
useState<OptionType | null>(null);
|
useState<OptionType | null>(null);
|
||||||
|
const [selectedDepletionProduct, setSelectedDepletionProduct] =
|
||||||
|
useState<OptionType | null>(null);
|
||||||
const [selectedProjectFlockLocationId, setSelectedProjectFlockLocationId] =
|
const [selectedProjectFlockLocationId, setSelectedProjectFlockLocationId] =
|
||||||
useState<string>('');
|
useState<string>('');
|
||||||
|
|
||||||
@@ -185,6 +187,15 @@ const InventoryAdjustmentForm = ({
|
|||||||
rawData: products,
|
rawData: products,
|
||||||
} = useSelect<Product>(ProductApi.basePath, 'id', 'name', 'search');
|
} = useSelect<Product>(ProductApi.basePath, 'id', 'name', 'search');
|
||||||
|
|
||||||
|
const {
|
||||||
|
setInputValue: setDepletionProductInputValue,
|
||||||
|
options: depletionProductOptions,
|
||||||
|
isLoadingOptions: isLoadingDepletionProductOptions,
|
||||||
|
loadMore: loadMoreDepletionProducts,
|
||||||
|
} = useSelect<Product>(ProductApi.basePath, 'id', 'name', 'search', {
|
||||||
|
is_depletion: 'true',
|
||||||
|
});
|
||||||
|
|
||||||
const productOptions = useMemo(() => {
|
const productOptions = useMemo(() => {
|
||||||
if (!isResponseSuccess(products)) return [];
|
if (!isResponseSuccess(products)) return [];
|
||||||
|
|
||||||
@@ -241,6 +252,8 @@ const InventoryAdjustmentForm = ({
|
|||||||
project_flock_kandang_id: 0,
|
project_flock_kandang_id: 0,
|
||||||
product: null,
|
product: null,
|
||||||
product_id: 0,
|
product_id: 0,
|
||||||
|
depletion_product: null,
|
||||||
|
depletion_product_id: 0,
|
||||||
transaction_type: '',
|
transaction_type: '',
|
||||||
transaction_subtype: '',
|
transaction_subtype: '',
|
||||||
qty: '',
|
qty: '',
|
||||||
@@ -260,7 +273,10 @@ const InventoryAdjustmentForm = ({
|
|||||||
setInventoryAdjustmentFormErrorMessage('');
|
setInventoryAdjustmentFormErrorMessage('');
|
||||||
const payload: CreateInventoryAdjustmentPayload = {
|
const payload: CreateInventoryAdjustmentPayload = {
|
||||||
project_flock_kandang_id: values.project_flock_kandang_id,
|
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,
|
transaction_subtype: values.transaction_subtype,
|
||||||
qty: Number(values.qty),
|
qty: Number(values.qty),
|
||||||
price: Number(values.price),
|
price: Number(values.price),
|
||||||
@@ -275,6 +291,8 @@ const InventoryAdjustmentForm = ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { setFieldValue, setFieldTouched, resetForm, setValues } = formik;
|
||||||
|
|
||||||
const transactionSubtypeOptions = useMemo(() => {
|
const transactionSubtypeOptions = useMemo(() => {
|
||||||
const transactionType = selectedTransactionType?.value;
|
const transactionType = selectedTransactionType?.value;
|
||||||
|
|
||||||
@@ -321,19 +339,31 @@ const InventoryAdjustmentForm = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedTransactionType?.value === 'RECORDING' && selectedProduct) {
|
if (selectedTransactionType?.value === 'RECORDING' && selectedProduct) {
|
||||||
setSelectedTransactionSubtype(null);
|
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 =====
|
// ===== EVENT HANDLERS =====
|
||||||
const locationChangeHandler = (val: OptionType | OptionType[] | null) => {
|
const locationChangeHandler = (val: OptionType | OptionType[] | null) => {
|
||||||
const location = val as OptionType | null;
|
const location = val as OptionType | null;
|
||||||
const locationId = location ? Number(location.value) : 0;
|
const locationId = location ? Number(location.value) : 0;
|
||||||
|
|
||||||
formik.setFieldTouched('location', true);
|
setFieldTouched('location', true);
|
||||||
formik.setFieldValue('location', location);
|
setFieldValue('location', location);
|
||||||
formik.setFieldTouched('location_id', true);
|
setFieldTouched('location_id', true);
|
||||||
formik.setFieldValue('location_id', locationId);
|
setFieldValue('location_id', locationId);
|
||||||
|
|
||||||
setSelectedLocation(location);
|
setSelectedLocation(location);
|
||||||
setSelectedProjectFlock(null);
|
setSelectedProjectFlock(null);
|
||||||
@@ -348,10 +378,10 @@ const InventoryAdjustmentForm = ({
|
|||||||
const projectFlock = val as OptionType | null;
|
const projectFlock = val as OptionType | null;
|
||||||
const projectFlockId = Number(projectFlock?.value);
|
const projectFlockId = Number(projectFlock?.value);
|
||||||
|
|
||||||
formik.setFieldTouched('project_flock', true);
|
setFieldTouched('project_flock', true);
|
||||||
formik.setFieldValue('project_flock', projectFlock);
|
setFieldValue('project_flock', projectFlock);
|
||||||
formik.setFieldTouched('project_flock_id', true);
|
setFieldTouched('project_flock_id', true);
|
||||||
formik.setFieldValue('project_flock_id', projectFlockId);
|
setFieldValue('project_flock_id', projectFlockId);
|
||||||
|
|
||||||
setSelectedProjectFlock(projectFlock);
|
setSelectedProjectFlock(projectFlock);
|
||||||
setSelectedKandang(null);
|
setSelectedKandang(null);
|
||||||
@@ -362,44 +392,58 @@ const InventoryAdjustmentForm = ({
|
|||||||
const kandang = val as OptionType | null;
|
const kandang = val as OptionType | null;
|
||||||
const kandangId = Number(kandang?.value);
|
const kandangId = Number(kandang?.value);
|
||||||
|
|
||||||
formik.setFieldTouched('kandang', true);
|
setFieldTouched('kandang', true);
|
||||||
formik.setFieldValue('kandang', kandang);
|
setFieldValue('kandang', kandang);
|
||||||
formik.setFieldTouched('kandang_id', true);
|
setFieldTouched('kandang_id', true);
|
||||||
formik.setFieldValue('kandang_id', kandangId);
|
setFieldValue('kandang_id', kandangId);
|
||||||
|
|
||||||
setSelectedKandang(kandang);
|
setSelectedKandang(kandang);
|
||||||
setSelectedProduct(null);
|
setSelectedProduct(null);
|
||||||
formik.setFieldTouched('project_flock_kandang', true);
|
setFieldTouched('project_flock_kandang', true);
|
||||||
formik.setFieldTouched('project_flock_kandang_id', true);
|
setFieldTouched('project_flock_kandang_id', true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const productChangeHandler = (val: OptionType | OptionType[] | null) => {
|
const productChangeHandler = (val: OptionType | OptionType[] | null) => {
|
||||||
const product = val as OptionType | null;
|
const product = val as OptionType | null;
|
||||||
const productId = (product?.value as number) ?? 0;
|
const productId = (product?.value as number) ?? 0;
|
||||||
|
|
||||||
formik.setFieldTouched('product', true);
|
setFieldTouched('product', true);
|
||||||
formik.setFieldValue('product', product);
|
setFieldValue('product', product);
|
||||||
formik.setFieldTouched('product_id', true);
|
setFieldTouched('product_id', true);
|
||||||
formik.setFieldValue('product_id', productId);
|
setFieldValue('product_id', productId);
|
||||||
|
|
||||||
setSelectedProduct(product);
|
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(() => {
|
useEffect(() => {
|
||||||
const transactionType = formik.values.transaction_type;
|
const transactionType = formik.values.transaction_type;
|
||||||
|
|
||||||
if (!transactionType) {
|
if (!transactionType) {
|
||||||
setSelectedTransactionSubtype(null);
|
setSelectedTransactionSubtype(null);
|
||||||
formik.setFieldValue('transaction_subtype', '');
|
setFieldValue('transaction_subtype', '');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setSelectedTransactionSubtype(null);
|
setSelectedTransactionSubtype(null);
|
||||||
formik.setFieldValue('transaction_subtype', '');
|
setFieldValue('transaction_subtype', '');
|
||||||
formik.setFieldTouched('transaction_subtype', true);
|
setFieldTouched('transaction_subtype', true);
|
||||||
|
|
||||||
if (transactionType === 'PEMBELIAN') {
|
if (transactionType === 'PEMBELIAN') {
|
||||||
formik.setFieldValue(
|
setFieldValue(
|
||||||
'transaction_subtype',
|
'transaction_subtype',
|
||||||
TRANSACTION_SUBTYPE_OPTIONS.PEMBELIAN.value
|
TRANSACTION_SUBTYPE_OPTIONS.PEMBELIAN.value
|
||||||
);
|
);
|
||||||
@@ -408,7 +452,7 @@ const InventoryAdjustmentForm = ({
|
|||||||
label: TRANSACTION_SUBTYPE_OPTIONS.PEMBELIAN.label,
|
label: TRANSACTION_SUBTYPE_OPTIONS.PEMBELIAN.label,
|
||||||
});
|
});
|
||||||
} else if (transactionType === 'PENJUALAN') {
|
} else if (transactionType === 'PENJUALAN') {
|
||||||
formik.setFieldValue(
|
setFieldValue(
|
||||||
'transaction_subtype',
|
'transaction_subtype',
|
||||||
TRANSACTION_SUBTYPE_OPTIONS.PENJUALAN.value
|
TRANSACTION_SUBTYPE_OPTIONS.PENJUALAN.value
|
||||||
);
|
);
|
||||||
@@ -417,7 +461,7 @@ const InventoryAdjustmentForm = ({
|
|||||||
label: TRANSACTION_SUBTYPE_OPTIONS.PENJUALAN.label,
|
label: TRANSACTION_SUBTYPE_OPTIONS.PENJUALAN.label,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [formik.values.transaction_type]);
|
}, [setFieldTouched, setFieldValue, formik.values.transaction_type]);
|
||||||
|
|
||||||
const transactionTypeChangeHandler = (
|
const transactionTypeChangeHandler = (
|
||||||
val: OptionType | OptionType[] | null
|
val: OptionType | OptionType[] | null
|
||||||
@@ -425,8 +469,8 @@ const InventoryAdjustmentForm = ({
|
|||||||
const typeOption = val as OptionType | null;
|
const typeOption = val as OptionType | null;
|
||||||
const selectedType = typeOption?.value as string;
|
const selectedType = typeOption?.value as string;
|
||||||
|
|
||||||
formik.setFieldValue('transaction_type', selectedType);
|
setFieldValue('transaction_type', selectedType);
|
||||||
formik.setFieldTouched('transaction_type', true);
|
setFieldTouched('transaction_type', true);
|
||||||
|
|
||||||
setSelectedTransactionType(typeOption);
|
setSelectedTransactionType(typeOption);
|
||||||
};
|
};
|
||||||
@@ -437,20 +481,21 @@ const InventoryAdjustmentForm = ({
|
|||||||
const subtypeOption = val as OptionType | null;
|
const subtypeOption = val as OptionType | null;
|
||||||
const selectedSubtype = subtypeOption?.value as string;
|
const selectedSubtype = subtypeOption?.value as string;
|
||||||
|
|
||||||
formik.setFieldTouched('transaction_subtype', true);
|
setFieldTouched('transaction_subtype', true);
|
||||||
formik.setFieldValue('transaction_subtype', selectedSubtype);
|
setFieldValue('transaction_subtype', selectedSubtype);
|
||||||
|
|
||||||
setSelectedTransactionSubtype(subtypeOption);
|
setSelectedTransactionSubtype(subtypeOption);
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetHandler = () => {
|
const resetHandler = () => {
|
||||||
formik.resetForm();
|
resetForm();
|
||||||
setSelectedLocation(null);
|
setSelectedLocation(null);
|
||||||
setSelectedProjectFlock(null);
|
setSelectedProjectFlock(null);
|
||||||
setSelectedKandang(null);
|
setSelectedKandang(null);
|
||||||
setSelectedProduct(null);
|
setSelectedProduct(null);
|
||||||
setSelectedTransactionType(null);
|
setSelectedTransactionType(null);
|
||||||
setSelectedTransactionSubtype(null);
|
setSelectedTransactionSubtype(null);
|
||||||
|
setSelectedDepletionProduct(null);
|
||||||
setSelectedProjectFlockLocationId('');
|
setSelectedProjectFlockLocationId('');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -460,14 +505,18 @@ const InventoryAdjustmentForm = ({
|
|||||||
projectFlockKandangLookup.project_flock_kandang_id;
|
projectFlockKandangLookup.project_flock_kandang_id;
|
||||||
|
|
||||||
if (formik.values.project_flock_kandang_id !== projectFlockKandangId) {
|
if (formik.values.project_flock_kandang_id !== projectFlockKandangId) {
|
||||||
formik.setFieldValue('project_flock_kandang_id', projectFlockKandangId);
|
setFieldValue('project_flock_kandang_id', projectFlockKandangId);
|
||||||
formik.setFieldValue('project_flock_kandang', {
|
setFieldValue('project_flock_kandang', {
|
||||||
value: projectFlockKandangId,
|
value: projectFlockKandangId,
|
||||||
label: `${projectFlockKandangLookup.project_flock.flock_name} - ${projectFlockKandangLookup.kandang.name}`,
|
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(() => {
|
useEffect(() => {
|
||||||
if (initialValues && type === 'detail') {
|
if (initialValues && type === 'detail') {
|
||||||
@@ -519,7 +568,7 @@ const InventoryAdjustmentForm = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
formik.setValues({
|
setValues({
|
||||||
location: initialValues.location
|
location: initialValues.location
|
||||||
? {
|
? {
|
||||||
value: initialValues.location.id,
|
value: initialValues.location.id,
|
||||||
@@ -550,6 +599,8 @@ const InventoryAdjustmentForm = ({
|
|||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
product_id: initialValues.product_warehouse?.product?.id ?? 0,
|
product_id: initialValues.product_warehouse?.product?.id ?? 0,
|
||||||
|
depletion_product: null,
|
||||||
|
depletion_product_id: 0,
|
||||||
transaction_type: transactionType,
|
transaction_type: transactionType,
|
||||||
transaction_subtype: transactionSubtype,
|
transaction_subtype: transactionSubtype,
|
||||||
qty: initialValues.qty ?? '',
|
qty: initialValues.qty ?? '',
|
||||||
@@ -557,7 +608,7 @@ const InventoryAdjustmentForm = ({
|
|||||||
notes: initialValues.notes ?? '',
|
notes: initialValues.notes ?? '',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [formik.setValues, initialValues, type]);
|
}, [setValues, initialValues, type]);
|
||||||
|
|
||||||
// ===== Formik Error List =====
|
// ===== Formik Error List =====
|
||||||
const { formErrorList, close, handleFormSubmit } = useFormikErrorList(formik);
|
const { formErrorList, close, handleFormSubmit } = useFormikErrorList(formik);
|
||||||
@@ -729,6 +780,29 @@ const InventoryAdjustmentForm = ({
|
|||||||
isSearchable
|
isSearchable
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* RECORDING_DEPLETION_IN */}
|
||||||
|
{isDepletionProductVisible && (
|
||||||
|
<SelectInput
|
||||||
|
required
|
||||||
|
label='Jenis Deplesi'
|
||||||
|
value={selectedDepletionProduct}
|
||||||
|
onChange={depletionProductChangeHandler}
|
||||||
|
onInputChange={setDepletionProductInputValue}
|
||||||
|
options={depletionProductOptions}
|
||||||
|
onMenuScrollToBottom={loadMoreDepletionProducts}
|
||||||
|
isLoading={isLoadingDepletionProductOptions}
|
||||||
|
isError={
|
||||||
|
formik.touched.depletion_product_id &&
|
||||||
|
Boolean(formik.errors.depletion_product_id)
|
||||||
|
}
|
||||||
|
errorMessage={formik.errors.depletion_product_id as string}
|
||||||
|
isDisabled={type === 'detail'}
|
||||||
|
placeholder='Pilih Jenis Deplesi'
|
||||||
|
isClearable
|
||||||
|
isSearchable
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Number Input Quantity */}
|
{/* Number Input Quantity */}
|
||||||
<NumberInput
|
<NumberInput
|
||||||
className={{
|
className={{
|
||||||
|
|||||||
Reference in New Issue
Block a user