From 289c8d567281e9aed44fa60e5f0512c8dfda2eea Mon Sep 17 00:00:00 2001 From: rstubryan Date: Tue, 4 Nov 2025 08:56:57 +0700 Subject: [PATCH] refactor(FE-208,212): enhance PurchaseRequestForm with product data fetching, update price and UOM fields based on selected products --- .../purchase/form/PurchaseRequestForm.tsx | 80 ++++++++++++++++--- 1 file changed, 71 insertions(+), 9 deletions(-) diff --git a/src/components/pages/purchase/form/PurchaseRequestForm.tsx b/src/components/pages/purchase/form/PurchaseRequestForm.tsx index ef213ebd..14c0fc62 100644 --- a/src/components/pages/purchase/form/PurchaseRequestForm.tsx +++ b/src/components/pages/purchase/form/PurchaseRequestForm.tsx @@ -27,8 +27,10 @@ import { AreaApi, LocationApi, WarehouseApi, + ProductApi, } from '@/services/api/master-data'; import { Supplier } from '@/types/api/master-data/supplier'; +import { Product } from '@/types/api/master-data/product'; import { ProductWarehouseApi } from '@/services/api/inventory'; import { isResponseSuccess, isResponseError } from '@/lib/api-helper'; import { PurchaseApi } from '@/services/api/purchasing'; @@ -63,11 +65,6 @@ const PurchaseRequestForm = ({ ] = useState(''); // ===== INTERFACES ===== - interface WarehouseOptionType extends OptionType { - area?: string; - location?: string; - } - interface ProductWarehouseOptionType extends OptionType { product_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 = {}; + productsResponse?.data?.forEach((product: Product) => { + data[product.id] = product; + }); + return data; + }, [productsResponse]); + // ===== API DATA FETCHING ===== const locationsUrl = useMemo(() => { const params = new URLSearchParams({ @@ -760,10 +788,12 @@ const PurchaseRequestForm = ({ (productWarehouse as ProductWarehouseOptionType) ?.value || 0 ); + const productId = + (productWarehouse as ProductWarehouseOptionType) + ?.product_id || 0; formik.setFieldValue( `purchase_items.${idx}.product_id`, - (productWarehouse as ProductWarehouseOptionType) - ?.product_id || 0 + productId ); }} options={getProductWarehouseOptionsForItem( @@ -821,6 +851,16 @@ const PurchaseRequestForm = ({ handlePurchaseItemChange( idx, @@ -829,26 +869,48 @@ const PurchaseRequestForm = ({ ) } onBlur={formik.handleBlur} - type='number' + type='text' className={{ wrapper: 'min-w-24', }} disabled={true} readOnly={true} 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')}` + : '' + } /> {type !== 'detail' && (