diff --git a/negodata/front/src/features/products/components/ExcelUploadModal.tsx b/negodata/front/src/features/products/components/ExcelUploadModal.tsx index c208868..3100f33 100644 --- a/negodata/front/src/features/products/components/ExcelUploadModal.tsx +++ b/negodata/front/src/features/products/components/ExcelUploadModal.tsx @@ -171,7 +171,9 @@ function toItemCreate(row: RawRow): ItemCreate { delivery_type: DELIVERY_LABEL_TO_CODE[row.delivery_type.trim()] ?? undefined, vat_yn: row.vat_yn.trim() ? parseYn(row.vat_yn) : undefined, delivery_fee_yn: row.delivery_fee_yn.trim() ? parseYn(row.delivery_fee_yn) : undefined, - internet_lowest_price_yn: false, + // minPrice(최저한도) = 인터넷 최저가(실값) → internet_lowest_price 로 저장(수기 폼과 동일). + internet_lowest_price: row.minPrice, + internet_lowest_price_yn: row.minPrice > 0, }; } diff --git a/negodata/front/src/features/products/components/ProductFormSheet.tsx b/negodata/front/src/features/products/components/ProductFormSheet.tsx index 3556da7..2cce47b 100644 --- a/negodata/front/src/features/products/components/ProductFormSheet.tsx +++ b/negodata/front/src/features/products/components/ProductFormSheet.tsx @@ -12,7 +12,7 @@ import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Sheet } from '@/components/ui/sheet'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; -import { type Product, toMinPrice } from '../types'; +import { type Product } from '../types'; // 폼 검증 스키마. 필수: 상품명/상품코드/단가/최저가. 나머지는 선택. const schema = z.object({ @@ -60,7 +60,7 @@ function buildDefaults(mode: 'create' | 'edit', product: Product | null): FormVa code: product.code || '', category: product.category || '', price: product.price || 0, - minPrice: toMinPrice(product.price), + minPrice: product.internet_lowest_price ?? 0, modelName: product.model_name || '', specification: product.spec || '', manufacturer: product.manufacturer || '', @@ -129,7 +129,7 @@ export function ProductFormSheet({ const deliveryTypes = DELIVERY_TYPE_OPTIONS; - // minPrice는 화면 전용(서버 미전송). 검증된 값만 payload로. + // minPrice = 인터넷 최저가(실값) → internet_lowest_price 로 저장한다. const onValid = async (v: FormValues) => { // 기존 카테고리면 그 category_type(id) 재사용, 처음 쓰는 카테고리면 max+1 부여. const categoryName = v.category.trim(); @@ -151,6 +151,7 @@ export function ProductFormSheet({ vat_yn: v.vatYn, delivery_fee_yn: v.deliveryFeeYn, internet_lowest_price_yn: v.internetLowestPriceYn, + internet_lowest_price: v.minPrice, purchase_price: v.purchasePrice, selling_price: v.sellingPrice, }; diff --git a/negodata/front/src/features/products/components/ProductTable.tsx b/negodata/front/src/features/products/components/ProductTable.tsx index bcbfbd2..c505592 100644 --- a/negodata/front/src/features/products/components/ProductTable.tsx +++ b/negodata/front/src/features/products/components/ProductTable.tsx @@ -2,7 +2,7 @@ import { Image as ImageIcon } from 'lucide-react'; import { Badge } from '@/components/ui/badge'; import { DataTable } from '@/components/ui/data-table'; import { TablePagination } from '@/components/ui/table-pagination'; -import { type Product, toMinPrice } from '../types'; +import { type Product } from '../types'; type ProductTableProps = { data: Product[]; @@ -91,7 +91,7 @@ export function ProductTable({ header: '인터넷 최저가', align: 'right', cellClassName: 'font-mono font-semibold text-rose-600 dark:text-rose-400', - cell: (prod) => `₩${(prod.minPrice || toMinPrice(prod.price)).toLocaleString()}`, + cell: (prod) => (prod.internet_lowest_price != null ? `₩${Number(prod.internet_lowest_price).toLocaleString()}` : '-'), }, ]} /> diff --git a/negodata/front/src/features/products/hooks/useProducts.ts b/negodata/front/src/features/products/hooks/useProducts.ts index 341db9a..22e628b 100644 --- a/negodata/front/src/features/products/hooks/useProducts.ts +++ b/negodata/front/src/features/products/hooks/useProducts.ts @@ -12,7 +12,7 @@ import type { ReqUpdateItem } from '@/api/generated/model/reqUpdateItem'; import type { ResItem } from '@/api/generated/model/resItem'; import type { ItemData } from '@/api/generated/model/itemData'; import type { BulkFailure } from '@/lib/excel'; -import { type Product, toMinPrice } from '../types'; +import { type Product } from '../types'; // 엑셀 중복검사 + 최저가 모달은 "현재 페이지 밖"의 상품도 코드/ID로 조회해야 해서 // 전체 목록(최대 100건)을 따로 받는다. (카테고리 목록은 더 이상 여기서 만들지 않는다 — 아래 categoriesQuery.) @@ -20,7 +20,7 @@ const META_PARAMS: ListItemsParams = { size: 100 }; // 서버 ItemData → UI Product (화면 전용 파생 필드 부여). function toProduct(it: ItemData): Product { - return { ...it, id: it.item_id, minPrice: toMinPrice(it.price), status: 'ACTIVE' }; + return { ...it, id: it.item_id, minPrice: it.internet_lowest_price ?? 0, status: 'ACTIVE' }; } // 서버 공통응답(result.success=false)을 한글 사유로 변환. 정상이면 null. diff --git a/negodata/front/src/features/products/types.ts b/negodata/front/src/features/products/types.ts index f1b2602..8b47d81 100644 --- a/negodata/front/src/features/products/types.ts +++ b/negodata/front/src/features/products/types.ts @@ -1,4 +1 @@ export type { Product } from '@/types'; - -// 인터넷 최저가 데모 산정(표준 단가의 83%). 서버 미연동 — 표시/초기값 용도. -export const toMinPrice = (price?: number | null) => Math.round((price || 0) * 0.83);