diff --git a/src/components/pages/inventory/movement/form/MovementForm.tsx b/src/components/pages/inventory/movement/form/MovementForm.tsx index d4c0c838..e4dd9c51 100644 --- a/src/components/pages/inventory/movement/form/MovementForm.tsx +++ b/src/components/pages/inventory/movement/form/MovementForm.tsx @@ -54,6 +54,8 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { const [selectedProducts, setSelectedProducts] = useState([]); const [selectedDeliveries, setSelectedDeliveries] = useState([]); const [formErrorList, setFormErrorList] = useState([]); + const [productQtyErrorShown, setProductQtyErrorShown] = useState(false); + const [deliveryQtyErrorShown, setDeliveryQtyErrorShown] = useState(false); // ===== FORM HANDLERS ===== const createMovementHandler = useCallback( @@ -465,17 +467,25 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { formik.setFieldValue('products', newProducts); }, []); - const removeProduct = useCallback((i: number) => { - const updatedProducts = - formik.values.products?.reduce((acc: ProductSchema[], item, index) => { - if (index !== i) { - acc.push(item); - } - return acc; - }, []) ?? []; + const removeProduct = useCallback( + (i: number) => { + const updatedProducts = + formik.values.products?.reduce((acc: ProductSchema[], item, index) => { + if (index !== i) { + acc.push(item); + } + return acc; + }, []) ?? []; - formik.setFieldValue('products', updatedProducts); - }, []); + formik.setFieldValue('products', updatedProducts); + + if (productQtyErrorShown) { + toast.dismiss(); + setProductQtyErrorShown(false); + } + }, + [productQtyErrorShown] + ); const bulkRemoveProduct = useCallback(() => { const updatedProducts = @@ -484,7 +494,12 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { ) ?? []; formik.setFieldValue('products', updatedProducts); setSelectedProducts([]); - }, [formik, selectedProducts, setSelectedProducts]); + + if (productQtyErrorShown) { + toast.dismiss(); + setProductQtyErrorShown(false); + } + }, [formik, selectedProducts, setSelectedProducts, productQtyErrorShown]); const handleProductChange = useCallback( (idx: number, val: OptionType | OptionType[] | null) => { @@ -544,17 +559,28 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { ]); }, []); - const removeDelivery = useCallback((i: number) => { - const updatedDeliveries = - formik.values.deliveries?.reduce((acc: DeliverySchema[], item, index) => { - if (index !== i) { - acc.push(item); - } - return acc; - }, []) ?? []; + const removeDelivery = useCallback( + (i: number) => { + const updatedDeliveries = + formik.values.deliveries?.reduce( + (acc: DeliverySchema[], item, index) => { + if (index !== i) { + acc.push(item); + } + return acc; + }, + [] + ) ?? []; - formik.setFieldValue('deliveries', updatedDeliveries); - }, []); + formik.setFieldValue('deliveries', updatedDeliveries); + + if (deliveryQtyErrorShown) { + toast.dismiss(); + setDeliveryQtyErrorShown(false); + } + }, + [deliveryQtyErrorShown] + ); const bulkRemoveDelivery = useCallback(() => { const updatedDeliveries = @@ -563,7 +589,17 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { ) ?? []; formik.setFieldValue('deliveries', updatedDeliveries); setSelectedDeliveries([]); - }, [formik, selectedDeliveries, setSelectedDeliveries]); + + if (deliveryQtyErrorShown) { + toast.dismiss(); + setDeliveryQtyErrorShown(false); + } + }, [ + formik, + selectedDeliveries, + setSelectedDeliveries, + deliveryQtyErrorShown, + ]); const handleDeliverySelectAllChange = useCallback( (e: React.ChangeEvent) => { @@ -1038,6 +1074,73 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { formik.errors.destination_warehouse_id, ]); + useEffect(() => { + if (productQtyErrorShown) { + toast.dismiss(); + setProductQtyErrorShown(false); + } + }, [formik.values.products?.map((p) => p.product_qty).join(',')]); + + useEffect(() => { + if (deliveryQtyErrorShown) { + toast.dismiss(); + setDeliveryQtyErrorShown(false); + } + }, [ + formik.values.deliveries + ?.map((d) => d.products.map((p) => p.product_qty).join(',')) + .join('|'), + ]); + + useEffect(() => { + if (hasExceededStock && !productQtyErrorShown && type !== 'detail') { + const firstErrorIndex = formik.values.products?.findIndex( + (product, idx) => getProductQtyError(idx) !== null + ); + if (firstErrorIndex !== undefined && firstErrorIndex >= 0) { + const errorMsg = getProductQtyError(firstErrorIndex); + if (errorMsg) { + toast.error(errorMsg, { duration: Infinity }); + setProductQtyErrorShown(true); + } + } + } + }, [ + hasExceededStock, + productQtyErrorShown, + type, + formik.values.products, + getProductQtyError, + ]); + + useEffect(() => { + if (hasInvalidQty && !deliveryQtyErrorShown && type !== 'detail') { + const firstError = formik.values.deliveries?.find( + (delivery, deliveryIdx) => + delivery.products.some( + (product, productIdx) => + getDeliveryQtyError(deliveryIdx, productIdx) !== null + ) + ); + if (firstError) { + const deliveryIdx = formik.values.deliveries?.indexOf(firstError); + if (deliveryIdx !== undefined && deliveryIdx >= 0) { + const errorMsg = getDeliveryQtyError(deliveryIdx, 0); + if (errorMsg) { + toast.error(errorMsg, { duration: Infinity }); + setDeliveryQtyErrorShown(true); + } + } + } + } + }, [ + hasInvalidQty, + deliveryQtyErrorShown, + type, + formik.values.deliveries, + getDeliveryQtyError, + ]); + const handleValidateForm = async () => { const errors = await formik.validateForm(); @@ -1856,8 +1959,6 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { className='px-4' isLoading={formik.isSubmitting} disabled={ - hasInvalidQty || - hasExceededStock || formik.isSubmitting || (formik.values.source_warehouse_id === formik.values.destination_warehouse_id &&