From c8beed57d9fb10c02b8951cd4267017984ca5beb Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Wed, 17 Sep 2025 10:41:29 +0000
Subject: (최겸) 구매 일반계약 프로젝트id추가, 선적지, 하역지 연동, numbering
 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../main/create-general-contract-dialog.tsx        | 156 +++++++--------------
 1 file changed, 50 insertions(+), 106 deletions(-)

(limited to 'lib/general-contracts/main/create-general-contract-dialog.tsx')

diff --git a/lib/general-contracts/main/create-general-contract-dialog.tsx b/lib/general-contracts/main/create-general-contract-dialog.tsx
index 3eb8b11c..2c3fc8bc 100644
--- a/lib/general-contracts/main/create-general-contract-dialog.tsx
+++ b/lib/general-contracts/main/create-general-contract-dialog.tsx
@@ -24,7 +24,7 @@ import { CalendarIcon } from "lucide-react"
 import { format } from "date-fns"
 import { ko } from "date-fns/locale"
 import { cn } from "@/lib/utils"
-import { createContract, getVendors } from "@/lib/general-contracts/service"
+import { createContract, getVendors, getProjects } from "@/lib/general-contracts/service"
 import { 
   GENERAL_CONTRACT_CATEGORIES, 
   GENERAL_CONTRACT_TYPES,
@@ -38,17 +38,12 @@ interface CreateContractForm {
   category: string
   type: string
   executionMethod: string
-  selectionMethod: string
   vendorId: number | null
+  projectId: number | null
   startDate: Date | undefined
   endDate: Date | undefined
   validityEndDate: Date | undefined
-  // contractScope: string
-  // specificationType: string
   notes: string
-  linkedRfqOrItb: string
-  linkedBidNumber: string
-  linkedPoNumber: string
 }
 
 export function CreateGeneralContractDialog() {
@@ -57,24 +52,20 @@ export function CreateGeneralContractDialog() {
   const [open, setOpen] = React.useState(false)
   const [isLoading, setIsLoading] = React.useState(false)
   const [vendors, setVendors] = React.useState<Array<{ id: number; vendorName: string; vendorCode: string | null }>>([])
-  
+  const [projects, setProjects] = React.useState<Array<{ id: number; code: string; name: string; type: string }>>([])
+
   const [form, setForm] = React.useState<CreateContractForm>({
     contractNumber: '',
     name: '',
     category: '',
     type: '',
     executionMethod: '',
-    selectionMethod: '',
     vendorId: null,
+    projectId: null,
     startDate: undefined,
     endDate: undefined,
     validityEndDate: undefined,
-    // contractScope: '',
-    // specificationType: '',
     notes: '',
-    linkedRfqOrItb: '',
-    linkedBidNumber: '',
-    linkedPoNumber: '',
   })
 
   // 업체 목록 조회
@@ -90,6 +81,20 @@ export function CreateGeneralContractDialog() {
     fetchVendors()
   }, [])
 
+  // 프로젝트 목록 조회
+  React.useEffect(() => {
+    const fetchProjects = async () => {
+      try {
+        const projectList = await getProjects()
+        console.log(projectList)
+        setProjects(projectList)
+      } catch (error) {
+        console.error('Error fetching projects:', error)
+      }
+    }
+    fetchProjects()
+  }, [])
+
   const handleSubmit = async () => {
     // 필수 필드 검증
     if (!form.name || !form.category || !form.type || !form.executionMethod || 
@@ -111,23 +116,19 @@ export function CreateGeneralContractDialog() {
         category: form.category,
         type: form.type,
         executionMethod: form.executionMethod,
-        selectionMethod: form.selectionMethod,
+        projectId: form.projectId,
+        contractSourceType: 'manual',
         vendorId: form.vendorId!,
         startDate: form.startDate!.toISOString().split('T')[0],
         endDate: form.endDate!.toISOString().split('T')[0],
         validityEndDate: (form.validityEndDate || form.endDate!).toISOString().split('T')[0],
-        // contractScope: form.contractScope,
-        // specificationType: form.specificationType,
         status: 'Draft',
         registeredById: session?.user?.id || 1,
         lastUpdatedById: session?.user?.id || 1,
         notes: form.notes,
-        linkedRfqOrItb: form.linkedRfqOrItb,
-        linkedBidNumber: form.linkedBidNumber,
-        linkedPoNumber: form.linkedPoNumber,
       }
 
-      const newContract = await createContract(contractData)
+      await createContract(contractData)
       
       toast.success("새 계약이 생성되었습니다.")
       setOpen(false)
@@ -150,17 +151,12 @@ export function CreateGeneralContractDialog() {
       category: '',
       type: '',
       executionMethod: '',
-      selectionMethod: '',
       vendorId: null,
+      projectId: null,
       startDate: undefined,
       endDate: undefined,
       validityEndDate: undefined,
-      // contractScope: '',
-      // specificationType: '',
       notes: '',
-      linkedRfqOrItb: '',
-      linkedBidNumber: '',
-      linkedPoNumber: '',
     })
   }
 
@@ -185,16 +181,6 @@ export function CreateGeneralContractDialog() {
         
         <div className="grid gap-4 py-4">
           <div className="grid grid-cols-1 gap-4">
-            {/* <div className="grid gap-2">
-              <Label htmlFor="contractNumber">계약번호</Label>
-              <Input
-                id="contractNumber"
-                value={form.contractNumber}
-                onChange={(e) => setForm(prev => ({ ...prev, contractNumber: e.target.value }))}
-                placeholder="자동 생성됩니다"
-              />
-            </div> */}
-            
             <div className="grid gap-2">
               <Label htmlFor="name">계약명 *</Label>
               <Input
@@ -214,11 +200,18 @@ export function CreateGeneralContractDialog() {
                   <SelectValue placeholder="계약구분 선택" />
                 </SelectTrigger>
                 <SelectContent>
-                  {GENERAL_CONTRACT_CATEGORIES.map((category) => (
+                  {GENERAL_CONTRACT_CATEGORIES.map((category) => {
+                    const categoryLabels = {
+                      'unit_price': '단가계약',
+                      'general': '일반계약',
+                      'sale': '매각계약'
+                    }
+                    return (
                     <SelectItem key={category} value={category}>
-                      {category}
-                    </SelectItem>
-                  ))}
+                      {category} - {categoryLabels[category as keyof typeof categoryLabels]}
+                      </SelectItem>
+                    )
+                  })}
                 </SelectContent>
               </Select>
             </div>
@@ -275,6 +268,22 @@ export function CreateGeneralContractDialog() {
             </div>
           </div>
 
+          <div className="grid gap-2">
+            <Label htmlFor="project">프로젝트</Label>
+            <Select value={form.projectId?.toString()} onValueChange={(value) => setForm(prev => ({ ...prev, projectId: parseInt(value) }))}>
+              <SelectTrigger>
+                <SelectValue placeholder="프로젝트 선택 (선택사항)" />
+              </SelectTrigger>
+              <SelectContent>
+                {projects.map((project) => (
+                  <SelectItem key={project.id} value={project.id.toString()}>
+                    {project.name} ({project.code})
+                  </SelectItem>
+                ))}
+              </SelectContent>
+            </Select>
+          </div>
+
           <div className="grid gap-2">
             <Label htmlFor="vendor">협력업체 *</Label>
             <Select value={form.vendorId?.toString()} onValueChange={(value) => setForm(prev => ({ ...prev, vendorId: parseInt(value) }))}>
@@ -370,71 +379,6 @@ export function CreateGeneralContractDialog() {
               </Popover>
             </div>
           </div>
-
-          {/* <div className="grid grid-cols-2 gap-4">
-            <div className="grid gap-2">
-              <Label htmlFor="contractScope">계약확정범위 *</Label>
-              <Select value={form.contractScope} onValueChange={(value) => setForm(prev => ({ ...prev, contractScope: value }))}>
-                <SelectTrigger>
-                  <SelectValue placeholder="계약확정범위 선택" />
-                </SelectTrigger>
-                <SelectContent>
-                  {GENERAL_CONTRACT_SCOPES.map((scope) => (
-                    <SelectItem key={scope} value={scope}>
-                      {scope}
-                    </SelectItem>
-                  ))}
-                </SelectContent>
-              </Select>
-            </div>
-
-            <div className="grid gap-2">
-              <Label htmlFor="specificationType">사양 *</Label>
-              <Select value={form.specificationType} onValueChange={(value) => setForm(prev => ({ ...prev, specificationType: value }))}>
-                <SelectTrigger>
-                  <SelectValue placeholder="사양 선택" />
-                </SelectTrigger>
-                <SelectContent>
-                  <SelectItem value="첨부파일">첨부파일</SelectItem>
-                  <SelectItem value="직접입력">직접입력</SelectItem>
-                  <SelectItem value="기타">기타</SelectItem>
-                </SelectContent>
-              </Select>
-            </div>
-          </div> */}
-
-          <div className="grid grid-cols-2 gap-4">
-            <div className="grid gap-2">
-              <Label htmlFor="linkedRfqOrItb">연계 견적/입찰번호</Label>
-              <Input
-                id="linkedRfqOrItb"
-                value={form.linkedRfqOrItb}
-                onChange={(e) => setForm(prev => ({ ...prev, linkedRfqOrItb: e.target.value }))}
-                placeholder="연계 견적/입찰번호를 입력하세요"
-              />
-            </div>
-
-            <div className="grid gap-2">
-              <Label htmlFor="linkedBidNumber">연계 BID번호</Label>
-              <Input
-                id="linkedBidNumber"
-                value={form.linkedBidNumber}
-                onChange={(e) => setForm(prev => ({ ...prev, linkedBidNumber: e.target.value }))}
-                placeholder="연계 BID번호를 입력하세요"
-              />
-            </div>
-          </div>
-
-          <div className="grid gap-2">
-            <Label htmlFor="linkedPoNumber">연계PO번호</Label>
-            <Input
-              id="linkedPoNumber"
-              value={form.linkedPoNumber}
-              onChange={(e) => setForm(prev => ({ ...prev, linkedPoNumber: e.target.value }))}
-              placeholder="연계PO번호를 입력하세요"
-            />
-          </div>
-
           <div className="grid gap-2">
             <Label htmlFor="notes">비고</Label>
             <Textarea
-- 
cgit v1.2.3

