From 7a1524ba54f43d0f2a19e4bca2c6a2e0b01c5ef1 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Tue, 17 Jun 2025 09:02:32 +0000
Subject: (대표님) 20250617 18시 작업사항
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/b-rfq/initial/add-initial-rfq-dialog.tsx | 326 +++++++++++++++------------
 1 file changed, 188 insertions(+), 138 deletions(-)

(limited to 'lib/b-rfq/initial/add-initial-rfq-dialog.tsx')

diff --git a/lib/b-rfq/initial/add-initial-rfq-dialog.tsx b/lib/b-rfq/initial/add-initial-rfq-dialog.tsx
index d0924be2..58a091ac 100644
--- a/lib/b-rfq/initial/add-initial-rfq-dialog.tsx
+++ b/lib/b-rfq/initial/add-initial-rfq-dialog.tsx
@@ -1,4 +1,3 @@
-// add-initial-rfq-dialog.tsx
 "use client"
 
 import * as React from "react"
@@ -45,6 +44,7 @@ import { Checkbox } from "@/components/ui/checkbox"
 import { cn, formatDate } from "@/lib/utils"
 import { addInitialRfqRecord, getIncotermsForSelection, getVendorsForSelection } from "../service"
 import { Calendar } from "@/components/ui/calendar"
+import { InitialRfqDetailView } from "@/db/schema"
 
 // Initial RFQ 추가 폼 스키마
 const addInitialRfqSchema = z.object({
@@ -70,22 +70,30 @@ const addInitialRfqSchema = z.object({
   returnRevision: z.number().default(0),
 })
 
-type AddInitialRfqFormData = z.infer<typeof addInitialRfqSchema>
+export type AddInitialRfqFormData = z.infer<typeof addInitialRfqSchema>
 
 interface Vendor {
   id: number
   vendorName: string
   vendorCode: string
   country: string
+  taxId: string
   status: string
 }
 
+interface Incoterm {
+  id: number
+  code: string
+  description: string
+}
+
 interface AddInitialRfqDialogProps {
   rfqId: number
   onSuccess?: () => void
+  defaultValues?: InitialRfqDetailView // 선택된 항목의 기본값
 }
 
-export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogProps) {
+export function AddInitialRfqDialog({ rfqId, onSuccess, defaultValues }: AddInitialRfqDialogProps) {
   const [open, setOpen] = React.useState(false)
   const [isSubmitting, setIsSubmitting] = React.useState(false)
   const [vendors, setVendors] = React.useState<Vendor[]>([])
@@ -95,16 +103,38 @@ export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogPro
   const [incotermsLoading, setIncotermsLoading] = React.useState(false)
   const [incotermsSearchOpen, setIncotermsSearchOpen] = React.useState(false)
 
-  const form = useForm<AddInitialRfqFormData>({
-    resolver: zodResolver(addInitialRfqSchema),
-    defaultValues: {
+  // 기본값 설정 (선택된 항목이 있으면 해당 값 사용, 없으면 일반 기본값)
+  const getDefaultFormValues = React.useCallback((): Partial<AddInitialRfqFormData> => {
+    if (defaultValues) {
+      return {
+        vendorId: defaultValues.vendorId,
+        initialRfqStatus: "DRAFT", // 새로 추가할 때는 항상 DRAFT로 시작
+        dueDate: defaultValues.dueDate || new Date(),
+        validDate: defaultValues.validDate,
+        incotermsCode: defaultValues.incotermsCode || "",
+        classification: defaultValues.classification || "",
+        sparepart: defaultValues.sparepart || "",
+        shortList: false, // 새로 추가할 때는 기본적으로 false
+        returnYn: false,
+        cpRequestYn: defaultValues.cpRequestYn || false,
+        prjectGtcYn: defaultValues.prjectGtcYn || false,
+        returnRevision: 0,
+      }
+    }
+    
+    return {
       initialRfqStatus: "DRAFT",
       shortList: false,
       returnYn: false,
       cpRequestYn: false,
       prjectGtcYn: false,
       returnRevision: 0,
-    },
+    }
+  }, [defaultValues])
+
+  const form = useForm<AddInitialRfqFormData>({
+    resolver: zodResolver(addInitialRfqSchema),
+    defaultValues: getDefaultFormValues(),
   })
 
   // 벤더 목록 로드
@@ -121,23 +151,27 @@ export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogPro
     }
   }, [])
 
-    // Incoterms 목록 로드
-    const loadIncoterms = React.useCallback(async () => {
-        setIncotermsLoading(true)
-        try {
-          const incotermsList = await getIncotermsForSelection()
-          setIncoterms(incotermsList)
-        } catch (error) {
-          console.error("Failed to load incoterms:", error)
-          toast.error("Incoterms 목록을 불러오는데 실패했습니다.")
-        } finally {
-          setIncotermsLoading(false)
-        }
-      }, [])
+  // Incoterms 목록 로드
+  const loadIncoterms = React.useCallback(async () => {
+    setIncotermsLoading(true)
+    try {
+      const incotermsList = await getIncotermsForSelection()
+      setIncoterms(incotermsList)
+    } catch (error) {
+      console.error("Failed to load incoterms:", error)
+      toast.error("Incoterms 목록을 불러오는데 실패했습니다.")
+    } finally {
+      setIncotermsLoading(false)
+    }
+  }, [])
 
-  // 다이얼로그 열릴 때 벤더 목록 로드
+  // 다이얼로그 열릴 때 실행
   React.useEffect(() => {
     if (open) {
+      // 폼을 기본값으로 리셋
+      form.reset(getDefaultFormValues())
+      
+      // 데이터 로드
       if (vendors.length === 0) {
         loadVendors()
       }
@@ -145,12 +179,12 @@ export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogPro
         loadIncoterms()
       }
     }
-  }, [open, vendors.length, incoterms.length, loadVendors, loadIncoterms])
+  }, [open, vendors.length, incoterms.length, loadVendors, loadIncoterms, form, getDefaultFormValues])
 
   // 다이얼로그 닫기 핸들러
   const handleOpenChange = (newOpen: boolean) => {
     if (!newOpen && !isSubmitting) {
-      form.reset()
+      form.reset(getDefaultFormValues())
     }
     setOpen(newOpen)
   }
