refactor(FE-208,212): enhance PurchaseRequestForm with product data fetching, update price and UOM fields based on selected products

This commit is contained in:
rstubryan
2025-11-04 08:56:57 +07:00
parent ee24ceaff1
commit 289c8d5672
@@ -27,8 +27,10 @@ import {
AreaApi, AreaApi,
LocationApi, LocationApi,
WarehouseApi, WarehouseApi,
ProductApi,
} from '@/services/api/master-data'; } from '@/services/api/master-data';
import { Supplier } from '@/types/api/master-data/supplier'; import { Supplier } from '@/types/api/master-data/supplier';
import { Product } from '@/types/api/master-data/product';
import { ProductWarehouseApi } from '@/services/api/inventory'; import { ProductWarehouseApi } from '@/services/api/inventory';
import { isResponseSuccess, isResponseError } from '@/lib/api-helper'; import { isResponseSuccess, isResponseError } from '@/lib/api-helper';
import { PurchaseApi } from '@/services/api/purchasing'; import { PurchaseApi } from '@/services/api/purchasing';
@@ -63,11 +65,6 @@ const PurchaseRequestForm = ({
] = useState(''); ] = useState('');
// ===== INTERFACES ===== // ===== INTERFACES =====
interface WarehouseOptionType extends OptionType {
area?: string;
location?: string;
}
interface ProductWarehouseOptionType extends OptionType { interface ProductWarehouseOptionType extends OptionType {
product_id: number; product_id: number;
warehouse_id: number; warehouse_id: number;
@@ -293,6 +290,37 @@ const PurchaseRequestForm = ({
}, },
}); });
// ===== PRODUCT DATA FETCHING =====
const productUrl = useMemo(() => {
const productIds =
formik.values.purchase_items
?.filter(
(item) => item.product_id && typeof item.product_id === 'number'
)
.map((item) => item.product_id as number) || [];
return productIds.length > 0
? `${ProductApi.basePath}?${new URLSearchParams({
id: productIds.join(','),
}).toString()}`
: null;
}, [formik.values.purchase_items]);
const { data: productsResponse } = useSWR(
productUrl,
ProductApi.getAllFetcher
);
const productData = useMemo(() => {
if (!isResponseSuccess(productsResponse)) return {};
const data: Record<number, Product> = {};
productsResponse?.data?.forEach((product: Product) => {
data[product.id] = product;
});
return data;
}, [productsResponse]);
// ===== API DATA FETCHING ===== // ===== API DATA FETCHING =====
const locationsUrl = useMemo(() => { const locationsUrl = useMemo(() => {
const params = new URLSearchParams({ const params = new URLSearchParams({
@@ -760,10 +788,12 @@ const PurchaseRequestForm = ({
(productWarehouse as ProductWarehouseOptionType) (productWarehouse as ProductWarehouseOptionType)
?.value || 0 ?.value || 0
); );
const productId =
(productWarehouse as ProductWarehouseOptionType)
?.product_id || 0;
formik.setFieldValue( formik.setFieldValue(
`purchase_items.${idx}.product_id`, `purchase_items.${idx}.product_id`,
(productWarehouse as ProductWarehouseOptionType) productId
?.product_id || 0
); );
}} }}
options={getProductWarehouseOptionsForItem( options={getProductWarehouseOptionsForItem(
@@ -821,6 +851,16 @@ const PurchaseRequestForm = ({
<TextInput <TextInput
required required
name={`purchase_items.${idx}.price`} name={`purchase_items.${idx}.price`}
value={
item.product_id && productData[item.product_id]
? (
productData[item.product_id].product_price *
(parseFloat(
item.sub_qty?.toString() || '0'
) || 0)
).toLocaleString('en-US')
: ''
}
onChange={(e) => onChange={(e) =>
handlePurchaseItemChange( handlePurchaseItemChange(
idx, idx,
@@ -829,26 +869,48 @@ const PurchaseRequestForm = ({
) )
} }
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
type='number' type='text'
className={{ className={{
wrapper: 'min-w-24', wrapper: 'min-w-24',
}} }}
disabled={true} disabled={true}
readOnly={true} readOnly={true}
inputPrefix={'Rp'} inputPrefix={'Rp'}
placeholder={
item.product_id
? 'Loading...'
: 'Pilih produk terlebih dahulu'
}
bottomLabel={
item.product_id && productData[item.product_id]
? `Harga per unit: Rp ${productData[
item.product_id
].product_price.toLocaleString('en-US')}`
: ''
}
/> />
</td> </td>
<td> <td>
<TextInput <TextInput
required required
name={`purchase_items.${idx}.uom`} name={`purchase_items.${idx}.uom`}
value={
item.product_id && productData[item.product_id]
? productData[item.product_id].uom.name
: ''
}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
type='number' type='text'
readOnly={true} readOnly={true}
disabled={true} disabled={true}
className={{ className={{
wrapper: 'min-w-24', wrapper: 'min-w-24',
}} }}
placeholder={
item.product_id
? 'Loading...'
: 'Pilih produk terlebih dahulu'
}
/> />
</td> </td>
{type !== 'detail' && ( {type !== 'detail' && (