mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +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] =
|
const [recordingFormErrorMessage, setRecordingFormErrorMessage] =
|
||||||
useState('');
|
useState('');
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
|
const [newRecordingData, setNewRecordingData] = useState<Recording | null>(
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const approveModal = useModal();
|
const approveModal = useModal();
|
||||||
const rejectModal = 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 =====
|
// ===== FORM HANDLERS =====
|
||||||
const createRecordingHandler = useCallback(
|
const createRecordingHandler = useCallback(
|
||||||
async (
|
async (
|
||||||
@@ -128,6 +196,35 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
[router]
|
[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(
|
const updateRecordingHandler = useCallback(
|
||||||
async (
|
async (
|
||||||
recordingId: number,
|
recordingId: number,
|
||||||
@@ -370,7 +467,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
const recordedProjectFlockKandangIds = useMemo(() => {
|
const recordedProjectFlockKandangIds = useMemo(() => {
|
||||||
if (!isResponseSuccess(existingRecordings)) return new Set<number>();
|
if (!isResponseSuccess(existingRecordings)) return new Set<number>();
|
||||||
|
|
||||||
const todayRecordings = existingRecordings?.data || [];
|
const todayRecordings = existingRecordings.data;
|
||||||
const recordedIds = new Set<number>();
|
const recordedIds = new Set<number>();
|
||||||
|
|
||||||
todayRecordings.forEach((recording) => {
|
todayRecordings.forEach((recording) => {
|
||||||
@@ -558,36 +655,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
onSubmit: async (values) => {
|
onSubmit: async (values) => {
|
||||||
if (isLayingCategory) {
|
if (isLayingCategory) {
|
||||||
const layingValues = values as RecordingLayingFormValues;
|
const layingValues = values as RecordingLayingFormValues;
|
||||||
|
const layingPayload = createLayingPayload(layingValues);
|
||||||
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,
|
|
||||||
})),
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'add':
|
case 'add':
|
||||||
@@ -604,32 +672,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const growingValues = values as RecordingGrowingFormValues;
|
const growingValues = values as RecordingGrowingFormValues;
|
||||||
|
const growingPayload = createGrowingPayload(growingValues);
|
||||||
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,
|
|
||||||
})),
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'add':
|
case 'add':
|
||||||
@@ -1243,6 +1286,9 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
} else {
|
} else {
|
||||||
setFormSteps(null);
|
setFormSteps(null);
|
||||||
}
|
}
|
||||||
|
if (type !== 'add') {
|
||||||
|
setNewRecordingData(null);
|
||||||
|
}
|
||||||
}, [isLayingCategory, type]);
|
}, [isLayingCategory, type]);
|
||||||
|
|
||||||
const bodyWeightValues = useMemo(() => {
|
const bodyWeightValues = useMemo(() => {
|
||||||
@@ -2464,13 +2510,22 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
type='button'
|
type='button'
|
||||||
color='primary'
|
color='primary'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
router.push(
|
const recordingId =
|
||||||
`/production/recording/grading/add?recording_id=${initialValues?.id}`
|
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} />
|
<Icon icon='material-symbols:egg' width={24} height={24} />
|
||||||
{hasGradingData(initialValues)
|
{hasGradingData(initialValues) ||
|
||||||
|
hasGradingData(newRecordingData || undefined)
|
||||||
? 'Edit Grading'
|
? 'Edit Grading'
|
||||||
: 'Lanjut ke Grading'}
|
: 'Lanjut ke Grading'}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -2536,20 +2591,45 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
formik.isSubmitting
|
formik.isSubmitting
|
||||||
}
|
}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await formik.submitForm();
|
if (!formik.isValid) {
|
||||||
if (
|
await formik.validateForm();
|
||||||
formik.isValid &&
|
return;
|
||||||
!formik.isSubmitting &&
|
}
|
||||||
!hasExceededStock
|
|
||||||
) {
|
setRecordingFormErrorMessage('');
|
||||||
toast.success(
|
formik.setSubmitting(true);
|
||||||
'Recording berhasil disimpan! Mengalihkan ke form Grading...'
|
|
||||||
|
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(() => {
|
} finally {
|
||||||
router.push(
|
formik.setSubmitting(false);
|
||||||
`/production/recording/grading/add?recording_id=${initialValues?.id || ''}`
|
|
||||||
);
|
|
||||||
}, 1000);
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user