@@ -167,7 +201,7 @@ export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogPro
       
       if (result.success) {
         toast.success(result.message || "초기 RFQ가 성공적으로 추가되었습니다.")
-        form.reset()
+        form.reset(getDefaultFormValues())
         handleOpenChange(false)
         onSuccess?.()
       } else {
@@ -186,20 +220,32 @@ export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogPro
   const selectedVendor = vendors.find(vendor => vendor.id === form.watch("vendorId"))
   const selectedIncoterm = incoterms.find(incoterm => incoterm.code === form.watch("incotermsCode"))
 
+  // 기본값이 있을 때 버튼 텍스트 변경
+  const buttonText = defaultValues ? "유사 항목 추가" : "초기 RFQ 추가"
+  const dialogTitle = defaultValues ? "유사 초기 RFQ 추가" : "초기 RFQ 추가"
+  const dialogDescription = defaultValues 
+    ? "선택된 항목을 기본값으로 하여 새로운 초기 RFQ를 추가합니다."
+    : "새로운 벤더를 대상으로 하는 초기 RFQ를 추가합니다."
+
   return (
     <Dialog open={open} onOpenChange={handleOpenChange}>
       <DialogTrigger asChild>
         <Button variant="outline" size="sm" className="gap-2">
           <Plus className="size-4" aria-hidden="true" />
-          <span className="hidden sm:inline">초기 RFQ 추가</span>
+          <span className="hidden sm:inline">{buttonText}</span>
         </Button>
       </DialogTrigger>
       
       <DialogContent className="sm:max-w-[600px] max-h-[80vh] overflow-y-auto">
         <DialogHeader>
-          <DialogTitle>초기 RFQ 추가</DialogTitle>
+          <DialogTitle>{dialogTitle}</DialogTitle>
           <DialogDescription>
-            새로운 벤더를 대상으로 하는 초기 RFQ를 추가합니다.
+            {dialogDescription}
+            {defaultValues && (
+              <div className="mt-2 p-2 bg-muted rounded-md text-sm">
+                <strong>기본값 출처:</strong> {defaultValues.vendorName} ({defaultValues.vendorCode})
+              </div>
+            )}
           </DialogDescription>
         </DialogHeader>
 
@@ -263,7 +309,7 @@ export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogPro
                                       {vendor.vendorName}
                                     </div>
                                     <div className="text-sm text-muted-foreground">
-                                      {vendor.vendorCode} • {vendor.country}
+                                      {vendor.vendorCode} • {vendor.country}  • {vendor.taxId} 
                                     </div>
                                   </div>
                                   <Check
@@ -287,98 +333,98 @@ export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogPro
 
             {/* 날짜 필드들 */}
             <div className="grid grid-cols-2 gap-4">
-            <FormField
-                  control={form.control}
-                  name="dueDate"
-                  render={({ field }) => (
-                    <FormItem className="flex flex-col">
-                      <FormLabel>견적 마감일</FormLabel>
-                      <Popover>
-                        <PopoverTrigger asChild>
-                          <FormControl>
-                            <Button
-                              variant="outline"
-                              className={cn(
-                                "w-full pl-3 text-left font-normal",
-                                !field.value && "text-muted-foreground"
-                              )}
-                            >
-                                                       {field.value ? (
-                                formatDate(field.value,"KR")
-                              ) : (
-                                <span>견적 유효일을 선택하세요</span>
-                              )}
-                              <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
-                            </Button>
-                          </FormControl>
-                        </PopoverTrigger>
-                        <PopoverContent className="w-auto p-0" align="start">
-                          <Calendar
-                            mode="single"
-                            selected={field.value}
-                            onSelect={field.onChange}
-                            disabled={(date) =>
-                              date < new Date() || date < new Date("1900-01-01")
-                            }
-                            initialFocus
-                          />
-                        </PopoverContent>
-                      </Popover>
-                      <FormMessage />
-                    </FormItem>
-                  )}
-                />
-                        <FormField
-                  control={form.control}
-                  name="validDate"
-                  render={({ field }) => (
-                    <FormItem className="flex flex-col">
-                      <FormLabel>견적 유효일</FormLabel>
-                      <Popover>
-                        <PopoverTrigger asChild>
-                          <FormControl>
-                            <Button
-                              variant="outline"
-                              className={cn(
-                                "w-full pl-3 text-left font-normal",
-                                !field.value && "text-muted-foreground"
-                              )}
-                            >
-                              {field.value ? (
-                                formatDate(field.value,"KR")
-                              ) : (
-                                <span>견적 유효일을 선택하세요</span>
-                              )}
-                              <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
-                            </Button>
-                          </FormControl>
-                        </PopoverTrigger>
-                        <PopoverContent className="w-auto p-0" align="start">
-                          <Calendar
-                            mode="single"
-                            selected={field.value}
-                            onSelect={field.onChange}
-                            disabled={(date) =>
-                              date < new Date() || date < new Date("1900-01-01")
-                            }
-                            initialFocus
-                          />
-                        </PopoverContent>
-                      </Popover>
-                      <FormMessage />
-                    </FormItem>
-                  )}
-                />
+              <FormField
+                control={form.control}
+                name="dueDate"
+                render={({ field }) => (
+                  <FormItem className="flex flex-col">
+                    <FormLabel>견적 마감일 *</FormLabel>
+                    <Popover>
+                      <PopoverTrigger asChild>
+                        <FormControl>
+                          <Button
+                            variant="outline"
+                            className={cn(
+                              "w-full pl-3 text-left font-normal",
+                              !field.value && "text-muted-foreground"
+                            )}
+                          >
+                            {field.value ? (
+                              formatDate(field.value, "KR")
+                            ) : (
+                              <span>견적 마감일을 선택하세요</span>
+                            )}
+                            <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
+                          </Button>
+                        </FormControl>
+                      </PopoverTrigger>
+                      <PopoverContent className="w-auto p-0" align="start">
+                        <Calendar
+                          mode="single"
+                          selected={field.value}
+                          onSelect={field.onChange}
+                          disabled={(date) =>
+                            date < new Date() || date < new Date("1900-01-01")
+                          }
+                          initialFocus
+                        />
+                      </PopoverContent>
+                    </Popover>
+                    <FormMessage />
+                  </FormItem>
+                )}
+              />
+              
+              <FormField
+                control={form.control}
+                name="validDate"
+                render={({ field }) => (
+                  <FormItem className="flex flex-col">
+                    <FormLabel>견적 유효일</FormLabel>
+                    <Popover>
+                      <PopoverTrigger asChild>
+                        <FormControl>
+                          <Button
+                            variant="outline"
+                            className={cn(
+                              "w-full pl-3 text-left font-normal",
+                              !field.value && "text-muted-foreground"
+                            )}
+                          >
+                            {field.value ? (
+                              formatDate(field.value, "KR")
+                            ) : (
+                              <span>견적 유효일을 선택하세요</span>
+                            )}
+                            <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
+                          </Button>
+                        </FormControl>
+                      </PopoverTrigger>
+                      <PopoverContent className="w-auto p-0" align="start">
+                        <Calendar
+                          mode="single"
+                          selected={field.value}
+                          onSelect={field.onChange}
+                          disabled={(date) =>
+                            date < new Date() || date < new Date("1900-01-01")
+                          }
+                          initialFocus
+                        />
+                      </PopoverContent>
+                    </Popover>
+                    <FormMessage />
+                  </FormItem>
+                )}
+              />
             </div>
 
-            {/* Incoterms 및 GTC */}
-            <div className="grid grid-cols-2 gap-4">
+            {/* Incoterms 선택 */}
             <FormField
               control={form.control}
-              name="vendorId"
+              name="incotermsCode"
               render={({ field }) => (
                 <FormItem className="flex flex-col">
-                  <FormLabel>Incoterms *</FormLabel>
+                  <FormLabel>Incoterms</FormLabel>
                   <Popover open={incotermsSearchOpen} onOpenChange={setIncotermsSearchOpen}>
                     <PopoverTrigger asChild>
                       <FormControl>
@@ -391,9 +437,8 @@ export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogPro
                         >
                           {selectedIncoterm ? (
                             <div className="flex items-center gap-2">
-                              <Building className="h-4 w-4" />
                               <span className="truncate">
-                                {selectedIncoterm.code} ({selectedIncoterm.description})
+                                {selectedIncoterm.code} - {selectedIncoterm.description}
                               </span>
                             </div>
                           ) : (
@@ -419,18 +464,20 @@ export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogPro
                                 key={incoterm.id}
                                 value={`${incoterm.code} ${incoterm.description}`}
                                 onSelect={() => {
-                                  field.onChange(vendor.id)
-                                  setVendorSearchOpen(false)
+                                  field.onChange(incoterm.code)
+                                  setIncotermsSearchOpen(false)
                                 }}
                               >
                                 <div className="flex items-center gap-2 w-full">
+                                  <div className="flex-1 min-w-0">
                                     <div className="font-medium truncate">
-                                      {incoterm.code}    {incoterm.description}
+                                      {incoterm.code} - {incoterm.description}
                                     </div>
+                                  </div>
                                   <Check
                                     className={cn(
                                       "ml-auto h-4 w-4",
-                                      incoterm.id === field.value ? "opacity-100" : "opacity-0"
+                                      incoterm.code === field.value ? "opacity-100" : "opacity-0"
                                     )}
                                   />
                                 </div>
@@ -445,34 +492,41 @@ export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogPro
                 </FormItem>
               )}
             />
-            </div>
 
-            {/* GTC 정보 */}
+            {/* 옵션 체크박스 */}
             <div className="grid grid-cols-2 gap-4">
               <FormField
                 control={form.control}
-                name="gtc"
+                name="cpRequestYn"
                 render={({ field }) => (
-                  <FormItem>
-                    <FormLabel>GTC</FormLabel>
+                  <FormItem className="flex flex-row items-start space-x-3 space-y-0">
                     <FormControl>
-                      <Input placeholder="GTC 정보" {...field} />
+                      <Checkbox
+                        checked={field.value}
+                        onCheckedChange={field.onChange}
+                      />
                     </FormControl>
-                    <FormMessage />
+                    <div className="space-y-1 leading-none ml-2">
+                      <FormLabel>CP 요청</FormLabel>
+                    </div>
                   </FormItem>
                 )}
               />
 
               <FormField
                 control={form.control}
-                name="gtcValidDate"
+                name="prjectGtcYn"
                 render={({ field }) => (
-                  <FormItem>
-                    <FormLabel>GTC 유효일</FormLabel>
+                  <FormItem className="flex flex-row items-start space-x-3 space-y-0">
                     <FormControl>
-                      <Input placeholder="GTC 유효일" {...field} />
+                      <Checkbox
+                        checked={field.value}
+                        onCheckedChange={field.onChange}
+                      />
                     </FormControl>
-                    <FormMessage />
+                    <div className="space-y-1 leading-none ml-2">
+                      <FormLabel>Project용 GTC 사용</FormLabel>
+                    </div>
                   </FormItem>
                 )}
               />
@@ -501,7 +555,7 @@ export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogPro
                   <FormItem>
                     <FormLabel>Spare part</FormLabel>
                     <FormControl>
-                      <Input placeholder="예비부품 정보" {...field} />
+                      <Input placeholder="O1, O2" {...field} />
                     </FormControl>
                     <FormMessage />
                   </FormItem>
@@ -509,8 +563,6 @@ export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogPro
               />
             </div>
 
-
-
             <DialogFooter>
               <Button
                 type="button"
@@ -529,6 +581,4 @@ export function AddInitialRfqDialog({ rfqId, onSuccess }: AddInitialRfqDialogPro
       </DialogContent>
     </Dialog>
   )
-}
-
-
+}
\ No newline at end of file
-- 
cgit v1.2.3

