From cc0b051a0a3f157a03b69975a3a744e61b036eaf Mon Sep 17 00:00:00 2001 From: rstubryan Date: Tue, 30 Dec 2025 21:55:37 +0700 Subject: [PATCH] refactor(FE-440): Remove body_weights handling from recording forms --- .../recording/form/RecordingForm.schema.ts | 43 -- .../recording/form/RecordingForm.tsx | 487 ------------------ src/types/api/production/recording.d.ts | 11 - 3 files changed, 541 deletions(-) diff --git a/src/components/pages/production/recording/form/RecordingForm.schema.ts b/src/components/pages/production/recording/form/RecordingForm.schema.ts index 30013001..4901b349 100644 --- a/src/components/pages/production/recording/form/RecordingForm.schema.ts +++ b/src/components/pages/production/recording/form/RecordingForm.schema.ts @@ -12,11 +12,6 @@ type RecordingGrowingFormSchemaType = { label: string; } | null; project_flock_kandang_id: number; - body_weights: { - weight: number | string; - avg_weight: number | string; - qty: number | string; - }[]; stocks: { product_warehouse_id: number; qty: number | string; @@ -35,12 +30,6 @@ type RecordingLayingFormSchemaType = RecordingGrowingFormSchemaType & { }[]; }; -export type BodyWeightSchema = { - weight: number | string; - avg_weight: number | string; - qty: number | string; -}; - export type StockSchema = { product_warehouse_id: number; qty: number | string; @@ -57,20 +46,6 @@ export type EggSchema = { weight: number | string; }; -const BodyWeightObjectSchema: Yup.ObjectSchema = Yup.object({ - weight: Yup.number() - .required('Berat ayam total wajib diisi!') - .min(1, 'Berat ayam total minimal 1 gram!') - .typeError('Berat ayam total harus berupa angka!'), - avg_weight: Yup.number() - .required('Berat ayam rata-rata wajib diisi!') - .typeError('Berat ayam rata-rata harus berupa angka!'), - qty: Yup.number() - .required('Jumlah ayam wajib diisi!') - .min(1, 'Jumlah ayam minimal 1 ekor!') - .typeError('Jumlah ayam harus berupa angka!'), -}); - const StockObjectSchema: Yup.ObjectSchema = Yup.object({ product_warehouse_id: Yup.number() .required('Produk wajib diisi!') @@ -140,10 +115,6 @@ export const RecordingGrowingFormSchema: Yup.ObjectSchema; type RecordingFormData = Partial & { - body_weights?: CreateGrowingRecordingPayload['body_weights']; stocks?: CreateGrowingRecordingPayload['stocks'] | Recording['stocks']; depletions?: | CreateGrowingRecordingPayload['depletions'] @@ -216,19 +186,6 @@ export const getRecordingGrowingFormInitialValues = ( } : null, project_flock_kandang_id: initialValues?.project_flock_kandang_id ?? 0, - body_weights: initialValues?.body_weights?.map( - (bw: NonNullable[0]) => ({ - weight: bw.avg_weight * bw.qty, - avg_weight: bw.avg_weight, - qty: bw.qty, - }) - ) ?? [ - { - weight: '', - avg_weight: '', - qty: '', - }, - ], stocks: initialValues?.stocks?.map((stock) => ({ product_warehouse_id: stock.product_warehouse_id, qty: diff --git a/src/components/pages/production/recording/form/RecordingForm.tsx b/src/components/pages/production/recording/form/RecordingForm.tsx index c8fa3ca0..f9182cab 100644 --- a/src/components/pages/production/recording/form/RecordingForm.tsx +++ b/src/components/pages/production/recording/form/RecordingForm.tsx @@ -71,16 +71,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { const router = useRouter(); // ===== STATE MANAGEMENT ===== - const [selectedBodyWeights, setSelectedBodyWeights] = useState([]); const [selectedStocks, setSelectedStocks] = useState([]); const [selectedDepletions, setSelectedDepletions] = useState([]); const [selectedEggs, setSelectedEggs] = useState([]); - const [editingAverageIndex] = useState(null); - const [manuallyEditedRows, setManuallyEditedRows] = useState>( - new Set() - ); - const [locationSearchValue, setLocationSearchValue] = useState(''); const [selectedLocation, setSelectedLocation] = useState( null @@ -122,19 +116,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { (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, @@ -152,15 +133,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { (values: RecordingLayingFormValues) => { return { project_flock_kandang_id: values.project_flock_kandang_id, - body_weights: (values.body_weights ?? []).map((bw) => { - return { - avg_weight: - typeof bw.avg_weight === 'number' - ? bw.avg_weight - : parseFloat(String(bw.avg_weight)) || 0, - qty: Number(bw.qty) || 0, - }; - }), stocks: (values.stocks ?? []).map((stock) => ({ product_warehouse_id: stock.product_warehouse_id, qty: Number(stock.qty) || 0, @@ -587,28 +559,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { return recordedIds; }, [existingRecordings, today]); - const getLatestTotalChickQty = useCallback( - (projectFlockKandangId: number) => { - if (!isResponseSuccess(existingRecordings)) return null; - - const projectFlockRecordings = existingRecordings.data.filter( - (recording) => - recording.project_flock_kandang_id === projectFlockKandangId - ); - - if (projectFlockRecordings.length === 0) return null; - - projectFlockRecordings.sort( - (a, b) => - new Date(b.record_datetime).getTime() - - new Date(a.record_datetime).getTime() - ); - - return projectFlockRecordings[0].total_chick_qty; - }, - [existingRecordings] - ); - const unifiedStockProducts = useMemo(() => { const options: OptionType[] = []; if (isResponseSuccess(stockProducts) && selectedKandang) { @@ -808,25 +758,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { }); // ===== HELPER FUNCTIONS ===== - const getTotalChickQtyError = useCallback( - (qty: number) => { - if (type === 'detail') return null; - if (!formik.values.project_flock_kandang_id) return null; - - const totalChickQty = getLatestTotalChickQty( - formik.values.project_flock_kandang_id - ); - if (!totalChickQty) return null; - - if (qty > totalChickQty) { - return `Jumlah ayam tidak boleh melebihi total ayam tersedia! Maksimal: ${formatNumber(totalChickQty)}`; - } - - return null; - }, - [formik.values.project_flock_kandang_id, getLatestTotalChickQty, type] - ); - useCallback((): OptionType | null => { if ( !formik.values.project_flock_kandang || @@ -1193,124 +1124,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { setIsRejectLoading(false); }; - const addBodyWeight = () => { - const newBodyWeights = [ - ...(formik.values.body_weights || []), - { - weight: '', - avg_weight: '', - qty: '', - }, - ]; - formik.setFieldValue('body_weights', newBodyWeights); - }; - - const handleWeightChange = (idx: number, value: number) => { - formik.setFieldValue(`body_weights.${idx}.weight`, value); - - setManuallyEditedRows((prev) => { - const newSet = new Set(prev); - newSet.delete(idx); - return newSet; - }); - - const currentWeight = formik.values.body_weights?.[idx]; - if (currentWeight) { - const qty = Number(currentWeight.qty) || 0; - const totalWeight = qty * value; - - if (qty > 0 && value > 0) { - const avgWeight = parseFloat((value / qty).toFixed(2)); - formik.setFieldValue(`body_weights.${idx}.avg_weight`, avgWeight); - } else { - formik.setFieldValue(`body_weights.${idx}.avg_weight`, ''); - } - - formik.setFieldValue(`body_weights.${idx}.total_weight`, totalWeight); - } - }; - - const handleAvgWeightChange = (idx: number, value: number) => { - formik.setFieldValue(`body_weights.${idx}.avg_weight`, value); - - setManuallyEditedRows((prev) => { - const newSet = new Set(prev); - newSet.add(idx); - return newSet; - }); - - const currentWeight = formik.values.body_weights?.[idx]; - if (currentWeight) { - const qty = Number(currentWeight.qty) || 0; - if (qty > 0 && value > 0) { - const totalWeight = value * qty; - formik.setFieldValue(`body_weights.${idx}.weight`, totalWeight); - formik.setFieldValue(`body_weights.${idx}.total_weight`, totalWeight); - } else { - formik.setFieldValue(`body_weights.${idx}.weight`, 0); - formik.setFieldValue(`body_weights.${idx}.total_weight`, 0); - } - } - }; - - const handleQtyChange = (idx: number, value: number) => { - formik.setFieldValue(`body_weights.${idx}.qty`, value); - - setManuallyEditedRows((prev) => { - const newSet = new Set(prev); - newSet.delete(idx); - return newSet; - }); - - const currentWeight = formik.values.body_weights?.[idx]; - if (currentWeight) { - const weight = Number(currentWeight.weight) || 0; - const totalWeight = value * weight; - - if (value > 0 && weight > 0) { - const avgWeight = parseFloat((weight / value).toFixed(2)); - formik.setFieldValue(`body_weights.${idx}.avg_weight`, avgWeight); - } else { - formik.setFieldValue(`body_weights.${idx}.avg_weight`, ''); - } - - formik.setFieldValue(`body_weights.${idx}.total_weight`, totalWeight); - } - }; - - const handleWeightChangeWrapper = - (idx: number) => (e: React.ChangeEvent) => { - const value = parseFloat(e.target.value) || 0; - handleWeightChange(idx, value); - }; - - const handleAvgWeightChangeWrapper = - (idx: number) => (e: React.ChangeEvent) => { - const value = parseFloat(e.target.value) || 0; - handleAvgWeightChange(idx, value); - }; - - const handleQtyChangeWrapper = - (idx: number) => (e: React.ChangeEvent) => { - const value = parseFloat(e.target.value) || 0; - handleQtyChange(idx, value); - }; - - const removeBodyWeight = (idx: number) => { - const updatedBodyWeights = formik.values.body_weights?.filter( - (_, i) => i !== idx - ); - formik.setFieldValue('body_weights', updatedBodyWeights); - }; - - const removeSelectedBodyWeights = () => { - const updatedBodyWeights = formik.values.body_weights?.filter( - (_, idx) => !selectedBodyWeights.includes(idx) - ); - formik.setFieldValue('body_weights', updatedBodyWeights); - setSelectedBodyWeights([]); - }; - const addStock = () => { const newStocks = [ ...(formik.values.stocks || []), @@ -1435,45 +1248,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { } }, [isLayingCategory, type]); - const bodyWeightValues = useMemo(() => { - if (!formik.values.body_weights) return []; - return formik.values.body_weights.map((w) => ({ - weight: w.weight, - qty: w.qty, - })); - }, [formik.values.body_weights]); - - useEffect(() => { - if (formik.values.body_weights && editingAverageIndex === null) { - const updatedBodyWeights = formik.values.body_weights.map( - (weight, idx) => { - if (idx === editingAverageIndex || manuallyEditedRows.has(idx)) { - return weight; - } - const qty = Number(weight.qty) || 0; - const weightValue = Number(weight.weight) || 0; - return { - ...weight, - avg_weight: - qty > 0 && weightValue > 0 - ? parseFloat((weightValue / qty).toFixed(2)) - : 0, - }; - } - ); - const hasChanges = updatedBodyWeights.some( - (updated, idx) => - idx !== editingAverageIndex && - !manuallyEditedRows.has(idx) && - updated.avg_weight !== - (formik.values.body_weights[idx]?.avg_weight || 0) - ); - if (hasChanges) { - formik.setFieldValue('body_weights', updatedBodyWeights, false); - } - } - }, [bodyWeightValues, editingAverageIndex, manuallyEditedRows]); - return ( <>
@@ -1763,267 +1537,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { )} - {/* Body Weights Table */} - -
- - - - {(type as 'add' | 'edit' | 'detail') !== 'detail' && ( - - )} - - - - {(type as 'add' | 'edit' | 'detail') !== 'detail' && ( - - )} - - - - {formik.values.body_weights?.map((bw, idx) => ( - - {(type as 'add' | 'edit' | 'detail') !== 'detail' && ( - - )} - - - - - {(type as 'add' | 'edit' | 'detail') !== 'detail' && ( - - )} - - ))} - -
- 0 - } - onChange={( - e: React.ChangeEvent - ) => { - if (e.target.checked) { - setSelectedBodyWeights( - formik.values.body_weights?.map( - (_, idx) => idx - ) ?? [] - ); - } else { - setSelectedBodyWeights([]); - } - }} - classNames={{ - wrapper: 'flex justify-center', - checkbox: 'checkbox checkbox-sm', - }} - /> - - Berat Ayam (gram) - - * - - - Jumlah Ayam - - * - - - Rata-rata Berat Ayam (gram) - - * - - Action
- - ) => { - if (e.target.checked) { - setSelectedBodyWeights([ - ...selectedBodyWeights, - idx, - ]); - } else { - setSelectedBodyWeights( - selectedBodyWeights.filter((i) => i !== idx) - ); - } - }} - classNames={{ - wrapper: 'flex justify-center', - checkbox: 'checkbox checkbox-sm', - }} - /> - - - - - - - -
- -
-
-
- {(type as 'add' | 'edit' | 'detail') !== 'detail' && ( -
- {selectedBodyWeights.length > 0 && ( - - )} - -
- )} -
- {/* Stocks Table */}