"use client" import * as React from "react" import { Send, CheckCircle, FileText, Truck, Calculator, Package } from "lucide-react" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Label } from "@/components/ui/label" import { Badge } from "@/components/ui/badge" import { Separator } from "@/components/ui/separator" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip" import { BiddingListItem } from "@/db/schema" import { transmitToContract, transmitToPO, getWinnerDetails } from "@/lib/bidding/actions" interface TransmissionDialogProps { open: boolean onOpenChange: (open: boolean) => void bidding: BiddingListItem | undefined userId: number } interface WinnerDetail { id: number companyId: number vendorName: string | null vendorCode: string | null awardRatio: number totalFinalAmount: number items: Array<{ prItemId: number proposedDeliveryDate: string | null bidUnitPrice: string | null bidAmount: string | null currency: string | null itemNumber: string | null itemInfo: string | null materialDescription: string | null quantity: string | null quantityUnit: string | null finalQuantity: number finalWeight: number finalAmount: number awardRatio: number }> } export function TransmissionDialog({ open, onOpenChange, bidding, userId }: TransmissionDialogProps) { const [isLoading, setIsLoading] = React.useState(false) const [winnerDetails, setWinnerDetails] = React.useState([]) const [isLoadingDetails, setIsLoadingDetails] = React.useState(false) // 낙찰 업체 상세 정보 로드 const loadWinnerDetails = React.useCallback(async () => { if (!bidding) return try { setIsLoadingDetails(true) const result = await getWinnerDetails(bidding.id) if (result.success) { setWinnerDetails(result.data || []) } else { toast.error(result.error || '낙찰 업체 정보를 불러오는데 실패했습니다.') } } catch (error) { console.error('Failed to load winner details:', error) toast.error('낙찰 업체 정보를 불러오는데 실패했습니다.') } finally { setIsLoadingDetails(false) } }, [bidding]) React.useEffect(() => { if (open && bidding) { loadWinnerDetails() } }, [open, bidding, loadWinnerDetails]) if (!bidding) return null // 업체선정이 완료되지 않은 경우 에러 표시 if (bidding.status !== 'vendor_selected') { return ( 전송 불가 업체선정이 완료된 입찰만 전송할 수 있습니다.

현재 상태: {bidding.status}

업체선정이 완료된 후 다시 시도해주세요.

) } const handleToContract = async () => { try { setIsLoading(true) console.log('bidding.id', bidding.id) console.log('userId', userId) await transmitToContract(bidding.id, userId) toast.success('계약서 생성이 완료되었습니다.') onOpenChange(false) } catch (error) { toast.error(`계약서 생성에 실패했습니다: ${error}`) } finally { setIsLoading(false) } } const handleToPO = async () => { try { setIsLoading(true) await transmitToPO(bidding.id) toast.success('PO 전송이 완료되었습니다.') onOpenChange(false) } catch (error) { toast.error(`PO 전송에 실패했습니다: ${error}`) } finally { setIsLoading(false) } } return ( 입찰 전송 선택된 입찰을 계약서 또는 PO로 전송합니다.
{/* 입찰 정보 */} 입찰 정보

{bidding.biddingNumber}

{bidding.title}

{bidding.contractType}

{bidding.budget ? `${bidding.budget.toLocaleString()} ${bidding.currency}` : '-'}

{/* 선정된 업체 상세 정보 */} 선정된 업체 ({winnerDetails.length}개) {isLoadingDetails ? (

업체 정보를 불러오는 중...

) : winnerDetails.length === 0 ? (

선정된 업체가 없습니다.

) : ( winnerDetails.map((winner) => (
{winner.vendorName || `업체 ${winner.companyId}`} {winner.vendorCode}
발주비율: {winner.awardRatio.toFixed(1)}%
최종 견적가: {winner.totalFinalAmount.toLocaleString()} {winner.items[0]?.currency || 'KRW'}
품목별 상세 ({winner.items.length}개 품목)
{winner.items.map((item, itemIndex) => (
품목: {item.itemInfo || item.itemNumber}
규격: {item.materialDescription}
원래 수량: {Number(item.quantity).toLocaleString()} {item.quantityUnit}
발주 수량: {item.finalQuantity.toLocaleString()} {item.quantityUnit}
단가: {Number(item.bidUnitPrice).toLocaleString()} {item.currency}
최종 금액: {item.finalAmount.toLocaleString()} {item.currency}
))}
)) )}
{bidding.ANFNR ? ( ) : (

해당 입찰은 SAP TO PO가 불가능합니다.

)}
) }