From b9990e0253465d2e823624753ce38d4cbf90eecf Mon Sep 17 00:00:00 2001 From: rstubryan Date: Fri, 21 Nov 2025 18:54:17 +0700 Subject: [PATCH] refactor(FE-208): enhance PurchaseRequestForm to fetch and display supplier-specific products --- .../form/request/PurchaseRequestForm.tsx | 78 +++++++++++-------- src/types/api/master-data/supplier.d.ts | 12 +++ 2 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/components/pages/purchase/form/request/PurchaseRequestForm.tsx b/src/components/pages/purchase/form/request/PurchaseRequestForm.tsx index 7c6d64e1..6fdbc78f 100644 --- a/src/components/pages/purchase/form/request/PurchaseRequestForm.tsx +++ b/src/components/pages/purchase/form/request/PurchaseRequestForm.tsx @@ -30,9 +30,9 @@ import { WarehouseApi, ProductApi, } from '@/services/api/master-data'; -import { Supplier } from '@/types/api/master-data/supplier'; -import { Product } from '@/types/api/master-data/product'; +import { Supplier, SupplierProducts } from '@/types/api/master-data/supplier'; import { isResponseSuccess, isResponseError } from '@/lib/api-helper'; +import { formatNumber } from '@/lib/helper'; import { PurchaseApi } from '@/services/api/purchase'; import Card from '@/components/Card'; @@ -148,7 +148,9 @@ const PurchaseRequestForm = ({ options: supplierOptions, isLoadingOptions: isLoadingSuppliers, rawData: supplierRawData, - } = useSelect(SupplierApi.basePath, 'id', 'name', 'search'); + } = useSelect(SupplierApi.basePath, 'id', 'name', 'search', { + category: 'SAPRONAK', + }); const { setInputValue: setAreaSelectInputValue, @@ -211,31 +213,39 @@ const PurchaseRequestForm = ({ }); // ===== API DATA FETCHING ===== - const { data: productsResponse, isLoading: isLoadingProducts } = useSWR( - `${ProductApi.basePath}`, - ProductApi.getAllFetcher + const { data: supplierData, isLoading: isLoadingProducts } = useSWR( + formik.values.supplier_id?.toString(), + (id: string) => SupplierApi.getSingle(Number(id)) ); - const productOptions = useMemo(() => { - if (!isResponseSuccess(productsResponse)) return []; + const supplierProductOptions = useMemo(() => { + if (!supplierData || !isResponseSuccess(supplierData)) { + return []; + } - return ( - productsResponse?.data.map((product: Product) => ({ - value: product.id, - label: product.name, - })) || [] - ); - }, [productsResponse]); + const supplier = supplierData.data as SupplierProducts; + const products = supplier.products || []; + return products.map((product) => ({ + value: product.id, + label: product.name, + })); + }, [supplierData]); - const productData = useMemo(() => { - if (!isResponseSuccess(productsResponse)) return {}; + const supplierProductData = useMemo(() => { + if (!supplierData || !isResponseSuccess(supplierData)) { + return {}; + } - const data: Record = {}; - productsResponse?.data?.forEach((product: Product) => { + const supplier = supplierData.data as SupplierProducts; + const products = supplier.products || []; + const data: Record[0]> = {}; + + products.forEach((product) => { data[product.id] = product; }); + return data; - }, [productsResponse]); + }, [supplierData]); const locationsUrl = useMemo(() => { const params = new URLSearchParams({ @@ -704,7 +714,7 @@ const PurchaseRequestForm = ({ productId ); }} - options={productOptions} + options={supplierProductOptions} isLoading={isLoadingProducts} isError={ isRepeaterInputError(idx, 'product_id').isError @@ -764,11 +774,13 @@ const PurchaseRequestForm = ({ required name={`items.${idx}.price`} value={ - item.product_id && productData[item.product_id] - ? ( - productData[item.product_id].product_price * + item.product_id && + supplierProductData[item.product_id] + ? formatNumber( + supplierProductData[item.product_id] + .ProductPrice * (parseFloat(item.qty?.toString() || '0') || 0) - ).toLocaleString('en-US') + ) : '' } onChange={() => {}} @@ -786,10 +798,13 @@ const PurchaseRequestForm = ({ : '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')}` + item.product_id && + supplierProductData[item.product_id] + ? `Harga per unit: Rp ${formatNumber( + supplierProductData[ + item.product_id + ].ProductPrice + )}` : '' } /> @@ -799,8 +814,9 @@ const PurchaseRequestForm = ({ required name={`items.${idx}.uom`} value={ - item.product_id && productData[item.product_id] - ? productData[item.product_id].uom.name + item.product_id && + supplierProductData[item.product_id] + ? supplierProductData[item.product_id].uom.name : '' } onBlur={formik.handleBlur} diff --git a/src/types/api/master-data/supplier.d.ts b/src/types/api/master-data/supplier.d.ts index 3782cddb..81d41771 100644 --- a/src/types/api/master-data/supplier.d.ts +++ b/src/types/api/master-data/supplier.d.ts @@ -1,4 +1,5 @@ import { BaseMetadata } from '@/types/api/api-general'; +import { Uom } from '@/types/api/master-data/uom'; export type BaseSupplier = { id: number; @@ -19,6 +20,17 @@ export type BaseSupplier = { export type Supplier = BaseMetadata & BaseSupplier; +export type SupplierProducts = Supplier & { + products?: Array<{ + id: number; + name: string; + ProductPrice: number; + SellingPrice?: number; + uom: Uom; + flags: string[]; + }>; +}; + export type CreateSupplierPayload = { name: string; alias: string;