refactor(FE-208,212,213): update PurchaseOrderForm and PurchaseOrderStaffApprovalForm to allow optional product and warehouse fields and control visibility of action buttons based on approval step

This commit is contained in:
rstubryan
2025-11-22 00:52:23 +07:00
parent 5b28067203
commit 30ab69ae21
2 changed files with 56 additions and 41 deletions
@@ -9,12 +9,12 @@ type PurchaseRequestStaffApprovalFormSchemaType = {
product_id?: number | null;
warehouse_id?: number | null;
product?: {
value: number;
label: string;
value?: number;
label?: string;
} | null;
warehouse?: {
value: number;
label: string;
value?: number;
label?: string;
} | null;
qty: number;
price: number | string;
@@ -54,12 +54,12 @@ export type PurchaseStaffApprovalItemSchema = {
product_id?: number | null;
warehouse_id?: number | null;
product?: {
value: number;
label: string;
value?: number;
label?: string;
} | null;
warehouse?: {
value: number;
label: string;
value?: number;
label?: string;
} | null;
qty: number;
price: number | string;
@@ -97,8 +97,8 @@ const PurchaseStaffApprovalItemObjectSchema: Yup.ObjectSchema<PurchaseStaffAppro
.min(0, 'Purchase item ID tidak valid!')
.typeError('Purchase item ID harus berupa angka!'),
product: Yup.object({
value: Yup.number().required(),
label: Yup.string().required(),
value: Yup.number(),
label: Yup.string(),
})
.nullable()
.optional(),
@@ -107,8 +107,8 @@ const PurchaseStaffApprovalItemObjectSchema: Yup.ObjectSchema<PurchaseStaffAppro
.nullable()
.typeError('Product ID harus berupa angka!'),
warehouse: Yup.object({
value: Yup.number().required(),
label: Yup.string().required(),
value: Yup.number(),
label: Yup.string(),
})
.nullable()
.optional(),
@@ -68,9 +68,20 @@ const PurchaseOrderStaffApprovalForm = ({
if (!initialValues?.approval) return false;
const currentStep = initialValues.approval.step_number;
// Allow editing from step 3 onwards
// Hide delete/add buttons from step 4 onwards
return currentStep >= 3;
}, [initialValues?.approval]);
const canShowDeleteAddButtons = useMemo(() => {
if (!initialValues?.approval) return false;
const currentStep = initialValues.approval.step_number;
// Show delete/add buttons only up to step 3
// Hide from step 4 onwards
return currentStep < 4;
}, [initialValues?.approval]);
const isRepeaterInputError = (
idx: number,
field: 'price' | 'total_price' | 'product_id' | 'warehouse_id'
@@ -344,6 +355,7 @@ const PurchaseOrderStaffApprovalForm = ({
notes: values.notes || null,
items: updateItemsPayload,
};
await updateStaffApprovalHandler(
initialValues?.id as number,
updatePayload
@@ -556,7 +568,7 @@ const PurchaseOrderStaffApprovalForm = ({
Total (Rp.)
<span className='text-error'>*</span>
</th>
<th>Action</th>
{canShowDeleteAddButtons && <th>Action</th>}
</tr>
</thead>
<tbody>
@@ -725,22 +737,23 @@ const PurchaseOrderStaffApprovalForm = ({
</td>
<td>
<div className='flex justify-center'>
{canUpdatePurchaseItems && (
<Button
type='button'
color='error'
onClick={() =>
removePurchaseItem(formItemIndex)
}
title='Hapus item'
>
<Icon
icon='mdi:trash-can'
width={16}
height={16}
/>
</Button>
)}
{canUpdatePurchaseItems &&
canShowDeleteAddButtons && (
<Button
type='button'
color='error'
onClick={() =>
removePurchaseItem(formItemIndex)
}
title='Hapus item'
>
<Icon
icon='mdi:trash-can'
width={16}
height={16}
/>
</Button>
)}
</div>
</td>
</tr>
@@ -757,7 +770,7 @@ const PurchaseOrderStaffApprovalForm = ({
<td>
<SelectInput
required
value={formItem.product}
value={formItem.product as OptionType | null}
onChange={(val) =>
handleProductChange(idx, val)
}
@@ -916,17 +929,19 @@ const PurchaseOrderStaffApprovalForm = ({
</div>
{/* Add Item Button */}
<div className='flex justify-center items-center mt-4'>
<Button
type='button'
color='success'
onClick={addPurchaseItem}
className='w-fit'
>
<Icon icon='ic:round-plus' width={24} height={24} />
Tambah Item Baru
</Button>
</div>
{canShowDeleteAddButtons && (
<div className='flex justify-center items-center mt-4'>
<Button
type='button'
color='success'
onClick={addPurchaseItem}
className='w-fit'
>
<Icon icon='ic:round-plus' width={24} height={24} />
Tambah Item Baru
</Button>
</div>
)}
{/* Add divider after table except for last item */}
{index < groupedPurchaseItems.length - 1 && (