refactor(FE-208,212): enhance PurchaseOrderStaffApprovalForm for edit functionality and validation checks

This commit is contained in:
rstubryan
2025-11-18 22:32:39 +07:00
parent f4bb87550c
commit f6afb741af
@@ -18,8 +18,10 @@ import { isResponseError } from '@/lib/api-helper';
import { StaffApprovalApi } from '@/services/api/purchase'; import { StaffApprovalApi } from '@/services/api/purchase';
import { import {
CreateStaffApprovalRequestPayload, CreateStaffApprovalRequestPayload,
UpdateStaffApprovalRequestPayload,
Purchase, Purchase,
} from '@/types/api/purchase/purchase'; } from '@/types/api/purchase/purchase';
import { router } from 'next/client';
interface PurchaseOrderStaffApprovalFormProps { interface PurchaseOrderStaffApprovalFormProps {
type?: 'add' | 'edit'; type?: 'add' | 'edit';
@@ -37,6 +39,13 @@ const PurchaseOrderStaffApprovalForm = ({
useState(''); useState('');
// ===== UTILITY FUNCTIONS ===== // ===== UTILITY FUNCTIONS =====
const canUpdatePurchase = useMemo(() => {
if (!initialValues?.approval) return false;
const currentStep = initialValues.approval.step_number;
return currentStep >= 4;
}, [initialValues?.approval]);
const getPurchaseItemError = ( const getPurchaseItemError = (
idx: number, idx: number,
field: 'price' | 'total_price' field: 'price' | 'total_price'
@@ -87,8 +96,8 @@ const PurchaseOrderStaffApprovalForm = ({
); );
const updateStaffApprovalHandler = useCallback( const updateStaffApprovalHandler = useCallback(
async (purchaseId: number, payload: CreateStaffApprovalRequestPayload) => { async (purchaseId: number, payload: UpdateStaffApprovalRequestPayload) => {
const res = await StaffApprovalApi.createStaffApproval( const res = await StaffApprovalApi.updateStaffApproval(
purchaseId, purchaseId,
payload payload
); );
@@ -98,7 +107,7 @@ const PurchaseOrderStaffApprovalForm = ({
} }
toast.success(res?.message as string); toast.success(res?.message as string);
onCancel?.(); onCancel?.();
window.location.href = '/purchase'; await router.push(`/purchase/detail?purchaseId=${purchaseId}`);
}, },
[] []
); );
@@ -116,36 +125,60 @@ const PurchaseOrderStaffApprovalForm = ({
validateOnChange: true, validateOnChange: true,
validateOnBlur: true, validateOnBlur: true,
onSubmit: async (values) => { onSubmit: async (values) => {
const payload: CreateStaffApprovalRequestPayload = { if (type === 'edit' && !canUpdatePurchase) {
notes: values.notes || '', setPurchaseOrderFormErrorMessage(
items: purchaseItems.map((purchaseItem, idx) => { 'Tidak bisa diupdate. Harus melewati step 4 dahulu (Tahapan Penerimaan Produk).'
const formItem = values.items?.[idx]; );
return { return;
product_id: purchaseItem.product_id || 0, }
warehouse_id: purchaseItem.warehouse_id || 0,
qty: purchaseItem.quantity || 0,
price:
typeof formItem?.price === 'string'
? parseFloat(formItem.price) || 0
: formItem?.price || 0,
total_price:
typeof formItem?.total_price === 'string'
? parseFloat(formItem.total_price) || 0
: formItem?.total_price || 0,
};
}),
};
switch (type) { if (type === 'add') {
case 'add': const createPayload: CreateStaffApprovalRequestPayload = {
await createStaffApprovalHandler(payload); notes: values.notes || '',
break; items: purchaseItems.map((purchaseItem, idx) => {
case 'edit': const formItem = values.items?.[idx];
await updateStaffApprovalHandler( return {
initialValues?.id as number, product_id: purchaseItem.product_id || 0,
payload warehouse_id: purchaseItem.warehouse_id || 0,
); qty: purchaseItem.quantity || 0,
break; price:
typeof formItem?.price === 'string'
? parseFloat(formItem.price) || 0
: formItem?.price || 0,
total_price:
typeof formItem?.total_price === 'string'
? parseFloat(formItem.total_price) || 0
: formItem?.total_price || 0,
};
}),
};
await createStaffApprovalHandler(createPayload);
} else if (type === 'edit') {
const updatePayload: UpdateStaffApprovalRequestPayload = {
'notes?': values.notes || null,
items: purchaseItems.map((purchaseItem, idx) => {
const formItem = values.items?.[idx];
return {
purchase_item_id:
formItem?.purchase_item_id || purchaseItem.value || 0,
qty: purchaseItem.quantity || 0,
price:
typeof formItem?.price === 'string'
? parseFloat(formItem.price) || 0
: formItem?.price || 0,
total_price:
typeof formItem?.total_price === 'string'
? parseFloat(formItem.total_price) || 0
: formItem?.total_price || 0,
};
}),
};
await updateStaffApprovalHandler(
initialValues?.id as number,
updatePayload
);
} }
}, },
}); });
@@ -175,17 +208,22 @@ const PurchaseOrderStaffApprovalForm = ({
}, [initialValues?.items]); }, [initialValues?.items]);
useEffect(() => { useEffect(() => {
if (purchaseItems.length > 0) { if (purchaseItems.length > 0 && initialValues?.items) {
const updatedItems = purchaseItems.map((purchaseItem) => ({ const updatedItems = purchaseItems.map((purchaseItem, idx) => {
product_id: purchaseItem.product_id || 0, const originalItem = initialValues.items?.[idx];
warehouse_id: purchaseItem.warehouse_id || 0, return {
qty: purchaseItem.quantity || 0, purchase_item_id: type === 'edit' ? purchaseItem.value : undefined,
price: '', product_id: purchaseItem.product_id || 0,
total_price: '', warehouse_id: purchaseItem.warehouse_id || 0,
})); qty: purchaseItem.quantity || 0,
price: type === 'edit' && originalItem ? originalItem.price : '',
total_price:
type === 'edit' && originalItem ? originalItem.total_price : '',
};
});
formik.setFieldValue('items', updatedItems); formik.setFieldValue('items', updatedItems);
} }
}, [purchaseItems]); }, [purchaseItems, type, initialValues]);
// ===== PURCHASE ITEM OPERATIONS ===== // ===== PURCHASE ITEM OPERATIONS =====
const handlePurchaseItemChange = ( const handlePurchaseItemChange = (