mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
feat(FE-62): add quantity validation for ekspedisi in MovementForm and filter product options
This commit is contained in:
@@ -30,6 +30,7 @@ import {
|
||||
SupplierApi,
|
||||
WarehouseApi,
|
||||
} from '@/services/api/master-data';
|
||||
import { toast } from 'react-hot-toast';
|
||||
|
||||
interface MovementFormProps {
|
||||
type?: 'add' | 'edit' | 'detail';
|
||||
@@ -251,6 +252,37 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
formikSetValues(formikInitialValues);
|
||||
}, [formikSetValues, formikInitialValues]);
|
||||
|
||||
const getFilteredProductOptions = useCallback(() => {
|
||||
return (
|
||||
formik.values.product
|
||||
?.filter((p) => p.product)
|
||||
.map((p) => ({
|
||||
value: p.product_id,
|
||||
label: (p.product as OptionType)?.label,
|
||||
})) ?? []
|
||||
);
|
||||
}, [formik.values.product]);
|
||||
|
||||
const validateEkspedisiQty = (ekspedisiIdx: number, qty: number) => {
|
||||
const productId = formik.values.ekspedisi?.[ekspedisiIdx]?.product_id;
|
||||
if (!productId) return true;
|
||||
|
||||
const relatedProduct = formik.values.product?.find(
|
||||
(p) => p.product_id === productId
|
||||
);
|
||||
if (!relatedProduct) return true;
|
||||
|
||||
const totalQtyUsed =
|
||||
formik.values.ekspedisi?.reduce((total, eks, i) => {
|
||||
if (eks.product_id === productId && i !== ekspedisiIdx) {
|
||||
return total + (Number(eks.qty) || 0);
|
||||
}
|
||||
return total;
|
||||
}, 0) || 0;
|
||||
|
||||
return totalQtyUsed + qty <= Number(relatedProduct.qty_product);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className='w-full max-w-5xl'>
|
||||
@@ -419,6 +451,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Products table */}
|
||||
<div className='card bg-base-100 shadow mb-4'>
|
||||
<div className='card-body'>
|
||||
@@ -657,10 +690,9 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
`ekspedisi.${idx}.product_id`,
|
||||
(val as OptionType)?.value
|
||||
);
|
||||
formik.setFieldValue(`ekspedisi.${idx}.qty`, '');
|
||||
}}
|
||||
options={productOptions}
|
||||
onInputChange={setProductSelectInputValue}
|
||||
isLoading={isLoadingProducts}
|
||||
options={getFilteredProductOptions()}
|
||||
isDisabled={type === 'detail'}
|
||||
isClearable
|
||||
isError={isRepeaterInputError(
|
||||
@@ -676,7 +708,16 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
type='number'
|
||||
name={`ekspedisi.${idx}.qty`}
|
||||
value={ekspedisi.qty ?? ''}
|
||||
onChange={formik.handleChange}
|
||||
onChange={(e) => {
|
||||
const newQty = Number(e.target.value);
|
||||
if (validateEkspedisiQty(idx, newQty)) {
|
||||
formik.handleChange(e);
|
||||
} else {
|
||||
toast.error(
|
||||
'Quantity exceeds available product quantity'
|
||||
);
|
||||
}
|
||||
}}
|
||||
onBlur={formik.handleBlur}
|
||||
isError={isRepeaterInputError(
|
||||
'ekspedisi',
|
||||
|
||||
Reference in New Issue
Block a user