diff --git a/src/components/pages/production/recording/form/RecordingForm.tsx b/src/components/pages/production/recording/form/RecordingForm.tsx index a18921e3..c7361269 100644 --- a/src/components/pages/production/recording/form/RecordingForm.tsx +++ b/src/components/pages/production/recording/form/RecordingForm.tsx @@ -32,6 +32,7 @@ import { UpdateGrowingRecordingPayload, UpdateLayingRecordingPayload, Recording, + NextDayRecording, } from '@/types/api/production/recording'; import { type BaseApiResponse } from '@/types/api/api-general'; import { ProjectFlockKandangLookup } from '@/types/api/production/project-flock'; @@ -93,13 +94,15 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { const [isApproveLoading, setIsApproveLoading] = useState(false); const [isRejectLoading, setIsRejectLoading] = useState(false); - const [approvalNotes, setApprovalNotes] = useState(''); + const [, setApprovalNotes] = useState(''); const [recordingFormErrorMessage, setRecordingFormErrorMessage] = useState(''); const [isDeleteLoading, setIsDeleteLoading] = useState(false); const [newRecordingData, setNewRecordingData] = useState( null ); + const [nextDayRecording, setNextDayRecording] = + useState(null); const approveModal = useModal(); const rejectModal = useModal(); @@ -382,6 +385,38 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { RecordingApi.getAllFetcher ); + const nextDayRecordingUrl = useMemo(() => { + if (!selectedProjectFlock) return null; + const projectFlockId = + typeof selectedProjectFlock.value === 'string' + ? parseInt(selectedProjectFlock.value, 10) + : selectedProjectFlock.value; + return `${RecordingApi.basePath}/next-day?project_flock_id=${projectFlockId}`; + }, [selectedProjectFlock]); + + const { data: nextDayRecordingData } = useSWR( + nextDayRecordingUrl, + nextDayRecordingUrl + ? () => { + const projectFlockId = + typeof selectedProjectFlock!.value === 'string' + ? parseInt(selectedProjectFlock!.value, 10) + : selectedProjectFlock!.value; + return RecordingApi.nextDayRecording(projectFlockId); + } + : null + ); + + useEffect(() => { + if (nextDayRecordingData?.status === 'success') { + setNextDayRecording( + nextDayRecordingData.data as unknown as NextDayRecording + ); + } else { + setNextDayRecording(null); + } + }, [nextDayRecordingData]); + const { data: stockProducts, isLoading: isLoadingStockProducts } = useSWR( stockProductsUrl, ProductWarehouseApi.getAllFetcher @@ -1057,12 +1092,33 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { const projectFlockKandangId = projectFlockKandangLookup.project_flock_kandang_id; - if ( - type === 'add' && - recordedProjectFlockKandangIds.has(projectFlockKandangId) - ) { - toast.error('Project Flock Kandang ini sudah direcord hari ini!'); - return; + if (type === 'add') { + if (recordedProjectFlockKandangIds.has(projectFlockKandangId)) { + toast.error('Project Flock Kandang ini sudah direcord hari ini!'); + return; + } + + if ( + nextDayRecording && + nextDayRecording.project_flock_kandang_id === projectFlockKandangId + ) { + const hasSameDayRecording = isResponseSuccess(existingRecordings) + ? existingRecordings.data?.some( + (recording: Recording) => + recording.project_flock_kandang_id === + projectFlockKandangId && + recording.day === nextDayRecording.next_day + ) + : false; + + if (hasSameDayRecording) { + toast.error( + `Recording untuk hari ${nextDayRecording.next_day} sudah ada. + Tidak bisa membuat recording duplikat, mohon perbarui recording yang sudah ada terlebih dahulu.` + ); + return; + } + } } if (formik.values.project_flock_kandang_id !== projectFlockKandangId) { @@ -1083,6 +1139,9 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { type, recordedProjectFlockKandangIds, formik.values.project_flock_kandang_id, + nextDayRecording, + existingRecordings, + today, ]); useEffect(() => { diff --git a/src/services/api/production.ts b/src/services/api/production.ts index 449a249e..1feead25 100644 --- a/src/services/api/production.ts +++ b/src/services/api/production.ts @@ -11,6 +11,7 @@ import { UpdateRecordingPayload, CreateGradingPayload, UpdateGradingPayload, + NextDayRecording, } from '@/types/api/production/recording'; import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang'; @@ -95,6 +96,17 @@ export class RecordingService extends BaseApiService< } ); } + + async nextDayRecording( + projectFlockId: number + ): Promise | undefined> { + return await this.customRequest>(`next-day`, { + method: 'GET', + params: { + project_flock_id: projectFlockId, + }, + }); + } } export const RecordingApi = new RecordingService('/production/recordings'); diff --git a/src/types/api/production/recording.d.ts b/src/types/api/production/recording.d.ts index 6c5a7ee9..e7b28f47 100644 --- a/src/types/api/production/recording.d.ts +++ b/src/types/api/production/recording.d.ts @@ -87,6 +87,11 @@ export type Recording = BaseMetadata & grading_eggs?: GradingEgg[]; }; +export type NextDayRecording = { + project_flock_kandang_id: number; + next_day: number; +}; + export type CreateGrowingRecordingPayload = { project_flock_kandang_id: number; body_weights: {