diff --git a/src/components/pages/purchase/form/request/PurchaseRequestForm.tsx b/src/components/pages/purchase/form/request/PurchaseRequestForm.tsx index 53ff5027..1fdb1e65 100644 --- a/src/components/pages/purchase/form/request/PurchaseRequestForm.tsx +++ b/src/components/pages/purchase/form/request/PurchaseRequestForm.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useFormik } from 'formik'; import useSWR from 'swr'; import { useRouter } from 'next/navigation'; @@ -234,6 +234,8 @@ const PurchaseRequestForm = ({ }, }); + const { setFieldValue, setFieldTouched, handleBlur } = formik; + const handleValidateForm = async () => { const errors = await formik.validateForm(); @@ -317,51 +319,73 @@ const PurchaseRequestForm = ({ }; // ===== UTILITY FUNCTIONS ===== - const updateCreditTermBasedOnSupplier = useCallback( - (supplierId: number) => { - if (supplierId > 0 && isResponseSuccess(supplierRawData)) { - const supplierData = supplierRawData.data.find( - (s: Supplier) => s.id === supplierId - ); - if (supplierData?.due_date) { - formik.setFieldTouched('credit_term', false); - formik.setFieldValue('credit_term', supplierData.due_date.toString()); - } else { - formik.setFieldTouched('credit_term', false); - formik.setFieldValue('credit_term', ''); - } - } else { - formik.setFieldTouched('credit_term', false); - formik.setFieldValue('credit_term', ''); - } - }, - [supplierRawData] - ); + const prevSupplierIdRef = useRef(''); - const resetPurchaseItems = useCallback(() => { - if (formik.values.items) { - formik.values.items.forEach((_, idx) => { - formik.setFieldTouched(`items.${idx}.product`, false); - formik.setFieldValue(`items.${idx}.product`, null); - formik.setFieldTouched(`items.${idx}.product_id`, false); - formik.setFieldValue(`items.${idx}.product_id`, 0); - formik.setFieldTouched(`items.${idx}.qty`, false); - formik.setFieldValue(`items.${idx}.qty`, 0); - }); - } - }, []); - - // ===== SIDE EFFECTS ===== useEffect(() => { - if (formik.values.supplier_id && Number(formik.values.supplier_id) > 0) { - updateCreditTermBasedOnSupplier(Number(formik.values.supplier_id)); - resetPurchaseItems(); - } else { - formik.setFieldTouched('credit_term', false); - formik.setFieldValue('credit_term', ''); - resetPurchaseItems(); + const currentSupplierId = formik.values.supplier_id || ''; + + if (currentSupplierId === prevSupplierIdRef.current) { + return; } - }, [formik.values.supplier_id]); + + prevSupplierIdRef.current = currentSupplierId; + + if (currentSupplierId && Number(currentSupplierId) > 0) { + if (isResponseSuccess(supplierRawData)) { + const supplierData = supplierRawData.data.find( + (s: Supplier) => s.id === Number(currentSupplierId) + ); + const newCreditTerm = supplierData?.due_date || 0; + if (formik.values.credit_term !== newCreditTerm) { + setFieldTouched('credit_term', false); + setFieldValue('credit_term', newCreditTerm); + } + } + + const itemsNeedReset = formik.values.items?.filter( + (item) => item.product_id !== 0 || item.product !== null + ); + if (itemsNeedReset && itemsNeedReset.length > 0) { + formik.values.items.forEach((item, idx) => { + if (item.product_id !== 0 || item.product !== null) { + setFieldTouched(`items.${idx}.product`, false); + setFieldValue(`items.${idx}.product`, null); + setFieldTouched(`items.${idx}.product_id`, false); + setFieldValue(`items.${idx}.product_id`, 0); + setFieldTouched(`items.${idx}.qty`, false); + setFieldValue(`items.${idx}.qty`, 0); + } + }); + } + } else { + if (formik.values.credit_term !== 0) { + setFieldTouched('credit_term', false); + setFieldValue('credit_term', 0); + } + const itemsNeedReset = formik.values.items?.filter( + (item) => item.product_id !== 0 || item.product !== null + ); + if (itemsNeedReset && itemsNeedReset.length > 0) { + formik.values.items.forEach((item, idx) => { + if (item.product_id !== 0 || item.product !== null) { + setFieldTouched(`items.${idx}.product`, false); + setFieldValue(`items.${idx}.product`, null); + setFieldTouched(`items.${idx}.product_id`, false); + setFieldValue(`items.${idx}.product_id`, 0); + setFieldTouched(`items.${idx}.qty`, false); + setFieldValue(`items.${idx}.qty`, 0); + } + }); + } + } + }, [ + formik.values.supplier_id, + formik.values.items, + formik.values.credit_term, + supplierRawData, + setFieldTouched, + setFieldValue, + ]); useEffect(() => { if (type !== 'add' && initialValues) { @@ -381,63 +405,63 @@ const PurchaseRequestForm = ({ const supplier = val as OptionType | null; const supplierId = Number(supplier?.value); - formik.setFieldTouched('supplier', true); - formik.setFieldValue('supplier', supplier); - formik.setFieldTouched('supplier_id', true); - formik.setFieldValue('supplier_id', supplierId); + setFieldTouched('supplier', true); + setFieldValue('supplier', supplier); + setFieldTouched('supplier_id', true); + setFieldValue('supplier_id', supplierId); }, - [] + [setFieldTouched, setFieldValue] ); const handleCreditTermChange = useCallback( (e: React.ChangeEvent) => { const value = e.target.value; - formik.setFieldTouched('credit_term', true); - formik.setFieldValue('credit_term', value); + setFieldTouched('credit_term', true); + setFieldValue('credit_term', value); }, - [] + [setFieldTouched, setFieldValue] ); const handleCreditTermBlur = useCallback( (e: React.FocusEvent) => { - formik.handleBlur(e); + handleBlur(e); }, - [formik] + [handleBlur] ); const handleAreaChange = useCallback( (val: OptionType | OptionType[] | null) => { const area = val as OptionType | null; - formik.setFieldTouched('area_id', true); - formik.setFieldValue('area_id', (area as OptionType)?.value || 0); - formik.setFieldTouched('area', true); - formik.setFieldValue('area', area); + setFieldTouched('area_id', true); + setFieldValue('area_id', (area as OptionType)?.value || 0); + setFieldTouched('area', true); + setFieldValue('area', area); setSelectedArea((area as OptionType)?.value as string); setSelectedLocation(''); const disabled = (area as OptionType)?.value == null; setDisabledLocation(disabled); - formik.setFieldTouched('location_id', false); - formik.setFieldValue('location_id', 0); - formik.setFieldTouched('location', false); - formik.setFieldValue('location', null); + setFieldTouched('location_id', false); + setFieldValue('location_id', 0); + setFieldTouched('location', false); + setFieldValue('location', null); }, - [] + [setFieldTouched, setFieldValue] ); const handleLocationChange = useCallback( (val: OptionType | OptionType[] | null) => { const location = val as OptionType | null; - formik.setFieldTouched('location_id', true); - formik.setFieldValue('location_id', (location as OptionType)?.value || 0); - formik.setFieldTouched('location', true); - formik.setFieldValue('location', location); + setFieldTouched('location_id', true); + setFieldValue('location_id', (location as OptionType)?.value || 0); + setFieldTouched('location', true); + setFieldValue('location', location); setSelectedLocation((location as OptionType)?.value as string); }, - [] + [setFieldTouched, setFieldValue] ); const handleWarehouseChange = useCallback( @@ -445,12 +469,12 @@ const PurchaseRequestForm = ({ const warehouse = val as OptionType | null; const warehouseId = (warehouse as OptionType)?.value || 0; - formik.setFieldTouched(`items.${idx}.warehouse`, true); - formik.setFieldValue(`items.${idx}.warehouse`, warehouse); - formik.setFieldTouched(`items.${idx}.warehouse_id`, true); - formik.setFieldValue(`items.${idx}.warehouse_id`, warehouseId); + setFieldTouched(`items.${idx}.warehouse`, true); + setFieldValue(`items.${idx}.warehouse`, warehouse); + setFieldTouched(`items.${idx}.warehouse_id`, true); + setFieldValue(`items.${idx}.warehouse_id`, warehouseId); }, - [] + [setFieldTouched, setFieldValue] ); // ===== PURCHASE ITEM OPERATIONS =====