diff --git a/src/components/pages/production/recording/form/RecordingForm.schema.ts b/src/components/pages/production/recording/form/RecordingForm.schema.ts index d468610e..73b41d8e 100644 --- a/src/components/pages/production/recording/form/RecordingForm.schema.ts +++ b/src/components/pages/production/recording/form/RecordingForm.schema.ts @@ -235,9 +235,11 @@ export type RecordingGradingFormValues = Yup.InferType< type RecordingFormData = Partial & { body_weights?: CreateGrowingRecordingPayload['body_weights']; - stocks?: CreateGrowingRecordingPayload['stocks']; - depletions?: CreateGrowingRecordingPayload['depletions']; - eggs?: CreateLayingRecordingPayload['eggs']; + stocks?: CreateGrowingRecordingPayload['stocks'] | Recording['stocks']; + depletions?: CreateGrowingRecordingPayload['depletions'] | Recording['depletions']; + eggs?: CreateLayingRecordingPayload['eggs'] | Recording['eggs']; + project_flock_kandang_id?: number; + project_flock_category?: string; }; export const getRecordingGrowingFormInitialValues = ( @@ -265,17 +267,15 @@ export const getRecordingGrowingFormInitialValues = ( total_weight: 0, }, ], - stocks: initialValues?.stocks?.map( - (stock: NonNullable[0]) => ({ + stocks: initialValues?.stocks?.map((stock) => ({ product_warehouse_id: stock.product_warehouse_id, - qty: stock.qty, - }) - ) ?? [ - { - product_warehouse_id: 0, - qty: '', - }, - ], + qty: (stock as { qty?: number; usage_amount?: number }).qty || (stock as { qty?: number; usage_amount?: number }).usage_amount || '', + })) ?? [ + { + product_warehouse_id: 0, + qty: '', + }, + ], depletions: initialValues?.depletions?.map( ( depletion: NonNullable[0] diff --git a/src/components/pages/production/recording/form/RecordingForm.tsx b/src/components/pages/production/recording/form/RecordingForm.tsx index cffa2222..9bf2bfbe 100644 --- a/src/components/pages/production/recording/form/RecordingForm.tsx +++ b/src/components/pages/production/recording/form/RecordingForm.tsx @@ -34,7 +34,7 @@ import { ProjectFlockApi } from '@/services/api/production'; import { LocationApi } from '@/services/api/master-data'; import { ProductWarehouseApi } from '@/services/api/inventory'; import { isResponseSuccess, isResponseError } from '@/lib/api-helper'; -import { cn } from '@/lib/helper'; +import { cn, formatDate } from '@/lib/helper'; import { ProjectFlockKandangLookup } from '@/types/api/production/project-flock'; import { useModal } from '@/components/Modal'; import toast from 'react-hot-toast'; @@ -197,7 +197,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { const today = new Date().toISOString().split('T')[0]; const existingRecordingsUrl = useMemo(() => { return `${RecordingApi.basePath}?record_date=${today}`; - }, []); + }, [today]); const { data: existingRecordings } = useSWR( existingRecordingsUrl, @@ -310,30 +310,15 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { initialValues.stocks && type !== 'add' ) { - const initialValuesWithStocks = initialValues as Recording & { - stocks?: Array<{ - product_warehouse_id: number; - usage_amount: number; - notes: string; - product_warehouse?: { - id: number; - product_id: number; - product_name: string; - warehouse_id: number; - warehouse_name: string; - }; - }>; - }; - - initialValuesWithStocks.stocks?.forEach((stock) => { - if (stock.product_warehouse && stock.product_warehouse.product_name) { + initialValues.stocks?.forEach((stock) => { + if (stock.product_warehouse && stock.product_warehouse.product) { const existingOption = options.find( (opt) => opt.value === stock.product_warehouse_id ); if (!existingOption) { options.push({ value: stock.product_warehouse_id, - label: `${stock.product_warehouse.product_name} - ${stock.product_warehouse.warehouse_name}`, + label: `${stock.product_warehouse.product.name} - ${stock.product_warehouse.product?.sku || ''}`, }); } } @@ -362,8 +347,27 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { }); } + if (initialValues && initialValues.depletions && type !== 'add') { + initialValues.depletions.forEach((depletion) => { + if ( + depletion.product_warehouse && + depletion.product_warehouse.product + ) { + const existingOption = options.find( + (opt) => opt.value === depletion.product_warehouse_id + ); + if (!existingOption) { + options.push({ + value: depletion.product_warehouse_id, + label: depletion.product_warehouse.product.name, + }); + } + } + }); + } + return options; - }, [depletionProductsData]); + }, [depletionProductsData, initialValues, type]); const eggProducts = useMemo(() => { const options: OptionType[] = []; @@ -383,10 +387,27 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { }); } + if (initialValues && initialValues.eggs && type !== 'add') { + initialValues.eggs.forEach((egg) => { + if (egg.product_warehouse && egg.product_warehouse.product) { + const existingOption = options.find( + (opt) => opt.value === egg.product_warehouse_id + ); + if (!existingOption) { + options.push({ + value: egg.product_warehouse_id, + label: egg.product_warehouse.product.name, + }); + } + } + }); + } + return options; - }, [eggProductsData]); + }, [eggProductsData, initialValues, type]); const isLayingCategory = + initialValues?.project_flock_category === 'LAYING' || projectFlockKandangLookup?.project_flock?.category === 'LAYING'; const formikInitialValues = useMemo(() => { @@ -824,7 +845,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { formik.setFieldValue(`body_weights.${idx}.avg_weight`, 0); } - // Update total_weight formik.setFieldValue(`body_weights.${idx}.total_weight`, totalWeight); } }; @@ -844,7 +864,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { if (qty > 0 && value > 0) { const totalWeight = value * qty; formik.setFieldValue(`body_weights.${idx}.weight`, totalWeight); - // Update total_weight formik.setFieldValue(`body_weights.${idx}.total_weight`, totalWeight); } else { formik.setFieldValue(`body_weights.${idx}.weight`, 0); @@ -874,7 +893,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { formik.setFieldValue(`body_weights.${idx}.avg_weight`, 0); } - // Update total_weight formik.setFieldValue(`body_weights.${idx}.total_weight`, totalWeight); } }; @@ -1045,6 +1063,14 @@ 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( @@ -1074,12 +1100,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { formik.setFieldValue('body_weights', updatedBodyWeights, false); } } - }, [ - formik.values.body_weights?.map((w) => w.weight), - formik.values.body_weights?.map((w) => w.qty), - editingAverageIndex, - manuallyEditedRows, - ]); + }, [bodyWeightValues, editingAverageIndex, manuallyEditedRows]); return ( <> @@ -1172,73 +1193,124 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { className='w-full mt-8 flex flex-col gap-6' > {/* Basic Info Card */} - -
- <> - + {(type === 'add' || type === 'edit') && ( + +
+ <> + - + - - -
-
+ + +
+
+ )} + + {/* Recording Info for Detail View */} + {type === 'detail' && initialValues && ( + +
+
+ Recording ID +

#{initialValues.id}

+
+
+ + Tanggal Recording + +

+ {formatDate( + initialValues.record_datetime || '', + 'DD MMMM YYYY' + )} +

+
+
+ Hari +

Hari ke-{initialValues.day}

+
+
+ Kategori +

+ + {initialValues.project_flock_category} + +

+
+
+
+ )} {/* Body Weights Table */} { option?.value || 0 ); }} - options={depletionProducts} + options={eggProducts} placeholder='Pilih Kondisi Telur' isLoading={isLoadingEggProducts} isError={ @@ -2228,7 +2300,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { hasExceededStock || !formik.isValid || formik.isSubmitting } onClick={async () => { - const result = await formik.submitForm(); + await formik.submitForm(); if ( formik.isValid && !formik.isSubmitting && diff --git a/src/types/api/production/recording.d.ts b/src/types/api/production/recording.d.ts index 7977d130..c3c67997 100644 --- a/src/types/api/production/recording.d.ts +++ b/src/types/api/production/recording.d.ts @@ -1,4 +1,5 @@ import { BaseApproval, BaseMetadata, User } from '@/types/api/api-general'; +import { ProductWarehouse } from '@/types/api/inventory/product-warehouse'; export type ProductionMetrics = { total_depletion_qty: number; @@ -33,14 +34,18 @@ export type RecordingDepletion = { recording_id: number; product_warehouse_id: number; qty: number; + product_warehouse: ProductWarehouse; }; export type RecordingStock = { id: number; recording_id: number; product_warehouse_id: number; + usage_amount?: number; usage_qty: number; + qty: number; pending_qty: number; + product_warehouse: ProductWarehouse; }; export type RecordingEgg = { @@ -49,6 +54,7 @@ export type RecordingEgg = { product_warehouse_id: number; qty: number; created_by: User; + product_warehouse: ProductWarehouse; }; export type GradingEgg = { @@ -66,6 +72,10 @@ export type Recording = BaseMetadata & egg_grading_status?: string | null; egg_grading_pending_qty?: number | null; egg_grading_completed_qty?: number | null; + body_weights?: RecordingBW[]; + depletions?: RecordingDepletion[]; + stocks?: RecordingStock[]; + eggs?: RecordingEgg[]; recording_bws?: RecordingBW[]; recording_depletions?: RecordingDepletion[]; recording_stocks?: RecordingStock[];