From b75b1cd920efd61923f7b2dbc4c49987b7b0c4e1 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Thu, 20 Nov 2025 10:25:41 +0000
Subject: (최겸) 구매 입찰 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/bidding/manage/bidding-items-editor.tsx | 74 +++++++++++++---------
 1 file changed, 44 insertions(+), 30 deletions(-)

(limited to 'components/bidding/manage/bidding-items-editor.tsx')

diff --git a/components/bidding/manage/bidding-items-editor.tsx b/components/bidding/manage/bidding-items-editor.tsx
index 38113dfa..f0287ae4 100644
--- a/components/bidding/manage/bidding-items-editor.tsx
+++ b/components/bidding/manage/bidding-items-editor.tsx
@@ -18,7 +18,7 @@ import {
   SelectValue,
 } from '@/components/ui/select'
 import { Checkbox } from '@/components/ui/checkbox'
-import { ProjectSelector } from '@/components/ProjectSelector'
+import { ProjectSelector } from '@/components/bidding/ProjectSelectorBid'
 import { MaterialGroupSelectorDialogSingle } from '@/components/common/material/material-group-selector-dialog-single'
 import { MaterialSelectorDialogSingle } from '@/components/common/selectors/material/material-selector-dialog-single'
 import { WbsCodeSingleSelector } from '@/components/common/selectors/wbs-code/wbs-code-single-selector'
