mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-25 15:55:48 +00:00
refactor(FE-208,212): enhance form validation and streamline change handlers in PurchaseRequestForm
This commit is contained in:
@@ -12,12 +12,12 @@ type PurchaseRequestFormSchemaType = {
|
|||||||
value: number;
|
value: number;
|
||||||
label: string;
|
label: string;
|
||||||
} | null;
|
} | null;
|
||||||
area_id: number;
|
area_id: number | undefined;
|
||||||
location?: {
|
location?: {
|
||||||
value: number;
|
value: number;
|
||||||
label: string;
|
label: string;
|
||||||
} | null;
|
} | null;
|
||||||
location_id: number;
|
location_id: number | undefined;
|
||||||
notes: string | null;
|
notes: string | null;
|
||||||
items: {
|
items: {
|
||||||
warehouse?: {
|
warehouse?: {
|
||||||
@@ -91,17 +91,15 @@ export const PurchaseRequestFormSchema: Yup.ObjectSchema<PurchaseRequestFormSche
|
|||||||
label: Yup.string().required(),
|
label: Yup.string().required(),
|
||||||
}).nullable(),
|
}).nullable(),
|
||||||
area_id: Yup.number()
|
area_id: Yup.number()
|
||||||
.required('Area wajib dipilih!')
|
.min(0, 'Area tidak boleh kurang dari 0!')
|
||||||
.min(1, 'Area wajib dipilih!')
|
.typeError('Area harus berupa angka!'),
|
||||||
.typeError('Area wajib dipilih!'),
|
|
||||||
location: Yup.object({
|
location: Yup.object({
|
||||||
value: Yup.number().min(1).required(),
|
value: Yup.number().min(1).required(),
|
||||||
label: Yup.string().required(),
|
label: Yup.string().required(),
|
||||||
}).nullable(),
|
}).nullable(),
|
||||||
location_id: Yup.number()
|
location_id: Yup.number()
|
||||||
.required('Lokasi wajib dipilih!')
|
.min(0, 'Lokasi tidak boleh kurang dari 0!')
|
||||||
.min(1, 'Lokasi wajib dipilih!')
|
.typeError('Lokasi harus berupa angka!'),
|
||||||
.typeError('Lokasi wajib dipilih!'),
|
|
||||||
notes: Yup.string().nullable().default(null),
|
notes: Yup.string().nullable().default(null),
|
||||||
items: Yup.array()
|
items: Yup.array()
|
||||||
.of(PurchaseItemObjectSchema)
|
.of(PurchaseItemObjectSchema)
|
||||||
@@ -133,14 +131,14 @@ export const getPurchaseRequestFormInitialValues = (
|
|||||||
label: initialValues.area.name,
|
label: initialValues.area.name,
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
area_id: initialValues?.area?.id ?? 0,
|
area_id: initialValues?.area?.id ?? undefined,
|
||||||
location: initialValues?.location
|
location: initialValues?.location
|
||||||
? {
|
? {
|
||||||
value: initialValues.location.id,
|
value: initialValues.location.id,
|
||||||
label: initialValues.location.name,
|
label: initialValues.location.name,
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
location_id: initialValues?.location?.id ?? 0,
|
location_id: initialValues?.location?.id ?? undefined,
|
||||||
notes: initialValues?.notes ?? null,
|
notes: initialValues?.notes ?? null,
|
||||||
items: [],
|
items: [],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -330,6 +330,79 @@ const PurchaseRequestForm = ({
|
|||||||
setSelectedPurchaseItems([]);
|
setSelectedPurchaseItems([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ===== FORM HANDLERS =====
|
||||||
|
const handleSupplierChange = useCallback(
|
||||||
|
(val: OptionType | OptionType[] | null) => {
|
||||||
|
const supplier = val as OptionType | null;
|
||||||
|
const supplierId = Number(supplier?.value);
|
||||||
|
|
||||||
|
formik.setFieldTouched('supplier', true);
|
||||||
|
formik.setFieldValue('supplier', supplier);
|
||||||
|
formik.setFieldTouched('supplier_id', true);
|
||||||
|
formik.setFieldValue('supplier_id', supplierId);
|
||||||
|
|
||||||
|
if (supplierId > 0 && isResponseSuccess(supplierRawData)) {
|
||||||
|
const supplierData = supplierRawData.data.find(
|
||||||
|
(s: Supplier) => s.id === supplierId
|
||||||
|
);
|
||||||
|
if (supplierData?.due_date) {
|
||||||
|
formik.setFieldTouched('credit_term', true);
|
||||||
|
formik.setFieldValue('credit_term', supplierData.due_date.toString());
|
||||||
|
} else {
|
||||||
|
formik.setFieldTouched('credit_term', false);
|
||||||
|
formik.setFieldValue('credit_term', '');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
formik.setFieldTouched('credit_term', false);
|
||||||
|
formik.setFieldValue('credit_term', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formik.values.items) {
|
||||||
|
formik.values.items.forEach((_, idx) => {
|
||||||
|
formik.setFieldValue(`items.${idx}.product`, null);
|
||||||
|
formik.setFieldValue(`items.${idx}.product_id`, 0);
|
||||||
|
formik.setFieldValue(`items.${idx}.qty`, 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[, supplierRawData]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleAreaChange = useCallback(
|
||||||
|
(val: OptionType | OptionType[] | null) => {
|
||||||
|
const area = val as OptionType | null;
|
||||||
|
formik.setFieldTouched('area_id', true);
|
||||||
|
formik.setFieldValue('area_id', (area as OptionType)?.value || 0);
|
||||||
|
formik.setFieldTouched('area', true);
|
||||||
|
formik.setFieldValue('area', area);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleLocationChange = useCallback(
|
||||||
|
(val: OptionType | OptionType[] | null) => {
|
||||||
|
const location = val as OptionType | null;
|
||||||
|
formik.setFieldTouched('location_id', true);
|
||||||
|
formik.setFieldValue('location_id', (location as OptionType)?.value || 0);
|
||||||
|
formik.setFieldTouched('location', true);
|
||||||
|
formik.setFieldValue('location', location);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleWarehouseChange = useCallback(
|
||||||
|
(idx: number, val: OptionType | OptionType[] | null) => {
|
||||||
|
const warehouse = val as OptionType | null;
|
||||||
|
const warehouseId = (warehouse as OptionType)?.value || 0;
|
||||||
|
|
||||||
|
formik.setFieldTouched(`items.${idx}.warehouse`, true);
|
||||||
|
formik.setFieldValue(`items.${idx}.warehouse`, warehouse);
|
||||||
|
formik.setFieldTouched(`items.${idx}.warehouse_id`, true);
|
||||||
|
formik.setFieldValue(`items.${idx}.warehouse_id`, warehouseId);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
// ===== PURCHASE ITEM OPERATIONS =====
|
// ===== PURCHASE ITEM OPERATIONS =====
|
||||||
const handlePurchaseItemChange = (
|
const handlePurchaseItemChange = (
|
||||||
idx: number,
|
idx: number,
|
||||||
@@ -381,51 +454,7 @@ const PurchaseRequestForm = ({
|
|||||||
label='Vendor'
|
label='Vendor'
|
||||||
placeholder='Pilih Vendor...'
|
placeholder='Pilih Vendor...'
|
||||||
value={formik.values.supplier}
|
value={formik.values.supplier}
|
||||||
onChange={(val) => {
|
onChange={handleSupplierChange}
|
||||||
const supplier = val as OptionType | null;
|
|
||||||
const supplierId = supplier?.value
|
|
||||||
? typeof supplier.value === 'string'
|
|
||||||
? parseInt(supplier.value)
|
|
||||||
: supplier.value
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
formik.setFieldTouched('supplier_id', true);
|
|
||||||
formik.setFieldValue('supplier_id', supplierId);
|
|
||||||
formik.setFieldTouched('supplier', true);
|
|
||||||
formik.setFieldValue('supplier', supplier);
|
|
||||||
|
|
||||||
if (supplierId > 0 && isResponseSuccess(supplierRawData)) {
|
|
||||||
const supplierData = supplierRawData.data.find(
|
|
||||||
(s: Supplier) => s.id === supplierId
|
|
||||||
);
|
|
||||||
if (supplierData?.due_date) {
|
|
||||||
formik.setFieldTouched('credit_term', true);
|
|
||||||
formik.setFieldValue(
|
|
||||||
'credit_term',
|
|
||||||
supplierData.due_date.toString()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (formik.values.items) {
|
|
||||||
formik.values.items.forEach((_, idx) => {
|
|
||||||
formik.setFieldValue(`items.${idx}.product`, null);
|
|
||||||
formik.setFieldValue(`items.${idx}.product_id`, 0);
|
|
||||||
formik.setFieldValue(`items.${idx}.qty`, 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
formik.setFieldTouched('credit_term', false);
|
|
||||||
formik.setFieldValue('credit_term', '');
|
|
||||||
|
|
||||||
if (formik.values.items) {
|
|
||||||
formik.values.items.forEach((_, idx) => {
|
|
||||||
formik.setFieldValue(`items.${idx}.product`, null);
|
|
||||||
formik.setFieldValue(`items.${idx}.product_id`, 0);
|
|
||||||
formik.setFieldValue(`items.${idx}.qty`, 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
options={supplierOptions}
|
options={supplierOptions}
|
||||||
onInputChange={setSupplierSelectInputValue}
|
onInputChange={setSupplierSelectInputValue}
|
||||||
isLoading={isLoadingSuppliers}
|
isLoading={isLoadingSuppliers}
|
||||||
@@ -462,81 +491,27 @@ const PurchaseRequestForm = ({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<SelectInput
|
<SelectInput
|
||||||
required
|
|
||||||
label='Area'
|
label='Area'
|
||||||
placeholder='Pilih Area...'
|
placeholder='Pilih Area...'
|
||||||
value={formik.values.area}
|
value={formik.values.area}
|
||||||
onChange={(val) => {
|
onChange={handleAreaChange}
|
||||||
const area = val as OptionType | null;
|
|
||||||
formik.setFieldTouched('area_id', true);
|
|
||||||
formik.setFieldValue(
|
|
||||||
'area_id',
|
|
||||||
(area as OptionType)?.value || 0
|
|
||||||
);
|
|
||||||
formik.setFieldTouched('area', true);
|
|
||||||
formik.setFieldValue('area', area);
|
|
||||||
|
|
||||||
formik.setFieldTouched('location', false);
|
|
||||||
formik.setFieldValue('location', undefined);
|
|
||||||
formik.setFieldTouched('location_id', false);
|
|
||||||
formik.setFieldValue('location_id', 0);
|
|
||||||
setLocationSelectInputValue('');
|
|
||||||
|
|
||||||
if (formik.values.items) {
|
|
||||||
formik.values.items.forEach((_, idx) => {
|
|
||||||
formik.setFieldValue(`items.${idx}.product`, null);
|
|
||||||
formik.setFieldValue(`items.${idx}.product_id`, 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
options={areaOptions}
|
options={areaOptions}
|
||||||
onInputChange={setAreaSelectInputValue}
|
onInputChange={setAreaSelectInputValue}
|
||||||
isLoading={isLoadingAreas}
|
isLoading={isLoadingAreas}
|
||||||
isError={
|
|
||||||
formik.touched.area_id && Boolean(formik.errors.area_id)
|
|
||||||
}
|
|
||||||
errorMessage={formik.errors.area_id as string}
|
|
||||||
isDisabled={type === 'detail'}
|
isDisabled={type === 'detail'}
|
||||||
isClearable
|
isClearable
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SelectInput
|
<SelectInput
|
||||||
required
|
|
||||||
label='Lokasi'
|
label='Lokasi'
|
||||||
placeholder={
|
placeholder='Pilih Lokasi...'
|
||||||
!formik.values.area_id
|
value={formik.values.location}
|
||||||
? 'Pilih Area terlebih dahulu'
|
onChange={handleLocationChange}
|
||||||
: 'Pilih Lokasi...'
|
|
||||||
}
|
|
||||||
value={formik.values.area_id ? formik.values.location : null}
|
|
||||||
onChange={(val) => {
|
|
||||||
const location = val as OptionType | null;
|
|
||||||
formik.setFieldTouched('location_id', true);
|
|
||||||
formik.setFieldValue(
|
|
||||||
'location_id',
|
|
||||||
(location as OptionType)?.value || 0
|
|
||||||
);
|
|
||||||
formik.setFieldTouched('location', true);
|
|
||||||
formik.setFieldValue('location', location);
|
|
||||||
|
|
||||||
if (formik.values.items) {
|
|
||||||
formik.values.items.forEach((_, idx) => {
|
|
||||||
formik.setFieldValue(`items.${idx}.product`, null);
|
|
||||||
formik.setFieldValue(`items.${idx}.product_id`, 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
options={locationOptions}
|
options={locationOptions}
|
||||||
onInputChange={setLocationSelectInputValue}
|
onInputChange={setLocationSelectInputValue}
|
||||||
isLoading={isLoadingLocations}
|
isLoading={isLoadingLocations}
|
||||||
isError={
|
isDisabled={type === 'detail'}
|
||||||
formik.touched.location_id &&
|
isClearable={type !== 'detail'}
|
||||||
Boolean(formik.errors.location_id)
|
|
||||||
}
|
|
||||||
errorMessage={formik.errors.location_id as string}
|
|
||||||
isDisabled={type === 'detail' || !formik.values.area_id}
|
|
||||||
isClearable={type !== 'detail' && !!formik.values.area_id}
|
|
||||||
key={`location-${formik.values.area_id}`}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className={'col-span-2'}>
|
<div className={'col-span-2'}>
|
||||||
@@ -643,40 +618,9 @@ const PurchaseRequestForm = ({
|
|||||||
)}
|
)}
|
||||||
<td>
|
<td>
|
||||||
<SelectInput
|
<SelectInput
|
||||||
required
|
placeholder='Pilih Gudang...'
|
||||||
placeholder={
|
|
||||||
!formik.values.area_id
|
|
||||||
? 'Pilih Area terlebih dahulu'
|
|
||||||
: formik.values.location_id
|
|
||||||
? 'Pilih Gudang...'
|
|
||||||
: 'Pilih Area dan Lokasi terlebih dahulu'
|
|
||||||
}
|
|
||||||
value={item.warehouse}
|
value={item.warehouse}
|
||||||
onChange={(val) => {
|
onChange={(val) => handleWarehouseChange(idx, val)}
|
||||||
const warehouse = val as OptionType | null;
|
|
||||||
const warehouseId =
|
|
||||||
(warehouse as OptionType)?.value || 0;
|
|
||||||
|
|
||||||
formik.setFieldTouched(
|
|
||||||
`items.${idx}.warehouse`,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
formik.setFieldValue(
|
|
||||||
`items.${idx}.warehouse`,
|
|
||||||
warehouse
|
|
||||||
);
|
|
||||||
formik.setFieldTouched(
|
|
||||||
`items.${idx}.warehouse_id`,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
formik.setFieldValue(
|
|
||||||
`items.${idx}.warehouse_id`,
|
|
||||||
warehouseId
|
|
||||||
);
|
|
||||||
|
|
||||||
formik.setFieldValue(`items.${idx}.product`, null);
|
|
||||||
formik.setFieldValue(`items.${idx}.product_id`, 0);
|
|
||||||
}}
|
|
||||||
options={warehouseOptions}
|
options={warehouseOptions}
|
||||||
onInputChange={setWarehouseSelectInputValue}
|
onInputChange={setWarehouseSelectInputValue}
|
||||||
isLoading={isLoadingWarehouses}
|
isLoading={isLoadingWarehouses}
|
||||||
@@ -687,17 +631,8 @@ const PurchaseRequestForm = ({
|
|||||||
isRepeaterInputError(idx, 'warehouse_id')
|
isRepeaterInputError(idx, 'warehouse_id')
|
||||||
.errorMessage
|
.errorMessage
|
||||||
}
|
}
|
||||||
isDisabled={
|
isDisabled={type === 'detail'}
|
||||||
type === 'detail' ||
|
isClearable={type !== 'detail'}
|
||||||
!formik.values.area_id ||
|
|
||||||
!formik.values.location_id
|
|
||||||
}
|
|
||||||
isClearable={
|
|
||||||
type !== 'detail' &&
|
|
||||||
!!formik.values.area_id &&
|
|
||||||
!!formik.values.location_id
|
|
||||||
}
|
|
||||||
key={`warehouse-${formik.values.area_id}-${formik.values.location_id}`}
|
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|||||||
Reference in New Issue
Block a user