diff --git a/src/components/pages/production/recording/form/RecordingForm.schema.ts b/src/components/pages/production/recording/form/RecordingForm.schema.ts index 8ebd4aa2..18dc9823 100644 --- a/src/components/pages/production/recording/form/RecordingForm.schema.ts +++ b/src/components/pages/production/recording/form/RecordingForm.schema.ts @@ -104,7 +104,7 @@ export const RecordingGrowingFormSchema: Yup.ObjectSchema; diff --git a/src/components/pages/production/recording/form/RecordingForm.tsx b/src/components/pages/production/recording/form/RecordingForm.tsx index b45f72d0..3e40b404 100644 --- a/src/components/pages/production/recording/form/RecordingForm.tsx +++ b/src/components/pages/production/recording/form/RecordingForm.tsx @@ -56,6 +56,7 @@ import { import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang'; import { Kandang } from '@/types/api/master-data/kandang'; +import * as Yup from 'yup'; import { RecordingGrowingFormSchema, RecordingLayingFormSchema, @@ -231,6 +232,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { const [, setNewRecordingData] = useState(null); const [nextDayRecording, setNextDayRecording] = useState(null); + const [currentRecordDate, setCurrentRecordDate] = useState( + new Date().toISOString().split('T')[0] + ); + const [duplicateErrorShown, setDuplicateErrorShown] = useState(false); const approveModal = useModal(); const rejectModal = useModal(); @@ -719,18 +724,18 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { const recordedProjectFlockKandangIds = useMemo(() => { if (!isResponseSuccess(existingRecordings)) return new Set(); - const todayRecordings = existingRecordings.data; + const allRecordings = existingRecordings.data; const recordedIds = new Set(); - todayRecordings.forEach((recording) => { + allRecordings.forEach((recording) => { const recordingDate = recording.record_datetime?.split('T')[0]; - if (recordingDate === today) { + if (recordingDate === currentRecordDate) { recordedIds.add(recording.project_flock?.project_flock_kandang_id); } }); return recordedIds; - }, [existingRecordings, today]); + }, [existingRecordings, currentRecordDate]); const currentTotalChickQty = useMemo(() => { if (type === 'add' && projectFlockKandangLookup) { @@ -910,14 +915,38 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { initialValues: formikInitialValues, enableReinitialize: true, validationSchema: (() => { + let schema; if (isLayingCategory) { - return type === 'edit' - ? UpdateRecordingLayingFormSchema - : RecordingLayingFormSchema; + schema = + type === 'edit' + ? UpdateRecordingLayingFormSchema + : RecordingLayingFormSchema; + } else { + schema = + type === 'edit' + ? UpdateRecordingGrowingFormSchema + : RecordingGrowingFormSchema; } - return type === 'edit' - ? UpdateRecordingGrowingFormSchema - : RecordingGrowingFormSchema; + return schema.clone().concat( + Yup.object().shape({ + project_flock_kandang_id: Yup.number().test( + 'not-already-recorded', + 'Project Flock ini sudah direcord pada tanggal tersebut!', + function (value) { + if (type !== 'add') return true; + if (value && recordedProjectFlockKandangIds.has(value)) { + if (this.createError) { + return this.createError({ + message: `Project Flock ini sudah direcord pada tanggal ${formatDate(currentRecordDate, 'DD MMMM YYYY')}!`, + }); + } + return false; + } + return true; + } + ), + }) + ); })(), validateOnChange: true, validateOnBlur: true, @@ -1149,6 +1178,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { setSelectedLocation(location); setSelectedProjectFlock(null); setSelectedKandang(null); + if (duplicateErrorShown) { + toast.dismiss(); + setDuplicateErrorShown(false); + } setSelectedProjectFlockLocationId( location ? location.value.toString() : '' ); @@ -1159,6 +1192,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { const projectFlockChangeHandler = (val: OptionType | OptionType[] | null) => { setSelectedProjectFlock(val as OptionType); setSelectedKandang(null); + if (duplicateErrorShown) { + toast.dismiss(); + setDuplicateErrorShown(false); + } formik.setFieldValue('project_flock_kandang', null); formik.setFieldValue('project_flock_kandang_id', 0); }; @@ -1166,6 +1203,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { const kandangChangeHandler = (val: OptionType | OptionType[] | null) => { const kandang = val as OptionType; setSelectedKandang(kandang); + if (duplicateErrorShown) { + toast.dismiss(); + setDuplicateErrorShown(false); + } if (selectedLocation && kandang) { setStockProductsLocationId(selectedLocation.value.toString()); setStockProductsKandangId(kandang.value.toString()); @@ -1187,9 +1228,18 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { const handleRecordDateChange = useCallback( (e: React.ChangeEvent) => { - formik.setFieldValue('record_date', e.target.value); + const newDate = e.target.value; + formik.setFieldValue('record_date', newDate); + setCurrentRecordDate(newDate); + if (duplicateErrorShown) { + toast.dismiss(); + setDuplicateErrorShown(false); + } + setTimeout(() => { + formik.validateField('project_flock_kandang_id'); + }, 0); }, - [formik] + [formik, duplicateErrorShown] ); useEffect(() => { @@ -1199,8 +1249,19 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { if (type === 'add') { if (recordedProjectFlockKandangIds.has(projectFlockKandangId)) { - toast.error('Project Flock Kandang ini sudah direcord hari ini!'); + if (!duplicateErrorShown) { + toast.error( + `Project Flock Kandang ini sudah direcord pada tanggal ${formatDate(currentRecordDate, 'DD MMMM YYYY')}!`, + { duration: Infinity } + ); + setDuplicateErrorShown(true); + } return; + } else { + if (duplicateErrorShown) { + toast.dismiss(); + setDuplicateErrorShown(false); + } } if (