@@ -255,12 +255,12 @@ export function BiddingItemsEditor({ biddingId, readonly = false }: BiddingItems
             costCenterName: item.costCenterName || null,
             glAccountCode: item.glAccountCode || null,
             glAccountName: item.glAccountName || null,
-            targetUnitPrice: item.targetUnitPrice ? parseFloat(item.targetUnitPrice) : null,
+            targetUnitPrice: item.targetUnitPrice ? parseFloat(item.targetUnitPrice.replace(/,/g, '')) : null,
             targetAmount: targetAmount ? parseFloat(targetAmount) : null,
             targetCurrency: item.targetCurrency || 'KRW',
-            budgetAmount: item.budgetAmount ? parseFloat(item.budgetAmount) : null,
+            budgetAmount: item.budgetAmount ? parseFloat(item.budgetAmount.replace(/,/g, '')) : null,
             budgetCurrency: item.budgetCurrency || 'KRW',
-            actualAmount: item.actualAmount ? parseFloat(item.actualAmount) : null,
+            actualAmount: item.actualAmount ? parseFloat(item.actualAmount.replace(/,/g, '')) : null,
             actualCurrency: item.actualCurrency || 'KRW',
             requestedDeliveryDate: item.requestedDeliveryDate ? new Date(item.requestedDeliveryDate) : null,
             currency: item.currency || 'KRW',
@@ -291,12 +291,12 @@ export function BiddingItemsEditor({ biddingId, readonly = false }: BiddingItems
             costCenterName: item.costCenterName ?? null,
             glAccountCode: item.glAccountCode ?? null,
             glAccountName: item.glAccountName ?? null,
-            targetUnitPrice: item.targetUnitPrice ?? null,
-            targetAmount: targetAmount ?? null,
+            targetUnitPrice: item.targetUnitPrice ? item.targetUnitPrice.replace(/,/g, '') : null,
+            targetAmount: targetAmount,
             targetCurrency: item.targetCurrency || 'KRW',
-            budgetAmount: item.budgetAmount ?? null,
+            budgetAmount: item.budgetAmount ? item.budgetAmount.replace(/,/g, '') : null,
             budgetCurrency: item.budgetCurrency || 'KRW',
-            actualAmount: item.actualAmount ?? null,
+            actualAmount: item.actualAmount ? item.actualAmount.replace(/,/g, '') : null,
             actualCurrency: item.actualCurrency || 'KRW',
             requestedDeliveryDate: item.requestedDeliveryDate ?? null,
             currency: item.currency || 'KRW',
@@ -519,8 +519,20 @@ export function BiddingItemsEditor({ biddingId, readonly = false }: BiddingItems
     setQuantityWeightMode(mode)
   }
 
-  const calculateTargetAmount = (item: PRItemInfo) => {
-    const unitPrice = parseFloat(item.targetUnitPrice || '0') || 0
+  // 천단위 콤마 포맷팅 헬퍼 함수들
+  const formatNumberWithCommas = (value: string | number | null | undefined): string => {
+    if (!value) return ''
+    const numValue = typeof value === 'number' ? value : parseFloat(value.toString().replace(/,/g, ''))
+    if (isNaN(numValue)) return ''
+    return numValue.toLocaleString()
+  }
+
+  const parseNumberFromCommas = (value: string): string => {
+    return value.replace(/,/g, '')
+  }
+
+  const calculateTargetAmount = (item: PRItemInfo): string => {
+    const unitPrice = parseFloat(item.targetUnitPrice?.replace(/,/g, '') || '0') || 0
     const purchaseUnit = parseFloat(item.purchaseUnit || '1') || 1
     let amount = 0
 
@@ -560,6 +572,7 @@ export function BiddingItemsEditor({ biddingId, readonly = false }: BiddingItems
                 </th>
                 <th className="border-r px-3 py-3 text-left text-xs font-medium min-w-[120px]">프로젝트코드</th>
                 <th className="border-r px-3 py-3 text-left text-xs font-medium min-w-[300px]">프로젝트명</th>
+                <th className="border-r px-3 py-3 text-left text-xs font-medium min-w-[120px]">PR 번호</th>
                 <th className="border-r px-3 py-3 text-left text-xs font-medium min-w-[150px]">자재그룹코드 <span className="text-red-500">*</span></th>
                 <th className="border-r px-3 py-3 text-left text-xs font-medium min-w-[300px]">자재그룹명 <span className="text-red-500">*</span></th>
                 <th className="border-r px-3 py-3 text-left text-xs font-medium min-w-[150px]">자재코드</th>
@@ -580,7 +593,7 @@ export function BiddingItemsEditor({ biddingId, readonly = false }: BiddingItems
                 <th className="border-r px-3 py-3 text-left text-xs font-medium min-w-[150px]">코스트센터명</th>
                 <th className="border-r px-3 py-3 text-left text-xs font-medium min-w-[120px]">GL계정코드</th>
                 <th className="border-r px-3 py-3 text-left text-xs font-medium min-w-[150px]">GL계정명</th>
-                <th className="border-r px-3 py-3 text-left text-xs font-medium min-w-[120px]">납품요청일</th>
+                <th className="border-r px-3 py-3 text-left text-xs font-medium min-w-[120px]">납품요청일 <span className="text-red-500">*</span></th>
                 <th className="sticky right-0 z-10 bg-muted/50 border-l px-3 py-3 text-center text-xs font-medium min-w-[100px]">
                   액션
                 </th>
@@ -620,6 +633,14 @@ export function BiddingItemsEditor({ biddingId, readonly = false }: BiddingItems
                       className="h-8 text-xs bg-muted/50"
                     />
                   </td>
+                  <td className="border-r px-3 py-2">
+                    <Input
+                      placeholder="PR 번호"
+                      value={item.prNumber || ''}
+                      readOnly
+                      className="h-8 text-xs bg-muted/50"
+                    />
+                  </td>
                   <td className="border-r px-3 py-2">
                     {biddingType !== 'equipment' ? (
                       <ProcurementItemSelectorDialogSingle
@@ -784,23 +805,19 @@ export function BiddingItemsEditor({ biddingId, readonly = false }: BiddingItems
                   </td>
                   <td className="border-r px-3 py-2">
                     <Input
-                      type="number"
-                      min="0"
-                      step="1"
+                      type="text"
                       placeholder="내정단가"
-                      value={item.targetUnitPrice || ''}
-                      onChange={(e) => updatePRItem(item.id, { targetUnitPrice: e.target.value })}
+                      value={formatNumberWithCommas(item.targetUnitPrice)}
+                      onChange={(e) => updatePRItem(item.id, { targetUnitPrice: parseNumberFromCommas(e.target.value) })}
                       className="h-8 text-xs"
                     />
                   </td>
                   <td className="border-r px-3 py-2">
                     <Input
-                      type="number"
-                      min="0"
-                      step="1"
+                      type="text"
                       placeholder="내정금액"
                       readOnly
-                      value={item.targetAmount || ''}
+                      value={formatNumberWithCommas(item.targetAmount)}
                       className="h-8 text-xs bg-muted/50"
                     />
                   </td>
@@ -822,12 +839,10 @@ export function BiddingItemsEditor({ biddingId, readonly = false }: BiddingItems
                   </td>
                   <td className="border-r px-3 py-2">
                     <Input
-                      type="number"
-                      min="0"
-                      step="1"
+                      type="text"
                       placeholder="예산금액"
-                      value={item.budgetAmount || ''}
-                      onChange={(e) => updatePRItem(item.id, { budgetAmount: e.target.value })}
+                      value={formatNumberWithCommas(item.budgetAmount)}
+                      onChange={(e) => updatePRItem(item.id, { budgetAmount: parseNumberFromCommas(e.target.value) })}
                       className="h-8 text-xs"
                     />
                   </td>
@@ -849,12 +864,10 @@ export function BiddingItemsEditor({ biddingId, readonly = false }: BiddingItems
                   </td>
                   <td className="border-r px-3 py-2">
                     <Input
-                      type="number"
-                      min="0"
-                      step="1"
+                      type="text"
                       placeholder="실적금액"
-                      value={item.actualAmount || ''}
-                      onChange={(e) => updatePRItem(item.id, { actualAmount: e.target.value })}
+                      value={formatNumberWithCommas(item.actualAmount)}
+                      onChange={(e) => updatePRItem(item.id, { actualAmount: parseNumberFromCommas(e.target.value) })}
                       className="h-8 text-xs"
                     />
                   </td>
@@ -1030,6 +1043,7 @@ export function BiddingItemsEditor({ biddingId, readonly = false }: BiddingItems
                       value={item.requestedDeliveryDate || ''}
                       onChange={(e) => updatePRItem(item.id, { requestedDeliveryDate: e.target.value })}
                       className="h-8 text-xs"
+                      required
                     />
                   </td>
                   <td className="sticky right-0 z-10 bg-background border-l px-3 py-2">
-- 
cgit v1.2.3

