mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +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;
|
||||
label: string;
|
||||
} | null;
|
||||
area_id: number;
|
||||
area_id: number | undefined;
|
||||
location?: {
|
||||
value: number;
|
||||
label: string;
|
||||
} | null;
|
||||
location_id: number;
|
||||
location_id: number | undefined;
|
||||
notes: string | null;
|
||||
items: {
|
||||
warehouse?: {
|
||||
@@ -91,17 +91,15 @@ export const PurchaseRequestFormSchema: Yup.ObjectSchema<PurchaseRequestFormSche
|
||||
label: Yup.string().required(),
|
||||
}).nullable(),
|
||||
area_id: Yup.number()
|
||||
.required('Area wajib dipilih!')
|
||||
.min(1, 'Area wajib dipilih!')
|
||||
.typeError('Area wajib dipilih!'),
|
||||
.min(0, 'Area tidak boleh kurang dari 0!')
|
||||
.typeError('Area harus berupa angka!'),
|
||||
location: Yup.object({
|
||||
value: Yup.number().min(1).required(),
|
||||
label: Yup.string().required(),
|
||||
}).nullable(),
|
||||
location_id: Yup.number()
|
||||
.required('Lokasi wajib dipilih!')
|
||||
.min(1, 'Lokasi wajib dipilih!')
|
||||
.typeError('Lokasi wajib dipilih!'),
|
||||
.min(0, 'Lokasi tidak boleh kurang dari 0!')
|
||||
.typeError('Lokasi harus berupa angka!'),
|
||||
notes: Yup.string().nullable().default(null),
|
||||
items: Yup.array()
|
||||
.of(PurchaseItemObjectSchema)
|
||||
@@ -133,14 +131,14 @@ export const getPurchaseRequestFormInitialValues = (
|
||||
label: initialValues.area.name,
|
||||
}
|
||||
: null,
|
||||
area_id: initialValues?.area?.id ?? 0,
|
||||
area_id: initialValues?.area?.id ?? undefined,
|
||||
location: initialValues?.location
|
||||
? {
|
||||
value: initialValues.location.id,
|
||||
label: initialValues.location.name,
|
||||
}
|
||||
: null,
|
||||
location_id: initialValues?.location?.id ?? 0,
|
||||
location_id: initialValues?.location?.id ?? undefined,
|
||||
notes: initialValues?.notes ?? null,
|
||||
items: [],
|
||||
});
|
||||
|
||||
@@ -330,6 +330,79 @@ const PurchaseRequestForm = ({
|
||||
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 =====
|
||||
const handlePurchaseItemChange = (
|
||||
idx: number,
|
||||
@@ -381,51 +454,7 @@ const PurchaseRequestForm = ({
|
||||
label='Vendor'
|
||||
placeholder='Pilih Vendor...'
|
||||
value={formik.values.supplier}
|
||||
onChange={(val) => {
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}}
|
||||
onChange={handleSupplierChange}
|
||||
options={supplierOptions}
|
||||
onInputChange={setSupplierSelectInputValue}
|
||||
isLoading={isLoadingSuppliers}
|
||||
@@ -462,81 +491,27 @@ const PurchaseRequestForm = ({
|
||||
/>
|
||||
|
||||
<SelectInput
|
||||
required
|
||||
label='Area'
|
||||
placeholder='Pilih Area...'
|
||||
value={formik.values.area}
|
||||
onChange={(val) => {
|
||||
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);
|
||||
});
|
||||
}
|
||||
}}
|
||||
onChange={handleAreaChange}
|
||||
options={areaOptions}
|
||||
onInputChange={setAreaSelectInputValue}
|
||||
isLoading={isLoadingAreas}
|
||||
isError={
|
||||
formik.touched.area_id && Boolean(formik.errors.area_id)
|
||||
}
|
||||
errorMessage={formik.errors.area_id as string}
|
||||
isDisabled={type === 'detail'}
|
||||
isClearable
|
||||
/>
|
||||
|
||||
<SelectInput
|
||||
required
|
||||
label='Lokasi'
|
||||
placeholder={
|
||||
!formik.values.area_id
|
||||
? 'Pilih Area terlebih dahulu'
|
||||
: '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);
|
||||
});
|
||||
}
|
||||
}}
|
||||
placeholder='Pilih Lokasi...'
|
||||
value={formik.values.location}
|
||||
onChange={handleLocationChange}
|
||||
options={locationOptions}
|
||||
onInputChange={setLocationSelectInputValue}
|
||||
isLoading={isLoadingLocations}
|
||||
isError={
|
||||
formik.touched.location_id &&
|
||||
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}`}
|
||||
isDisabled={type === 'detail'}
|
||||
isClearable={type !== 'detail'}
|
||||
/>
|
||||
|
||||
<div className={'col-span-2'}>
|
||||
@@ -643,40 +618,9 @@ const PurchaseRequestForm = ({
|
||||
)}
|
||||
<td>
|
||||
<SelectInput
|
||||
required
|
||||
placeholder={
|
||||
!formik.values.area_id
|
||||
? 'Pilih Area terlebih dahulu'
|
||||
: formik.values.location_id
|
||||
? 'Pilih Gudang...'
|
||||
: 'Pilih Area dan Lokasi terlebih dahulu'
|
||||
}
|
||||
placeholder='Pilih Gudang...'
|
||||
value={item.warehouse}
|
||||
onChange={(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);
|
||||
}}
|
||||
onChange={(val) => handleWarehouseChange(idx, val)}
|
||||
options={warehouseOptions}
|
||||
onInputChange={setWarehouseSelectInputValue}
|
||||
isLoading={isLoadingWarehouses}
|
||||
@@ -687,17 +631,8 @@ const PurchaseRequestForm = ({
|
||||
isRepeaterInputError(idx, 'warehouse_id')
|
||||
.errorMessage
|
||||
}
|
||||
isDisabled={
|
||||
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}`}
|
||||
isDisabled={type === 'detail'}
|
||||
isClearable={type !== 'detail'}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Reference in New Issue
Block a user