summaryrefslogtreecommitdiff
path: root/components/bidding
diff options
context:
space:
mode:
Diffstat (limited to 'components/bidding')
-rw-r--r--components/bidding/create/bidding-create-dialog.tsx4
-rw-r--r--components/bidding/manage/bidding-basic-info-editor.tsx4
-rw-r--r--components/bidding/manage/bidding-companies-editor.tsx44
-rw-r--r--components/bidding/manage/bidding-detail-vendor-create-dialog.tsx16
4 files changed, 57 insertions, 11 deletions
diff --git a/components/bidding/create/bidding-create-dialog.tsx b/components/bidding/create/bidding-create-dialog.tsx
index 30550ca4..bdb00a01 100644
--- a/components/bidding/create/bidding-create-dialog.tsx
+++ b/components/bidding/create/bidding-create-dialog.tsx
@@ -609,7 +609,7 @@ export function BiddingCreateDialog({ form, onSuccess }: BiddingCreateDialogProp
{/* 4행: 하도급법적용여부, SHI 지급조건 */}
<div className="grid grid-cols-2 gap-4">
- <FormField
+ {/* <FormField
control={form.control}
name="biddingConditions.isPriceAdjustmentApplicable"
render={({ field }) => (
@@ -634,7 +634,7 @@ export function BiddingCreateDialog({ form, onSuccess }: BiddingCreateDialogProp
<FormMessage />
</FormItem>
)}
- />
+ /> */}
<FormField
control={form.control}
diff --git a/components/bidding/manage/bidding-basic-info-editor.tsx b/components/bidding/manage/bidding-basic-info-editor.tsx
index 2f55d563..e92c39a5 100644
--- a/components/bidding/manage/bidding-basic-info-editor.tsx
+++ b/components/bidding/manage/bidding-basic-info-editor.tsx
@@ -1090,7 +1090,7 @@ export function BiddingBasicInfoEditor({ biddingId }: BiddingBasicInfoEditorProp
/>
</div>
- <div className="flex flex-row items-center justify-between rounded-lg border p-3">
+ {/* <div className="flex flex-row items-center justify-between rounded-lg border p-3">
<div className="space-y-0.5">
<FormLabel className="text-base">연동제 적용 가능</FormLabel>
<div className="text-sm text-muted-foreground">
@@ -1106,7 +1106,7 @@ export function BiddingBasicInfoEditor({ biddingId }: BiddingBasicInfoEditorProp
}))
}}
/>
- </div>
+ </div> */}
</div>
{/* 5행: 스페어파트 옵션 */}
diff --git a/components/bidding/manage/bidding-companies-editor.tsx b/components/bidding/manage/bidding-companies-editor.tsx
index 1ce8b014..4992c2ab 100644
--- a/components/bidding/manage/bidding-companies-editor.tsx
+++ b/components/bidding/manage/bidding-companies-editor.tsx
@@ -5,13 +5,14 @@ import { Building, User, Plus, Trash2 } from 'lucide-react'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
-import {
- getBiddingVendors,
+import {
+ getBiddingVendors,
getBiddingCompanyContacts,
createBiddingCompanyContact,
deleteBiddingCompanyContact,
getVendorContactsByVendorId,
- updateBiddingCompanyPriceAdjustmentQuestion
+ updateBiddingCompanyPriceAdjustmentQuestion,
+ getBiddingById
} from '@/lib/bidding/service'
import { deleteBiddingCompany } from '@/lib/bidding/pre-quote/service'
import { BiddingDetailVendorCreateDialog } from './bidding-detail-vendor-create-dialog'
@@ -87,7 +88,11 @@ export function BiddingCompaniesEditor({ biddingId }: BiddingCompaniesEditorProp
const [isLoadingContacts, setIsLoadingContacts] = React.useState(false)
// 각 업체별 첫 번째 담당자 정보 저장 (vendorId -> 첫 번째 담당자)
const [vendorFirstContacts, setVendorFirstContacts] = React.useState<Map<number, BiddingCompanyContact>>(new Map())
-
+
+ // 입찰 정보 (단수/복수 낙찰 확인용)
+ const [biddingInfo, setBiddingInfo] = React.useState<any>(null)
+ const [isLoadingBiddingInfo, setIsLoadingBiddingInfo] = React.useState(false)
+
// 담당자 추가 다이얼로그
const [addContactDialogOpen, setAddContactDialogOpen] = React.useState(false)
const [newContact, setNewContact] = React.useState({
@@ -141,6 +146,29 @@ export function BiddingCompaniesEditor({ biddingId }: BiddingCompaniesEditorProp
}
}, [biddingId])
+ // 입찰 정보 로딩
+ const loadBiddingInfo = React.useCallback(async () => {
+ setIsLoadingBiddingInfo(true)
+ try {
+ const result = await getBiddingById(biddingId)
+ if (result) {
+ setBiddingInfo(result)
+ } else {
+ console.error('Failed to load bidding info')
+ setBiddingInfo(null)
+ }
+ } catch (error) {
+ console.error('Failed to load bidding info:', error)
+ setBiddingInfo(null)
+ } finally {
+ setIsLoadingBiddingInfo(false)
+ }
+ }, [biddingId])
+
+ // 단수 입찰 여부 확인 및 업체 추가 제한
+ const isSingleAwardBidding = biddingInfo?.awardCount === 'single'
+ const canAddVendor = !isSingleAwardBidding || vendors.length === 0
+
// 데이터 로딩
React.useEffect(() => {
const loadVendors = async () => {
@@ -177,7 +205,7 @@ export function BiddingCompaniesEditor({ biddingId }: BiddingCompaniesEditorProp
console.error(`Failed to load contact for vendor ${vendor.companyId}:`, error)
}
})
-
+
await Promise.all(contactPromises)
setVendorFirstContacts(firstContactsMap)
} else {
@@ -194,7 +222,8 @@ export function BiddingCompaniesEditor({ biddingId }: BiddingCompaniesEditorProp
}
loadVendors()
- }, [biddingId])
+ loadBiddingInfo()
+ }, [biddingId, loadBiddingInfo])
// 업체 선택 핸들러 (단일 선택)
const handleVendorSelect = async (vendor: QuotationVendor) => {
@@ -482,6 +511,7 @@ export function BiddingCompaniesEditor({ biddingId }: BiddingCompaniesEditorProp
<p className="text-sm text-muted-foreground mt-1">
입찰에 참여하는 업체들을 관리합니다. 업체를 선택하면 하단에 담당자 목록이 표시됩니다.
</p>
+ <p className="text-sm text-muted-foreground mt-1"> 단수 입찰의 경우 1개 업체만 등록 가능합니다. </p>
</div>
<Button onClick={() => setAddVendorDialogOpen(true)} className="flex items-center gap-2">
<Plus className="h-4 w-4" />
@@ -657,6 +687,8 @@ export function BiddingCompaniesEditor({ biddingId }: BiddingCompaniesEditorProp
open={addVendorDialogOpen}
onOpenChange={setAddVendorDialogOpen}
onSuccess={reloadVendors}
+ isSingleAwardBidding={isSingleAwardBidding}
+ currentVendorCount={vendors.length}
/>
{/* 담당자 추가 다이얼로그 (직접 입력) */}
diff --git a/components/bidding/manage/bidding-detail-vendor-create-dialog.tsx b/components/bidding/manage/bidding-detail-vendor-create-dialog.tsx
index ed3e2be6..205224b9 100644
--- a/components/bidding/manage/bidding-detail-vendor-create-dialog.tsx
+++ b/components/bidding/manage/bidding-detail-vendor-create-dialog.tsx
@@ -39,6 +39,8 @@ interface BiddingDetailVendorCreateDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
onSuccess: () => void
+ isSingleAwardBidding?: boolean
+ currentVendorCount?: number
}
interface Vendor {
@@ -57,7 +59,9 @@ export function BiddingDetailVendorCreateDialog({
biddingId,
open,
onOpenChange,
- onSuccess
+ onSuccess,
+ isSingleAwardBidding = false,
+ currentVendorCount = 0
}: BiddingDetailVendorCreateDialogProps) {
const { toast } = useToast()
const [isPending, startTransition] = useTransition()
@@ -100,6 +104,16 @@ export function BiddingDetailVendorCreateDialog({
// 벤더 추가
const handleAddVendor = (vendor: Vendor) => {
+ // 단수 입찰이고 이미 업체가 선택되었거나 기존 업체가 있는 경우 제한
+ if (isSingleAwardBidding && (selectedVendorsWithQuestion.length > 0 || currentVendorCount > 0)) {
+ toast({
+ title: '제한 사항',
+ description: '단수 입찰의 경우 1개 업체만 등록 가능합니다.',
+ variant: 'destructive',
+ })
+ return
+ }
+
if (!selectedVendorsWithQuestion.find(v => v.vendor.id === vendor.id)) {
setSelectedVendorsWithQuestion([
...selectedVendorsWithQuestion,