mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-25 07:45:47 +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,
|
SupplierApi,
|
||||||
WarehouseApi,
|
WarehouseApi,
|
||||||
} from '@/services/api/master-data';
|
} from '@/services/api/master-data';
|
||||||
|
import { toast } from 'react-hot-toast';
|
||||||
|
|
||||||
interface MovementFormProps {
|
interface MovementFormProps {
|
||||||
type?: 'add' | 'edit' | 'detail';
|
type?: 'add' | 'edit' | 'detail';
|
||||||
@@ -251,6 +252,37 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
|||||||
formikSetValues(formikInitialValues);
|
formikSetValues(formikInitialValues);
|
||||||
}, [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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<section className='w-full max-w-5xl'>
|
<section className='w-full max-w-5xl'>
|
||||||
@@ -419,6 +451,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Products table */}
|
{/* Products table */}
|
||||||
<div className='card bg-base-100 shadow mb-4'>
|
<div className='card bg-base-100 shadow mb-4'>
|
||||||
<div className='card-body'>
|
<div className='card-body'>
|
||||||
@@ -657,10 +690,9 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
|||||||
`ekspedisi.${idx}.product_id`,
|
`ekspedisi.${idx}.product_id`,
|
||||||
(val as OptionType)?.value
|
(val as OptionType)?.value
|
||||||
);
|
);
|
||||||
|
formik.setFieldValue(`ekspedisi.${idx}.qty`, '');
|
||||||
}}
|
}}
|
||||||
options={productOptions}
|
options={getFilteredProductOptions()}
|
||||||
onInputChange={setProductSelectInputValue}
|
|
||||||
isLoading={isLoadingProducts}
|
|
||||||
isDisabled={type === 'detail'}
|
isDisabled={type === 'detail'}
|
||||||
isClearable
|
isClearable
|
||||||
isError={isRepeaterInputError(
|
isError={isRepeaterInputError(
|
||||||
@@ -676,7 +708,16 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
|||||||
type='number'
|
type='number'
|
||||||
name={`ekspedisi.${idx}.qty`}
|
name={`ekspedisi.${idx}.qty`}
|
||||||
value={ekspedisi.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}
|
onBlur={formik.handleBlur}
|
||||||
isError={isRepeaterInputError(
|
isError={isRepeaterInputError(
|
||||||
'ekspedisi',
|
'ekspedisi',
|
||||||
|
|||||||
Reference in New Issue
Block a user