mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 05:22:02 +00:00
feat(FE-170,175): implement payload creation for growing and laying recordings in RecordingForm
This commit is contained in:
@@ -89,6 +89,9 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
const [recordingFormErrorMessage, setRecordingFormErrorMessage] =
|
||||
useState('');
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
const [newRecordingData, setNewRecordingData] = useState<Recording | null>(
|
||||
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<number>();
|
||||
|
||||
const todayRecordings = existingRecordings?.data || [];
|
||||
const todayRecordings = existingRecordings.data;
|
||||
const recordedIds = new Set<number>();
|
||||
|
||||
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.'
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon icon='material-symbols:egg' width={24} height={24} />
|
||||
{hasGradingData(initialValues)
|
||||
{hasGradingData(initialValues) ||
|
||||
hasGradingData(newRecordingData || undefined)
|
||||
? 'Edit Grading'
|
||||
: 'Lanjut ke Grading'}
|
||||
</Button>
|
||||
@@ -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);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user