diff --git a/src/components/pages/production/recording/form/RecordingForm.tsx b/src/components/pages/production/recording/form/RecordingForm.tsx index cbb9242b..2e4ebc48 100644 --- a/src/components/pages/production/recording/form/RecordingForm.tsx +++ b/src/components/pages/production/recording/form/RecordingForm.tsx @@ -89,6 +89,9 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { const [recordingFormErrorMessage, setRecordingFormErrorMessage] = useState(''); const [isDeleteLoading, setIsDeleteLoading] = useState(false); + const [newRecordingData, setNewRecordingData] = useState( + null + ); const approveModal = useModal(); const rejectModal = useModal(); @@ -112,6 +115,71 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { ); }, []); + // ===== PAYLOAD CREATION HELPERS ===== + const createGrowingPayload = useCallback( + (values: RecordingGrowingFormValues) => { + return { + project_flock_kandang_id: values.project_flock_kandang_id, + body_weights: (values.body_weights ?? []).map((bw) => { + const qty = Number(bw.qty) || 0; + const weight = Number(bw.weight) || 0; + const totalWeight = qty * weight; + return { + avg_weight: + typeof bw.avg_weight === 'number' + ? bw.avg_weight + : parseFloat(String(bw.avg_weight)) || 0, + qty: qty, + total_weight: parseFloat(String(totalWeight)) || 0, + }; + }), + stocks: (values.stocks ?? []).map((stock) => ({ + product_warehouse_id: stock.product_warehouse_id, + qty: Number(stock.qty) || 0, + })), + depletions: (values.depletions ?? []).map((depletion) => ({ + product_warehouse_id: depletion.product_warehouse_id, + qty: Number(depletion.qty) || 0, + })), + }; + }, + [] + ); + + const createLayingPayload = useCallback( + (values: RecordingLayingFormValues) => { + return { + project_flock_kandang_id: values.project_flock_kandang_id, + body_weights: (values.body_weights ?? []).map((bw) => { + const qty = Number(bw.qty) || 0; + const weight = Number(bw.weight) || 0; + const totalWeight = qty * weight; + return { + avg_weight: + typeof bw.avg_weight === 'number' + ? bw.avg_weight + : parseFloat(String(bw.avg_weight)) || 0, + qty: qty, + total_weight: parseFloat(String(totalWeight)) || 0, + }; + }), + stocks: (values.stocks ?? []).map((stock) => ({ + product_warehouse_id: stock.product_warehouse_id, + qty: Number(stock.qty) || 0, + })), + depletions: (values.depletions ?? []).map((depletion) => ({ + product_warehouse_id: depletion.product_warehouse_id, + qty: Number(depletion.qty) || 0, + })), + eggs: (values.eggs ?? []).map((egg) => ({ + product_warehouse_id: egg.product_warehouse_id, + qty: Number(egg.qty) || 0, + })), + }; + }, + [] + ); + // ===== FORM HANDLERS ===== const createRecordingHandler = useCallback( async ( @@ -128,6 +196,35 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { [router] ); + const createRecordingHandlerWithRedirect = useCallback( + async ( + payload: CreateGrowingRecordingPayload | CreateLayingRecordingPayload, + redirectToGrading: boolean = false + ) => { + const res = await RecordingApi.create(payload); + if (isResponseError(res)) { + setRecordingFormErrorMessage(res.message); + return null; + } + + toast.success(res?.message as string); + + if (res?.status === 'success' && res.data) { + setNewRecordingData(res.data); + return res.data; + } + + if (redirectToGrading) { + toast.error( + 'Gagal mendapatkan ID recording. Silakan coba dari halaman list.' + ); + router.push('/production/recording'); + } + return null; + }, + [router] + ); + const updateRecordingHandler = useCallback( async ( recordingId: number, @@ -370,7 +467,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { const recordedProjectFlockKandangIds = useMemo(() => { if (!isResponseSuccess(existingRecordings)) return new Set(); - const todayRecordings = existingRecordings?.data || []; + const todayRecordings = existingRecordings.data; const recordedIds = new Set(); todayRecordings.forEach((recording) => { @@ -558,36 +655,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { onSubmit: async (values) => { if (isLayingCategory) { const layingValues = values as RecordingLayingFormValues; - - const layingPayload = { - project_flock_kandang_id: layingValues.project_flock_kandang_id, - body_weights: (layingValues.body_weights ?? []).map((bw) => { - const qty = Number(bw.qty) || 0; - const weight = Number(bw.weight) || 0; - const totalWeight = qty * weight; - - return { - avg_weight: - typeof bw.avg_weight === 'number' - ? bw.avg_weight - : parseFloat(String(bw.avg_weight)) || 0, - qty: qty, - total_weight: parseFloat(String(totalWeight)) || 0, - }; - }), - stocks: (layingValues.stocks ?? []).map((stock) => ({ - product_warehouse_id: stock.product_warehouse_id, - qty: Number(stock.qty) || 0, - })), - depletions: (layingValues.depletions ?? []).map((depletion) => ({ - product_warehouse_id: depletion.product_warehouse_id, - qty: Number(depletion.qty) || 0, - })), - eggs: (layingValues.eggs ?? []).map((egg) => ({ - product_warehouse_id: egg.product_warehouse_id, - qty: Number(egg.qty) || 0, - })), - }; + const layingPayload = createLayingPayload(layingValues); switch (type) { case 'add': @@ -604,32 +672,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { } } else { const growingValues = values as RecordingGrowingFormValues; - - const growingPayload = { - project_flock_kandang_id: growingValues.project_flock_kandang_id, - body_weights: (growingValues.body_weights ?? []).map((bw) => { - const qty = Number(bw.qty) || 0; - const weight = Number(bw.weight) || 0; - const totalWeight = qty * weight; - - return { - avg_weight: - typeof bw.avg_weight === 'number' - ? bw.avg_weight - : parseFloat(String(bw.avg_weight)) || 0, - qty: qty, - total_weight: parseFloat(String(totalWeight)) || 0, - }; - }), - stocks: (growingValues.stocks ?? []).map((stock) => ({ - product_warehouse_id: stock.product_warehouse_id, - qty: Number(stock.qty) || 0, - })), - depletions: (growingValues.depletions ?? []).map((depletion) => ({ - product_warehouse_id: depletion.product_warehouse_id, - qty: Number(depletion.qty) || 0, - })), - }; + const growingPayload = createGrowingPayload(growingValues); switch (type) { case 'add': @@ -1243,6 +1286,9 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { } else { setFormSteps(null); } + if (type !== 'add') { + setNewRecordingData(null); + } }, [isLayingCategory, type]); const bodyWeightValues = useMemo(() => { @@ -2464,13 +2510,22 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { type='button' color='primary' onClick={() => { - router.push( - `/production/recording/grading/add?recording_id=${initialValues?.id}` - ); + const recordingId = + newRecordingData?.id || initialValues?.id; + if (recordingId) { + router.push( + `/production/recording/grading/add?recording_id=${recordingId}` + ); + } else { + toast.error( + 'Recording ID tidak ditemukan. Silakan refresh halaman.' + ); + } }} > - {hasGradingData(initialValues) + {hasGradingData(initialValues) || + hasGradingData(newRecordingData || undefined) ? 'Edit Grading' : 'Lanjut ke Grading'} @@ -2536,20 +2591,45 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { formik.isSubmitting } onClick={async () => { - await formik.submitForm(); - if ( - formik.isValid && - !formik.isSubmitting && - !hasExceededStock - ) { - toast.success( - 'Recording berhasil disimpan! Mengalihkan ke form Grading...' + if (!formik.isValid) { + await formik.validateForm(); + return; + } + + setRecordingFormErrorMessage(''); + formik.setSubmitting(true); + + try { + if (isLayingCategory) { + const layingValues = + formik.values as RecordingLayingFormValues; + const layingPayload = + createLayingPayload(layingValues); + + const recordingData = + await createRecordingHandlerWithRedirect( + layingPayload as CreateLayingRecordingPayload, + true + ); + + if (recordingData?.id) { + toast.success( + 'Recording berhasil disimpan! Mengalihkan ke form Grading...' + ); + setTimeout(() => { + router.push( + `/production/recording/grading/add?recording_id=${recordingData.id}` + ); + }, 1000); + } + } + } catch (error) { + console.error('Error creating recording:', error); + toast.error( + 'Gagal membuat recording. Silakan coba lagi.' ); - setTimeout(() => { - router.push( - `/production/recording/grading/add?recording_id=${initialValues?.id || ''}` - ); - }, 1000); + } finally { + formik.setSubmitting(false); } }} >