refactor(FE-208,212): update PurchaseRequestForm schema and component to handle warehouse IDs

This commit is contained in:
rstubryan
2025-10-30 09:29:38 +07:00
parent b2c38cd06f
commit b0e8a460fd
3 changed files with 68 additions and 73 deletions
@@ -9,28 +9,9 @@ export const PurchaseRequestFormSchema = Yup.object({
label: Yup.string().required(), label: Yup.string().required(),
}).nullable(), }).nullable(),
supplier_id: Yup.number() supplier_id: Yup.number()
.default(0) .required('Supplier wajib diisi!')
.typeError('Supplier wajib diisi!') .min(1, 'Supplier wajib diisi!')
.test( .typeError('Supplier wajib diisi!'),
'is-valid-supplier',
'Supplier wajib diisi!',
(value) => value !== undefined && value !== null && value > 0
)
.required('Supplier wajib diisi!'),
warehouse: Yup.array()
.of(
Yup.object({
value: Yup.number().min(1).required(),
label: Yup.string().required(),
})
)
.min(1, 'Minimal harus ada 1 warehouse!')
.required('Warehouse wajib diisi!')
.nullable(),
warehouse_ids: Yup.array()
.of(Yup.number().min(1))
.min(1, 'Minimal harus ada 1 warehouse!')
.required('Warehouse wajib diisi!'),
credit_term: Yup.number() credit_term: Yup.number()
.required('Termin kredit wajib diisi!') .required('Termin kredit wajib diisi!')
.min(1, 'Termin kredit tidak boleh negatif!') .min(1, 'Termin kredit tidak boleh negatif!')
@@ -39,6 +20,14 @@ export const PurchaseRequestFormSchema = Yup.object({
purchase_items: Yup.array() purchase_items: Yup.array()
.of( .of(
Yup.object({ Yup.object({
warehouse: Yup.object({
value: Yup.number().min(1).required(),
label: Yup.string().required(),
}).nullable(),
warehouse_ids: Yup.number()
.required('Warehouse wajib diisi!')
.min(1, 'Produk wajib diisi!')
.typeError('Warehouse harus berupa angka!'),
product_id: Yup.number() product_id: Yup.number()
.required('Produk wajib diisi!') .required('Produk wajib diisi!')
.min(1, 'Produk wajib diisi!') .min(1, 'Produk wajib diisi!')
@@ -58,7 +47,8 @@ export const PurchaseRequestFormSchema = Yup.object({
}) })
) )
.min(1, 'Minimal harus ada 1 item pembelian!') .min(1, 'Minimal harus ada 1 item pembelian!')
.required('Item pembelian wajib diisi!'), .required('Item pembelian wajib diisi!')
.typeError('Item pembelian wajib diisi!'),
}); });
export const UpdatePurchaseRequestFormSchema = PurchaseRequestFormSchema; export const UpdatePurchaseRequestFormSchema = PurchaseRequestFormSchema;
@@ -83,16 +73,21 @@ export const getPurchaseRequestFormInitialValues = (
} }
: null, : null,
supplier_id: initialValues?.supplier_id ?? 0, supplier_id: initialValues?.supplier_id ?? 0,
warehouse:
initialValues?.warehouse?.map((warehouse) => ({
value: warehouse.id,
label: warehouse.name,
})) ?? [],
warehouse_ids: initialValues?.warehouse_ids ?? [],
credit_term: initialValues?.credit_term ?? 0, credit_term: initialValues?.credit_term ?? 0,
notes: initialValues?.notes ?? '', notes: initialValues?.notes ?? '',
purchase_items: initialValues?.purchase_items?.map( purchase_items: initialValues?.purchase_items?.map(
(item: NonNullable<CreatePurchaseRequestPayload['purchase_items']>[0]) => ({ (item: NonNullable<CreatePurchaseRequestPayload['purchase_items']>[0]) => ({
warehouse: initialValues?.warehouse?.find(
(w) => w.id === item.warehouse_ids
)
? {
value: item.warehouse_ids,
label:
initialValues.warehouse.find((w) => w.id === item.warehouse_ids)
?.name || '',
}
: null,
warehouse_ids: item.warehouse_ids,
product_id: item.product_id, product_id: item.product_id,
product_warehouse_id: item.product_warehouse_id, product_warehouse_id: item.product_warehouse_id,
total_qty: item.total_qty, total_qty: item.total_qty,
@@ -100,6 +95,8 @@ export const getPurchaseRequestFormInitialValues = (
}) })
) ?? [ ) ?? [
{ {
warehouse: null,
warehouse_ids: 0,
product_id: 0, product_id: 0,
product_warehouse_id: 0, product_warehouse_id: 0,
total_qty: 0, total_qty: 0,
@@ -98,13 +98,10 @@ const PurchaseRequestForm = ({
onSubmit: async (values) => { onSubmit: async (values) => {
const payload: CreatePurchaseRequestPayload = { const payload: CreatePurchaseRequestPayload = {
supplier_id: values.supplier_id, supplier_id: values.supplier_id,
warehouse_ids:
(values.warehouse_ids?.filter(
(id) => id !== undefined && id !== null
) as number[]) || [],
credit_term: values.credit_term || 0, credit_term: values.credit_term || 0,
notes: values.notes || '', notes: values.notes || '',
purchase_items: (values.purchase_items || []).map((item) => ({ purchase_items: (values.purchase_items || []).map((item) => ({
warehouse_ids: item.warehouse_ids,
product_id: item.product_id, product_id: item.product_id,
product_warehouse_id: item.product_warehouse_id, product_warehouse_id: item.product_warehouse_id,
total_qty: total_qty:
@@ -147,36 +144,14 @@ const PurchaseRequestForm = ({
} }
}; };
const warehouseChangeHandler = (val: string) => {
const warehouseId = parseInt(val) || 0;
const currentWarehouseIds = formik.values.warehouse_ids || [];
if (warehouseId > 0 && !currentWarehouseIds.includes(warehouseId)) {
const newWarehouseIds = [...currentWarehouseIds, warehouseId].filter(
(id) => id !== undefined && id !== null
);
formik.setFieldValue('warehouse_ids', newWarehouseIds);
const selectedWarehouse = warehouseOptions.find(
(option) => option.value === warehouseId
);
if (selectedWarehouse) {
const currentWarehouses = formik.values.warehouse || [];
formik.setFieldValue('warehouse', [
...currentWarehouses,
selectedWarehouse,
]);
}
}
};
// Purchase Items Handlers // Purchase Items Handlers
const addPurchaseItem = () => { const addPurchaseItem = () => {
const newPurchaseItems = [ const newPurchaseItems = [
...(formik.values.purchase_items || []), ...(formik.values.purchase_items || []),
{ {
warehouse_ids: 0,
product_id: 0, product_id: 0,
product_warehouse_id: null, product_warehouse_id: 0,
total_qty: 0, total_qty: 0,
price: 0, price: 0,
}, },
@@ -204,8 +179,13 @@ const PurchaseRequestForm = ({
field: string, field: string,
value: string | number value: string | number
) => { ) => {
const numValue = typeof value === 'string' ? parseFloat(value) || 0 : value; if (field === 'warehouse_ids') {
formik.setFieldValue(`purchase_items.${idx}.${field}`, numValue); formik.setFieldValue(`purchase_items.${idx}.${field}`, value);
} else {
const numValue =
typeof value === 'string' ? parseFloat(value) || 0 : value;
formik.setFieldValue(`purchase_items.${idx}.${field}`, numValue);
}
}; };
return ( return (
@@ -233,7 +213,7 @@ const PurchaseRequestForm = ({
> >
<TextInput <TextInput
required required
label='Supplier ID' label='Vendor'
name='supplier_id' name='supplier_id'
value={formik.values.supplier_id} value={formik.values.supplier_id}
onChange={(e) => supplierChangeHandler(e.target.value)} onChange={(e) => supplierChangeHandler(e.target.value)}
@@ -248,19 +228,9 @@ const PurchaseRequestForm = ({
placeholder='Masukkan Supplier ID' placeholder='Masukkan Supplier ID'
/> />
<TextInput
label='Warehouse IDs'
name='warehouse_ids_input'
onChange={(e) => warehouseChangeHandler(e.target.value)}
onBlur={formik.handleBlur}
readOnly={type === 'detail'}
type='number'
placeholder='Tambahkan Warehouse ID'
/>
<TextInput <TextInput
required required
label='Credit Term (hari)' label='Jatuh tempo (hari)'
name='credit_term' name='credit_term'
value={formik.values.credit_term} value={formik.values.credit_term}
onChange={formik.handleChange} onChange={formik.handleChange}
@@ -327,11 +297,18 @@ const PurchaseRequestForm = ({
/> />
</th> </th>
)} )}
<th>
Warehouse ID
<span className='text-error'>*</span>
</th>
<th> <th>
Product ID Product ID
<span className='text-error'>*</span> <span className='text-error'>*</span>
</th> </th>
<th>Product Warehouse ID</th> <th>
Product Warehouse ID
<span className='text-error'>*</span>
</th>
<th> <th>
Total Qty Total Qty
<span className='text-error'>*</span> <span className='text-error'>*</span>
@@ -367,6 +344,27 @@ const PurchaseRequestForm = ({
/> />
</td> </td>
)} )}
<td>
<TextInput
required
name={`purchase_items.${idx}.warehouse_ids`}
value={item.warehouse_ids}
onChange={(e) =>
handlePurchaseItemChange(
idx,
'warehouse_ids',
e.target.value
)
}
onBlur={formik.handleBlur}
type='number'
placeholder='Warehouse IDs'
readOnly={type === 'detail'}
className={{
wrapper: 'min-w-24',
}}
/>
</td>
<td> <td>
<TextInput <TextInput
required required
+1 -1
View File
@@ -21,10 +21,10 @@ export type Purchase = BaseMetadata & BasePurchase;
export type CreatePurchaseRequestPayload = { export type CreatePurchaseRequestPayload = {
supplier_id: number; supplier_id: number;
warehouse_ids: number[];
credit_term: number; credit_term: number;
notes?: string | null; notes?: string | null;
purchase_items: { purchase_items: {
warehouse_ids: number;
product_id: number; product_id: number;
product_warehouse_id: number; product_warehouse_id: number;
total_qty: number; total_qty: number;